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

Last change on this file since 9532 was 9532, checked in by Mathieu Morlighem, 14 years ago

removed verticestype2d and elementstype2d
elementstype and verticestype are not enums anymore

File size: 7.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.elementoniceshelf);
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
87 %get field
88 field=md1.(model_fields{i});
89 fieldsize=size(field);
90
91 %size = number of nodes * n
92 if fieldsize(1)==numberofnodes1
93 md2.(model_fields{i})=field(pos_node,:);
94
95 %size = number of elements * n
96 elseif fieldsize(1)==numberofelements1
97 md2.(model_fields{i})=field(pos_elem,:);
98 end
99 end
100
101 %modify some specific fields
102
103 %Mesh
104 md2.numberofelements=numberofelements2;
105 md2.numberofnodes=numberofnodes2;
106 md2.elements=elements_2;
107
108 %uppernodes lowernodes
109 if md1.dim==3
110 md2.uppernodes=md1.uppernodes(pos_node);
111 pos=find(~isnan(md2.uppernodes));
112 md2.uppernodes(pos)=Pnode(md2.uppernodes(pos));
113
114 md2.lowernodes=md1.lowernodes(pos_node);
115 pos=find(~isnan(md2.lowernodes));
116 md2.lowernodes(pos)=Pnode(md2.lowernodes(pos));
117
118 md2.upperelements=md1.upperelements(pos_elem);
119 pos=find(~isnan(md2.upperelements));
120 md2.upperelements(pos)=Pelem(md2.upperelements(pos));
121
122 md2.lowerelements=md1.lowerelements(pos_elem);
123 pos=find(~isnan(md2.lowerelements));
124 md2.lowerelements(pos)=Pelem(md2.lowerelements(pos));
125 end
126
127 %Initial 2d mesh
128 if md1.dim==3
129 flag_elem_2d=flag_elem(1:md1.numberofelements2d);
130 pos_elem_2d=find(flag_elem_2d);
131 flag_node_2d=flag_node(1:md1.numberofnodes2d);
132 pos_node_2d=find(flag_node_2d);
133
134 md2.numberofelements2d=length(pos_elem_2d);
135 md2.numberofnodes2d=length(pos_node_2d);
136 md2.elements2d=md1.elements2d(pos_elem_2d,:);
137 md2.elements2d(:,1)=Pnode(md2.elements2d(:,1));
138 md2.elements2d(:,2)=Pnode(md2.elements2d(:,2));
139 md2.elements2d(:,3)=Pnode(md2.elements2d(:,3));
140
141 md2.x2d=md1.x(pos_node_2d);
142 md2.y2d=md1.y(pos_node_2d);
143 end
144
145 %Edges
146 if size(md2.edges,2)>1, %do not use ~isnan because there are some NaNs...
147 %renumber first two columns
148 pos=find(~isnan(md2.edges(:,4)));
149 md2.edges(: ,1)=Pnode(md2.edges(:,1));
150 md2.edges(: ,2)=Pnode(md2.edges(:,2));
151 md2.edges(: ,3)=Pelem(md2.edges(:,3));
152 md2.edges(pos,4)=Pelem(md2.edges(pos,4));
153 %remove edges when the 2 vertices are not in the domain.
154 md2.edges=md2.edges(find(md2.edges(:,1) & md2.edges(:,2)),:);
155 %Replace all zeros by NaN in the last two columns;
156 pos=find(md2.edges(:,3)==0);
157 md2.edges(pos,3)=NaN;
158 pos=find(md2.edges(:,4)==0);
159 md2.edges(pos,4)=NaN;
160 %Invert NaN of the third column with last column (Also invert first two columns!!)
161 pos=find(isnan(md2.edges(:,3)));
162 md2.edges(pos,3)=md2.edges(pos,4);
163 md2.edges(pos,4)=NaN;
164 values=md2.edges(pos,2);
165 md2.edges(pos,2)=md2.edges(pos,1);
166 md2.edges(pos,1)=values;
167 %Finally remove edges that do not belong to any element
168 pos=find(isnan(md2.edges(:,3)) & isnan(md2.edges(:,4)));
169 md2.edges(pos,:)=[];
170 end
171
172 %Penalties
173 if ~isnan(md2.penalties),
174 for i=1:size(md1.penalties,1);
175 md2.penalties(i,:)=Pnode(md1.penalties(i,:));
176 end
177 md2.penalties=md2.penalties(find(md2.penalties(:,1)),:);
178 end
179
180 %recreate segments
181 if md1.dim==2
182 md2.nodeconnectivity=NodeConnectivity(md2.elements,md2.numberofnodes);
183 md2.elementconnectivity=ElementConnectivity(md2.elements,md2.nodeconnectivity);
184 md2.segments=contourenvelope(md2);
185 md2.nodeonboundary=zeros(numberofnodes2,1); md2.nodeonboundary(md2.segments(:,1:2))=1;
186 end
187
188 %Boundary conditions: Dirichlets on new boundary
189 %Catch the elements that have not been extracted
190 orphans_elem=find(~flag_elem);
191 orphans_node=unique(md1.elements(orphans_elem,:))';
192 %Figure out which node are on the boundary between md2 and md1
193 nodestoflag1=intersect(orphans_node,pos_node);
194 nodestoflag2=Pnode(nodestoflag1);
195 if numel(md1.spcvx)>1 & numel(md1.spcvy)>2 & numel(md1.spcvz)>2,
196 if numel(md1.vx_obs)>1 & numel(md1.vy_obs)>1
197 md2.spcvx(nodestoflag2)=md2.vx_obs(nodestoflag2);
198 md2.spcvy(nodestoflag2)=md2.vy_obs(nodestoflag2);
199 else
200 md2.spcvx(nodestoflag2)=NaN;
201 md2.spcvy(nodestoflag2)=NaN;
202 disp(' ')
203 disp('!! modelextract warning: spc values should be checked !!')
204 disp(' ')
205 end
206 %put 0 for vz
207 md2.spcvz(nodestoflag2)=0;
208 end
209 if ~isnan(md1.spctemperature),
210 md2.spctemperature(nodestoflag2,1)=1;
211 end
212
213 %Diagnostic
214 if ~isnan(md2.pressureload)
215 md2.pressureload(:,1)=Pnode(md1.pressureload(:,1));
216 md2.pressureload(:,2)=Pnode(md1.pressureload(:,2));
217 md2.pressureload(:,end-1)=Pelem(md1.pressureload(:,end-1));
218 if md1.dim==3
219 md2.pressureload(:,3)=Pnode(md1.pressureload(:,3));
220 md2.pressureload(:,4)=Pnode(md1.pressureload(:,4));
221 end
222 md2.pressureload=md2.pressureload(find(md2.pressureload(:,1) & md2.pressureload(:,2) & md2.pressureload(:,end)),:);
223 end
224
225 %Results fields
226 if isstruct(md1.results),
227 md2.results=struct();
228 solutionfields=fields(md1.results);
229 for i=1:length(solutionfields),
230 %get subfields
231 solutionsubfields=fields(md1.results.(solutionfields(i)));
232 for j=1:length(solutionsubfields),
233 field=md1.results.(solutionfields(i)).(solutionsubfields(j));
234 if length(field)==numberofnodes1,
235 md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_node);
236 elseif length(field)==numberofelements1,
237 md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_elem);
238 else
239 md2.results.(solutionfields(i)).(solutionsubfields(j))=field;
240 end
241 end
242 end
243 end
244
245%Keep track of pos_node and pos_elem
246md2.extractednodes=pos_node;
247md2.extractedelements=pos_elem;
Note: See TracBrowser for help on using the repository browser.