source: issm/trunk/src/m/model/modelextract.m@ 11237

Last change on this file since 11237 was 11237, checked in by Eric.Larour, 13 years ago

merged trunk-jpl and trunk for revision 11236

File size: 9.6 KB
Line 
1function md2=modelextract(md1,area)
2%modelextract - extract a model according to an Argus contour or flag list
3%
4% This routine extracts a submodel from a bigger model with respect to a given contour
5% md must be followed by the corresponding exp file or flags list
6% It can either be a domain file (argus type, .exp extension), or an array of element flags.
7% If user wants every element outside the domain to be
8% modelextract2d, add '~' to the name of the domain file (ex: '~Pattyn.exp');
9% an empty string '' will be considered as an empty domain
10% a string 'all' will be considered as the entire domain
11% add an argument 0 if you do not want the elements to be checked (faster)
12%
13% Usage:
14% md2=modelextract(md1,area);
15%
16% Examples:
17% md2=modelextract(md,'Domain.exp');
18% md2=modelextract(md,md.mask.elementonfloatingice);
19%
20% See also: EXTRUDE, COLLAPSE
21
22%some checks
23if ((nargin~=2) | (nargout~=1)),
24 help modelextract
25 error('modelextract error message: bad usage');
26end
27
28%get check option
29if (nargin==3 & varargin{1}==0),
30 checkoutline=0;
31else
32 checkoutline=1;
33end
34
35%get elements that are inside area
36flag_elem=FlagElements(md1,area);
37if ~any(flag_elem),
38 error('extracted model is empty');
39end
40
41%kick out all elements with 3 dirichlets
42spc_elem=find(~flag_elem);
43spc_node=sort(unique(md1.mesh.elements(spc_elem,:)));
44flag=ones(md1.mesh.numberofvertices,1);
45flag(spc_node)=0;
46pos=find(sum(flag(md1.mesh.elements),2)==0);
47flag_elem(pos)=0;
48
49%extracted elements and nodes lists
50pos_elem=find(flag_elem);
51pos_node=sort(unique(md1.mesh.elements(pos_elem,:)));
52
53%keep track of some fields
54numberofvertices1=md1.mesh.numberofvertices;
55numberofelements1=md1.mesh.numberofelements;
56numberofvertices2=length(pos_node);
57numberofelements2=length(pos_elem);
58flag_node=zeros(numberofvertices1,1);
59flag_node(pos_node)=1;
60
61%Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements)
62Pelem=zeros(numberofelements1,1);
63Pelem(pos_elem)=[1:numberofelements2]';
64Pnode=zeros(numberofvertices1,1);
65Pnode(pos_node)=[1:numberofvertices2]';
66
67%renumber the elements (some node won't exist anymore)
68elements_1=md1.mesh.elements;
69elements_2=elements_1(pos_elem,:);
70elements_2(:,1)=Pnode(elements_2(:,1));
71elements_2(:,2)=Pnode(elements_2(:,2));
72elements_2(:,3)=Pnode(elements_2(:,3));
73if md1.mesh.dimension==3,
74 elements_2(:,4)=Pnode(elements_2(:,4));
75 elements_2(:,5)=Pnode(elements_2(:,5));
76 elements_2(:,6)=Pnode(elements_2(:,6));
77end
78
79%OK, now create the new model !
80
81 %take every fields from model
82 md2=md1;
83
84 %automatically modify fields
85
86 %loop over model fields
87 model_fields=fields(md1);
88 for i=1:length(model_fields),
89 %get field
90 field=md1.(model_fields{i});
91 fieldsize=size(field);
92 if isobject(field), %recursive call
93 object_fields=fields(md1.(model_fields{i}));
94 for j=1:length(object_fields),
95 %get field
96 field=md1.(model_fields{i}).(object_fields{j});
97 fieldsize=size(field);
98 %size = number of nodes * n
99 if fieldsize(1)==numberofvertices1
100 md2.(model_fields{i}).(object_fields{j})=field(pos_node,:);
101 elseif (fieldsize(1)==numberofvertices1+1)
102 md2.(model_fields{i}).(object_fields{j})=[field(pos_node,:); field(end,:)];
103 %size = number of elements * n
104 elseif fieldsize(1)==numberofelements1
105 md2.(model_fields{i}).(object_fields{j})=field(pos_elem,:);
106 end
107 end
108 else
109 %size = number of nodes * n
110 if fieldsize(1)==numberofvertices1
111 md2.(model_fields{i})=field(pos_node,:);
112 elseif (fieldsize(1)==numberofvertices1+1)
113 md2.(model_fields{i})=[field(pos_node,:); field(end,:)];
114 %size = number of elements * n
115 elseif fieldsize(1)==numberofelements1
116 md2.(model_fields{i})=field(pos_elem,:);
117 end
118 end
119 end
120
121 %modify some specific fields
122
123 %Mesh
124 md2.mesh.numberofelements=numberofelements2;
125 md2.mesh.numberofvertices=numberofvertices2;
126 md2.mesh.elements=elements_2;
127
128 %mesh.uppervertex mesh.lowervertex
129 if md1.mesh.dimension==3
130 md2.mesh.uppervertex=md1.mesh.uppervertex(pos_node);
131 pos=find(~isnan(md2.mesh.uppervertex));
132 md2.mesh.uppervertex(pos)=Pnode(md2.mesh.uppervertex(pos));
133
134 md2.mesh.lowervertex=md1.mesh.lowervertex(pos_node);
135 pos=find(~isnan(md2.mesh.lowervertex));
136 md2.mesh.lowervertex(pos)=Pnode(md2.mesh.lowervertex(pos));
137
138 md2.mesh.upperelements=md1.mesh.upperelements(pos_elem);
139 pos=find(~isnan(md2.mesh.upperelements));
140 md2.mesh.upperelements(pos)=Pelem(md2.mesh.upperelements(pos));
141
142 md2.mesh.lowerelements=md1.mesh.lowerelements(pos_elem);
143 pos=find(~isnan(md2.mesh.lowerelements));
144 md2.mesh.lowerelements(pos)=Pelem(md2.mesh.lowerelements(pos));
145 end
146
147 %Initial 2d mesh
148 if md1.mesh.dimension==3
149 flag_elem_2d=flag_elem(1:md1.mesh.numberofelements2d);
150 pos_elem_2d=find(flag_elem_2d);
151 flag_node_2d=flag_node(1:md1.mesh.numberofvertices2d);
152 pos_node_2d=find(flag_node_2d);
153
154 md2.mesh.numberofelements2d=length(pos_elem_2d);
155 md2.mesh.numberofvertices2d=length(pos_node_2d);
156 md2.mesh.elements2d=md1.mesh.elements2d(pos_elem_2d,:);
157 md2.mesh.elements2d(:,1)=Pnode(md2.mesh.elements2d(:,1));
158 md2.mesh.elements2d(:,2)=Pnode(md2.mesh.elements2d(:,2));
159 md2.mesh.elements2d(:,3)=Pnode(md2.mesh.elements2d(:,3));
160
161 md2.mesh.x2d=md1.mesh.x(pos_node_2d);
162 md2.mesh.y2d=md1.mesh.y(pos_node_2d);
163 end
164
165 %Edges
166 if size(md2.mesh.edges,2)>1, %do not use ~isnan because there are some NaNs...
167 %renumber first two columns
168 pos=find(~isnan(md2.mesh.edges(:,4)));
169 md2.mesh.edges(: ,1)=Pnode(md2.mesh.edges(:,1));
170 md2.mesh.edges(: ,2)=Pnode(md2.mesh.edges(:,2));
171 md2.mesh.edges(: ,3)=Pelem(md2.mesh.edges(:,3));
172 md2.mesh.edges(pos,4)=Pelem(md2.mesh.edges(pos,4));
173 %remove edges when the 2 vertices are not in the domain.
174 md2.mesh.edges=md2.mesh.edges(find(md2.mesh.edges(:,1) & md2.mesh.edges(:,2)),:);
175 %Replace all zeros by NaN in the last two columns;
176 pos=find(md2.mesh.edges(:,3)==0);
177 md2.mesh.edges(pos,3)=NaN;
178 pos=find(md2.mesh.edges(:,4)==0);
179 md2.mesh.edges(pos,4)=NaN;
180 %Invert NaN of the third column with last column (Also invert first two columns!!)
181 pos=find(isnan(md2.mesh.edges(:,3)));
182 md2.mesh.edges(pos,3)=md2.mesh.edges(pos,4);
183 md2.mesh.edges(pos,4)=NaN;
184 values=md2.mesh.edges(pos,2);
185 md2.mesh.edges(pos,2)=md2.mesh.edges(pos,1);
186 md2.mesh.edges(pos,1)=values;
187 %Finally remove edges that do not belong to any element
188 pos=find(isnan(md2.mesh.edges(:,3)) & isnan(md2.mesh.edges(:,4)));
189 md2.mesh.edges(pos,:)=[];
190 end
191
192 %Penalties
193 if ~isnan(md2.diagnostic.vertex_pairing),
194 for i=1:size(md1.diagnostic.vertex_pairing,1);
195 md2.diagnostic.vertex_pairing(i,:)=Pnode(md1.diagnostic.vertex_pairing(i,:));
196 end
197 md2.diagnostic.vertex_pairing=md2.diagnostic.vertex_pairing(find(md2.diagnostic.vertex_pairing(:,1)),:);
198 end
199 if ~isnan(md2.prognostic.vertex_pairing),
200 for i=1:size(md1.prognostic.vertex_pairing,1);
201 md2.prognostic.vertex_pairing(i,:)=Pnode(md1.prognostic.vertex_pairing(i,:));
202 end
203 md2.prognostic.vertex_pairing=md2.prognostic.vertex_pairing(find(md2.prognostic.vertex_pairing(:,1)),:);
204 end
205
206 %recreate segments
207 if md1.mesh.dimension==2
208 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices);
209 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity);
210 md2.mesh.segments=contourenvelope(md2);
211 md2.mesh.vertexonboundary=zeros(numberofvertices2,1); md2.mesh.vertexonboundary(md2.mesh.segments(:,1:2))=1;
212 end
213
214 %Boundary conditions: Dirichlets on new boundary
215 %Catch the elements that have not been extracted
216 orphans_elem=find(~flag_elem);
217 orphans_node=unique(md1.mesh.elements(orphans_elem,:))';
218 %Figure out which node are on the boundary between md2 and md1
219 nodestoflag1=intersect(orphans_node,pos_node);
220 nodestoflag2=Pnode(nodestoflag1);
221 if numel(md1.diagnostic.spcvx)>1 & numel(md1.diagnostic.spcvy)>2 & numel(md1.diagnostic.spcvz)>2,
222 if numel(md1.inversion.vx_obs)>1 & numel(md1.inversion.vy_obs)>1
223 md2.diagnostic.spcvx(nodestoflag2)=md2.inversion.vx_obs(nodestoflag2);
224 md2.diagnostic.spcvy(nodestoflag2)=md2.inversion.vy_obs(nodestoflag2);
225 else
226 md2.diagnostic.spcvx(nodestoflag2)=NaN;
227 md2.diagnostic.spcvy(nodestoflag2)=NaN;
228 disp(' ')
229 disp('!! modelextract warning: spc values should be checked !!')
230 disp(' ')
231 end
232 %put 0 for vz
233 md2.diagnostic.spcvz(nodestoflag2)=0;
234 end
235 if ~isnan(md1.thermal.spctemperature),
236 md2.thermal.spctemperature(nodestoflag2,1)=1;
237 end
238
239 %Diagnostic
240 if ~isnan(md2.diagnostic.icefront)
241 md2.diagnostic.icefront(:,1)=Pnode(md1.diagnostic.icefront(:,1));
242 md2.diagnostic.icefront(:,2)=Pnode(md1.diagnostic.icefront(:,2));
243 md2.diagnostic.icefront(:,end-1)=Pelem(md1.diagnostic.icefront(:,end-1));
244 if md1.mesh.dimension==3
245 md2.diagnostic.icefront(:,3)=Pnode(md1.diagnostic.icefront(:,3));
246 md2.diagnostic.icefront(:,4)=Pnode(md1.diagnostic.icefront(:,4));
247 end
248 md2.diagnostic.icefront=md2.diagnostic.icefront(find(md2.diagnostic.icefront(:,1) & md2.diagnostic.icefront(:,2) & md2.diagnostic.icefront(:,end)),:);
249 end
250
251 %Results fields
252 if isstruct(md1.results),
253 md2.results=struct();
254 solutionfields=fields(md1.results);
255 for i=1:length(solutionfields),
256 %get subfields
257 solutionsubfields=fields(md1.results.(solutionfields{i}));
258 for j=1:length(solutionsubfields),
259 field=md1.results.(solutionfields{i}).(solutionsubfields{j});
260 if length(field)==numberofvertices1,
261 md2.results.(solutionfields{i}).(solutionsubfields{j})=field(pos_node);
262 elseif length(field)==numberofelements1,
263 md2.results.(solutionfields{i}).(solutionsubfields{j})=field(pos_elem);
264 else
265 md2.results.(solutionfields{i}).(solutionsubfields{j})=field;
266 end
267 end
268 end
269 end
270
271%Keep track of pos_node and pos_elem
272md2.mesh.extractedvertices=pos_node;
273md2.mesh.extractedelements=pos_elem;
Note: See TracBrowser for help on using the repository browser.