source: issm/trunk/src/m/parameterization/setflowequation.m@ 16137

Last change on this file since 16137 was 16137, checked in by Mathieu Morlighem, 12 years ago

merged trunk-jpl and trunk for revision 16135

File size: 11.4 KB
RevLine 
[9664]1function md=setflowequation(md,varargin)
[1]2%SETELEMENTSTYPE - associate a solution type to each element
3%
4% This routine works like plotmodel: it works with an even number of inputs
[16137]5% 'SIA','SSA','L1L2','HO','FS' and 'fill' are the possible options
[1]6% that must be followed by the corresponding exp file or flags list
7% It can either be a domain file (argus type, .exp extension), or an array of element flags.
8% If user wants every element outside the domain to be
[16137]9% setflowequationd, add '~' to the name of the domain file (ex: '~HO.exp');
[1]10% an empty string '' will be considered as an empty domain
11% a string 'all' will be considered as the entire domain
[5379]12% You can specify the type of coupling, 'penalties' or 'tiling', to use with the input 'coupling'
[16137]13% NB: L1L2 cannot currently be coupled to any other ice flow model
[1]14%
15% Usage:
[9664]16% md=setflowequation(md,varargin)
[1]17%
18% Example:
[16137]19% md=setflowequation(md,'HO','HO.exp',fill','SIA','coupling','tiling');
[1]20
21%some checks on list of arguments
22if ((nargin<2) | (nargout~=1)),
[9664]23 error('setflowequation error message');
[1]24end
25
[13028]26%Process options
27options=pairoptions(varargin{:});
28options=deleteduplicates(options,1);
29
[5379]30%Find_out what kind of coupling to use
31coupling_method=getfieldvalue(options,'coupling','tiling');
32if (~strcmpi(coupling_method,'tiling') & ~strcmpi(coupling_method,'penalties')),
33 error('coupling type can only be: tiling or penalties');
34end
35
[13028]36%recover elements distribution
[16137]37SIAflag = FlagElements(md,getfieldvalue(options,'SIA',''));
38SSAflag = FlagElements(md,getfieldvalue(options,'SSA',''));
39HOflag = FlagElements(md,getfieldvalue(options,'HO',''));
40L1L2flag = FlagElements(md,getfieldvalue(options,'L1L2',''));
41FSflag = FlagElements(md,getfieldvalue(options,'FS',''));
42filltype = getfieldvalue(options,'fill','none');
43displayunused(options);
[1]44
[12888]45%Flag the elements that have not been flagged as filltype
[16137]46if strcmpi(filltype,'SIA'),
47 SIAflag(find(~(SSAflag | HOflag)))=1;
48elseif strcmpi(filltype,'SSA'),
49 SSAflag(find(~(SIAflag | HOflag | FSflag)))=1;
50elseif strcmpi(filltype,'HO'),
51 HOflag(find(~(SIAflag | SSAflag | FSflag)))=1;
[1]52end
53
54%check that each element has at least one flag
[16137]55if any(SIAflag+SSAflag+HOflag+L1L2flag+FSflag==0),
56 error('elements type not assigned, supported models are ''SIA'',''SSA'',''HO'' and ''FS''')
[1]57end
58
59%check that each element has only one flag
[16137]60if any(SIAflag+SSAflag+HOflag+L1L2flag+FSflag>1),
[9664]61 disp('setflowequation warning message: some elements have several types, higher order type is used for them')
[16137]62 SIAflag(find(SIAflag & SSAflag))=0;
63 SIAflag(find(SIAflag & HOflag))=0;
64 SSAflag(find(SSAflag & HOflag))=0;
[1]65end
66
[16137]67%check that L1L2 is not coupled to any other model for now
68if any(L1L2flag) & any(SIAflag | SSAflag | HOflag | FSflag)
69 error('L1L2 cannot be coupled to any other model');
[13048]70end
71
[16137]72%Check that no L1L2 or HO or FS for 2d mesh
[9719]73if (md.mesh.dimension==2),
[16137]74 if any(L1L2flag | FSflag | HOflag)
75 error('FS and HO elements not allowed in 2d mesh, extrude it first')
[1]76 end
77end
78
[16137]79%FS can only be used alone for now:
80if any(FSflag) &any(SIAflag),
81 error('FS cannot be used with any other model for now, put FS everywhere')
[5433]82end
[1]83
[11004]84%Initialize node fields
[16137]85nodeonSIA=zeros(md.mesh.numberofvertices,1);
86nodeonSIA(md.mesh.elements(find(SIAflag),:))=1;
87nodeonSSA=zeros(md.mesh.numberofvertices,1);
88nodeonSSA(md.mesh.elements(find(SSAflag),:))=1;
89nodeonHO=zeros(md.mesh.numberofvertices,1);
90nodeonHO(md.mesh.elements(find(HOflag),:))=1;
91nodeonL1L2=zeros(md.mesh.numberofvertices,1);
92nodeonL1L2(md.mesh.elements(find(L1L2flag),:))=1;
93nodeonFS=zeros(md.mesh.numberofvertices,1);
[11004]94noneflag=zeros(md.mesh.numberofelements,1);
[1]95
[16137]96%First modify FSflag to get rid of elements contrained everywhere (spc + border with HO or SSA)
97if any(FSflag),
98 fullspcnodes=double((~isnan(md.stressbalance.spcvx)+~isnan(md.stressbalance.spcvy)+~isnan(md.stressbalance.spcvz))==3 | (nodeonHO & nodeonFS)); %find all the nodes on the boundary of the domain without icefront
[9733]99 fullspcelems=double(sum(fullspcnodes(md.mesh.elements),2)==6); %find all the nodes on the boundary of the domain without icefront
[16137]100 FSflag(find(fullspcelems))=0;
101 nodeonFS(md.mesh.elements(find(FSflag),:))=1;
[5613]102end
[1]103
[16137]104%Then complete with NoneApproximation or the other model used if there is no FS
105if any(FSflag),
106 if any(HOflag), %fill with HO
107 HOflag(~FSflag)=1;
108 nodeonHO(md.mesh.elements(find(HOflag),:))=1;
109 elseif any(SSAflag), %fill with SSA
110 SSAflag(~FSflag)=1;
111 nodeonSSA(md.mesh.elements(find(SSAflag),:))=1;
[5613]112 else %fill with none
[16137]113 noneflag(find(~FSflag))=1;
[5613]114 end
[5433]115end
[1]116
[16137]117%Now take care of the coupling between SSA and HO
118md.stressbalance.vertex_pairing=[];
119nodeonSSAHO=zeros(md.mesh.numberofvertices,1);
120nodeonHOFS=zeros(md.mesh.numberofvertices,1);
121nodeonSSAFS=zeros(md.mesh.numberofvertices,1);
122SSAHOflag=zeros(md.mesh.numberofelements,1);
123SSAFSflag=zeros(md.mesh.numberofelements,1);
124HOFSflag=zeros(md.mesh.numberofelements,1);
[5379]125if strcmpi(coupling_method,'penalties'),
[16137]126 %Create the border nodes between HO and SSA and extrude them
[9725]127 numnodes2d=md.mesh.numberofvertices2d;
128 numlayers=md.mesh.numberoflayers;
[16137]129 bordernodes2d=find(nodeonHO(1:numnodes2d) & nodeonSSA(1:numnodes2d)); %Nodes connected to two different types of elements
[5379]130
131 %initialize and fill in penalties structure
[8298]132 if ~isnan(bordernodes2d),
[5379]133 penalties=[];
134 for i=1:numlayers-1,
[9725]135 penalties=[penalties; [bordernodes2d bordernodes2d+md.mesh.numberofvertices2d*(i)]];
[5379]136 end
[16137]137 md.stressbalance.vertex_pairing=penalties;
[5379]138 end
139elseif strcmpi(coupling_method,'tiling'),
[16137]140 if any(SSAflag) & any(HOflag), %coupling SSA HO
[8298]141 %Find node at the border
[16137]142 nodeonSSAHO(find(nodeonSSA & nodeonHO))=1;
143 %SSA elements in contact with this layer become SSAHO elements
144 matrixelements=ismember(md.mesh.elements,find(nodeonSSAHO));
[5613]145 commonelements=sum(matrixelements,2)~=0;
[16137]146 commonelements(find(HOflag))=0; %only one layer: the elements previously in SSA
147 SSAflag(find(commonelements))=0; %these elements are now SSAHOelements
148 SSAHOflag(find(commonelements))=1;
149 nodeonSSA(:)=0;
150 nodeonSSA(md.mesh.elements(find(SSAflag),:))=1;
[5379]151
[11003]152 %rule out elements that don't touch the 2 boundaries
[16137]153 pos=find(SSAHOflag);
[12959]154 elist=zeros(length(pos),1);
[16137]155 elist = elist + any(sum(nodeonSSA(md.mesh.elements(pos,:)),2),2);
156 elist = elist - any(sum(nodeonHO(md.mesh.elements(pos,:)) ,2),2);
[12959]157 pos1=find(elist==1);
[16137]158 SSAflag(pos(pos1))=1;
159 SSAHOflag(pos(pos1))=0;
[12959]160 pos2=find(elist==-1);
[16137]161 HOflag(pos(pos2))=1;
162 SSAHOflag(pos(pos2))=0;
[5379]163
[11004]164 %Recompute nodes associated to these elements
[16137]165 nodeonSSA(:)=0;
166 nodeonSSA(md.mesh.elements(find(SSAflag),:))=1;
167 nodeonHO(:)=0;
168 nodeonHO(md.mesh.elements(find(HOflag),:))=1;
169 nodeonSSAHO(:)=0;
170 nodeonSSAHO(md.mesh.elements(find(SSAHOflag),:))=1;
[11003]171
[16137]172 elseif any(HOflag) & any(FSflag), %coupling HO FS
[8298]173 %Find node at the border
[16137]174 nodeonHOFS(find(nodeonHO & nodeonFS))=1;
175 %FS elements in contact with this layer become HOFS elements
176 matrixelements=ismember(md.mesh.elements,find(nodeonHOFS));
[5613]177 commonelements=sum(matrixelements,2)~=0;
[16137]178 commonelements(find(HOflag))=0; %only one layer: the elements previously in SSA
179 FSflag(find(commonelements))=0; %these elements are now SSAHOelements
180 HOFSflag(find(commonelements))=1;
181 nodeonFS=zeros(md.mesh.numberofvertices,1);
182 nodeonFS(md.mesh.elements(find(FSflag),:))=1;
[5613]183
[11004]184 %rule out elements that don't touch the 2 boundaries
[16137]185 pos=find(HOFSflag);
[12959]186 elist=zeros(length(pos),1);
[16137]187 elist = elist + any(sum(nodeonFS(md.mesh.elements(pos,:)),2),2);
188 elist = elist - any(sum(nodeonHO(md.mesh.elements(pos,:)),2),2);
[12959]189 pos1=find(elist==1);
[16137]190 FSflag(pos(pos1))=1;
191 HOFSflag(pos(pos1))=0;
[12959]192 pos2=find(elist==-1);
[16137]193 HOflag(pos(pos2))=1;
194 HOFSflag(pos(pos2))=0;
[11004]195
196 %Recompute nodes associated to these elements
[16137]197 nodeonFS(:)=0;
198 nodeonFS(md.mesh.elements(find(FSflag),:))=1;
199 nodeonHO(:)=0;
200 nodeonHO(md.mesh.elements(find(HOflag),:))=1;
201 nodeonHOFS(:)=0;
202 nodeonHOFS(md.mesh.elements(find(HOFSflag),:))=1;
[11004]203
[16137]204 elseif any(FSflag) & any(SSAflag),
[8298]205 %Find node at the border
[16137]206 nodeonSSAFS(find(nodeonSSA & nodeonFS))=1;
207 %FS elements in contact with this layer become SSAFS elements
208 matrixelements=ismember(md.mesh.elements,find(nodeonSSAFS));
[6705]209 commonelements=sum(matrixelements,2)~=0;
[16137]210 commonelements(find(SSAflag))=0; %only one layer: the elements previously in SSA
211 FSflag(find(commonelements))=0; %these elements are now SSASSAelements
212 SSAFSflag(find(commonelements))=1;
213 nodeonFS=zeros(md.mesh.numberofvertices,1);
214 nodeonFS(md.mesh.elements(find(FSflag),:))=1;
[6705]215
[11004]216 %rule out elements that don't touch the 2 boundaries
[16137]217 pos=find(SSAFSflag);
[12959]218 elist=zeros(length(pos),1);
[16137]219 elist = elist + any(sum(nodeonSSA(md.mesh.elements(pos,:)),2),2);
220 elist = elist - any(sum(nodeonFS(md.mesh.elements(pos,:)) ,2),2);
[12959]221 pos1=find(elist==1);
[16137]222 SSAflag(pos(pos1))=1;
223 SSAFSflag(pos(pos1))=0;
[12959]224 pos2=find(elist==-1);
[16137]225 FSflag(pos(pos2))=1;
226 SSAFSflag(pos(pos2))=0;
[11004]227
228 %Recompute nodes associated to these elements
[16137]229 nodeonSSA(:)=0;
230 nodeonSSA(md.mesh.elements(find(SSAflag),:))=1;
231 nodeonFS(:)=0;
232 nodeonFS(md.mesh.elements(find(FSflag),:))=1;
233 nodeonSSAFS(:)=0;
234 nodeonSSAFS(md.mesh.elements(find(SSAFSflag),:))=1;
[11004]235
[16137]236 elseif any(FSflag) & any(SIAflag),
[5613]237 error('type of coupling not supported yet');
238 end
[5379]239end
240
[16137]241%Create MacaAyealHOApproximation where needed
[11003]242md.flowequation.element_equation=zeros(md.mesh.numberofelements,1);
243md.flowequation.element_equation(find(noneflag))=0;
[16137]244md.flowequation.element_equation(find(SIAflag))=1;
245md.flowequation.element_equation(find(SSAflag))=2;
246md.flowequation.element_equation(find(L1L2flag))=8;
247md.flowequation.element_equation(find(HOflag))=3;
248md.flowequation.element_equation(find(FSflag))=4;
249md.flowequation.element_equation(find(SSAHOflag))=5;
250md.flowequation.element_equation(find(SSAFSflag))=6;
251md.flowequation.element_equation(find(HOFSflag))=7;
[11003]252
253%border
[16137]254md.flowequation.borderHO=nodeonHO;
255md.flowequation.borderSSA=nodeonSSA;
256md.flowequation.borderFS=nodeonFS;
[11003]257
[5071]258%Create vertices_type
[9725]259md.flowequation.vertex_equation=zeros(md.mesh.numberofvertices,1);
[16137]260pos=find(nodeonSSA);
[9661]261md.flowequation.vertex_equation(pos)=2;
[16137]262pos=find(nodeonL1L2);
[13048]263md.flowequation.vertex_equation(pos)=8;
[16137]264pos=find(nodeonHO);
[9661]265md.flowequation.vertex_equation(pos)=3;
[16137]266pos=find(nodeonSIA);
[13058]267md.flowequation.vertex_equation(pos)=1;
[16137]268pos=find(nodeonSSAHO);
[9661]269md.flowequation.vertex_equation(pos)=5;
[16137]270pos=find(nodeonFS);
[9661]271md.flowequation.vertex_equation(pos)=4;
[16137]272if any(FSflag),
273 pos=find(~nodeonFS);
274 if(~any(HOflag) & ~any(SSAflag)),
[9661]275 md.flowequation.vertex_equation(pos)=0;
[5969]276 end
[5433]277end
[16137]278pos=find(nodeonHOFS);
[9661]279md.flowequation.vertex_equation(pos)=7;
[16137]280pos=find(nodeonSSAFS);
[9661]281md.flowequation.vertex_equation(pos)=6;
[5071]282
[202]283%figure out solution types
[16137]284md.flowequation.isSIA = double(any(md.flowequation.element_equation == 1));
285md.flowequation.isSSA = double(any(md.flowequation.element_equation == 2));
286md.flowequation.isHO = double(any(md.flowequation.element_equation == 3));
287md.flowequation.isL1L2 = double(any(md.flowequation.element_equation == 8));
288md.flowequation.isFS = double(any(md.flowequation.element_equation == 4));
[202]289
[11003]290return
291
292%Check that tiling can work:
[16137]293if any(md.flowequation.borderSSA) & any(md.flowequation.borderHO) & any(md.flowequation.borderHO + md.flowequation.borderSSA ~=1),
[11003]294 error('error coupling domain too irregular');
[1]295end
[16137]296if any(md.flowequation.borderSSA) & any(md.flowequation.borderFS) & any(md.flowequation.borderFS + md.flowequation.borderSSA ~=1),
[11003]297 error('error coupling domain too irregular');
298end
[16137]299if any(md.flowequation.borderFS) & any(md.flowequation.borderHO) & any(md.flowequation.borderHO + md.flowequation.borderFS~=1),
[11003]300 error('error coupling domain too irregular');
301end
Note: See TracBrowser for help on using the repository browser.