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

Last change on this file since 9641 was 9641, checked in by Mathieu Morlighem, 13 years ago

Added mask object

File size: 8.3 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%first
36flag_elem=FlagElements(md1,area);
37
38%kick out all elements with 3 dirichlets
39spc_elem=find(~flag_elem);
40spc_node=sort(unique(md1.elements(spc_elem,:)));
41flag=ones(md1.numberofnodes,1);
42flag(spc_node)=0;
43pos=find(sum(flag(md1.elements),2)==0);
44flag_elem(pos)=0;
45
46%extracted elements and nodes lists
47pos_elem=find(flag_elem);
48pos_node=sort(unique(md1.elements(pos_elem,:)));
49
50%keep track of some fields
51numberofnodes1=md1.numberofnodes;
52numberofelements1=md1.numberofelements;
53numberofnodes2=length(pos_node);
54numberofelements2=length(pos_elem);
55flag_node=zeros(numberofnodes1,1);
56flag_node(pos_node)=1;
57
58%Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements)
59Pelem=zeros(numberofelements1,1);
60Pelem(pos_elem)=[1:numberofelements2]';
61Pnode=zeros(numberofnodes1,1);
62Pnode(pos_node)=[1:numberofnodes2]';
63
64%renumber the elements (some node won't exist anymore)
65elements_1=md1.elements;
66elements_2=elements_1(pos_elem,:);
67elements_2(:,1)=Pnode(elements_2(:,1));
68elements_2(:,2)=Pnode(elements_2(:,2));
69elements_2(:,3)=Pnode(elements_2(:,3));
70if md1.dim==3,
71 elements_2(:,4)=Pnode(elements_2(:,4));
72 elements_2(:,5)=Pnode(elements_2(:,5));
73 elements_2(:,6)=Pnode(elements_2(:,6));
74end
75
76%OK, now create the new model !
77
78 %take every fields from model
79 md2=md1;
80
81 %automatically modify fields
82
83 %loop over model fields
84 model_fields=fields(md1);
85 for i=1:length(model_fields),
86 %get field
87 field=md1.(model_fields{i});
88 fieldsize=size(field);
89 if isobject(field), %recursive call
90 object_fields=fields(md1.(model_fields{i}));
91 for j=1:length(object_fields),
92 %get field
93 field=md1.(model_fields{i}).(object_fields{j});
94 fieldsize=size(field);
95 %size = number of nodes * n
96 if fieldsize(1)==numberofnodes1
97 md2.(model_fields{i}).(object_fields{j})=field(pos_node,:);
98 elseif (fieldsize(1)==numberofnodes1+1)
99 md2.(model_fields(i)).(object_fields{j})=[field(pos_node,:); field(end,:)];
100 %size = number of elements * n
101 elseif fieldsize(1)==numberofelements1
102 md2.(model_fields{i}).(object_fields{j})=field(pos_elem,:);
103 end
104 end
105 else
106 %size = number of nodes * n
107 if fieldsize(1)==numberofnodes1
108 md2.(model_fields{i})=field(pos_node,:);
109 elseif (fieldsize(1)==numberofnodes1+1)
110 md2.(model_fields(i))=[field(pos_node,:); field(end,:)];
111 %size = number of elements * n
112 elseif fieldsize(1)==numberofelements1
113 md2.(model_fields{i})=field(pos_elem,:);
114 end
115 end
116 end
117
118 %modify some specific fields
119
120 %Mesh
121 md2.numberofelements=numberofelements2;
122 md2.numberofnodes=numberofnodes2;
123 md2.elements=elements_2;
124
125 %uppernodes lowernodes
126 if md1.dim==3
127 md2.uppernodes=md1.uppernodes(pos_node);
128 pos=find(~isnan(md2.uppernodes));
129 md2.uppernodes(pos)=Pnode(md2.uppernodes(pos));
130
131 md2.lowernodes=md1.lowernodes(pos_node);
132 pos=find(~isnan(md2.lowernodes));
133 md2.lowernodes(pos)=Pnode(md2.lowernodes(pos));
134
135 md2.upperelements=md1.upperelements(pos_elem);
136 pos=find(~isnan(md2.upperelements));
137 md2.upperelements(pos)=Pelem(md2.upperelements(pos));
138
139 md2.lowerelements=md1.lowerelements(pos_elem);
140 pos=find(~isnan(md2.lowerelements));
141 md2.lowerelements(pos)=Pelem(md2.lowerelements(pos));
142 end
143
144 %Initial 2d mesh
145 if md1.dim==3
146 flag_elem_2d=flag_elem(1:md1.numberofelements2d);
147 pos_elem_2d=find(flag_elem_2d);
148 flag_node_2d=flag_node(1:md1.numberofnodes2d);
149 pos_node_2d=find(flag_node_2d);
150
151 md2.numberofelements2d=length(pos_elem_2d);
152 md2.numberofnodes2d=length(pos_node_2d);
153 md2.elements2d=md1.elements2d(pos_elem_2d,:);
154 md2.elements2d(:,1)=Pnode(md2.elements2d(:,1));
155 md2.elements2d(:,2)=Pnode(md2.elements2d(:,2));
156 md2.elements2d(:,3)=Pnode(md2.elements2d(:,3));
157
158 md2.x2d=md1.x(pos_node_2d);
159 md2.y2d=md1.y(pos_node_2d);
160 end
161
162 %Edges
163 if size(md2.edges,2)>1, %do not use ~isnan because there are some NaNs...
164 %renumber first two columns
165 pos=find(~isnan(md2.edges(:,4)));
166 md2.edges(: ,1)=Pnode(md2.edges(:,1));
167 md2.edges(: ,2)=Pnode(md2.edges(:,2));
168 md2.edges(: ,3)=Pelem(md2.edges(:,3));
169 md2.edges(pos,4)=Pelem(md2.edges(pos,4));
170 %remove edges when the 2 vertices are not in the domain.
171 md2.edges=md2.edges(find(md2.edges(:,1) & md2.edges(:,2)),:);
172 %Replace all zeros by NaN in the last two columns;
173 pos=find(md2.edges(:,3)==0);
174 md2.edges(pos,3)=NaN;
175 pos=find(md2.edges(:,4)==0);
176 md2.edges(pos,4)=NaN;
177 %Invert NaN of the third column with last column (Also invert first two columns!!)
178 pos=find(isnan(md2.edges(:,3)));
179 md2.edges(pos,3)=md2.edges(pos,4);
180 md2.edges(pos,4)=NaN;
181 values=md2.edges(pos,2);
182 md2.edges(pos,2)=md2.edges(pos,1);
183 md2.edges(pos,1)=values;
184 %Finally remove edges that do not belong to any element
185 pos=find(isnan(md2.edges(:,3)) & isnan(md2.edges(:,4)));
186 md2.edges(pos,:)=[];
187 end
188
189 %Penalties
190 if ~isnan(md2.penalties),
191 for i=1:size(md1.penalties,1);
192 md2.penalties(i,:)=Pnode(md1.penalties(i,:));
193 end
194 md2.penalties=md2.penalties(find(md2.penalties(:,1)),:);
195 end
196
197 %recreate segments
198 if md1.dim==2
199 md2.nodeconnectivity=NodeConnectivity(md2.elements,md2.numberofnodes);
200 md2.elementconnectivity=ElementConnectivity(md2.elements,md2.nodeconnectivity);
201 md2.segments=contourenvelope(md2);
202 md2.nodeonboundary=zeros(numberofnodes2,1); md2.nodeonboundary(md2.segments(:,1:2))=1;
203 end
204
205 %Boundary conditions: Dirichlets on new boundary
206 %Catch the elements that have not been extracted
207 orphans_elem=find(~flag_elem);
208 orphans_node=unique(md1.elements(orphans_elem,:))';
209 %Figure out which node are on the boundary between md2 and md1
210 nodestoflag1=intersect(orphans_node,pos_node);
211 nodestoflag2=Pnode(nodestoflag1);
212 if numel(md1.spcvx)>1 & numel(md1.spcvy)>2 & numel(md1.spcvz)>2,
213 if numel(md1.vx_obs)>1 & numel(md1.vy_obs)>1
214 md2.spcvx(nodestoflag2)=md2.vx_obs(nodestoflag2);
215 md2.spcvy(nodestoflag2)=md2.vy_obs(nodestoflag2);
216 else
217 md2.spcvx(nodestoflag2)=NaN;
218 md2.spcvy(nodestoflag2)=NaN;
219 disp(' ')
220 disp('!! modelextract warning: spc values should be checked !!')
221 disp(' ')
222 end
223 %put 0 for vz
224 md2.spcvz(nodestoflag2)=0;
225 end
226 if ~isnan(md1.thermal.spctemperature),
227 md2.thermal.spctemperature(nodestoflag2,1)=1;
228 end
229
230 %Diagnostic
231 if ~isnan(md2.pressureload)
232 md2.pressureload(:,1)=Pnode(md1.pressureload(:,1));
233 md2.pressureload(:,2)=Pnode(md1.pressureload(:,2));
234 md2.pressureload(:,end-1)=Pelem(md1.pressureload(:,end-1));
235 if md1.dim==3
236 md2.pressureload(:,3)=Pnode(md1.pressureload(:,3));
237 md2.pressureload(:,4)=Pnode(md1.pressureload(:,4));
238 end
239 md2.pressureload=md2.pressureload(find(md2.pressureload(:,1) & md2.pressureload(:,2) & md2.pressureload(:,end)),:);
240 end
241
242 %Results fields
243 if isstruct(md1.results),
244 md2.results=struct();
245 solutionfields=fields(md1.results);
246 for i=1:length(solutionfields),
247 %get subfields
248 solutionsubfields=fields(md1.results.(solutionfields(i)));
249 for j=1:length(solutionsubfields),
250 field=md1.results.(solutionfields(i)).(solutionsubfields(j));
251 if length(field)==numberofnodes1,
252 md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_node);
253 elseif length(field)==numberofelements1,
254 md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_elem);
255 else
256 md2.results.(solutionfields(i)).(solutionsubfields(j))=field;
257 end
258 end
259 end
260 end
261
262%Keep track of pos_node and pos_elem
263md2.extractednodes=pos_node;
264md2.extractedelements=pos_elem;
Note: See TracBrowser for help on using the repository browser.