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
RevLine 
[1495]1function md2=modelextract(md1,area)
2%modelextract - extract a model according to an Argus contour or flag list
[1348]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:
[1495]14% md2=modelextract(md1,area);
[1348]15%
16% Examples:
[1495]17% md2=modelextract(md,'Domain.exp');
[9641]18% md2=modelextract(md,md.mask.elementonfloatingice);
[1348]19%
20% See also: EXTRUDE, COLLAPSE
21
22%some checks
[1368]23if ((nargin~=2) | (nargout~=1)),
[3589]24 help modelextract
25 error('modelextract error message: bad usage');
[1348]26end
27
28%get check option
29if (nargin==3 & varargin{1}==0),
30 checkoutline=0;
31else
32 checkoutline=1;
33end
34
[11237]35%get elements that are inside area
[2988]36flag_elem=FlagElements(md1,area);
[11237]37if ~any(flag_elem),
38 error('extracted model is empty');
39end
[1348]40
[1361]41%kick out all elements with 3 dirichlets
42spc_elem=find(~flag_elem);
[9733]43spc_node=sort(unique(md1.mesh.elements(spc_elem,:)));
[9736]44flag=ones(md1.mesh.numberofvertices,1);
[8298]45flag(spc_node)=0;
[9733]46pos=find(sum(flag(md1.mesh.elements),2)==0);
[1361]47flag_elem(pos)=0;
48
49%extracted elements and nodes lists
[1348]50pos_elem=find(flag_elem);
[9733]51pos_node=sort(unique(md1.mesh.elements(pos_elem,:)));
[1348]52
53%keep track of some fields
[9736]54numberofvertices1=md1.mesh.numberofvertices;
55numberofelements1=md1.mesh.numberofelements;
56numberofvertices2=length(pos_node);
[1348]57numberofelements2=length(pos_elem);
[9736]58flag_node=zeros(numberofvertices1,1);
[8298]59flag_node(pos_node)=1;
[1348]60
[8298]61%Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements)
[1348]62Pelem=zeros(numberofelements1,1);
63Pelem(pos_elem)=[1:numberofelements2]';
[9736]64Pnode=zeros(numberofvertices1,1);
65Pnode(pos_node)=[1:numberofvertices2]';
[1348]66
[8298]67%renumber the elements (some node won't exist anymore)
[9733]68elements_1=md1.mesh.elements;
[1348]69elements_2=elements_1(pos_elem,:);
[8298]70elements_2(:,1)=Pnode(elements_2(:,1));
71elements_2(:,2)=Pnode(elements_2(:,2));
72elements_2(:,3)=Pnode(elements_2(:,3));
[9736]73if md1.mesh.dimension==3,
[8298]74 elements_2(:,4)=Pnode(elements_2(:,4));
75 elements_2(:,5)=Pnode(elements_2(:,5));
76 elements_2(:,6)=Pnode(elements_2(:,6));
[1348]77end
78
79%OK, now create the new model !
80
81 %take every fields from model
82 md2=md1;
83
[1361]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
[9436]90 field=md1.(model_fields{i});
[1361]91 fieldsize=size(field);
[9641]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
[9736]99 if fieldsize(1)==numberofvertices1
[9641]100 md2.(model_fields{i}).(object_fields{j})=field(pos_node,:);
[9736]101 elseif (fieldsize(1)==numberofvertices1+1)
[10093]102 md2.(model_fields{i}).(object_fields{j})=[field(pos_node,:); field(end,:)];
[9641]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
[9736]110 if fieldsize(1)==numberofvertices1
[9641]111 md2.(model_fields{i})=field(pos_node,:);
[9736]112 elseif (fieldsize(1)==numberofvertices1+1)
[10093]113 md2.(model_fields{i})=[field(pos_node,:); field(end,:)];
[9641]114 %size = number of elements * n
115 elseif fieldsize(1)==numberofelements1
116 md2.(model_fields{i})=field(pos_elem,:);
117 end
[1361]118 end
119 end
120
[1348]121 %modify some specific fields
122
123 %Mesh
[9736]124 md2.mesh.numberofelements=numberofelements2;
125 md2.mesh.numberofvertices=numberofvertices2;
[9733]126 md2.mesh.elements=elements_2;
[1348]127
[9729]128 %mesh.uppervertex mesh.lowervertex
[9736]129 if md1.mesh.dimension==3
[9729]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));
[1368]133
[9729]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));
[4690]137
[9728]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));
[4690]141
[9728]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));
[1368]145 end
146
[1348]147 %Initial 2d mesh
[9736]148 if md1.mesh.dimension==3
149 flag_elem_2d=flag_elem(1:md1.mesh.numberofelements2d);
[1348]150 pos_elem_2d=find(flag_elem_2d);
[9736]151 flag_node_2d=flag_node(1:md1.mesh.numberofvertices2d);
[8298]152 pos_node_2d=find(flag_node_2d);
[1348]153
[9736]154 md2.mesh.numberofelements2d=length(pos_elem_2d);
155 md2.mesh.numberofvertices2d=length(pos_node_2d);
[9731]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));
[1348]160
[9736]161 md2.mesh.x2d=md1.mesh.x(pos_node_2d);
162 md2.mesh.y2d=md1.mesh.y(pos_node_2d);
[1348]163 end
164
[3583]165 %Edges
[9733]166 if size(md2.mesh.edges,2)>1, %do not use ~isnan because there are some NaNs...
[3583]167 %renumber first two columns
[9733]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));
[5442]173 %remove edges when the 2 vertices are not in the domain.
[9733]174 md2.mesh.edges=md2.mesh.edges(find(md2.mesh.edges(:,1) & md2.mesh.edges(:,2)),:);
[5442]175 %Replace all zeros by NaN in the last two columns;
[9733]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;
[5451]180 %Invert NaN of the third column with last column (Also invert first two columns!!)
[9733]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;
[5442]187 %Finally remove edges that do not belong to any element
[9733]188 pos=find(isnan(md2.mesh.edges(:,3)) & isnan(md2.mesh.edges(:,4)));
189 md2.mesh.edges(pos,:)=[];
[3583]190 end
191
[1348]192 %Penalties
[9694]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,:));
[1348]196 end
[9694]197 md2.diagnostic.vertex_pairing=md2.diagnostic.vertex_pairing(find(md2.diagnostic.vertex_pairing(:,1)),:);
[1348]198 end
[9642]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
[1348]205
206 %recreate segments
[9736]207 if md1.mesh.dimension==2
208 md2.mesh.vertexconnectivity=NodeConnectivity(md2.mesh.elements,md2.mesh.numberofvertices);
[9733]209 md2.mesh.elementconnectivity=ElementConnectivity(md2.mesh.elements,md2.mesh.vertexconnectivity);
[9736]210 md2.mesh.segments=contourenvelope(md2);
211 md2.mesh.vertexonboundary=zeros(numberofvertices2,1); md2.mesh.vertexonboundary(md2.mesh.segments(:,1:2))=1;
[1368]212 end
[1348]213
[1361]214 %Boundary conditions: Dirichlets on new boundary
[1348]215 %Catch the elements that have not been extracted
216 orphans_elem=find(~flag_elem);
[9733]217 orphans_node=unique(md1.mesh.elements(orphans_elem,:))';
[8298]218 %Figure out which node are on the boundary between md2 and md1
219 nodestoflag1=intersect(orphans_node,pos_node);
220 nodestoflag2=Pnode(nodestoflag1);
[9679]221 if numel(md1.diagnostic.spcvx)>1 & numel(md1.diagnostic.spcvy)>2 & numel(md1.diagnostic.spcvz)>2,
[9694]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);
[1361]225 else
[9679]226 md2.diagnostic.spcvx(nodestoflag2)=NaN;
227 md2.diagnostic.spcvy(nodestoflag2)=NaN;
[1361]228 disp(' ')
[1755]229 disp('!! modelextract warning: spc values should be checked !!')
[1361]230 disp(' ')
231 end
[8833]232 %put 0 for vz
[9679]233 md2.diagnostic.spcvz(nodestoflag2)=0;
[1348]234 end
[9632]235 if ~isnan(md1.thermal.spctemperature),
236 md2.thermal.spctemperature(nodestoflag2,1)=1;
[1361]237 end
[1348]238
239 %Diagnostic
[9694]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));
[9736]244 if md1.mesh.dimension==3
[9694]245 md2.diagnostic.icefront(:,3)=Pnode(md1.diagnostic.icefront(:,3));
246 md2.diagnostic.icefront(:,4)=Pnode(md1.diagnostic.icefront(:,4));
[1348]247 end
[9694]248 md2.diagnostic.icefront=md2.diagnostic.icefront(find(md2.diagnostic.icefront(:,1) & md2.diagnostic.icefront(:,2) & md2.diagnostic.icefront(:,end)),:);
[1348]249 end
250
251 %Results fields
252 if isstruct(md1.results),
[2530]253 md2.results=struct();
[1348]254 solutionfields=fields(md1.results);
255 for i=1:length(solutionfields),
256 %get subfields
[10094]257 solutionsubfields=fields(md1.results.(solutionfields{i}));
[1348]258 for j=1:length(solutionsubfields),
[10094]259 field=md1.results.(solutionfields{i}).(solutionsubfields{j});
[9736]260 if length(field)==numberofvertices1,
[10094]261 md2.results.(solutionfields{i}).(solutionsubfields{j})=field(pos_node);
[1348]262 elseif length(field)==numberofelements1,
[10094]263 md2.results.(solutionfields{i}).(solutionsubfields{j})=field(pos_elem);
[2530]264 else
[10094]265 md2.results.(solutionfields{i}).(solutionsubfields{j})=field;
[1348]266 end
267 end
268 end
269 end
270
[8298]271%Keep track of pos_node and pos_elem
[9706]272md2.mesh.extractedvertices=pos_node;
273md2.mesh.extractedelements=pos_elem;
Note: See TracBrowser for help on using the repository browser.