source: issm/trunk-jpl/src/c/analyses/HydrologyShreveAnalysis.cpp@ 18055

Last change on this file since 18055 was 18055, checked in by Mathieu Morlighem, 11 years ago

NEW: added new method for gradient calculation

File size: 13.4 KB
RevLine 
[16534]1#include "./HydrologyShreveAnalysis.h"
2#include "../toolkits/toolkits.h"
3#include "../classes/classes.h"
4#include "../shared/shared.h"
5#include "../modules/modules.h"
6
7/*Model processing*/
[17686]8int HydrologyShreveAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
[16534]9 return 1;
10}/*}}}*/
[16542]11void HydrologyShreveAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
[16539]12
13 /*retrieve some parameters: */
[16542]14 int hydrology_model;
[16539]15 iomodel->Constant(&hydrology_model,HydrologyModelEnum);
16
17 /*Now, do we really want Shreve?*/
[16542]18 if(hydrology_model!=HydrologyshreveEnum) return;
[16539]19
20 parameters->AddObject(new IntParam(HydrologyModelEnum,hydrology_model));
21 parameters->AddObject(iomodel->CopyConstantObject(HydrologyshreveStabilizationEnum));
22
23}/*}}}*/
24void HydrologyShreveAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
25
26 /*Fetch data needed: */
27 int hydrology_model;
28 iomodel->Constant(&hydrology_model,HydrologyModelEnum);
29
30 /*Now, do we really want Shreve?*/
31 if(hydrology_model!=HydrologyshreveEnum) return;
32
33 /*Update elements: */
34 int counter=0;
35 for(int i=0;i<iomodel->numberofelements;i++){
36 if(iomodel->my_elements[i]){
37 Element* element=(Element*)elements->GetObjectByOffset(counter);
38 element->Update(i,iomodel,analysis_counter,analysis_type,P1Enum);
39 counter++;
40 }
41 }
42
43 iomodel->FetchDataToInput(elements,ThicknessEnum);
44 iomodel->FetchDataToInput(elements,SurfaceEnum);
[17555]45 iomodel->FetchDataToInput(elements,BaseEnum);
[17886]46 if(iomodel->domaintype!=Domain2DhorizontalEnum){
47 iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
48 iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
49 }
[16539]50 iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
51 iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
52 iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
53 iomodel->FetchDataToInput(elements,WatercolumnEnum);
54
55 elements->InputDuplicate(WatercolumnEnum,WaterColumnOldEnum);
56}/*}}}*/
[16542]57void HydrologyShreveAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
[16539]58
59 /*Fetch parameters: */
60 int hydrology_model;
61 iomodel->Constant(&hydrology_model,HydrologyModelEnum);
62
63 /*Now, do we really want Shreve?*/
64 if(hydrology_model!=HydrologyshreveEnum) return;
65
[17700]66 if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
[16542]67 ::CreateNodes(nodes,iomodel,HydrologyShreveAnalysisEnum,P1Enum);
[17610]68 iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
[16539]69}/*}}}*/
[16542]70void HydrologyShreveAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
[16539]71
72 /*retrieve some parameters: */
73 int hydrology_model;
74 iomodel->Constant(&hydrology_model,HydrologyModelEnum);
75
76 if(hydrology_model!=HydrologyshreveEnum) return;
77
78 IoModelToConstraintsx(constraints,iomodel,HydrologyshreveSpcwatercolumnEnum,HydrologyShreveAnalysisEnum,P1Enum);
79
80}/*}}}*/
[16542]81void HydrologyShreveAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
[16539]82 /*No loads*/
83}/*}}}*/
[16675]84
[16782]85/*Finite Element Analysis*/
[17005]86void HydrologyShreveAnalysis::Core(FemModel* femmodel){/*{{{*/
87 _error_("not implemented");
88}/*}}}*/
[17000]89ElementVector* HydrologyShreveAnalysis::CreateDVector(Element* element){/*{{{*/
90 /*Default, return NULL*/
91 return NULL;
92}/*}}}*/
[16992]93ElementMatrix* HydrologyShreveAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
94_error_("Not implemented");
95}/*}}}*/
[16782]96ElementMatrix* HydrologyShreveAnalysis::CreateKMatrix(Element* element){/*{{{*/
[16903]97
98 /*Intermediaries */
99 IssmDouble diffusivity;
100 IssmDouble Jdet,D_scalar,dt,h;
101 IssmDouble vx,vy,vel,dvxdx,dvydy;
102 IssmDouble dvx[2],dvy[2];
103 IssmDouble* xyz_list = NULL;
104
105 /*Fetch number of nodes and dof for this finite element*/
106 int numnodes = element->GetNumberOfNodes();
107
108 /*Initialize Element vector and other vectors*/
109 ElementMatrix* Ke = element->NewElementMatrix();
110 IssmDouble* basis = xNew<IssmDouble>(numnodes);
111 IssmDouble* B = xNew<IssmDouble>(2*numnodes);
112 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);
113 IssmDouble D[2][2]={0.};
114
115 /*Create water velocity vx and vy from current inputs*/
116 CreateHydrologyWaterVelocityInput(element);
117
118 /*Retrieve all inputs and parameters*/
119 element->GetVerticesCoordinates(&xyz_list);
120 element->FindParam(&dt,TimesteppingTimeStepEnum);
[17294]121 element->FindParam(&diffusivity,HydrologyshreveStabilizationEnum);
[16903]122 Input* vx_input=element->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);
123 Input* vy_input=element->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);
124 h = element->CharacteristicLength();
125
126 /* Start looping on the number of gaussian points: */
127 Gauss* gauss=element->NewGauss(2);
128 for(int ig=gauss->begin();ig<gauss->end();ig++){
129 gauss->GaussPoint(ig);
130
131 element->JacobianDeterminant(&Jdet,xyz_list,gauss);
132 element->NodalFunctions(basis,gauss);
133
134 vx_input->GetInputValue(&vx,gauss);
135 vy_input->GetInputValue(&vy,gauss);
136 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
137 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
138
139 D_scalar=gauss->weight*Jdet;
140
141 TripleMultiply(basis,1,numnodes,1,
142 &D_scalar,1,1,0,
143 basis,1,numnodes,0,
144 Ke->values,1);
145
146 GetB(B,element,xyz_list,gauss);
147 GetBprime(Bprime,element,xyz_list,gauss);
148
149 dvxdx=dvx[0];
150 dvydy=dvy[1];
151 D_scalar=dt*gauss->weight*Jdet;
152
153 D[0][0]=D_scalar*dvxdx;
154 D[1][1]=D_scalar*dvydy;
155 TripleMultiply(B,2,numnodes,1,
156 &D[0][0],2,2,0,
157 B,2,numnodes,0,
158 &Ke->values[0],1);
159
160 D[0][0]=D_scalar*vx;
161 D[1][1]=D_scalar*vy;
162 TripleMultiply(B,2,numnodes,1,
163 &D[0][0],2,2,0,
164 Bprime,2,numnodes,0,
165 &Ke->values[0],1);
166
167 /*Artificial diffusivity*/
168 vel=sqrt(vx*vx+vy*vy);
169 D[0][0]=D_scalar*diffusivity*h/(2*vel)*vx*vx;
170 D[1][0]=D_scalar*diffusivity*h/(2*vel)*vy*vx;
171 D[0][1]=D_scalar*diffusivity*h/(2*vel)*vx*vy;
172 D[1][1]=D_scalar*diffusivity*h/(2*vel)*vy*vy;
173 TripleMultiply(Bprime,2,numnodes,1,
174 &D[0][0],2,2,0,
175 Bprime,2,numnodes,0,
176 &Ke->values[0],1);
177 }
178
179 /*Clean up and return*/
180 xDelete<IssmDouble>(xyz_list);
181 xDelete<IssmDouble>(basis);
182 xDelete<IssmDouble>(B);
183 xDelete<IssmDouble>(Bprime);
184 delete gauss;
185 return Ke;
[16782]186}/*}}}*/
187ElementVector* HydrologyShreveAnalysis::CreatePVector(Element* element){/*{{{*/
[16853]188
189 /*Skip if water or ice shelf element*/
190 if(element->IsFloating()) return NULL;
191
192 /*Intermediaries */
193 IssmDouble Jdet,dt;
194 IssmDouble mb,oldw;
195 IssmDouble* xyz_list = NULL;
196
197 /*Fetch number of nodes and dof for this finite element*/
198 int numnodes = element->GetNumberOfNodes();
199
200 /*Initialize Element vector and other vectors*/
201 ElementVector* pe = element->NewElementVector();
202 IssmDouble* basis = xNew<IssmDouble>(numnodes);
203
204 /*Retrieve all inputs and parameters*/
205 element->GetVerticesCoordinates(&xyz_list);
206 element->FindParam(&dt,TimesteppingTimeStepEnum);
207 Input* mb_input = element->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);
[16939]208 Input* oldw_input = element->GetInput(WaterColumnOldEnum); _assert_(oldw_input);
[16853]209
210 /*Initialize mb_correction to 0, do not forget!:*/
211 /* Start looping on the number of gaussian points: */
212 Gauss* gauss=element->NewGauss(2);
213 for(int ig=gauss->begin();ig<gauss->end();ig++){
214 gauss->GaussPoint(ig);
215
216 element->JacobianDeterminant(&Jdet,xyz_list,gauss);
217 element->NodalFunctions(basis,gauss);
218
219 mb_input->GetInputValue(&mb,gauss);
220 oldw_input->GetInputValue(&oldw,gauss);
221
222 if(dt!=0.){
223 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(oldw+dt*mb)*basis[i];
224 }
225 else{
226 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*mb*basis[i];
227 }
228 }
229
230 /*Clean up and return*/
231 xDelete<IssmDouble>(xyz_list);
232 xDelete<IssmDouble>(basis);
233 delete gauss;
234 return pe;
[16782]235}/*}}}*/
[16903]236void HydrologyShreveAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
237 /*Compute B matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.
238 * For node i, Bi can be expressed in the actual coordinate system
239 * by:
240 * Bi=[ N ]
241 * [ N ]
242 * where N is the finiteelement function for node i.
243 *
244 * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
245 */
246
247 /*Fetch number of nodes for this finite element*/
248 int numnodes = element->GetNumberOfNodes();
249
250 /*Get nodal functions*/
251 IssmDouble* basis=xNew<IssmDouble>(numnodes);
252 element->NodalFunctions(basis,gauss);
253
254 /*Build B: */
255 for(int i=0;i<numnodes;i++){
256 B[numnodes*0+i] = basis[i];
257 B[numnodes*1+i] = basis[i];
258 }
259
260 /*Clean-up*/
261 xDelete<IssmDouble>(basis);
262}/*}}}*/
263void HydrologyShreveAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
264 /*Compute B' matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2.
265 * For node i, Bi' can be expressed in the actual coordinate system
266 * by:
267 * Bi_prime=[ dN/dx ]
268 * [ dN/dy ]
269 * where N is the finiteelement function for node i.
270 *
271 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
272 */
273
274 /*Fetch number of nodes for this finite element*/
275 int numnodes = element->GetNumberOfNodes();
276
277 /*Get nodal functions derivatives*/
278 IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
279 element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
280
281 /*Build B': */
282 for(int i=0;i<numnodes;i++){
283 Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
284 Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
285 }
286
287 /*Clean-up*/
288 xDelete<IssmDouble>(dbasis);
289
290}/*}}}*/
[16675]291void HydrologyShreveAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
292 element->GetSolutionFromInputsOneDof(solution,WatercolumnEnum);
293}/*}}}*/
[18055]294void HydrologyShreveAnalysis::GradientJ(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
295 _error_("Not implemented yet");
296}/*}}}*/
[16684]297void HydrologyShreveAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
[16761]298
299 /*Intermediary*/
300 int* doflist = NULL;
301
302 /*Fetch number of nodes for this finite element*/
303 int numnodes = element->GetNumberOfNodes();
304
305 /*Fetch dof list and allocate solution vector*/
306 element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
307 IssmDouble* values = xNew<IssmDouble>(numnodes);
308
309 /*Use the dof list to index into the solution vector: */
310 for(int i=0;i<numnodes;i++){
311 values[i]=solution[doflist[i]];
312 if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
313 if (values[i]<10e-10) values[i]=10e-10; //correcting the water column to positive values
314 }
315
316 /*Add input to the element: */
[17609]317 element->AddInput(WatercolumnEnum,values,element->GetElementType());
[16761]318
319 /*Free ressources:*/
320 xDelete<IssmDouble>(values);
321 xDelete<int>(doflist);
[16684]322}/*}}}*/
[17212]323void HydrologyShreveAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
324 /*Default, do nothing*/
325 return;
326}/*}}}*/
[16903]327
328/*Intermediaries*/
329void HydrologyShreveAnalysis::CreateHydrologyWaterVelocityInput(Element* element){/*{{{*/
330
331 /*Intermediaries*/
332 IssmDouble dsdx,dsdy,dbdx,dbdy,w;
333
334 /*Retrieve all inputs and parameters*/
335 IssmDouble rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum);
[17946]336 IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
[16903]337 IssmDouble g = element->GetMaterialParameter(ConstantsGEnum);
338 IssmDouble mu_water = element->GetMaterialParameter(MaterialsMuWaterEnum);
339 Input* surfaceslopex_input = element->GetInput(SurfaceSlopeXEnum); _assert_(surfaceslopex_input);
340 Input* surfaceslopey_input = element->GetInput(SurfaceSlopeYEnum); _assert_(surfaceslopey_input);
341 Input* bedslopex_input = element->GetInput(BedSlopeXEnum); _assert_(bedslopex_input);
342 Input* bedslopey_input = element->GetInput(BedSlopeYEnum); _assert_(bedslopey_input);
343 Input* watercolumn_input = element->GetInput(WatercolumnEnum); _assert_(watercolumn_input);
344
345 /*Fetch number of vertices and allocate output*/
346 int numvertices = element->GetNumberOfVertices();
347 IssmDouble* vx = xNew<IssmDouble>(numvertices);
348 IssmDouble* vy = xNew<IssmDouble>(numvertices);
349
350 Gauss* gauss=element->NewGauss();
351 for(int iv=0;iv<numvertices;iv++){
352 gauss->GaussVertex(iv);
353 surfaceslopex_input->GetInputValue(&dsdx,gauss);
354 surfaceslopey_input->GetInputValue(&dsdy,gauss);
355 bedslopex_input->GetInputValue(&dbdx,gauss);
356 bedslopey_input->GetInputValue(&dbdy,gauss);
357 watercolumn_input->GetInputValue(&w,gauss);
358
359 /* Water velocity x and y components */
[17882]360 vx[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
361 vy[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
[16903]362 }
363
364 /*clean-up*/
365 delete gauss;
366
367 /*Add to inputs*/
368 element->AddInput(HydrologyWaterVxEnum,vx,P1Enum);
369 element->AddInput(HydrologyWaterVyEnum,vy,P1Enum);
370 xDelete<IssmDouble>(vx);
371 xDelete<IssmDouble>(vy);
372}/*}}}*/
[17882]373
374
375
376/*Needed changes to switch to the Johnson formulation*//*{{{*/
377/*All the changes are to be done in the velocity computation.
378 The new velocity needs some new parameter that should be introduce in the hydrologyshreve class:
379 'p' and 'q' which are the exponent of the Manning formula for laminar (p=2,q=1) or turbulent (p=2/3,q=1/2) flow
380 'R' the hydraulic radius
381 'n' the manning roughness coeficient
382
383 With these, the velocity reads ;
384
385 v= - (1/n)* pow(R,p)*pow((grad phi(rho_water*g)),q)
386
387 you should also redefine the water pressure potential 'phi' with respect to the effective pressure deffinition given in Johson:
388 phi=(rho_ice*g*( surface + ((rho_water/rho_ice)-1)*base - k_n*((thickness* grad(base))/omega) )
389
390 where
391 'omega' is the fractional area of the base occupied by the water film
392 'k_n' is a parameter
393 This last equation derives from the effective pressure definition developped in Alley 1989
394*/
395/*}}}*/
Note: See TracBrowser for help on using the repository browser.