source: issm/trunk/src/m/classes/public/extrude.m@ 2307

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

Changed antzoom to basinzoom.
marshall: added parameteroutput in marshalling.
extrude: added extrusion of balanced velocities.
ismodelselfconsistent: checked that numoutput and parameteroutput are same size.

File size: 7.5 KB
Line 
1function md=extrude(md,varargin)
2%EXTRUDE - vertically extrude a 2d mesh
3%
4% vertically extrude a 2d mesh and create corresponding 3d mesh.
5% The vertical distribution can:
6% - follow a polynomial law
7% - follow two polynomial laws, one for the lower part and one for the upper part of the mesh
8% - be discribed by a list of coefficients (between 0 and 1)
9%
10%
11% Usage:
12% md=extrude(md,numlayers,extrusionexponent);
13% md=extrude(md,numlayers,lowerexponent,upperexponent);
14% md=extrude(md,listofcoefficients);
15%
16% Example:
17% md=extrude(md,8,3);
18% md=extrude(md,8,3,2);
19% md=extrude(md,[0 0.2 0.5 0.7 0.9 0.95 1]);
20%
21% See also: MODELEXTRACT, COLLAPSE
22
23%some checks on list of arguments
24if ((nargin>4) | (nargin<2) | (nargout~=1)),
25 help extrude;
26 error('extrude error message');
27end
28
29if md.counter<3,
30 help extrude;
31 error('only fully parameterized 2d models can be extruded');
32end
33
34if md.counter>=4,
35 error('This model has already been extruded!','s');
36end
37
38%Extrude the mesh
39if nargin==2, %list of coefficients
40 list=varargin{1};
41 if any(list<0) | any(list>1),
42 error('extrusioncoefficients must be between 0 and 1');
43 end
44 extrusionlist=sort(unique([list(:);0;1]));
45 numlayers=length(extrusionlist);
46elseif nargin==3, %one polynomial law
47 if varargin{2}<=0,
48 help extrude;
49 error('extrusionexponent must be >=0');
50 end
51 numlayers=varargin{1};
52 extrusionlist=((0:1:numlayers-1)/(numlayers-1)).^varargin{2};
53elseif nargin==4, %two polynomial laws
54 numlayers=varargin{1};
55 lowerexp=varargin{2};
56 upperexp=varargin{3};
57
58 if varargin{2}<=0 | varargin{3}<=0,
59 help extrude;
60 error('lower and upper extrusionexponents must be >=0');
61 end
62
63 lowerextrusionlist=[(0:2/(numlayers-1):1).^lowerexp]/2;
64 upperextrusionlist=[(0:2/(numlayers-1):1).^upperexp]/2;
65 extrusionlist=sort(unique([lowerextrusionlist 1-upperextrusionlist]));
66
67end
68
69if numlayers<2,
70 disp('number of layers should be at least 2. returning initial model...');
71 return
72end
73
74%Initialize with the 2d mesh
75x3d=[];
76y3d=[];
77z3d=[]; %the lower grid is on the bed
78thickness3d=md.thickness; %thickness and bed for these grids
79bed3d=md.bed;
80
81%Create the new layers
82for i=1:numlayers,
83 x3d=[x3d; md.x];
84 y3d=[y3d; md.y];
85 %grids are distributed between bed and surface accordingly to the given exponent
86 z3d=[z3d; bed3d+thickness3d*extrusionlist(i)];
87end
88number_grids3d=size(x3d,1); %number of 3d grids for the non extruded part of the mesh
89
90%Extrude elements
91elements3d=[];
92for i=1:numlayers-1,
93 elements3d=[elements3d;[md.elements+(i-1)*md.numberofgrids md.elements+i*md.numberofgrids]]; %Create the elements of the 3d mesh for the non extruded part
94end
95number_el3d=size(elements3d,1); %number of 3d grids for the non extruded part of the mesh
96
97%Keep a trace of lower and upper grids
98lowergrids=NaN*ones(number_grids3d,1);
99uppergrids=NaN*ones(number_grids3d,1);
100lowergrids(md.numberofgrids+1:end)=1:(numlayers-1)*md.numberofgrids;
101uppergrids(1:(numlayers-1)*md.numberofgrids)=md.numberofgrids+1:number_grids3d;
102md.lowergrids=lowergrids;
103md.uppergrids=uppergrids;
104
105%Save old mesh
106md.x2d=md.x;
107md.y2d=md.y;
108md.z2d=md.z;
109md.elements2d=md.elements;
110md.elements_type2d=md.elements_type;
111md.numberofelements2d=md.numberofelements;
112md.numberofgrids2d=md.numberofgrids;
113
114%Update mesh type
115md.type='3d';
116
117%Build global 3d mesh
118md.elements=elements3d;
119md.x=x3d;
120md.y=y3d;
121md.z=z3d;
122md.numberofelements=number_el3d;
123md.numberofgrids=number_grids3d;
124md.numlayers=numlayers;
125
126%Ok, now deal with the other fields from the 2d mesh:
127
128%drag is limited to grids that are on the bedrock.
129md.drag=project3d(md,md.drag,'node',1);
130
131%p and q (same deal, except for element that are on the bedrock: )
132md.p=project3d(md,md.p,'element');
133md.q=project3d(md,md.q,'element');
134
135%observations
136md.vx_obs=project3d(md,md.vx_obs,'node');
137md.vy_obs=project3d(md,md.vy_obs,'node');
138md.vel_obs=project3d(md,md.vel_obs,'node');
139md.vx_bal=project3d(md,md.vx_bal,'node');
140md.vy_bal=project3d(md,md.vy_bal,'node');
141md.vel_bal=project3d(md,md.vel_bal,'node');
142md.vel_obs_raw=project3d(md,md.vel_obs_raw,'node');
143md.accumulation=project3d(md,md.accumulation,'node');
144md.firn_layer=project3d(md,md.firn_layer,'node',md.numlayers);
145
146%results
147if ~isnan(md.vx),md.vx=project3d(md,md.vx,'node');end;
148if ~isnan(md.vy),md.vy=project3d(md,md.vy,'node');end;
149if ~isnan(md.vz),md.vz=project3d(md,md.vz,'node');end;
150if ~isnan(md.vel),md.vel=project3d(md,md.vel,'node');end;
151if ~isnan(md.temperature),md.temperature=project3d(md,md.temperature,'node');end;
152if ~isnan(md.surface_slopex),md.surface_slopex=project3d(md,md.surface_slopex,'node');end;
153if ~isnan(md.surface_slopey),md.surface_slopey=project3d(md,md.surface_slopey,'node');end;
154if ~isnan(md.bed_slopex),md.bed_slopex=project3d(md,md.bed_slopex,'node');end;
155if ~isnan(md.bed_slopey),md.bed_slopey=project3d(md,md.bed_slopey,'node');end;
156
157%bedinfo and surface info
158md.elementonbed=project3d(md,ones(md.numberofelements2d,1),'element',1);
159md.elementonsurface=project3d(md,ones(md.numberofelements2d,1),'element',md.numlayers-1);
160md.gridonbed=project3d(md,ones(md.numberofgrids2d,1),'node',1);
161md.gridonsurface=project3d(md,ones(md.numberofgrids2d,1),'node',md.numlayers);
162
163%elementstype
164if ~isnan(md.elements_type)
165 oldelements_type=md.elements_type2d;
166 md.elements_type=zeros(number_el3d,2);
167 md.elements_type(:,1)=project3d(md,oldelements_type(:,1),'element');
168 md.elements_type(:,2)=project3d(md,oldelements_type(:,2),'element');
169 md.gridonhutter=project3d(md,md.gridonhutter,'node');
170 md.gridonmacayeal=project3d(md,md.gridonmacayeal,'node');
171 md.gridonpattyn=project3d(md,md.gridonpattyn,'node');
172 md.gridonstokes=project3d(md,md.gridonstokes,'node');
173
174 %dead grids
175 md.deadgrids=ones(md.numberofgrids,1);
176 md.deadgrids(md.elements(md.elements_type(:,1)~=MacAyealFormulationEnum,:))=0;%non macayeal grids are not dead
177 md.deadgrids(find(md.gridonbed))=0;%grids from elements on bed are not dead
178end
179
180%boundary conditions
181md.spcvelocity=project3d(md,md.spcvelocity,'node');
182md.spctemperature=project3d(md,md.spctemperature,'node',md.numlayers);
183md.spcthickness=project3d(md,md.spcthickness,'node');
184
185%Extrusion of Neumann BC
186%in 3d, segmentonnumann is: [grid1 grid2 grid3 grid4 element]
187oldpressureload=md.pressureload;
188pressureload_layer1=[oldpressureload(:,1:2) oldpressureload(:,2)+md.numberofgrids2d oldpressureload(:,1)+md.numberofgrids2d oldpressureload(:,3)]; %Add two columns on the first layer
189pressureload=[];
190for i=1:numlayers-1,
191 pressureload=[pressureload ;pressureload_layer1(:,1:4)+(i-1)*md.numberofgrids2d pressureload_layer1(:,5)+(i-1)*md.numberofelements2d ];
192end
193
194%plug into md
195md.pressureload=pressureload;
196
197%materials
198md.B=project3d(md,md.B,'node');
199md.n=project3d(md,md.n,'element');
200
201%parameters
202md.surface=project3d(md,md.surface,'node');
203md.thickness=project3d(md,md.thickness,'node');
204md.bed=project3d(md,md.bed,'node');
205md.gridonboundary=project3d(md,md.gridonboundary,'node');
206md.elementoniceshelf=project3d(md,md.elementoniceshelf,'element');
207md.gridoniceshelf=project3d(md,md.gridoniceshelf,'node');
208md.elementonicesheet=project3d(md,md.elementonicesheet,'element');
209md.gridonicesheet=project3d(md,md.gridonicesheet,'node');
210md.elementonwater=project3d(md,md.elementonwater,'element');
211md.gridonwater=project3d(md,md.gridonwater,'node');
212
213%special for thermal modeling:
214md.melting=project3d(md,md.melting,'node',1);
215md.observed_temperature=project3d(md,md.observed_temperature,'node');
216md.geothermalflux=project3d(md,md.geothermalflux,'node',1); %bedrock only gets geothermal flux
217
218%increase connectivity if less than 25:
219if md.connectivity<=25,
220 md.connectivity=100;
221end
222
223%augment counter keeping track of what has been done to this model
224md.counter=4;
Note: See TracBrowser for help on using the repository browser.