function md2=modelextract(md1,area) %modelextract - extract a model according to an Argus contour or flag list % % This routine extracts a submodel from a bigger model with respect to a given contour % md must be followed by the corresponding exp file or flags list % It can either be a domain file (argus type, .exp extension), or an array of element flags. % If user wants every element outside the domain to be % modelextract2d, add '~' to the name of the domain file (ex: '~Pattyn.exp'); % an empty string '' will be considered as an empty domain % a string 'all' will be considered as the entire domain % add an argument 0 if you do not want the elements to be checked (faster) % % Usage: % md2=modelextract(md1,area); % % Examples: % md2=modelextract(md,'Domain.exp'); % md2=modelextract(md,md.elementoniceshelf); % % See also: EXTRUDE, COLLAPSE %some checks if ((nargin~=2) | (nargout~=1)), help modelextract error('modelextract error message: bad usage'); end %get check option if (nargin==3 & varargin{1}==0), checkoutline=0; else checkoutline=1; end %first flag_elem=FlagElements(md1,area); %kick out all elements with 3 dirichlets spc_elem=find(~flag_elem); spc_node=sort(unique(md1.elements(spc_elem,:))); flag=ones(md1.numberofnodes,1); flag(spc_node)=0; pos=find(sum(flag(md1.elements),2)==0); flag_elem(pos)=0; %extracted elements and nodes lists pos_elem=find(flag_elem); pos_node=sort(unique(md1.elements(pos_elem,:))); %keep track of some fields numberofnodes1=md1.numberofnodes; numberofelements1=md1.numberofelements; numberofnodes2=length(pos_node); numberofelements2=length(pos_elem); flag_node=zeros(numberofnodes1,1); flag_node(pos_node)=1; %Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements) Pelem=zeros(numberofelements1,1); Pelem(pos_elem)=[1:numberofelements2]'; Pnode=zeros(numberofnodes1,1); Pnode(pos_node)=[1:numberofnodes2]'; %renumber the elements (some node won't exist anymore) elements_1=md1.elements; elements_2=elements_1(pos_elem,:); elements_2(:,1)=Pnode(elements_2(:,1)); elements_2(:,2)=Pnode(elements_2(:,2)); elements_2(:,3)=Pnode(elements_2(:,3)); if md1.dim==3, elements_2(:,4)=Pnode(elements_2(:,4)); elements_2(:,5)=Pnode(elements_2(:,5)); elements_2(:,6)=Pnode(elements_2(:,6)); end %OK, now create the new model ! %take every fields from model md2=md1; %automatically modify fields %loop over model fields model_fields=fields(md1); for i=1:length(model_fields), %get field field=md1.(model_fields{i}); fieldsize=size(field); %size = number of nodes * n if fieldsize(1)==numberofnodes1 md2.(model_fields{i})=field(pos_node,:); elseif (fieldsize(1)==numberofnodes1+1) md2.(model_fields(i))=[field(pos_node,:); field(end,:)]; %size = number of elements * n elseif fieldsize(1)==numberofelements1 md2.(model_fields{i})=field(pos_elem,:); end end %modify some specific fields %Mesh md2.numberofelements=numberofelements2; md2.numberofnodes=numberofnodes2; md2.elements=elements_2; %uppernodes lowernodes if md1.dim==3 md2.uppernodes=md1.uppernodes(pos_node); pos=find(~isnan(md2.uppernodes)); md2.uppernodes(pos)=Pnode(md2.uppernodes(pos)); md2.lowernodes=md1.lowernodes(pos_node); pos=find(~isnan(md2.lowernodes)); md2.lowernodes(pos)=Pnode(md2.lowernodes(pos)); md2.upperelements=md1.upperelements(pos_elem); pos=find(~isnan(md2.upperelements)); md2.upperelements(pos)=Pelem(md2.upperelements(pos)); md2.lowerelements=md1.lowerelements(pos_elem); pos=find(~isnan(md2.lowerelements)); md2.lowerelements(pos)=Pelem(md2.lowerelements(pos)); end %Initial 2d mesh if md1.dim==3 flag_elem_2d=flag_elem(1:md1.numberofelements2d); pos_elem_2d=find(flag_elem_2d); flag_node_2d=flag_node(1:md1.numberofnodes2d); pos_node_2d=find(flag_node_2d); md2.numberofelements2d=length(pos_elem_2d); md2.numberofnodes2d=length(pos_node_2d); md2.elements2d=md1.elements2d(pos_elem_2d,:); md2.elements2d(:,1)=Pnode(md2.elements2d(:,1)); md2.elements2d(:,2)=Pnode(md2.elements2d(:,2)); md2.elements2d(:,3)=Pnode(md2.elements2d(:,3)); md2.x2d=md1.x(pos_node_2d); md2.y2d=md1.y(pos_node_2d); end %Edges if size(md2.edges,2)>1, %do not use ~isnan because there are some NaNs... %renumber first two columns pos=find(~isnan(md2.edges(:,4))); md2.edges(: ,1)=Pnode(md2.edges(:,1)); md2.edges(: ,2)=Pnode(md2.edges(:,2)); md2.edges(: ,3)=Pelem(md2.edges(:,3)); md2.edges(pos,4)=Pelem(md2.edges(pos,4)); %remove edges when the 2 vertices are not in the domain. md2.edges=md2.edges(find(md2.edges(:,1) & md2.edges(:,2)),:); %Replace all zeros by NaN in the last two columns; pos=find(md2.edges(:,3)==0); md2.edges(pos,3)=NaN; pos=find(md2.edges(:,4)==0); md2.edges(pos,4)=NaN; %Invert NaN of the third column with last column (Also invert first two columns!!) pos=find(isnan(md2.edges(:,3))); md2.edges(pos,3)=md2.edges(pos,4); md2.edges(pos,4)=NaN; values=md2.edges(pos,2); md2.edges(pos,2)=md2.edges(pos,1); md2.edges(pos,1)=values; %Finally remove edges that do not belong to any element pos=find(isnan(md2.edges(:,3)) & isnan(md2.edges(:,4))); md2.edges(pos,:)=[]; end %Penalties if ~isnan(md2.penalties), for i=1:size(md1.penalties,1); md2.penalties(i,:)=Pnode(md1.penalties(i,:)); end md2.penalties=md2.penalties(find(md2.penalties(:,1)),:); end %recreate segments if md1.dim==2 md2.nodeconnectivity=NodeConnectivity(md2.elements,md2.numberofnodes); md2.elementconnectivity=ElementConnectivity(md2.elements,md2.nodeconnectivity); md2.segments=contourenvelope(md2); md2.nodeonboundary=zeros(numberofnodes2,1); md2.nodeonboundary(md2.segments(:,1:2))=1; end %Boundary conditions: Dirichlets on new boundary %Catch the elements that have not been extracted orphans_elem=find(~flag_elem); orphans_node=unique(md1.elements(orphans_elem,:))'; %Figure out which node are on the boundary between md2 and md1 nodestoflag1=intersect(orphans_node,pos_node); nodestoflag2=Pnode(nodestoflag1); if numel(md1.spcvx)>1 & numel(md1.spcvy)>2 & numel(md1.spcvz)>2, if numel(md1.vx_obs)>1 & numel(md1.vy_obs)>1 md2.spcvx(nodestoflag2)=md2.vx_obs(nodestoflag2); md2.spcvy(nodestoflag2)=md2.vy_obs(nodestoflag2); else md2.spcvx(nodestoflag2)=NaN; md2.spcvy(nodestoflag2)=NaN; disp(' ') disp('!! modelextract warning: spc values should be checked !!') disp(' ') end %put 0 for vz md2.spcvz(nodestoflag2)=0; end if ~isnan(md1.spctemperature), md2.spctemperature(nodestoflag2,1)=1; end %Diagnostic if ~isnan(md2.pressureload) md2.pressureload(:,1)=Pnode(md1.pressureload(:,1)); md2.pressureload(:,2)=Pnode(md1.pressureload(:,2)); md2.pressureload(:,end-1)=Pelem(md1.pressureload(:,end-1)); if md1.dim==3 md2.pressureload(:,3)=Pnode(md1.pressureload(:,3)); md2.pressureload(:,4)=Pnode(md1.pressureload(:,4)); end md2.pressureload=md2.pressureload(find(md2.pressureload(:,1) & md2.pressureload(:,2) & md2.pressureload(:,end)),:); end %Results fields if isstruct(md1.results), md2.results=struct(); solutionfields=fields(md1.results); for i=1:length(solutionfields), %get subfields solutionsubfields=fields(md1.results.(solutionfields(i))); for j=1:length(solutionsubfields), field=md1.results.(solutionfields(i)).(solutionsubfields(j)); if length(field)==numberofnodes1, md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_node); elseif length(field)==numberofelements1, md2.results.(solutionfields(i)).(solutionsubfields(j))=field(pos_elem); else md2.results.(solutionfields(i)).(solutionsubfields(j))=field; end end end end %Keep track of pos_node and pos_elem md2.extractednodes=pos_node; md2.extractedelements=pos_elem;