Ice Sheet System Model  4.18
Code documentation
Penta.cpp
Go to the documentation of this file.
1 
5 /*Headers:*/
6 /*{{{*/
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #else
10 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
11 #endif
12 
13 #include "../classes.h"
14 #include "../Inputs2/PentaInput2.h"
15 #include "../Inputs2/ControlInput2.h"
16 #include "../Inputs2/TransientInput2.h"
17 #include "../Inputs2/DatasetInput2.h"
18 #include "../../shared/shared.h"
19 /*}}}*/
20 
21 /*Element macros*/
22 #define NUMVERTICES 6
23 #define NUMVERTICES2D 3
24 
25 /*Constructors/destructor/copy*/
26 Penta::~Penta(){/*{{{*/
27  this->parameters=NULL;
28 }
29 /*}}}*/
30 Penta::Penta(int penta_id, int penta_sid,int penta_lid,IoModel* iomodel,int nummodels)/*{{{*/
31  :ElementHook(nummodels,penta_id,NUMVERTICES,iomodel){
32 
33  int penta_elements_ids[2];
34 
35  /*Checks in debugging mode*/
36  _assert_(iomodel->Data("md.mesh.upperelements"));
37  _assert_(iomodel->Data("md.mesh.lowerelements"));
38 
39  /*id: */
40  this->id = penta_id;
41  this->sid = penta_sid;
42  this->lid = penta_lid;
43 
44  /*surface and base*/
45  this->isonsurface = false;
46  this->isonbase = false;
47 
48  /*Build neighbors list*/
49  if (xIsNan<IssmDouble>(iomodel->Data("md.mesh.upperelements")[penta_sid]) || iomodel->Data("md.mesh.upperelements")[penta_sid]==-1.) penta_elements_ids[1]=this->id; //upper penta is the same penta
50  else penta_elements_ids[1]=reCast<int,IssmDouble>((iomodel->Data("md.mesh.upperelements")[penta_sid]));
51  if (xIsNan<IssmDouble>(iomodel->Data("md.mesh.lowerelements")[penta_sid]) || iomodel->Data("md.mesh.lowerelements")[penta_sid]==-1.) penta_elements_ids[0]=this->id; //lower penta is the same penta
52  else penta_elements_ids[0]=reCast<int,IssmDouble>((iomodel->Data("md.mesh.lowerelements")[penta_sid]));
53  this->InitHookNeighbors(penta_elements_ids);
54 
55  //this->parameters: we still can't point to it, it may not even exist. Configure will handle this.
56  this->parameters=NULL;
57 
58  /*initialize pointers:*/
59  this->nodes = NULL;
60  this->vertices = NULL;
61  this->material = NULL;
62  this->verticalneighbors = NULL;
63 
64  /*Only allocate pointer*/
65  this->element_type_list=xNew<int>(nummodels);
66 
67  /*surface and base*/
68  _assert_(iomodel->Data("md.mesh.vertexonsurface"));
69  _assert_(iomodel->Data("md.mesh.vertexonbase"));
70  this->isonsurface = false;
71  this->isonbase = false;
72  IssmDouble sum = 0.;
73  for(int i=0;i<NUMVERTICES;i++) sum += iomodel->Data("md.mesh.vertexonsurface")[reCast<int>(iomodel->elements[(penta_id-1)*NUMVERTICES+i])-1];
74  _assert_(sum>=0 && sum<4);
75  if(sum>2.5) this->isonsurface = true;
76  sum = 0.;
77  for(int i=0;i<NUMVERTICES;i++) sum += iomodel->Data("md.mesh.vertexonbase")[reCast<int>(iomodel->elements[(penta_id-1)*NUMVERTICES+i])-1];
78  _assert_(sum>=0 && sum<4);
79  if(sum>2.5) this->isonbase = true;
80 }
81 /*}}}*/
82 Object* Penta::copy() {/*{{{*/
83 
84  int i;
85  Penta* penta=NULL;
86 
87  penta=new Penta();
88 
89  //deal with PentaRef mother class
90  int nanalyses = this->numanalyses;
91  if(nanalyses > 0){
92  penta->element_type_list=xNew<int>(nanalyses);
93  for(i=0;i<nanalyses;i++) {
94  if (this->element_type_list[i]) penta->element_type_list[i]=this->element_type_list[i];
95  else penta->element_type_list[i] = 0;
96  }
97  }
98  else penta->element_type_list = NULL;
99  penta->element_type=this->element_type;
100  penta->numanalyses=nanalyses;
101 
102  //deal with ElementHook mother class
103  if (this->hnodes){
104  penta->hnodes=xNew<Hook*>(penta->numanalyses);
105  for(i=0;i<penta->numanalyses;i++){
106  if (this->hnodes[i]) penta->hnodes[i] = (Hook*)(this->hnodes[i]->copy());
107  else penta->hnodes[i] = NULL;
108  }
109  }
110  else penta->hnodes = NULL;
111 
112  penta->hvertices = (Hook*)this->hvertices->copy();
113  penta->hmaterial = (Hook*)this->hmaterial->copy();
114  if (this->hneighbors) penta->hneighbors = (Hook*)(this->hneighbors->copy());
115  else penta->hneighbors = NULL;
116 
117  /*deal with Tria fields: */
118  penta->id = this->id;
119  penta->sid = this->sid;
120  penta->lid = this->lid;
121  penta->isonbase = this->isonbase;
122  penta->isonsurface = this->isonsurface;
123 
124  /*point parameters: */
125  penta->parameters=this->parameters;
126 
127  /*recover objects: */
128  if (this->nodes) {
129  unsigned int num_nodes = 6;
130  penta->nodes = xNew<Node*>(num_nodes); //we cannot rely on an analysis_counter to tell us which analysis_type we are running, so we just copy the nodes.
131  for(i=0;i<num_nodes;i++) if(this->nodes[i]) penta->nodes[i]=this->nodes[i]; else penta->nodes[i] = NULL;
132  }
133  else penta->nodes = NULL;
134 
135  penta->vertices = (Vertex**)this->hvertices->deliverp();
136  penta->material = (Material*)this->hmaterial->delivers();
137  penta->verticalneighbors = (Penta**)this->hneighbors->deliverp();
138 
139  return penta;
140 
141 }
142 /*}}}*/
143 void Penta::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
144 
146  MARSHALLING(this->isonsurface);
147  MARSHALLING(this->isonbase);
148 
149  /*Call parent classes: */
150  ElementHook::Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
151  Element::MarshallElement(pmarshalled_data,pmarshalled_data_size,marshall_direction,this->numanalyses);
152  PentaRef::Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
153 
154  vertices = (Vertex**)this->hvertices->deliverp();
155  material = (Material*)this->hmaterial->delivers();
157 
158 }
159 /*}}}*/
160 
161 /*Other*/
162 void Penta::AddBasalInput2(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
163 
164  _assert_(this->inputs2);
165  if(!IsOnBase()) return;
166  else{
167  if(interpolation_enum==P1Enum || interpolation_enum==P1DGEnum){
168  IssmDouble extrudedvalues[NUMVERTICES];
169  for(int i=0;i<NUMVERTICES2D;i++){
170  extrudedvalues[i]=values[i];
171  extrudedvalues[i+NUMVERTICES2D]=values[i];
172  }
173  Penta* penta=this;
174  for(;;){
175  penta->AddInput2(input_enum,&extrudedvalues[0],interpolation_enum);
176  if (penta->IsOnSurface()) break;
177  penta=penta->GetUpperPenta(); _assert_(penta->Id()!=this->id);
178  }
179  }
180  else _error_("not implemented yet");
181  }
182 
183 }
184 /*}}}*/
185 void Penta::AddInput2(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
186 
187 
188  int vertexlids[NUMVERTICES];
189 
190  /*Call inputs method*/
191  _assert_(this->inputs2);
192  switch(interpolation_enum){
193  case P1Enum:
194  for(int i=0;i<NUMVERTICES;i++) vertexlids[i]=this->vertices[i]->lid;
195  inputs2->SetPentaInput(input_enum,interpolation_enum,NUMVERTICES,vertexlids,values);
196  break;
197  case P1DGEnum:
198  inputs2->SetPentaInput(input_enum,interpolation_enum,this->lid,NUMVERTICES,values);
199  break;
200  default:
201  inputs2->SetPentaInput(input_enum,interpolation_enum,this->lid,this->GetNumberOfNodes(interpolation_enum),values);
202  }
203 
204 }
205 /*}}}*/
206 void Penta::AddControlInput(int input_enum,Inputs2* inputs2,IoModel* iomodel,IssmDouble* values,IssmDouble* values_min,IssmDouble* values_max, int interpolation_enum,int id){/*{{{*/
207 
208  /*Intermediaries*/
209  int vertexlids[NUMVERTICES];
210 
211  _assert_(iomodel->elements);
212  for(int i=0;i<NUMVERTICES;i++){
213  int vertexid =reCast<int>(iomodel->elements[NUMVERTICES*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
214  vertexlids[i]=iomodel->my_vertices_lids[vertexid-1];
215  }
216 
217  /*Call inputs method*/
218  switch(interpolation_enum){
219  case P1Enum:
220  inputs2->SetPentaControlInput(input_enum,PentaInput2Enum,interpolation_enum,id,NUMVERTICES,vertexlids,values,values_min,values_max);
221  break;
222  default:
223  _error_("Cannot add \""<<EnumToStringx(input_enum)<<"\" interpolation "<<EnumToStringx(interpolation_enum)<<" not supported");
224  }
225 
226 }
227 /*}}}*/
228 void Penta::DatasetInputCreate(IssmDouble* array,int M,int N,int* individual_enums,int num_inputs,Inputs2* inputs2,IoModel* iomodel,int input_enum){/*{{{*/
229 
230  /*Intermediaries*/
231  int vertexsids[NUMVERTICES];
232  int vertexlids[NUMVERTICES];
233  IssmDouble nodeinputs[NUMVERTICES];
234 
235  /*Some sanity checks*/
236  if(num_inputs<1) _error_("Cannot create a DatasetInput of size <1");
237  if(M!=iomodel->numberofvertices) _error_("Input size not supported yet");
238  if(N!=num_inputs) _error_("Sizes are not consistent");
239 
240  /*Get indices*/
241  _assert_(iomodel->elements);
242  for(int i=0;i<NUMVERTICES;i++){
243  vertexsids[i] = reCast<int>(iomodel->elements[NUMVERTICES*this->Sid()+i])-1;
244  vertexlids[i] = iomodel->my_vertices_lids[vertexsids[i]];
245  }
246 
247  /*Create inputs and add to DataSetInput*/
248  for(int i=0;i<num_inputs;i++){
249  for(int j=0;j<NUMVERTICES;j++) nodeinputs[j]=array[vertexsids[j]*N+i];
250  inputs2->SetPentaDatasetInput(input_enum,individual_enums[i],P1Enum,NUMVERTICES,vertexlids,nodeinputs);
251  }
252 }
253 /*}}}*/
254 void Penta::BasalNodeIndices(int* pnumindices,int** pindices,int finiteelement){/*{{{*/
255 
256  PentaRef::BasalNodeIndices(pnumindices,pindices,finiteelement);
257 
258 }
259 /*}}}*/
260 void Penta::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){/*{{{*/
261  _error_("Not supported yet!");
262 }
263 /*}}}*/
265 
266  if(!this->IsOnBase()) return;
267 
268  IssmDouble xyz_list[NUMVERTICES][3];
269  IssmDouble epsilon[3]; /* epsilon=[exx,eyy,exy];*/
270  IssmDouble calvingratex[NUMVERTICES];
271  IssmDouble calvingratey[NUMVERTICES];
272  IssmDouble calvingrate[NUMVERTICES];
273  IssmDouble lambda1,lambda2,ex,ey,vx,vy,vel;
274  IssmDouble B,sigma_max,sigma_max_floating,sigma_max_grounded,n;
275  IssmDouble epse_2,groundedice,bed,sealevel;
276  IssmDouble sigma_vm[NUMVERTICES];
277 
278  /* Get node coordinates and dof list: */
280 
281  /*Depth average B for stress calculation*/
285 
286  /*Retrieve all inputs and parameters we will need*/
287  Input2* vx_input = this->GetInput2(VxAverageEnum); _assert_(vx_input);
288  Input2* vy_input = this->GetInput2(VyAverageEnum); _assert_(vy_input);
289  Input2* gr_input = this->GetInput2(MaskOceanLevelsetEnum); _assert_(gr_input);
290  Input2* bs_input = this->GetInput2(BaseEnum); _assert_(bs_input);
291  Input2* B_input = this->GetInput2(MaterialsRheologyBbarEnum); _assert_(B_input);
292  Input2* n_input = this->GetInput2(MaterialsRheologyNEnum); _assert_(n_input);
293  Input2* smax_fl_input = this->GetInput2(CalvingStressThresholdFloatingiceEnum); _assert_(smax_fl_input);
294  Input2* smax_gr_input = this->GetInput2(CalvingStressThresholdGroundediceEnum); _assert_(smax_gr_input);
295  Input2* sl_input = this->GetInput2(SealevelEnum); _assert_(sl_input);
296 
297  /* Start looping on the number of vertices: */
298  GaussPenta* gauss=new GaussPenta();
299  for(int iv=0;iv<3;iv++){
300  gauss->GaussVertex(iv);
301 
302  /*Get velocity components and thickness*/
303  B_input->GetInputValue(&B,gauss);
304  n_input->GetInputValue(&n,gauss);
305  vx_input->GetInputValue(&vx,gauss);
306  vy_input->GetInputValue(&vy,gauss);
307  gr_input->GetInputValue(&groundedice,gauss);
308  bs_input->GetInputValue(&bed,gauss);
309  smax_fl_input->GetInputValue(&sigma_max_floating,gauss);
310  smax_gr_input->GetInputValue(&sigma_max_grounded,gauss);
311  vel=sqrt(vx*vx+vy*vy)+1.e-14;
312  sl_input->GetInputValue(&sealevel,gauss);
313 
314  /*Compute strain rate and viscosity: */
315  this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
316 
317  /*Get Eigen values*/
318  Matrix2x2Eigen(&lambda1,&lambda2,&ex,&ey,epsilon[0],epsilon[2],epsilon[1]);
319  _assert_(!xIsNan<IssmDouble>(lambda1));
320  _assert_(!xIsNan<IssmDouble>(lambda2));
321 
322  /*Process Eigen values (only account for extension)*/
323  lambda1 = max(lambda1,0.);
324  lambda2 = max(lambda2,0.);
325 
326  /*Calculate sigma_vm*/
327  epse_2 = 1./2. *(lambda1*lambda1 + lambda2*lambda2);
328  sigma_vm[iv] = sqrt(3.) * B * pow(epse_2,1./(2.*n));
329 
330  /*Tensile stress threshold*/
331  if(groundedice<0)
332  sigma_max = sigma_max_floating;
333  else
334  sigma_max = sigma_max_grounded;
335 
336  /*Assign values*/
337  if(bed>sealevel){
338  calvingratex[iv]=0.;
339  calvingratey[iv]=0.;
340  }
341  else{
342  calvingratex[iv]=vx*sigma_vm[iv]/sigma_max;
343  calvingratey[iv]=vy*sigma_vm[iv]/sigma_max;
344  }
345  calvingrate[iv] =sqrt(calvingratex[iv]*calvingratex[iv] + calvingratey[iv]*calvingratey[iv]);
346  }
347 
348  /*Add input*/
349  this->AddBasalInput2(CalvingratexEnum,&calvingratex[0],P1DGEnum);
350  this->AddBasalInput2(CalvingrateyEnum,&calvingratey[0],P1DGEnum);
351  this->AddBasalInput2(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
352  this->AddBasalInput2(SigmaVMEnum,&sigma_vm[0],P1DGEnum);
353 
354  this->InputExtrude(CalvingratexEnum,-1);
355  this->InputExtrude(CalvingrateyEnum,-1);
357  this->InputExtrude(SigmaVMEnum,-1);
358 
359  /*Clean up and return*/
360  delete gauss;
361 }
362 /*}}}*/
364 
365  IssmDouble xyz_list[NUMVERTICES][3];
366  GaussPenta* gauss=NULL;
367  IssmDouble vx,vy,vel;
368  IssmDouble strainparallel;
369  IssmDouble propcoeff;
370  IssmDouble strainperpendicular;
371  IssmDouble calvingratex[NUMVERTICES];
372  IssmDouble calvingratey[NUMVERTICES];
373  IssmDouble calvingrate[NUMVERTICES];
374 
375  /* Get node coordinates and dof list: */
377 
378  /*Retrieve all inputs and parameters we will need*/
379  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
380  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
381  Input2* strainparallel_input=this->GetInput2(StrainRateparallelEnum); _assert_(strainparallel_input);
382  Input2* strainperpendicular_input=this->GetInput2(StrainRateperpendicularEnum); _assert_(strainperpendicular_input);
383  Input2* levermanncoeff_input=this->GetInput2(CalvinglevermannCoeffEnum); _assert_(levermanncoeff_input);
384 
385  /* Start looping on the number of vertices: */
386  gauss=new GaussPenta();
387  for (int iv=0;iv<NUMVERTICES;iv++){
388  gauss->GaussVertex(iv);
389 
390  /* Get the value we need*/
391  vx_input->GetInputValue(&vx,gauss);
392  vy_input->GetInputValue(&vy,gauss);
393  vel=vx*vx+vy*vy;
394  strainparallel_input->GetInputValue(&strainparallel,gauss);
395  strainperpendicular_input->GetInputValue(&strainperpendicular,gauss);
396  levermanncoeff_input->GetInputValue(&propcoeff,gauss);
397 
398  /*Calving rate proportionnal to the positive product of the strain rate along the ice flow direction and the strain rate perpendicular to the ice flow */
399  calvingrate[iv]=propcoeff*strainparallel*strainperpendicular;
400  if(calvingrate[iv]<0){
401  calvingrate[iv]=0;
402  }
403  calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14);
404  calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14);
405  }
406 
407  /*Add input*/
408  this->AddBasalInput2(CalvingratexEnum,&calvingratex[0],P1DGEnum);
409  this->AddBasalInput2(CalvingrateyEnum,&calvingratey[0],P1DGEnum);
410  this->AddBasalInput2(CalvingCalvingrateEnum,&calvingrate[0],P1DGEnum);
411 
412  /*Clean up and return*/
413  delete gauss;
414 
415 }
416 /*}}}*/
418 
419  /*Make sure there is an ice front here*/
421  IssmDouble flux_per_area=0;
422  this->AddInput2(CalvingFluxLevelsetEnum,&flux_per_area,P0Enum);
423  }
424  else{
425  int domaintype,index1,index2;
426  const IssmPDouble epsilon = 1.e-15;
427  IssmDouble s1,s2;
429  IssmDouble xyz_front[2][3];
430 
431  IssmDouble *xyz_list = NULL;
432  this->GetVerticesCoordinates(&xyz_list);
433 
434  /*Recover parameters and values*/
436 
437  /*Be sure that values are not zero*/
438  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
439  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
440  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
441 
442  int pt1 = 0;
443  int pt2 = 1;
444  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
445 
446  /*Portion of the segments*/
447  s1=gl[2]/(gl[2]-gl[1]);
448  s2=gl[2]/(gl[2]-gl[0]);
449  if(gl[2]<0.){
450  pt1 = 1; pt2 = 0;
451  }
452  xyz_front[pt2][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
453  xyz_front[pt2][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
454  xyz_front[pt2][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
455  xyz_front[pt1][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
456  xyz_front[pt1][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
457  xyz_front[pt1][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
458  }
459  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
460 
461  /*Portion of the segments*/
462  s1=gl[0]/(gl[0]-gl[1]);
463  s2=gl[0]/(gl[0]-gl[2]);
464  if(gl[0]<0.){
465  pt1 = 1; pt2 = 0;
466  }
467 
468  xyz_front[pt1][0]=xyz_list[3*0+0]+s1*(xyz_list[3*1+0]-xyz_list[3*0+0]);
469  xyz_front[pt1][1]=xyz_list[3*0+1]+s1*(xyz_list[3*1+1]-xyz_list[3*0+1]);
470  xyz_front[pt1][2]=xyz_list[3*0+2]+s1*(xyz_list[3*1+2]-xyz_list[3*0+2]);
471  xyz_front[pt2][0]=xyz_list[3*0+0]+s2*(xyz_list[3*2+0]-xyz_list[3*0+0]);
472  xyz_front[pt2][1]=xyz_list[3*0+1]+s2*(xyz_list[3*2+1]-xyz_list[3*0+1]);
473  xyz_front[pt2][2]=xyz_list[3*0+2]+s2*(xyz_list[3*2+2]-xyz_list[3*0+2]);
474  }
475  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
476 
477  /*Portion of the segments*/
478  s1=gl[1]/(gl[1]-gl[0]);
479  s2=gl[1]/(gl[1]-gl[2]);
480  if(gl[1]<0.){
481  pt1 = 1; pt2 = 0;
482  }
483 
484  xyz_front[pt2][0]=xyz_list[3*1+0]+s1*(xyz_list[3*0+0]-xyz_list[3*1+0]);
485  xyz_front[pt2][1]=xyz_list[3*1+1]+s1*(xyz_list[3*0+1]-xyz_list[3*1+1]);
486  xyz_front[pt2][2]=xyz_list[3*1+2]+s1*(xyz_list[3*0+2]-xyz_list[3*1+2]);
487  xyz_front[pt1][0]=xyz_list[3*1+0]+s2*(xyz_list[3*2+0]-xyz_list[3*1+0]);
488  xyz_front[pt1][1]=xyz_list[3*1+1]+s2*(xyz_list[3*2+1]-xyz_list[3*1+1]);
489  xyz_front[pt1][2]=xyz_list[3*1+2]+s2*(xyz_list[3*2+2]-xyz_list[3*1+2]);
490  }
491  else{
492  _error_("case not possible");
493  }
494 
495  /*Some checks in debugging mode*/
496  _assert_(s1>=0 && s1<=1.);
497  _assert_(s2>=0 && s2<=1.);
498 
499  /*Get normal vector*/
500  IssmDouble normal[3];
501  this->NormalSectionBase(&normal[0],&xyz_front[0][0]);
502  normal[0] = -normal[0];
503  normal[1] = -normal[1];
504 
505  /*Get inputs*/
506  IssmDouble flux = 0.;
507  IssmDouble area = 0.;
508  IssmDouble calvingratex,calvingratey,thickness,Jdet,flux_per_area;
510  Input2* thickness_input=this->GetInput2(ThicknessEnum); _assert_(thickness_input);
511  Input2* calvingratex_input=NULL;
512  Input2* calvingratey_input=NULL;
513  calvingratex_input=this->GetInput2(CalvingratexEnum); _assert_(calvingratex_input);
514  calvingratey_input=this->GetInput2(CalvingrateyEnum); _assert_(calvingratey_input);
515 
516  /*Start looping on Gaussian points*/
517  Gauss* gauss=this->NewGaussBase(xyz_list,&xyz_front[0][0],3);
518  for(int ig=gauss->begin();ig<gauss->end();ig++){
519 
520  gauss->GaussPoint(ig);
521  thickness_input->GetInputValue(&thickness,gauss);
522  calvingratex_input->GetInputValue(&calvingratex,gauss);
523  calvingratey_input->GetInputValue(&calvingratey,gauss);
524  this->JacobianDeterminantLine(&Jdet,&xyz_front[0][0],gauss);
525 
526  flux += rho_ice*Jdet*gauss->weight*thickness*(calvingratex*normal[0] + calvingratey*normal[1]);
527  area += Jdet*gauss->weight*thickness;
528 
529  flux_per_area=flux/area;
530  }
531 
532  this->AddInput2(CalvingFluxLevelsetEnum,&flux_per_area,P0Enum);
533 
534  /*Clean up and return*/
535  delete gauss;
536  }
537 }
538 /*}}}*/
540 
541  /*Make sure there is an ice front here*/
543  IssmDouble flux_per_area=0;
544  this->AddInput2(CalvingMeltingFluxLevelsetEnum,&flux_per_area,P0Enum);
545  }
546  else{
547  int domaintype,index1,index2;
548  const IssmPDouble epsilon = 1.e-15;
549  IssmDouble s1,s2;
551  IssmDouble xyz_front[2][3];
552 
553  IssmDouble *xyz_list = NULL;
554  this->GetVerticesCoordinates(&xyz_list);
555 
556  /*Recover parameters and values*/
558 
559  /*Be sure that values are not zero*/
560  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
561  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
562  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
563 
564  int pt1 = 0;
565  int pt2 = 1;
566  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
567 
568  /*Portion of the segments*/
569  s1=gl[2]/(gl[2]-gl[1]);
570  s2=gl[2]/(gl[2]-gl[0]);
571  if(gl[2]<0.){
572  pt1 = 1; pt2 = 0;
573  }
574  xyz_front[pt2][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
575  xyz_front[pt2][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
576  xyz_front[pt2][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
577  xyz_front[pt1][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
578  xyz_front[pt1][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
579  xyz_front[pt1][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
580  }
581  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
582 
583  /*Portion of the segments*/
584  s1=gl[0]/(gl[0]-gl[1]);
585  s2=gl[0]/(gl[0]-gl[2]);
586  if(gl[0]<0.){
587  pt1 = 1; pt2 = 0;
588  }
589 
590  xyz_front[pt1][0]=xyz_list[3*0+0]+s1*(xyz_list[3*1+0]-xyz_list[3*0+0]);
591  xyz_front[pt1][1]=xyz_list[3*0+1]+s1*(xyz_list[3*1+1]-xyz_list[3*0+1]);
592  xyz_front[pt1][2]=xyz_list[3*0+2]+s1*(xyz_list[3*1+2]-xyz_list[3*0+2]);
593  xyz_front[pt2][0]=xyz_list[3*0+0]+s2*(xyz_list[3*2+0]-xyz_list[3*0+0]);
594  xyz_front[pt2][1]=xyz_list[3*0+1]+s2*(xyz_list[3*2+1]-xyz_list[3*0+1]);
595  xyz_front[pt2][2]=xyz_list[3*0+2]+s2*(xyz_list[3*2+2]-xyz_list[3*0+2]);
596  }
597  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
598 
599  /*Portion of the segments*/
600  s1=gl[1]/(gl[1]-gl[0]);
601  s2=gl[1]/(gl[1]-gl[2]);
602  if(gl[1]<0.){
603  pt1 = 1; pt2 = 0;
604  }
605 
606  xyz_front[pt2][0]=xyz_list[3*1+0]+s1*(xyz_list[3*0+0]-xyz_list[3*1+0]);
607  xyz_front[pt2][1]=xyz_list[3*1+1]+s1*(xyz_list[3*0+1]-xyz_list[3*1+1]);
608  xyz_front[pt2][2]=xyz_list[3*1+2]+s1*(xyz_list[3*0+2]-xyz_list[3*1+2]);
609  xyz_front[pt1][0]=xyz_list[3*1+0]+s2*(xyz_list[3*2+0]-xyz_list[3*1+0]);
610  xyz_front[pt1][1]=xyz_list[3*1+1]+s2*(xyz_list[3*2+1]-xyz_list[3*1+1]);
611  xyz_front[pt1][2]=xyz_list[3*1+2]+s2*(xyz_list[3*2+2]-xyz_list[3*1+2]);
612  }
613  else{
614  _error_("case not possible");
615  }
616 
617  /*Some checks in debugging mode*/
618  _assert_(s1>=0 && s1<=1.);
619  _assert_(s2>=0 && s2<=1.);
620 
621  /*Get normal vector*/
622  IssmDouble normal[3];
623  this->NormalSectionBase(&normal[0],&xyz_front[0][0]);
624  normal[0] = -normal[0];
625  normal[1] = -normal[1];
626 
627  /*Get inputs*/
628  IssmDouble flux = 0.;
629  IssmDouble area = 0.;
630  IssmDouble calvingratex,calvingratey,vx,vy,vel,meltingrate,meltingratex,meltingratey,thickness,Jdet,flux_per_area;
632  Input2* thickness_input=this->GetInput2(ThicknessEnum); _assert_(thickness_input);
633  Input2* calvingratex_input=NULL;
634  Input2* calvingratey_input=NULL;
635  Input2* vx_input=NULL;
636  Input2* vy_input=NULL;
637  Input2* meltingrate_input=NULL;
638  calvingratex_input=this->GetInput2(CalvingratexEnum); _assert_(calvingratex_input);
639  calvingratey_input=this->GetInput2(CalvingrateyEnum); _assert_(calvingratey_input);
640  vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
641  vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
642  meltingrate_input=this->GetInput2(CalvingMeltingrateEnum); _assert_(meltingrate_input);
643 
644  /*Start looping on Gaussian points*/
645  Gauss* gauss=this->NewGaussBase(xyz_list,&xyz_front[0][0],3);
646  for(int ig=gauss->begin();ig<gauss->end();ig++){
647 
648  gauss->GaussPoint(ig);
649  thickness_input->GetInputValue(&thickness,gauss);
650  calvingratex_input->GetInputValue(&calvingratex,gauss);
651  calvingratey_input->GetInputValue(&calvingratey,gauss);
652  vx_input->GetInputValue(&vx,gauss);
653  vy_input->GetInputValue(&vy,gauss);
654  vel=vx*vx+vy*vy;
655  meltingrate_input->GetInputValue(&meltingrate,gauss);
656  meltingratex=meltingrate*vx/(sqrt(vel)+1.e-14);
657  meltingratey=meltingrate*vy/(sqrt(vel)+1.e-14);
658  this->JacobianDeterminantLine(&Jdet,&xyz_front[0][0],gauss);
659 
660  flux += rho_ice*Jdet*gauss->weight*thickness*((calvingratex+meltingratex)*normal[0] + (calvingratey+meltingratey)*normal[1]);
661  area += Jdet*gauss->weight*thickness;
662 
663  flux_per_area=flux/area;
664  }
665 
666  this->AddInput2(CalvingMeltingFluxLevelsetEnum,&flux_per_area,P0Enum);
667 
668  /*Clean up and return*/
669  delete gauss;
670  }
671 }
672 /*}}}*/
673 void Penta::ComputeBasalStress(void){/*{{{*/
674 
675  _error_("not implemented (needs to be redone)");
676  int i,j;
677  int dofv[3]={0,1,2};
678  int dofp[1]={3};
679  int analysis_type,approximation;
680  IssmDouble xyz_list[NUMVERTICES][3];
681  IssmDouble xyz_list_tria[3][3];
682  IssmDouble rho_ice,gravity,FSreconditioning;
683  IssmDouble pressure,viscosity,Jdet2d;
684  IssmDouble bed_normal[3];
685  IssmDouble basalforce[3] = {0.};
686  IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
687  IssmDouble stresstensor[6]={0.0};
688  IssmDouble sigma_xx,sigma_yy,sigma_zz;
689  IssmDouble sigma_xy,sigma_xz,sigma_yz;
690  IssmDouble surface=0,value=0;
691  GaussPenta* gauss;
692 
693  /*retrive parameters: */
694  parameters->FindParam(&analysis_type,AnalysisTypeEnum);
695  this->GetInput2Value(&approximation,ApproximationEnum);
696 
697  /*Check analysis_types*/
698  if (analysis_type!=StressbalanceAnalysisEnum) _error_("Not supported yet!");
699  if (approximation!=FSApproximationEnum) _error_("Not supported yet!");
700 
701  /*retrieve some parameters: */
702  this->parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);
703 
704  if(!IsOnBase()){
705  //put zero
706  //sigma_b->SetValue(id-1,0.0,INS_VAL);
707  return;
708  }
709 
710  /*recovre material parameters: */
712  gravity=FindParam(ConstantsGEnum);
713 
714  /* Get node coordinates and dof list: */
716  for(i=0;i<3;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
717 
718  /*Retrieve all inputs we will be needing: */
719  Input2* pressure_input=this->GetInput2(PressureEnum); _assert_(pressure_input);
720  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
721  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
722  Input2* vz_input=this->GetInput2(VzEnum); _assert_(vz_input);
723 
724  /* Start looping on the number of gaussian points: */
725  gauss=new GaussPenta(0,1,2,2);
726  for(int ig=gauss->begin();ig<gauss->end();ig++){
727 
728  gauss->GaussPoint(ig);
729 
730  /*Compute strain rate viscosity and pressure: */
731  this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
732  this->material->ViscosityFS(&viscosity,3,&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
733  pressure_input->GetInputValue(&pressure,gauss);
734 
735  /*Compute Stress*/
736  sigma_xx=2*viscosity*epsilon[0]-pressure*FSreconditioning; // sigma = nu eps - pressure
737  sigma_yy=2*viscosity*epsilon[1]-pressure*FSreconditioning;
738  sigma_zz=2*viscosity*epsilon[2]-pressure*FSreconditioning;
739  sigma_xy=2*viscosity*epsilon[3];
740  sigma_xz=2*viscosity*epsilon[4];
741  sigma_yz=2*viscosity*epsilon[5];
742 
743  /*Get normal vector to the bed */
744  NormalBase(&bed_normal[0],&xyz_list_tria[0][0]);
745 
746  /*basalforce*/
747  basalforce[0] += sigma_xx*bed_normal[0] + sigma_xy*bed_normal[1] + sigma_xz*bed_normal[2];
748  basalforce[1] += sigma_xy*bed_normal[0] + sigma_yy*bed_normal[1] + sigma_yz*bed_normal[2];
749  basalforce[2] += sigma_xz*bed_normal[0] + sigma_yz*bed_normal[1] + sigma_zz*bed_normal[2];
750 
751  GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
752  value+=sigma_zz*Jdet2d*gauss->weight;
753  surface+=Jdet2d*gauss->weight;
754  }
755  value=value/surface;
756 
757  /*Add value to output*/
758  //sigma_b->SetValue(id-1,value,INS_VAL);
759 }
760 /*}}}*/
762 
763  IssmDouble xyz_list[NUMVERTICES][3];
764  IssmDouble viscosity;
765  IssmDouble epsilon[6]; /* epsilon=[exx,eyy,exy];*/
766  IssmDouble tau_xx[NUMVERTICES];
767  IssmDouble tau_yy[NUMVERTICES];
768  IssmDouble tau_zz[NUMVERTICES];
769  IssmDouble tau_xy[NUMVERTICES];
770  IssmDouble tau_xz[NUMVERTICES];
771  IssmDouble tau_yz[NUMVERTICES];
772  IssmDouble tau_eff[NUMVERTICES];
773  GaussPenta* gauss=NULL;
774 
775  /* Get node coordinates and dof list: */
777 
778  /*Retrieve all inputs we will be needing: */
779  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
780  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
781  Input2* vz_input=this->GetInput2(VzEnum); _assert_(vz_input);
782 
783  /* Start looping on the number of vertices: */
784  gauss=new GaussPenta();
785  for (int iv=0;iv<NUMVERTICES;iv++){
786  gauss->GaussVertex(iv);
787 
788  /*Compute strain rate viscosity and pressure: */
789  this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
790  this->material->ViscosityFS(&viscosity,3,&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
791 
792  /*Compute Stress*/
793  tau_xx[iv]=2*viscosity*epsilon[0]; // tau = nu eps
794  tau_yy[iv]=2*viscosity*epsilon[1];
795  tau_zz[iv]=2*viscosity*epsilon[2];
796  tau_xy[iv]=2*viscosity*epsilon[3];
797  tau_xz[iv]=2*viscosity*epsilon[4];
798  tau_yz[iv]=2*viscosity*epsilon[5];
799 
800  tau_eff[iv] = tau_xx[iv]*tau_xx[iv] + tau_yy[iv]*tau_yy[iv] + tau_zz[iv]*tau_zz[iv] +
801  2*tau_xy[iv]*tau_xy[iv] + 2*tau_xz[iv]*tau_xz[iv] + 2*tau_yz[iv]*tau_yz[iv];
802 
803  tau_eff[iv] = sqrt(tau_eff[iv]/2.);
804  }
805 
806  /*Add Stress tensor components into inputs*/
807  this->AddInput2(DeviatoricStressxxEnum,&tau_xx[0],P1DGEnum);
808  this->AddInput2(DeviatoricStressxyEnum,&tau_xy[0],P1DGEnum);
809  this->AddInput2(DeviatoricStressxzEnum,&tau_xz[0],P1DGEnum);
810  this->AddInput2(DeviatoricStressyyEnum,&tau_yy[0],P1DGEnum);
811  this->AddInput2(DeviatoricStressyzEnum,&tau_yz[0],P1DGEnum);
812  this->AddInput2(DeviatoricStresszzEnum,&tau_zz[0],P1DGEnum);
814 
815  /*Clean up and return*/
816  delete gauss;
817 }
818 /*}}}*/
820 
821  IssmDouble xyz_list[NUMVERTICES][3];
822  IssmDouble pressure,viscosity;
823  IssmDouble epsilon[6]; /* epsilon=[exx,eyy,exy];*/
824  IssmDouble sigma_xx[NUMVERTICES];
825  IssmDouble sigma_yy[NUMVERTICES];
826  IssmDouble sigma_zz[NUMVERTICES];
827  IssmDouble sigma_xy[NUMVERTICES];
828  IssmDouble sigma_xz[NUMVERTICES];
829  IssmDouble sigma_yz[NUMVERTICES];
830  GaussPenta* gauss=NULL;
831 
832  /* Get node coordinates and dof list: */
834 
835  /*Retrieve all inputs we will be needing: */
836  Input2* pressure_input=this->GetInput2(PressureEnum); _assert_(pressure_input);
837  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
838  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
839  Input2* vz_input=this->GetInput2(VzEnum); _assert_(vz_input);
840 
841  /* Start looping on the number of vertices: */
842  gauss=new GaussPenta();
843  for (int iv=0;iv<NUMVERTICES;iv++){
844  gauss->GaussVertex(iv);
845 
846  /*Compute strain rate viscosity and pressure: */
847  this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
848  this->material->ViscosityFS(&viscosity,3,&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
849  pressure_input->GetInputValue(&pressure,gauss);
850 
851  /*Compute Stress*/
852  sigma_xx[iv]=2*viscosity*epsilon[0]-pressure; // sigma = nu eps - pressure
853  sigma_yy[iv]=2*viscosity*epsilon[1]-pressure;
854  sigma_zz[iv]=2*viscosity*epsilon[2]-pressure;
855  sigma_xy[iv]=2*viscosity*epsilon[3];
856  sigma_xz[iv]=2*viscosity*epsilon[4];
857  sigma_yz[iv]=2*viscosity*epsilon[5];
858  }
859 
860  /*Add Stress tensor components into inputs*/
861  this->AddInput2(StressTensorxxEnum,&sigma_xx[0],P1DGEnum);
862  this->AddInput2(StressTensorxyEnum,&sigma_xy[0],P1DGEnum);
863  this->AddInput2(StressTensorxzEnum,&sigma_xz[0],P1DGEnum);
864  this->AddInput2(StressTensoryyEnum,&sigma_yy[0],P1DGEnum);
865  this->AddInput2(StressTensoryzEnum,&sigma_yz[0],P1DGEnum);
866  this->AddInput2(StressTensorzzEnum,&sigma_zz[0],P1DGEnum);
867 
868  /*Clean up and return*/
869  delete gauss;
870 }
871 /*}}}*/
872 void Penta::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin,Inputs2* inputs2in){/*{{{*/
873 
874  int analysis_counter;
875 
876  /*go into parameters and get the analysis_counter: */
877  parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
878 
879  /*Get Element type*/
880  this->element_type=this->element_type_list[analysis_counter];
881 
882  /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective
883  * datasets, using internal ids and offsets hidden in hooks: */
884  if (this->hnodes[analysis_counter]) this->hnodes[analysis_counter]->configure(nodesin);
885  this->hvertices->configure(verticesin);
886  this->hmaterial->configure(materialsin);
887  this->hneighbors->configure(elementsin);
888 
889  /*Now, go pick up the objects inside the hooks: */
890  if (this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
891  else this->nodes=NULL;
892  this->vertices = (Vertex**)this->hvertices->deliverp();
893  this->material = (Material*)this->hmaterial->delivers();
894  this->verticalneighbors = (Penta**)this->hneighbors->deliverp();
895 
896  /*point parameters to real dataset: */
897  this->parameters=parametersin;
898  this->inputs2=inputs2in;
899 }
900 /*}}}*/
901 void Penta::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index,int offset,int N,int M){/*{{{*/
902 
903  if(enum_type==MaterialsRheologyBbarEnum) enum_type = MaterialsRheologyBEnum;
904  if(enum_type==DamageDbarEnum) enum_type = DamageDEnum;
905 
906  _error_("not implemented");
907  int vertexpidlist[NUMVERTICES];
908  IssmDouble grad_list[NUMVERTICES];
909  Input2* grad_input=NULL;
910  Input2* input=NULL;
911 
912  if(enum_type==MaterialsRheologyBbarEnum){
913  input=this->GetInput2(MaterialsRheologyBEnum);
914  }
915  else if(enum_type==DamageDbarEnum){
916  input=this->GetInput2(DamageDEnum);
917  }
918  else{
919  input=this->GetInput2(enum_type);
920  }
921  if (!input) _error_("Input " << EnumToStringx(enum_type) << " not found");
922  if(input->ObjectEnum()!=ControlInput2Enum) _error_("Input " << EnumToStringx(enum_type) << " is not a ControlInput");
923 
924  GradientIndexing(&vertexpidlist[0],control_index);
925 
926  //for(int i=0;i<NUMVERTICES;i++) grad_list[i]=gradient[vertexpidlist[i]];
927  //grad_input=new PentaInput(GradientEnum,grad_list,P1Enum);
928  //((ControlInput*)input)->SetGradient(grad_input);
929  _error_("not implemented");
930 
931 }
932 /*}}}*/
933 void Penta::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){/*{{{*/
934 
935  int idlist[NUMVERTICES];
936  int vertexlids[NUMVERTICES];
937  IssmDouble grad_list[NUMVERTICES];
938 
939  if(enum_type==MaterialsRheologyBbarEnum) enum_type = MaterialsRheologyBEnum;
940  if(enum_type==DamageDbarEnum) enum_type = DamageDEnum;
941 
942  GradientIndexing(&idlist[0],control_index);
943  for(int i=0;i<NUMVERTICES;i++) grad_list[i]=gradient[idlist[i]];
944  for(int i=0;i<NUMVERTICES;i++) vertexlids[i]=this->vertices[i]->lid;
945 
946  this->inputs2->SetTriaControlInputGradient(enum_type,P1Enum,NUMVERTICES,&vertexlids[0],&grad_list[0]);
947 }/*}}}*/
948 void Penta::ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){/*{{{*/
949 
950  int sidlist[NUMVERTICES];
951  int lidlist[NUMVERTICES];
952  int connectivity[NUMVERTICES];
953  IssmPDouble values[NUMVERTICES];
954  IssmPDouble gradients[NUMVERTICES];
955  IssmDouble value,gradient;
956 
957  if(control_enum==MaterialsRheologyBbarEnum) control_enum = MaterialsRheologyBEnum;
958  if(control_enum==DamageDbarEnum) control_enum = DamageDEnum;
959 
960  this->GetVerticesConnectivityList(&connectivity[0]);
961  this->GetVerticesSidList(&sidlist[0]);
962  this->GetVerticesLidList(&lidlist[0]);
963 
964  ElementInput2* control_value = this->inputs2->GetControlInput2Data(control_enum,"value"); _assert_(control_value);
965  ElementInput2* control_gradient = this->inputs2->GetControlInput2Data(control_enum,"gradient"); _assert_(control_gradient);
966  control_value->Serve(NUMVERTICES,&lidlist[0]);
967  control_gradient->Serve(NUMVERTICES,&lidlist[0]);
968 
969  GaussPenta* gauss=new GaussPenta();
970  for (int iv=0;iv<NUMVERTICES;iv++){
971  gauss->GaussVertex(iv);
972 
973  control_value->GetInputValue(&value,gauss);
974  control_gradient->GetInputValue(&gradient,gauss);
975 
976  values[iv] = reCast<IssmPDouble>(value)/reCast<IssmPDouble>(connectivity[iv]);
977  gradients[iv] = reCast<IssmPDouble>(gradient)/reCast<IssmPDouble>(connectivity[iv]);
978  }
979  delete gauss;
980 
981  vector_control->SetValues(NUMVERTICES,&sidlist[0],&values[0],ADD_VAL);
982  vector_gradient->SetValues(NUMVERTICES,&sidlist[0],&gradients[0],ADD_VAL);
983 }/*}}}*/
984 void Penta::CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum){/*{{{*/
985 
986  /*Get current field and vertex coordinates*/
987  IssmDouble ls[NUMVERTICES],distance;
988  Element::GetInputListOnVertices(&ls[0],distanceenum);
989 
990  /*Get distance from list of segments and reset ls*/
991  for(int j=0;j<NUMVERTICES;j++){
992  distance=distances[this->vertices[j]->Lid()];
993  if(xIsNan<IssmDouble>(distance)) _error_("NaN found in vector");
994  if(xIsInf<IssmDouble>(distance)) _error_("Inf found in vector");
995 
996  /*FIXME: do we really need this?*/
997  if(distanceenum==MaskIceLevelsetEnum) if(distance>10000) distance=10000;
998  if(ls[j]>0){
999  ls[j] = distance;
1000  }
1001  else{
1002  ls[j] = - distance;
1003  }
1004  }
1005 
1006  /*Update Levelset*/
1007  this->AddInput2(distanceenum,&ls[0],P1Enum);
1008 }
1009 /*}}}*/
1010 void Penta::CreateInputTimeAverage(int transientinput_enum,int averagedinput_enum,IssmDouble start_time,IssmDouble end_time,int averaging_method){/*{{{*/
1011  _assert_(end_time>start_time);
1012 
1013  /*Get transient input time steps*/
1014  TransientInput2* transient_input = this->inputs2->GetTransientInput(transientinput_enum);
1015  PentaInput2* averaged_input = transient_input->GetPentaInput(start_time,end_time,averaging_method);
1016  Input2* averaged_copy = averaged_input->copy();
1017 
1018  averaged_copy->ChangeEnum(averagedinput_enum);
1019  this->inputs2->AddInput(averaged_copy);
1020 }
1021 /*}}}*/
1022 void Penta::ElementResponse(IssmDouble* presponse,int response_enum){/*{{{*/
1023 
1024  switch(response_enum){
1026  *presponse=this->material->GetBbar(NULL);
1027  break;
1028  case DamageDbarEnum:
1029  *presponse=this->material->GetDbar(NULL);
1030  break;
1031  case VelEnum:
1032  {
1033 
1034  /*Get input:*/
1035  IssmDouble vel;
1036  Input2* vel_input=this->GetInput2(VelEnum); _assert_(vel_input);
1037  vel_input->GetInputAverage(&vel);
1038 
1039  /*Assign output pointers:*/
1040  *presponse=vel;
1041  }
1042  break;
1043  default:
1044  _error_("Response type " << EnumToStringx(response_enum) << " not supported yet!");
1045  }
1046 
1047 }
1048 /*}}}*/
1050 
1051  IssmDouble xyz_list[NUMVERTICES][3];
1052  IssmDouble xmin,ymin,zmin;
1053  IssmDouble xmax,ymax,zmax;
1054 
1055  /*Get xyz list: */
1057  xmin=xyz_list[0][0]; xmax=xyz_list[0][0];
1058  ymin=xyz_list[0][1]; ymax=xyz_list[0][1];
1059  zmin=xyz_list[0][2]; zmax=xyz_list[0][2];
1060 
1061  for(int i=1;i<NUMVERTICES;i++){
1062  if(xyz_list[i][0]<xmin) xmin=xyz_list[i][0];
1063  if(xyz_list[i][0]>xmax) xmax=xyz_list[i][0];
1064  if(xyz_list[i][1]<ymin) ymin=xyz_list[i][1];
1065  if(xyz_list[i][1]>ymax) ymax=xyz_list[i][1];
1066  if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];
1067  if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];
1068  }
1069 
1070  *hx=xmax-xmin;
1071  *hy=ymax-ymin;
1072  *hz=zmax-zmin;
1073 }
1074 /*}}}*/
1075 int Penta::FiniteElement(void){/*{{{*/
1076  return this->element_type;
1077 }
1078 /*}}}*/
1079 IssmDouble Penta::FloatingArea(bool scaled){/*{{{*/
1080 
1081  /*Intermediaries*/
1082  int domaintype;
1083  IssmDouble phi,base_area,scalefactor,floatingarea;
1084  IssmDouble xyz_list[NUMVERTICES][3];
1085 
1086  if(!IsIceInElement() || !IsOnBase())return 0.;
1087 
1088  /*Get problem dimension*/
1089  this->FindParam(&domaintype,DomainTypeEnum);
1090  if(domaintype!=Domain3DEnum) _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
1091 
1093  phi=this->GetGroundedPortion(&xyz_list[0][0]);
1094  base_area= 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
1095 
1096  floatingarea=(1-phi)*base_area;
1097 
1098  if(scaled==true){
1099  Input2* scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
1100  scalefactor_input->GetInputAverage(&scalefactor);
1101  floatingarea=floatingarea*scalefactor;
1102  }
1103 
1104  /*Clean up and return*/
1105  return floatingarea;
1106 }
1107 /*}}}*/
1108 void Penta::FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure){/*{{{*/
1109 
1110  if(!IsOnBase()) return;
1111 
1112  int approximation;
1113  this->GetInput2Value(&approximation,ApproximationEnum);
1114  if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum || approximation==HOFSApproximationEnum){
1115  _error_("Cannot compute contact condition for non FS elements");
1116  }
1117 
1118  /*Intermediaries*/
1119  IssmDouble* xyz_list = NULL;
1120  IssmDouble bed_normal[3],base[NUMVERTICES],bed[NUMVERTICES],surface[NUMVERTICES],phi[NUMVERTICES];
1121  IssmDouble water_pressure[NUMVERTICES],pressureice[NUMVERTICES],pressure[NUMVERTICES];
1122  IssmDouble sigmaxx[NUMVERTICES],sigmayy[NUMVERTICES],sigmazz[NUMVERTICES],sigmaxy[NUMVERTICES];
1123  IssmDouble sigmayz[NUMVERTICES],sigmaxz[NUMVERTICES],sigma_nn[NUMVERTICES];
1124  IssmDouble viscosity,epsilon[NUMVERTICES];
1132  IssmDouble gravity = FindParam(ConstantsGEnum);
1133 
1134  /* Get node coordinates and dof list: */
1135  GetVerticesCoordinates(&xyz_list);
1136 
1137  /*Retrieve all inputs we will be needing: */
1138  Input2* vx_input = this->GetInput2(VxEnum); _assert_(vx_input);
1139  Input2* vy_input = this->GetInput2(VyEnum); _assert_(vy_input);
1140  Input2* vz_input = this->GetInput2(VzEnum); _assert_(vz_input);
1141 
1142  /*1. Recover stresses at the base*/
1143  GaussPenta* gauss=new GaussPenta();
1144  for (int iv=0;iv<NUMVERTICES;iv++){
1145  gauss->GaussVertex(iv);
1146 
1147  /*Compute strain rate viscosity and pressure: */
1148  this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
1149  this->material->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
1150  /*FIXME: this is for Hongju only*/
1151  //pressureice[iv]=gravity*rho_ice*(surface[iv]-base[iv]);
1152  //if (pressure[iv]/pressureice[iv]>1) pressure[iv]=pressureice[iv];
1153 
1154  /*Compute Stress*/
1155  sigmaxx[iv]=2*viscosity*epsilon[0]-pressure[iv]; // sigma = nu eps - pressure
1156  sigmayy[iv]=2*viscosity*epsilon[1]-pressure[iv];
1157  sigmazz[iv]=2*viscosity*epsilon[2]-pressure[iv];
1158  sigmaxy[iv]=2*viscosity*epsilon[3];
1159  sigmaxz[iv]=2*viscosity*epsilon[4];
1160  sigmayz[iv]=2*viscosity*epsilon[5];
1161  }
1162 
1163  /*2. compute contact condition*/
1164  for(int i=0;i<NUMVERTICES;i++){
1165 
1166  /*If was grounded*/
1167  if (phi[i]>=0.){
1168  NormalBase(&bed_normal[0],xyz_list);
1169  sigma_nn[i]=-1*(sigmaxx[i]*bed_normal[0]*bed_normal[0] + sigmayy[i]*bed_normal[1]*bed_normal[1] + sigmazz[i]*bed_normal[2]*bed_normal[2]+2*sigmaxy[i]*bed_normal[0]*bed_normal[1]+2*sigmaxz[i]*bed_normal[0]*bed_normal[2]+2*sigmayz[i]*bed_normal[1]*bed_normal[2]);
1170  water_pressure[i]=-gravity*rho_water*base[i];
1171  vertex_sigmann->SetValue(vertices[i]->Pid(),sigma_nn[i],ADD_VAL);
1172  vertex_waterpressure->SetValue(vertices[i]->Pid(),water_pressure[i],ADD_VAL);
1173  }
1174 
1175  /*If was floating*/
1176  else{
1177  /*Tricky part:
1178  * 1. if base is now touching, we put 1 for sigma_nn and leave water pressure at 0 so that the rest of the module will reground this vertex
1179  * 2. if base is still above bed, water pressure is set as 1, sigma_nn is left as 0, so the GL module will keep it afloat*/
1180  if(base[i]<bed[i]) vertex_sigmann->SetValue(vertices[i]->Pid(),+1.,ADD_VAL);
1181  else vertex_waterpressure->SetValue(vertices[i]->Pid(),+1.,ADD_VAL);
1182  }
1183  }
1184 
1185  /*clean up*/
1186  delete gauss;
1187  xDelete<IssmDouble>(xyz_list);
1188 }
1189 /*}}}*/
1190 void Penta::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){/*{{{*/
1191  /*Computeportion of the element that is grounded*/
1192 
1193  int i,j,k;
1194  IssmDouble area_init,area_portion;
1195  IssmDouble xyz_bis[3][3];
1196 
1197  area_init=fabs(xyz_list[1*3+0]*xyz_list[2*3+1] - xyz_list[1*3+1]*xyz_list[2*3+0] + xyz_list[0*3+0]*xyz_list[1*3+1] - xyz_list[0*3+1]*xyz_list[1*3+0] + xyz_list[2*3+0]*xyz_list[0*3+1] - xyz_list[2*3+1]*xyz_list[0*3+0])/2.;
1198 
1199  /*Initialize xyz_list with original xyz_list of triangle coordinates*/
1200  for(j=0;j<3;j++){
1201  for(k=0;k<3;k++){
1202  xyz_bis[j][k]=xyz_list[j*3+k];
1203  }
1204  }
1205  for(i=0;i<numpoints;i++){
1206  for(j=0;j<3;j++){
1207  for(k=0;k<3;k++){
1208  /*Change appropriate line*/
1209  xyz_bis[j][k]=xyz_zero[i*3+k];
1210  }
1211 
1212  /*Compute area fraction*/
1213  area_portion=fabs(xyz_bis[1][0]*xyz_bis[2][1] - xyz_bis[1][1]*xyz_bis[2][0] + xyz_bis[0][0]*xyz_bis[1][1] - xyz_bis[0][1]*xyz_bis[1][0] + xyz_bis[2][0]*xyz_bis[0][1] - xyz_bis[2][1]*xyz_bis[0][0])/2.;
1214  *(area_coordinates+3*i+j)=area_portion/area_init;
1215 
1216  /*Reinitialize xyz_list*/
1217  for(k=0;k<3;k++){
1218  /*Reinitialize xyz_list with original coordinates*/
1219  xyz_bis[j][k]=xyz_list[j*3+k];
1220  }
1221  }
1222  }
1223 }
1224 /*}}}*/
1226 
1227  /*Output*/
1228  Element* element=this->GetBasalPenta();
1229  return element;
1230 }
1231 /*}}}*/
1233 
1234  /*Output*/
1235  Penta* penta=NULL;
1236 
1237  /*Go through all pentas till the bed is reached*/
1238  penta=this;
1239  for(;;){
1240  /*Stop if we have reached the surface, else, take lower penta*/
1241  if (penta->IsOnBase()) break;
1242 
1243  /* get lower Penta*/
1244  penta=penta->GetLowerPenta();
1245  _assert_(penta->Id()!=this->id);
1246  }
1247 
1248  /*return output*/
1249  return penta;
1250 }
1251 /*}}}*/
1253 
1254  /*return PentaRef field*/
1255  return this->element_type;
1256 }
1257 /*}}}*/
1258 void Penta::GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating){/*{{{*/
1259  /*Computeportion of the element that is grounded*/
1260 
1261  bool floating=true;
1262  int point;
1263  const IssmPDouble epsilon= 1.e-15;
1264  IssmDouble gl[NUMVERTICES];
1265  IssmDouble f1,f2;
1266 
1267  /*Recover parameters and values*/
1269 
1270  /*Be sure that values are not zero*/
1271  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
1272  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
1273  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
1274 
1275  /*Check that not all nodes are grounded or floating*/
1276  if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded
1277  point=0;
1278  f1=1.;
1279  f2=1.;
1280  }
1281  else if(gl[0]<0 && gl[1]<0 && gl[2]<0){ //All floating
1282  point=0;
1283  f1=0.;
1284  f2=0.;
1285  }
1286  else{
1287  if(gl[0]*gl[1]*gl[2]<0) floating=false;
1288 
1289  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
1290  point=2;
1291  f1=gl[2]/(gl[2]-gl[0]);
1292  f2=gl[2]/(gl[2]-gl[1]);
1293  }
1294  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
1295  point=0;
1296  f1=gl[0]/(gl[0]-gl[1]);
1297  f2=gl[0]/(gl[0]-gl[2]);
1298  }
1299  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
1300  point=1;
1301  f1=gl[1]/(gl[1]-gl[2]);
1302  f2=gl[1]/(gl[1]-gl[0]);
1303  }
1304  else _error_("case not possible");
1305  }
1306  *point1=point;
1307  *fraction1=f1;
1308  *fraction2=f2;
1309  *mainlyfloating=floating;
1310 }
1311 /*}}}*/
1313  /*Computeportion of the element that is grounded*/
1314 
1315  bool mainlyfloating = true;
1316  const IssmPDouble epsilon= 1.e-15;
1317  IssmDouble phi,s1,s2,area_init,area_grounded;
1318  IssmDouble gl[NUMVERTICES];
1319  IssmDouble xyz_bis[NUMVERTICES2D][3];
1320 
1321  /*Recover parameters and values*/
1323 
1324  /*Be sure that values are not zero*/
1325  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
1326  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
1327  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
1328 
1329  /*Check that not all nodes are grounded or floating*/
1330  if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded
1331  phi=1;
1332  }
1333  else if(gl[0]<0 && gl[1]<0 && gl[2]<0){ //All floating
1334  phi=0;
1335  }
1336  else{
1337  /*Figure out if two nodes are floating or grounded*/
1338  if(gl[0]*gl[1]*gl[2]>0) mainlyfloating=false;
1339 
1340  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
1341  /*Coordinates of point 2: same as initial point 2*/
1342  xyz_bis[2][0]=xyz_list[3*2+0];
1343  xyz_bis[2][1]=xyz_list[3*2+1];
1344  xyz_bis[2][2]=xyz_list[3*2+2];
1345 
1346  /*Portion of the segments*/
1347  s1=gl[2]/(gl[2]-gl[1]);
1348  s2=gl[2]/(gl[2]-gl[0]);
1349 
1350  /*New point 1*/
1351  xyz_bis[1][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
1352  xyz_bis[1][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
1353  xyz_bis[1][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
1354 
1355  /*New point 0*/
1356  xyz_bis[0][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
1357  xyz_bis[0][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
1358  xyz_bis[0][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
1359  }
1360  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
1361  /*Coordinates of point 0: same as initial point 2*/
1362  xyz_bis[0][0]=*(xyz_list+3*0+0);
1363  xyz_bis[0][1]=*(xyz_list+3*0+1);
1364  xyz_bis[0][2]=*(xyz_list+3*0+2);
1365 
1366  /*Portion of the segments*/
1367  s1=gl[0]/(gl[0]-gl[1]);
1368  s2=gl[0]/(gl[0]-gl[2]);
1369 
1370  /*New point 1*/
1371  xyz_bis[1][0]=*(xyz_list+3*0+0)+s1*(*(xyz_list+3*1+0)-*(xyz_list+3*0+0));
1372  xyz_bis[1][1]=*(xyz_list+3*0+1)+s1*(*(xyz_list+3*1+1)-*(xyz_list+3*0+1));
1373  xyz_bis[1][2]=*(xyz_list+3*0+2)+s1*(*(xyz_list+3*1+2)-*(xyz_list+3*0+2));
1374 
1375  /*New point 2*/
1376  xyz_bis[2][0]=*(xyz_list+3*0+0)+s2*(*(xyz_list+3*2+0)-*(xyz_list+3*0+0));
1377  xyz_bis[2][1]=*(xyz_list+3*0+1)+s2*(*(xyz_list+3*2+1)-*(xyz_list+3*0+1));
1378  xyz_bis[2][2]=*(xyz_list+3*0+2)+s2*(*(xyz_list+3*2+2)-*(xyz_list+3*0+2));
1379  }
1380  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
1381  /*Coordinates of point 1: same as initial point 2*/
1382  xyz_bis[1][0]=*(xyz_list+3*1+0);
1383  xyz_bis[1][1]=*(xyz_list+3*1+1);
1384  xyz_bis[1][2]=*(xyz_list+3*1+2);
1385 
1386  /*Portion of the segments*/
1387  s1=gl[1]/(gl[1]-gl[0]);
1388  s2=gl[1]/(gl[1]-gl[2]);
1389 
1390  /*New point 0*/
1391  xyz_bis[0][0]=*(xyz_list+3*1+0)+s1*(*(xyz_list+3*0+0)-*(xyz_list+3*1+0));
1392  xyz_bis[0][1]=*(xyz_list+3*1+1)+s1*(*(xyz_list+3*0+1)-*(xyz_list+3*1+1));
1393  xyz_bis[0][2]=*(xyz_list+3*1+2)+s1*(*(xyz_list+3*0+2)-*(xyz_list+3*1+2));
1394 
1395  /*New point 2*/
1396  xyz_bis[2][0]=*(xyz_list+3*1+0)+s2*(*(xyz_list+3*2+0)-*(xyz_list+3*1+0));
1397  xyz_bis[2][1]=*(xyz_list+3*1+1)+s2*(*(xyz_list+3*2+1)-*(xyz_list+3*1+1));
1398  xyz_bis[2][2]=*(xyz_list+3*1+2)+s2*(*(xyz_list+3*2+2)-*(xyz_list+3*1+2));
1399  }
1400  else _error_("case not possible");
1401 
1402  /*Compute fraction of grounded element*/
1403  GetTriaJacobianDeterminant(&area_init, xyz_list,NULL);
1404  GetTriaJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL);
1405  if(mainlyfloating==true) area_grounded=area_init-area_grounded;
1406  phi=area_grounded/area_init;
1407  }
1408 
1409  if(phi>1. || phi<0.) _error_("Error. Problem with portion of grounded element: value should be between 0 and 1");
1410 
1411  return phi;
1412 }
1413 /*}}}*/
1415 
1416  IssmDouble bed[NUMVERTICES]; //basinId[NUMVERTICES];
1417  IssmDouble Haverage,frontarea;
1418  IssmDouble x1,y1,x2,y2,distance;
1419  IssmDouble lsf[NUMVERTICES], Haux[NUMVERTICES], surfaces[NUMVERTICES], bases[NUMVERTICES];
1420  int* indices=NULL;
1421  IssmDouble* H=NULL;;
1422  int nrfrontbed,numiceverts;
1423 
1424  if(!this->IsOnBase()) return 0;
1425  if(!IsZeroLevelset(MaskIceLevelsetEnum)) return 0;
1426 
1427  /*Retrieve all inputs and parameters*/
1432 
1433  nrfrontbed=0;
1434  for(int i=0;i<NUMVERTICES2D;i++){
1435  /*Find if bed<0*/
1436  if(bed[i]<0.) nrfrontbed++;
1437  }
1438 
1439  if(nrfrontbed==3){
1440  /*2. Find coordinates of where levelset crosses 0*/
1441  int numiceverts;
1442  IssmDouble s[2],x[2],y[2];
1443  this->GetLevelsetIntersectionBase(&indices, &numiceverts,&s[0],MaskIceLevelsetEnum,0.);
1444  _assert_(numiceverts);
1445 
1446  /*3 Write coordinates*/
1447  IssmDouble xyz_list[NUMVERTICES][3];
1448  ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
1449  int counter = 0;
1450  if((numiceverts>0) && (numiceverts<NUMVERTICES2D)){
1451  for(int i=0;i<numiceverts;i++){
1452  for(int n=numiceverts;n<NUMVERTICES2D;n++){ // iterate over no-ice vertices
1453  x[counter] = xyz_list[indices[i]][0]+s[counter]*(xyz_list[indices[n]][0]-xyz_list[indices[i]][0]);
1454  y[counter] = xyz_list[indices[i]][1]+s[counter]*(xyz_list[indices[n]][1]-xyz_list[indices[i]][1]);
1455  counter++;
1456  }
1457  }
1458  }
1459  else if(numiceverts==NUMVERTICES2D){ //NUMVERTICES ice vertices: calving front lies on element edge
1460 
1461  for(int i=0;i<NUMVERTICES2D;i++){
1462  if(lsf[indices[i]]==0.){
1463  x[counter]=xyz_list[indices[i]][0];
1464  y[counter]=xyz_list[indices[i]][1];
1465  counter++;
1466  }
1467  if(counter==2) break;
1468  }
1469  if(counter==1){
1470  /*We actually have only 1 vertex on levelset, write a single point as a segment*/
1471  x[counter]=x[0];
1472  y[counter]=y[0];
1473  counter++;
1474  }
1475  }
1476  else{
1477  _error_("not sure what's going on here...");
1478  }
1479  x1=x[0]; y1=y[0]; x2=x[1]; y2=y[1];
1480  distance=sqrt(pow((x1-x2),2)+pow((y1-y2),2));
1481 
1482  int numthk=numiceverts+2;
1483  H=xNew<IssmDouble>(numthk);
1484  for(int iv=0;iv<NUMVERTICES2D;iv++) Haux[iv]=-bed[indices[iv]]; //sort bed in ice/noice
1485 
1486  switch(numiceverts){
1487  case 1: // average over triangle
1488  H[0]=Haux[0];
1489  H[1]=Haux[0]+s[0]*(Haux[1]-Haux[0]);
1490  H[2]=Haux[0]+s[1]*(Haux[2]-Haux[0]);
1491  Haverage=(H[1]+H[2])/2;
1492  break;
1493  case 2: // average over quadrangle
1494  H[0]=Haux[0];
1495  H[1]=Haux[1];
1496  H[2]=Haux[0]+s[0]*(Haux[2]-Haux[0]);
1497  H[3]=Haux[1]+s[1]*(Haux[2]-Haux[1]);
1498  Haverage=(H[2]+H[3])/2;
1499  break;
1500  default:
1501  _error_("Number of ice covered vertices wrong in Tria::GetIceFrontArea(void)");
1502  break;
1503  }
1504  frontarea=distance*Haverage;
1505  }
1506  else return 0;
1507 
1508  xDelete<int>(indices);
1509  xDelete<IssmDouble>(H);
1510 
1511  _assert_(frontarea>0);
1512  return frontarea;
1513 }
1514 /*}}}*/
1515 void Penta::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
1516 
1517  /* Intermediaries */
1518  const int dim=3;
1519  int i, dir,nrfrontnodes;
1520  IssmDouble levelset[NUMVERTICES];
1521 
1522  /*Recover parameters and values*/
1523  Element::GetInputListOnVertices(&levelset[0],levelsetenum);
1524 
1525  int* indicesfront = xNew<int>(NUMVERTICES);
1526  /* Get basal nodes where there is no ice */
1527  nrfrontnodes=0;
1528  for(i=0;i<NUMVERTICES2D;i++){
1529  if(levelset[i]>=0.){
1530  indicesfront[nrfrontnodes]=i;
1531  nrfrontnodes++;
1532  }
1533  }
1534  _assert_(nrfrontnodes==2);
1535 
1536  /* arrange order of basal frontnodes such that they are oriented counterclockwise */
1537  if((NUMVERTICES2D+indicesfront[0]-indicesfront[1])%NUMVERTICES2D!=NUMVERTICES2D-1){
1538  int index=indicesfront[0];
1539  indicesfront[0]=indicesfront[1];
1540  indicesfront[1]=index;
1541  }
1542 
1543  IssmDouble* xyz_front = xNew<IssmDouble>(2*dim*nrfrontnodes);
1544  /* Return basal and top front nodes */
1545  for(i=0;i<nrfrontnodes;i++){
1546  for(dir=0;dir<dim;dir++){
1547  int ind1=i*dim+dir, ind2=(2*nrfrontnodes-1-i)*dim+dir; // vertex structure front segment: base0, base1, top1, top0
1548  xyz_front[ind1]=xyz_list[dim*indicesfront[i]+dir];
1549  xyz_front[ind2]=xyz_list[dim*(indicesfront[i]+NUMVERTICES2D)+dir];
1550  }
1551  }
1552 
1553  *pxyz_front=xyz_front;
1554 
1555  xDelete<int>(indicesfront);
1556 }/*}}}*/
1557 Input2* Penta::GetInput2(int inputenum){/*{{{*/
1558 
1559  /*Get Input from dataset*/
1560  PentaInput2* input = this->inputs2->GetPentaInput(inputenum);
1561  if(!input) return input;
1562 
1563  /*Intermediaries*/
1564  int numindices;
1565  int indices[30]; /*Max numnodes*/
1566 
1567  /*Check interpolation*/
1568  int interpolation = input->GetInterpolation();
1569  if(interpolation==P1Enum){
1570  numindices = 6;
1571  for(int i=0;i<6;i++) indices[i] = vertices[i]->lid;
1572  input->Serve(numindices,&indices[0]);
1573  }
1574  else{
1575  input->Serve(this->lid,this->GetNumberOfNodes(interpolation));
1576  }
1577 
1578  /*Tell input it is NOT collapsed*/
1579  //input->SetServeCollapsed(0); FIXME: not needed?
1580 
1581  /*Return*/
1582  return input;
1583 }/*}}}*/
1584 Input2* Penta::GetInput2(int inputenum,IssmDouble time){/*{{{*/
1585 
1586  /*Get Input from dataset*/
1587  PentaInput2* input = this->inputs2->GetPentaInput(inputenum,time);
1588  if(!input) return input;
1589 
1590  /*Intermediaries*/
1591  int numindices;
1592  int indices[30]; /*Max numnodes*/
1593 
1594  /*Check interpolation*/
1595  int interpolation = input->GetInterpolation();
1596  if(interpolation==P1Enum){
1597  numindices = 6;
1598  for(int i=0;i<6;i++) indices[i] = vertices[i]->lid;
1599  input->Serve(numindices,&indices[0]);
1600  }
1601  else{
1602  input->Serve(this->lid,this->GetNumberOfNodes(interpolation));
1603  }
1604 
1605  /*Tell input it is NOT collapsed*/
1606  //input->SetServeCollapsed(0); FIXME: not needed?
1607 
1608  /*Return*/
1609  return input;
1610 }/*}}}*/
1611 void Penta::GetInputListOnVertices(IssmDouble* pvalue,Input2* input,IssmDouble default_value){/*{{{*/
1612 
1613  /*Checks in debugging mode*/
1614  _assert_(pvalue);
1615 
1616  /* Start looping on the number of vertices: */
1617  if(input){
1618  GaussPenta gauss;
1619  for(int iv=0;iv<NUMVERTICES;iv++){
1620  gauss.GaussVertex(iv);
1621  input->GetInputValue(&pvalue[iv],&gauss);
1622  }
1623  }
1624  else{
1625  for(int iv=0;iv<NUMVERTICES;iv++) pvalue[iv] = default_value;
1626  }
1627 }
1628 /*}}}*/
1629 void Penta::GetInputListOnNodes(IssmDouble* pvalue,Input2* input,IssmDouble default_value){/*{{{*/
1630 
1631  /*Checks in debugging mode*/
1632  _assert_(pvalue);
1633 
1634  /*What type of finite element are we dealing with?*/
1635  int fe = this->FiniteElement();
1636  int numnodes = this->GetNumberOfNodes();
1637 
1638  /* Start looping on the number of vertices: */
1639  if(input){
1640  GaussPenta gauss;
1641  for(int iv=0;iv<numnodes;iv++){
1642  gauss.GaussNode(fe,iv);
1643  input->GetInputValue(&pvalue[iv],&gauss);
1644  }
1645  }
1646  else{
1647  for(int iv=0;iv<numnodes;iv++) pvalue[iv] = default_value;
1648  }
1649 }
1650 /*}}}*/
1652 
1653  DatasetInput2* datasetinput = this->inputs2->GetDatasetInput2(inputenum);
1654  if(!datasetinput) return NULL;
1655 
1656  for(int i=0;i<datasetinput->GetNumIds();i++){
1657 
1658  PentaInput2* input = datasetinput->GetPentaInputByOffset(i); _assert_(input);
1659 
1660  /*Intermediaries*/
1661  int numindices;
1662  int indices[30]; /*Max numnodes*/
1663 
1664  /*Check interpolation*/
1665  int interpolation = input->GetInterpolation();
1666  if(interpolation==P1Enum){
1667  numindices = 6;
1668  for(int i=0;i<6;i++) indices[i] = vertices[i]->lid;
1669  input->Serve(numindices,&indices[0]);
1670  }
1671  else{
1672  input->Serve(this->lid,this->GetNumberOfNodes(interpolation));
1673  }
1674 
1675  }
1676 
1677  return datasetinput;
1678 }/*}}}*/
1679 void Penta::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){/*{{{*/
1680 
1681  Input2* input=this->GetInput2(enumtype);
1682  if(!input) _error_("No input of type " << EnumToStringx(enumtype) << " found in tria");
1683 
1684  int index = this->GetNodeIndex(node);
1685 
1686  GaussPenta* gauss=new GaussPenta();
1687  gauss->GaussNode(this->element_type,index);
1688 
1689  input->GetInputValue(pvalue,gauss);
1690  delete gauss;
1691 }
1692 /*}}}*/
1693 void Penta::GetInputValue(IssmDouble* pvalue,Vertex* vertex,int enumtype){/*{{{*/
1694 
1695  Input2* input=this->GetInput2(enumtype);
1696  if(!input) _error_("No input of type " << EnumToStringx(enumtype) << " found in tria");
1697 
1698  int index = this->GetVertexIndex(vertex);
1699 
1700  GaussPenta* gauss=new GaussPenta();
1701  gauss->GaussVertex(index);
1702 
1703  input->GetInputValue(pvalue,gauss);
1704  delete gauss;
1705 }
1706 /*}}}*/
1708 
1709  Penta* lower_penta=NULL;
1710 
1711  lower_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above
1712 
1713  return lower_penta;
1714 }
1715 /*}}}*/
1716 void Penta::GetLevelsetIntersectionBase(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/
1717 
1718  /* GetLevelsetIntersection computes:
1719  * 1. indices of element, sorted in [iceverts, noiceverts] in counterclockwise fashion,
1720  * 2. fraction of intersected triangle edges intersected by levelset, lying below level*/
1721 
1722  /*Intermediaries*/
1723  int i, numiceverts, numnoiceverts;
1724  int ind0, ind1, lastindex;
1725  int indices_ice[NUMVERTICES2D],indices_noice[NUMVERTICES2D];
1726  IssmDouble lsf[NUMVERTICES];
1727  int* indices = xNew<int>(NUMVERTICES2D);
1728 
1729  /*Retrieve all inputs and parameters*/
1730  Element::GetInputListOnVertices(&lsf[0],levelset_enum);
1731 
1732  /* Determine distribution of ice over element.
1733  * Exploit: ice/no-ice parts are connected, so find starting vertex of segment*/
1734  lastindex=0;
1735  for(i=0;i<NUMVERTICES2D;i++){ // go backwards along vertices, and check for sign change
1736  ind0=(NUMVERTICES2D-i)%NUMVERTICES2D;
1737  ind1=(ind0-1+NUMVERTICES2D)%NUMVERTICES2D;
1738  if((lsf[ind0]-level)*(lsf[ind1]-level)<=0.){ // levelset has been crossed, find last index belonging to segment
1739  if(lsf[ind1]==level) //if levelset intersects 2nd vertex, choose this vertex as last
1740  lastindex=ind1;
1741  else
1742  lastindex=ind0;
1743  break;
1744  }
1745  }
1746 
1747  numiceverts=0;
1748  numnoiceverts=0;
1749  for(i=0;i<NUMVERTICES2D;i++){
1750  ind0=(lastindex+i)%NUMVERTICES2D;
1751  if(lsf[i]<=level){
1752  indices_ice[numiceverts]=i;
1753  numiceverts++;
1754  }
1755  else{
1756  indices_noice[numnoiceverts]=i;
1757  numnoiceverts++;
1758  }
1759  }
1760  //merge indices
1761  for(i=0;i<numiceverts;i++){indices[i]=indices_ice[i];}
1762  for(i=0;i<numnoiceverts;i++){indices[numiceverts+i]=indices_noice[i];}
1763 
1764  switch (numiceverts){
1765  case 0: // no vertex has ice: element is ice free, no intersection
1766  for(i=0;i<2;i++)
1767  fraction[i]=0.;
1768  break;
1769  case 1: // one vertex has ice:
1770  for(i=0;i<2;i++){
1771  fraction[i]=(level-lsf[indices[0]])/(lsf[indices[numiceverts+i]]-lsf[indices[0]]);
1772  }
1773  break;
1774  case 2: // two vertices have ice: fraction is computed from first ice vertex to last in CCW fashion
1775  for(i=0;i<2;i++){
1776  fraction[i]=(level-lsf[indices[i]])/(lsf[indices[numiceverts]]-lsf[indices[i]]);
1777  }
1778  break;
1779  case NUMVERTICES2D: // all vertices have ice: return triangle area
1780  for(i=0;i<2;i++)
1781  fraction[i]=1.;
1782  break;
1783  default:
1784  _error_("Wrong number of ice vertices in Penta::GetLevelsetIntersectionBase!");
1785  break;
1786  }
1787 
1788  *pindices=indices;
1789  *pnumiceverts=numiceverts;
1790 }
1791 /*}}}*/
1792 int Penta::GetVertexIndex(Vertex* vertex){/*{{{*/
1793  _assert_(vertices);
1794  for(int i=0;i<NUMVERTICES;i++){
1795  if(vertex==vertices[i])
1796  return i;
1797  }
1798  _error_("Vertex provided not found among element vertices");
1799 }
1800 /*}}}*/
1801 int Penta::GetNumberOfNodes(void){/*{{{*/
1802  return this->NumberofNodes(this->element_type);
1803 }
1804 /*}}}*/
1805 int Penta::GetNumberOfNodes(int enum_type){/*{{{*/
1806  return this->NumberofNodes(enum_type);
1807 }
1808 /*}}}*/
1810  return NUMVERTICES;
1811 }
1812 /*}}}*/
1814 
1815  Penta* upper_penta=NULL;
1816 
1817  upper_penta=(Penta*)verticalneighbors[1]; //first one (0) under, second one (1) above
1818 
1819  return upper_penta;
1820 }
1821 /*}}}*/
1822 void Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/
1823 
1824  /*Get out if this is not an element input*/
1825  if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
1826 
1827  /*Prepare index list*/
1828  int idlist[NUMVERTICES];
1829  GradientIndexing(&idlist[0],control_index);
1830 
1831  /*Get input (either in element or material)*/
1832  if(control_enum==MaterialsRheologyBbarEnum) control_enum=MaterialsRheologyBEnum;
1833  ElementInput2* input=this->inputs2->GetControlInput2Data(control_enum,data); _assert_(input);
1834 
1835  /*Intermediaries*/
1836  int numindices;
1837  int indices[NUMVERTICES];
1838 
1839  /*Check interpolation*/
1840  int interpolation = input->GetInterpolation();
1841  switch(interpolation){
1842  case P1Enum:
1843  numindices = NUMVERTICES;
1844  for(int i=0;i<NUMVERTICES;i++) indices[i] = vertices[i]->lid;
1845  input->Serve(numindices,&indices[0]);
1846  break;
1847  default: _error_("interpolation "<<EnumToStringx(interpolation)<<" not supported");
1848  }
1849 
1850  /* Start looping on the number of vertices: */
1851  IssmDouble values[NUMVERTICES];
1852  Gauss*gauss=this->NewGauss();
1853  for(int iv=0;iv<NUMVERTICES;iv++){
1854  gauss->GaussVertex(iv);
1855  input->GetInputValue(&values[iv],gauss);
1856  }
1857  delete gauss;
1858 
1859  vector->SetValues(NUMVERTICES,idlist,&values[0],INS_VAL);
1860 }
1861 /*}}}*/
1862 void Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset){/*{{{*/
1863 
1864  int* idlist = NULL;
1865  IssmDouble* values = NULL;
1866 
1867  /*Get input*/
1868  ElementInput2* input=this->inputs2->GetControlInput2Data(control_enum,data); _assert_(input);
1869 
1870  /*Check what input we are dealing with*/
1871  switch(input->ObjectEnum()){
1872  case PentaInput2Enum:
1873  {
1874  PentaInput2* pentainput = xDynamicCast<PentaInput2*>(input);
1875  if(pentainput->GetInputInterpolationType()!=P1Enum) _error_("not supported yet");
1876 
1877  /*Create list of indices and values for global vector*/
1878  idlist = xNew<int>(NUMVERTICES);
1879  values = xNew<IssmDouble>(NUMVERTICES);
1880  GradientIndexing(&idlist[0],control_index);
1881  for(int i=0;i<NUMVERTICES;i++){
1882  values[i] = pentainput->element_values[i];
1883  }
1884  vector->SetValues(NUMVERTICES,idlist,values,INS_VAL);
1885  break;
1886  }
1887 
1888  case TransientInputEnum:
1889  {
1890  _error_("not implemented (see Tria)");
1891  break;
1892  }
1893  default: _error_("input "<<input->ObjectEnum()<<" not supported yet");
1894 
1895  }
1896  xDelete<int>(idlist);
1897  xDelete<IssmDouble>(values);
1898  }
1899 /*}}}*/
1901 
1902  IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES2D*3);
1904 
1905  /*Assign output pointer*/
1906  *pxyz_list = xyz_list;
1907 
1908 }/*}}}*/
1910 
1911  IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES2D*3);
1912  ::GetVerticesCoordinates(xyz_list,&this->vertices[3],NUMVERTICES2D);
1913 
1914  /*Assign output pointer*/
1915  *pxyz_list = xyz_list;
1916 
1917 }/*}}}*/
1918 IssmDouble Penta::GroundedArea(bool scaled){/*{{{*/
1919 
1920  /*Intermediaries*/
1921  int domaintype;
1922  IssmDouble phi,base_area,scalefactor,groundedarea;
1923  IssmDouble xyz_list[NUMVERTICES][3];
1924 
1925  if(!IsIceInElement() || !IsOnBase())return 0.;
1926 
1927  /*Get problem dimension*/
1928  this->FindParam(&domaintype,DomainTypeEnum);
1929  if(domaintype!=Domain3DEnum) _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
1930 
1932  phi=this->GetGroundedPortion(&xyz_list[0][0]);
1933  base_area= 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
1934 
1935  groundedarea=phi*base_area;
1936 
1937  if(scaled==true){
1938  Input2* scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
1939  scalefactor_input->GetInputAverage(&scalefactor);
1940  groundedarea=groundedarea*scalefactor;
1941  }
1942  /*Clean up and return*/
1943  return groundedarea;
1944 }
1945 /*}}}*/
1947 
1948  /*Make sure there is a grounding line here*/
1949  if(!IsOnBase()) return 0;
1950  if(!IsIceInElement()) return 0;
1951  if(!IsZeroLevelset(MaskOceanLevelsetEnum)) return 0;
1952 
1953  /*Scaled not implemented yet...*/
1954  _assert_(!scaled);
1955 
1956  int domaintype,index1,index2;
1957  const IssmPDouble epsilon = 1.e-15;
1958  IssmDouble s1,s2;
1959  IssmDouble gl[NUMVERTICES];
1960  IssmDouble xyz_front[2][3];
1961 
1962  IssmDouble *xyz_list = NULL;
1963  this->GetVerticesCoordinates(&xyz_list);
1964 
1965  /*Recover parameters and values*/
1967 
1968  /*Be sure that values are not zero*/
1969  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
1970  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
1971  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
1972 
1973  int pt1 = 0;
1974  int pt2 = 1;
1975  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
1976 
1977  /*Portion of the segments*/
1978  s1=gl[2]/(gl[2]-gl[1]);
1979  s2=gl[2]/(gl[2]-gl[0]);
1980  if(gl[2]<0.){
1981  pt1 = 1; pt2 = 0;
1982  }
1983  xyz_front[pt2][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
1984  xyz_front[pt2][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
1985  xyz_front[pt2][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
1986  xyz_front[pt1][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
1987  xyz_front[pt1][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
1988  xyz_front[pt1][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
1989  }
1990  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
1991 
1992  /*Portion of the segments*/
1993  s1=gl[0]/(gl[0]-gl[1]);
1994  s2=gl[0]/(gl[0]-gl[2]);
1995  if(gl[0]<0.){
1996  pt1 = 1; pt2 = 0;
1997  }
1998 
1999  xyz_front[pt1][0]=xyz_list[3*0+0]+s1*(xyz_list[3*1+0]-xyz_list[3*0+0]);
2000  xyz_front[pt1][1]=xyz_list[3*0+1]+s1*(xyz_list[3*1+1]-xyz_list[3*0+1]);
2001  xyz_front[pt1][2]=xyz_list[3*0+2]+s1*(xyz_list[3*1+2]-xyz_list[3*0+2]);
2002  xyz_front[pt2][0]=xyz_list[3*0+0]+s2*(xyz_list[3*2+0]-xyz_list[3*0+0]);
2003  xyz_front[pt2][1]=xyz_list[3*0+1]+s2*(xyz_list[3*2+1]-xyz_list[3*0+1]);
2004  xyz_front[pt2][2]=xyz_list[3*0+2]+s2*(xyz_list[3*2+2]-xyz_list[3*0+2]);
2005  }
2006  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
2007 
2008  /*Portion of the segments*/
2009  s1=gl[1]/(gl[1]-gl[0]);
2010  s2=gl[1]/(gl[1]-gl[2]);
2011  if(gl[1]<0.){
2012  pt1 = 1; pt2 = 0;
2013  }
2014 
2015  xyz_front[pt2][0]=xyz_list[3*1+0]+s1*(xyz_list[3*0+0]-xyz_list[3*1+0]);
2016  xyz_front[pt2][1]=xyz_list[3*1+1]+s1*(xyz_list[3*0+1]-xyz_list[3*1+1]);
2017  xyz_front[pt2][2]=xyz_list[3*1+2]+s1*(xyz_list[3*0+2]-xyz_list[3*1+2]);
2018  xyz_front[pt1][0]=xyz_list[3*1+0]+s2*(xyz_list[3*2+0]-xyz_list[3*1+0]);
2019  xyz_front[pt1][1]=xyz_list[3*1+1]+s2*(xyz_list[3*2+1]-xyz_list[3*1+1]);
2020  xyz_front[pt1][2]=xyz_list[3*1+2]+s2*(xyz_list[3*2+2]-xyz_list[3*1+2]);
2021  }
2022  else{
2023  _error_("case not possible");
2024  }
2025 
2026 
2027  /*Some checks in debugging mode*/
2028  _assert_(s1>=0 && s1<=1.);
2029  _assert_(s2>=0 && s2<=1.);
2030 
2031  /*Get normal vector*/
2032  IssmDouble normal[3];
2033  this->NormalSectionBase(&normal[0],&xyz_front[0][0]);
2034  normal[0] = -normal[0];
2035  normal[1] = -normal[1];
2036 
2039 
2040  /*Get inputs*/
2041  IssmDouble flux = 0.;
2042  IssmDouble vx,vy,thickness,Jdet;
2044  Input2 *thickness_input = this->GetInput2(ThicknessEnum); _assert_(thickness_input);
2045  Input2 *vx_input = this->GetInput2(VxAverageEnum); _assert_(vx_input);
2046  Input2 *vy_input = this->GetInput2(VyAverageEnum); _assert_(vy_input);
2047 
2048  /*Start looping on Gaussian points*/
2049  Gauss* gauss=this->NewGaussBase(xyz_list,&xyz_front[0][0],3);
2050  for(int ig=gauss->begin();ig<gauss->end();ig++){
2051 
2052  gauss->GaussPoint(ig);
2053  thickness_input->GetInputValue(&thickness,gauss);
2054  vx_input->GetInputValue(&vx,gauss);
2055  vy_input->GetInputValue(&vy,gauss);
2056  this->JacobianDeterminantLine(&Jdet,&xyz_front[0][0],gauss);
2057 
2058  flux += rho_ice*Jdet*gauss->weight*thickness*(vx*normal[0] + vy*normal[1]);
2059  }
2060 
2061  /*Clean up and return*/
2062  delete gauss;
2063  xDelete<IssmDouble>(xyz_list);
2064  return flux;
2065 
2066 }
2067 /*}}}*/
2069 
2070  /*Make sure there is an ice front here*/
2071  if(!IsIceInElement() || !IsZeroLevelset(MaskIceLevelsetEnum) || !IsOnBase()) return 0;
2072 
2073  /*Scaled not implemented yet...*/
2074  _assert_(!scaled);
2075 
2076  int domaintype,index1,index2;
2077  const IssmPDouble epsilon = 1.e-15;
2078  IssmDouble s1,s2;
2079  IssmDouble gl[NUMVERTICES];
2080  IssmDouble xyz_front[2][3];
2081 
2082  IssmDouble *xyz_list = NULL;
2083  this->GetVerticesCoordinates(&xyz_list);
2084 
2085  /*Recover parameters and values*/
2087 
2088  /*Be sure that values are not zero*/
2089  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
2090  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
2091  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
2092 
2093  int pt1 = 0;
2094  int pt2 = 1;
2095  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
2096 
2097  /*Portion of the segments*/
2098  s1=gl[2]/(gl[2]-gl[1]);
2099  s2=gl[2]/(gl[2]-gl[0]);
2100  if(gl[2]<0.){
2101  pt1 = 1; pt2 = 0;
2102  }
2103  xyz_front[pt2][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
2104  xyz_front[pt2][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
2105  xyz_front[pt2][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
2106  xyz_front[pt1][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
2107  xyz_front[pt1][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
2108  xyz_front[pt1][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
2109  }
2110  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
2111 
2112  /*Portion of the segments*/
2113  s1=gl[0]/(gl[0]-gl[1]);
2114  s2=gl[0]/(gl[0]-gl[2]);
2115  if(gl[0]<0.){
2116  pt1 = 1; pt2 = 0;
2117  }
2118 
2119  xyz_front[pt1][0]=xyz_list[3*0+0]+s1*(xyz_list[3*1+0]-xyz_list[3*0+0]);
2120  xyz_front[pt1][1]=xyz_list[3*0+1]+s1*(xyz_list[3*1+1]-xyz_list[3*0+1]);
2121  xyz_front[pt1][2]=xyz_list[3*0+2]+s1*(xyz_list[3*1+2]-xyz_list[3*0+2]);
2122  xyz_front[pt2][0]=xyz_list[3*0+0]+s2*(xyz_list[3*2+0]-xyz_list[3*0+0]);
2123  xyz_front[pt2][1]=xyz_list[3*0+1]+s2*(xyz_list[3*2+1]-xyz_list[3*0+1]);
2124  xyz_front[pt2][2]=xyz_list[3*0+2]+s2*(xyz_list[3*2+2]-xyz_list[3*0+2]);
2125  }
2126  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
2127 
2128  /*Portion of the segments*/
2129  s1=gl[1]/(gl[1]-gl[0]);
2130  s2=gl[1]/(gl[1]-gl[2]);
2131  if(gl[1]<0.){
2132  pt1 = 1; pt2 = 0;
2133  }
2134 
2135  xyz_front[pt2][0]=xyz_list[3*1+0]+s1*(xyz_list[3*0+0]-xyz_list[3*1+0]);
2136  xyz_front[pt2][1]=xyz_list[3*1+1]+s1*(xyz_list[3*0+1]-xyz_list[3*1+1]);
2137  xyz_front[pt2][2]=xyz_list[3*1+2]+s1*(xyz_list[3*0+2]-xyz_list[3*1+2]);
2138  xyz_front[pt1][0]=xyz_list[3*1+0]+s2*(xyz_list[3*2+0]-xyz_list[3*1+0]);
2139  xyz_front[pt1][1]=xyz_list[3*1+1]+s2*(xyz_list[3*2+1]-xyz_list[3*1+1]);
2140  xyz_front[pt1][2]=xyz_list[3*1+2]+s2*(xyz_list[3*2+2]-xyz_list[3*1+2]);
2141  }
2142  else{
2143  _error_("case not possible");
2144  }
2145 
2146 
2147  /*Some checks in debugging mode*/
2148  _assert_(s1>=0 && s1<=1.);
2149  _assert_(s2>=0 && s2<=1.);
2150 
2151  /*Get normal vector*/
2152  IssmDouble normal[3];
2153  this->NormalSectionBase(&normal[0],&xyz_front[0][0]);
2154  normal[0] = -normal[0];
2155  normal[1] = -normal[1];
2156 
2159 
2160  /*Get inputs*/
2161  IssmDouble flux = 0.;
2162  IssmDouble vx,vy,thickness,Jdet;
2164  Input2* thickness_input=this->GetInput2(ThicknessEnum); _assert_(thickness_input);
2165  Input2* vx_input=NULL;
2166  Input2* vy_input=NULL;
2167  vx_input=this->GetInput2(VxAverageEnum); _assert_(vx_input);
2168  vy_input=this->GetInput2(VyAverageEnum); _assert_(vy_input);
2169 
2170  /*Start looping on Gaussian points*/
2171  Gauss* gauss=this->NewGaussBase(xyz_list,&xyz_front[0][0],3);
2172  for(int ig=gauss->begin();ig<gauss->end();ig++){
2173 
2174  gauss->GaussPoint(ig);
2175  thickness_input->GetInputValue(&thickness,gauss);
2176  vx_input->GetInputValue(&vx,gauss);
2177  vy_input->GetInputValue(&vy,gauss);
2178  this->JacobianDeterminantLine(&Jdet,&xyz_front[0][0],gauss);
2179 
2180  flux += rho_ice*Jdet*gauss->weight*thickness*(vx*normal[0] + vy*normal[1]);
2181  }
2182 
2183  /*Clean up and return*/
2184  xDelete<IssmDouble>(xyz_list);
2185  delete gauss;
2186  return flux;
2187 
2188 }
2189 /*}}}*/
2190 IssmDouble Penta::IceVolume(bool scaled){/*{{{*/
2191 
2192  /*The volume of a troncated prism is base * 1/3 sum(length of edges)*/
2193  IssmDouble base,height,scalefactor;
2194  IssmDouble xyz_list[NUMVERTICES][3];
2195 
2196  if(!IsIceInElement())return 0;
2197 
2199 
2200  /*First calculate the area of the base (cross section triangle)
2201  * http://en.wikipedia.org/wiki/Pentangle
2202  * base = 1/2 abs((xA-xC)(yB-yA)-(xA-xB)(yC-yA))*/
2203  base = 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
2204 
2205  if(scaled==true){ //scale for area projection correction
2206  Input2* scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
2207  scalefactor_input->GetInputAverage(&scalefactor);
2208  base=base*scalefactor;
2209  }
2210 
2211  /*Now get the average height*/
2212  height = 1./3.*((xyz_list[3][2]-xyz_list[0][2])+(xyz_list[4][2]-xyz_list[1][2])+(xyz_list[5][2]-xyz_list[2][2]));
2213 
2214  /*Return: */
2215  return base*height;
2216 }
2217 /*}}}*/
2219 
2220  /*Volume above floatation: H + rho_water/rho_ice*bathymetry for nodes on the bed*/
2221  IssmDouble rho_ice,rho_water;
2222  IssmDouble base,bed,surface,bathymetry,scalefactor;
2223  IssmDouble xyz_list[NUMVERTICES][3];
2224 
2225  if(!IsIceInElement() || IsFloating() || !IsOnBase())return 0;
2226 
2227  rho_ice=FindParam(MaterialsRhoIceEnum);
2230 
2231  /*First calculate the area of the base (cross section triangle)
2232  * http://en.wikipedia.org/wiki/Pentangle
2233  * base = 1/2 abs((xA-xC)(yB-yA)-(xA-xB)(yC-yA))*/
2234  base = 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
2235  if(scaled==true){
2236  Input2* scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
2237  scalefactor_input->GetInputAverage(&scalefactor);
2238  base=base*scalefactor;
2239  }
2240 
2241  /*Now get the average height above floatation*/
2242  Input2* surface_input = this->GetInput2(SurfaceEnum); _assert_(surface_input);
2243  Input2* base_input = this->GetInput2(BaseEnum); _assert_(base_input);
2244  Input2* bed_input = this->GetInput2(BedEnum); _assert_(bed_input);
2245  if(!bed_input) _error_("Could not find bed");
2246  surface_input->GetInputAverage(&surface);
2247  base_input->GetInputAverage(&bed);
2248  bed_input->GetInputAverage(&bathymetry);
2249 
2250  /*Return: */
2251  return base*(surface - bed + min( rho_water/rho_ice * bathymetry, 0.) );
2252 }
2253 /*}}}*/
2254 void Penta::InputDepthAverageAtBase(int original_enum,int average_enum){/*{{{*/
2255 
2256  IssmDouble Jdet,value;
2257  IssmDouble xyz_list[NUMVERTICES][3];
2258  IssmDouble xyz_list_line[2][3];
2259  IssmDouble total[NUMVERTICES] = {0.};
2260  int lidlist[NUMVERTICES];
2261  IssmDouble intz[NUMVERTICES] = {0.};
2262  Input2 *original_input = NULL;
2263  Input2 *depth_averaged_input = NULL;
2264 
2265  /*Are we on the base? If not, return*/
2266  if(!IsOnBase()) return;
2267 
2268  /*Now follow all the upper element from the base to the surface to integrate the input*/
2269  Penta* penta = this;
2270  int step = 0;
2271  Gauss* gauss[3];
2272  for(int iv=0;iv<3;iv++) gauss[iv] = penta->NewGaussLine(iv,iv+3,3);
2273 
2274  for(;;){
2275 
2276  /*Step1: Get original input (to be depth-avegaged): */
2277  original_input=penta->GetInput2(original_enum);
2278  if(!original_input) _error_("could not find input with enum " << EnumToStringx(original_enum));
2279 
2280  /*Step2: Create element thickness input*/
2281  ::GetVerticesCoordinates(&xyz_list[0][0],penta->vertices,NUMVERTICES);
2282  for(int iv=0;iv<3;iv++){
2283  /*Get segment length*/
2284  for(int i=0;i<3;i++){
2285  xyz_list_line[0][i]=xyz_list[iv][i];
2286  xyz_list_line[1][i]=xyz_list[iv+3][i];
2287  }
2288  /*Integrate over edge*/
2289  for(int ig=gauss[iv]->begin();ig<gauss[iv]->end();ig++){
2290  gauss[iv]->GaussPoint(ig);
2291  penta->JacobianDeterminantLine(&Jdet,&xyz_list_line[0][0],gauss[iv]);
2292  original_input->GetInputValue(&value,gauss[iv]);
2293  total[iv] += value*Jdet*gauss[iv]->weight;
2294  intz[iv] += Jdet*gauss[iv]->weight;
2295  }
2296  }
2297 
2298  /*Stop if we have reached the surface, else, take upper penta*/
2299  if(penta->IsOnSurface()) break;
2300 
2301  /* get upper Penta*/
2302  penta=penta->GetUpperPenta(); _assert_(penta->Id()!=this->id);
2303  step++;
2304  }
2305  for(int iv=0;iv<3;iv++) delete gauss[iv];
2306 
2307  /*Now we only need to divide the depth integrated input by the total thickness!*/
2308  for(int iv=0;iv<3;iv++){
2309  total[iv ] = total[iv]/intz[iv];
2310  total[iv+3] = total[iv];
2311  }
2312  GetVerticesLidList(&lidlist[0]);
2313  switch(original_input->ObjectEnum()){
2314  case PentaInputEnum:
2315  case PentaInput2Enum:
2316  case ControlInputEnum:
2317  this->inputs2->SetPentaInput(average_enum,P1Enum,NUMVERTICES,lidlist,&total[0]);
2318  break;
2319  default:
2320  _error_("Interpolation " << EnumToStringx(original_input->ObjectEnum()) << " not supported yet");
2321  }
2322 }
2323 /*}}}*/
2324 void Penta::DatasetInputExtrude(int enum_type,int start){/*{{{*/
2325 
2326  _assert_(start==-1 || start==+1);
2327  _assert_(this->inputs2);
2328 
2329  /*Are we on the the boundary we want to be?*/
2330  if(start==-1 && !IsOnBase()) return;
2331  if(start==+1 && !IsOnSurface()) return;
2332 
2333  /*Get original input*/
2334  DatasetInput2* dinput = this->inputs2->GetDatasetInput2(enum_type);
2335 
2336  int lidlist[NUMVERTICES];
2337  this->GetVerticesLidList(&lidlist[0]);
2338 
2339  for(int id=0;id<dinput->GetNumIds();id++){
2340 
2341  PentaInput2* pentainput = dinput->GetPentaInputByOffset(id);
2342  pentainput->Serve(NUMVERTICES,&lidlist[0]);
2343 
2344  if(pentainput->GetInterpolation()==P1Enum){
2345 
2346  /*Extrude values first*/
2347  IssmDouble extrudedvalues[NUMVERTICES];
2348  this->GetInputListOnVertices(&extrudedvalues[0],pentainput,0.);
2349 
2350  if(start==-1){
2351  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues[i+NUMVERTICES2D]=extrudedvalues[i];
2352  }
2353  else{
2354  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues[i]=extrudedvalues[i+NUMVERTICES2D];
2355  }
2356 
2357  /*Propagate to other Pentas*/
2358  Penta* penta=this;
2359  for(;;){
2360 
2361  /*Add input of the basal element to penta->inputs*/
2362  int vertexlids[NUMVERTICES];
2363  penta->GetVerticesLidList(&vertexlids[0]);
2364  pentainput->SetInput(P1Enum,NUMVERTICES,&vertexlids[0],&extrudedvalues[0]);
2365 
2366  /*Stop if we have reached the surface/base*/
2367  if(start==-1 && penta->IsOnSurface()) break;
2368  if(start==+1 && penta->IsOnBase()) break;
2369 
2370  /*get upper/lower Penta*/
2371  if(start==-1) penta=penta->GetUpperPenta();
2372  else penta=penta->GetLowerPenta();
2373  _assert_(penta->Id()!=this->id);
2374  }
2375  }
2376  else{
2377  _error_("not implemented yet");
2378  }
2379  }
2380 }
2381 /*}}}*/
2382 void Penta::ControlInputExtrude(int enum_type,int start){/*{{{*/
2383 
2384  _assert_(start==-1 || start==+1);
2385  _assert_(this->inputs2);
2386 
2387  /*Are we on the the boundary we want to be?*/
2388  if(start==-1 && !IsOnBase()) return;
2389  if(start==+1 && !IsOnSurface()) return;
2390 
2391  /*Get original input*/
2392  ElementInput2* input = this->inputs2->GetControlInput2Data(enum_type,"value");
2393  if(input->ObjectEnum()!=PentaInput2Enum) _error_("not supported yet");
2394  PentaInput2* pentainput = xDynamicCast<PentaInput2*>(input);
2395  ElementInput2* input2 = this->inputs2->GetControlInput2Data(enum_type,"savedvalues");
2396  if(input->ObjectEnum()!=PentaInput2Enum) _error_("not supported yet");
2397  PentaInput2* pentainput2= xDynamicCast<PentaInput2*>(input2);
2398  /*FIXME: this should not be necessary*/
2399  ElementInput2* input3 = this->inputs2->GetControlInput2Data(enum_type,"gradient");
2400  if(input->ObjectEnum()!=PentaInput2Enum) _error_("not supported yet");
2401  PentaInput2* pentainput3= xDynamicCast<PentaInput2*>(input3);
2402 
2403  int lidlist[NUMVERTICES];
2404  this->GetVerticesLidList(&lidlist[0]);
2405  pentainput->Serve(NUMVERTICES,&lidlist[0]);
2406  pentainput2->Serve(NUMVERTICES,&lidlist[0]);
2407  pentainput3->Serve(NUMVERTICES,&lidlist[0]);
2408 
2409  if(pentainput->GetInterpolation()==P1Enum){
2410 
2411  /*Extrude values first*/
2412  IssmDouble extrudedvalues[NUMVERTICES];
2413  IssmDouble extrudedvalues2[NUMVERTICES];
2414  IssmDouble extrudedvalues3[NUMVERTICES];
2415 
2416  this->GetInputListOnVertices(&extrudedvalues[0],pentainput,0.);
2417  this->GetInputListOnVertices(&extrudedvalues2[0],pentainput2,0.);
2418  this->GetInputListOnVertices(&extrudedvalues3[0],pentainput3,0.);
2419 
2420  if(start==-1){
2421  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues[i+NUMVERTICES2D]=extrudedvalues[i];
2422  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues2[i+NUMVERTICES2D]=extrudedvalues2[i];
2423  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues3[i+NUMVERTICES2D]=extrudedvalues3[i]/2.; /*FIXME: this is just for NR*/
2424  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues3[i]=extrudedvalues3[i]/2.; /*FIXME: this is just for NR*/
2425  }
2426  else{
2427  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues[i]=extrudedvalues[i+NUMVERTICES2D];
2428  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues2[i]=extrudedvalues2[i+NUMVERTICES2D];
2429  }
2430 
2431  /*Propagate to other Pentas*/
2432  Penta* penta=this;
2433  for(;;){
2434 
2435  if(penta->IsOnSurface() && start==-1){ /*FIXME: this is just for NR*/
2436  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues3[i+NUMVERTICES2D]=0.;
2437  }
2438 
2439  /*Add input of the basal element to penta->inputs*/
2440  int vertexlids[NUMVERTICES];
2441  penta->GetVerticesLidList(&vertexlids[0]);
2442  pentainput->SetInput(P1Enum,NUMVERTICES,&vertexlids[0],&extrudedvalues[0]);
2443  pentainput2->SetInput(P1Enum,NUMVERTICES,&vertexlids[0],&extrudedvalues2[0]);
2444  if(start==-1 && !penta->IsOnBase()){
2445  pentainput3->SetInput(P1Enum,NUMVERTICES,&vertexlids[0],&extrudedvalues3[0]);
2446  }
2447 
2448  /*Stop if we have reached the surface/base*/
2449  if(start==-1 && penta->IsOnSurface()) break;
2450  if(start==+1 && penta->IsOnBase()) break;
2451 
2452  /*get upper/lower Penta*/
2453  if(start==-1) penta=penta->GetUpperPenta();
2454  else penta=penta->GetLowerPenta();
2455  _assert_(penta->Id()!=this->id);
2456  }
2457  }
2458  else{
2459  _error_("not implemented yet");
2460  }
2461 }
2462 /*}}}*/
2463 void Penta::InputExtrude(int enum_type,int start){/*{{{*/
2464 
2465  _assert_(start==-1 || start==+1);
2466  _assert_(this->inputs2);
2467 
2468  /*Are we on the the boundary we want to be?*/
2469  if(start==-1 && !IsOnBase()) return;
2470  if(start==+1 && !IsOnSurface()) return;
2471 
2472 
2473  /*Get original input*/
2474  Input2* input = this->GetInput2(enum_type);
2475  if(input->ObjectEnum()!=PentaInput2Enum) _error_("not supported yet");
2476  PentaInput2* pentainput = xDynamicCast<PentaInput2*>(input);
2477 
2478  if(pentainput->GetInterpolation()==P1Enum || pentainput->GetInterpolation()==P1DGEnum){
2479  /*Extrude values first*/
2480  IssmDouble extrudedvalues[NUMVERTICES];
2481 
2482  Element::GetInputListOnVertices(&extrudedvalues[0],enum_type);
2483  if(start==-1){
2484  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues[i+NUMVERTICES2D]=extrudedvalues[i];
2485  }
2486  else{
2487  for(int i=0;i<NUMVERTICES2D;i++) extrudedvalues[i]=extrudedvalues[i+NUMVERTICES2D];
2488  }
2489 
2490  /*Propagate to other Pentas*/
2491  Penta* penta=this;
2492  for(;;){
2493 
2494  /*Add input of the basal element to penta->inputs*/
2495  penta->AddInput2(enum_type,&extrudedvalues[0],pentainput->GetInterpolation());
2496 
2497  /*Stop if we have reached the surface/base*/
2498  if(start==-1 && penta->IsOnSurface()) break;
2499  if(start==+1 && penta->IsOnBase()) break;
2500 
2501  /*get upper/lower Penta*/
2502  if(start==-1) penta=penta->GetUpperPenta();
2503  else penta=penta->GetLowerPenta();
2504  _assert_(penta->Id()!=this->id);
2505  }
2506  }
2507  else{
2508  _error_("interpolation "<<EnumToStringx(pentainput->GetInterpolation())<<" not implemented yet (while trying to extrude "<<EnumToStringx(enum_type)<<")");
2509  }
2510 }
2511 /*}}}*/
2512 void Penta::InputUpdateFromIoModel(int index,IoModel* iomodel){ /*{{{*/
2513 
2514  /*Intermediaries*/
2515  int i,j;
2516  int penta_vertex_ids[NUMVERTICES];
2517  IssmDouble nodeinputs[NUMVERTICES];
2518  IssmDouble cmmininputs[NUMVERTICES];
2519  IssmDouble cmmaxinputs[NUMVERTICES];
2520 
2521  IssmDouble yts;
2522  bool control_analysis;
2523  char** controls = NULL;
2524  int num_control_type,num_responses;
2525 
2526  /*Fetch parameters: */
2527  iomodel->FindConstant(&yts,"md.constants.yts");
2528  iomodel->FindConstant(&control_analysis,"md.inversion.iscontrol");
2529  if(control_analysis) iomodel->FindConstant(&num_control_type,"md.inversion.num_control_parameters");
2530  if(control_analysis) iomodel->FindConstant(&num_responses,"md.inversion.num_cost_functions");
2531 
2532  /*Recover vertices ids needed to initialize inputs*/
2533  _assert_(iomodel->elements);
2534  for(i=0;i<NUMVERTICES;i++){
2535  penta_vertex_ids[i]=iomodel->elements[NUMVERTICES*index+i]; //ids for vertices are in the elements array from Matlab
2536  }
2537 }
2538 /*}}}*/
2539 void Penta::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){/*{{{*/
2540 
2541  /*Intermediary*/
2542  int* doflist = NULL;
2543 
2544  /*Fetch number of nodes for this finite element*/
2545  int numnodes = this->NumberofNodes(this->element_type);
2546 
2547  /*Fetch dof list and allocate solution vector*/
2549  IssmDouble* values = xNew<IssmDouble>(numnodes);
2550 
2551  /*Use the dof list to index into the solution vector: */
2552  for(int i=0;i<numnodes;i++){
2553  values[i]=solution[doflist[i]];
2554  if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
2555  if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in solution vector");
2556  }
2557 
2558  /*Add input to the element: */
2559  this->AddInput2(enum_type,values,this->element_type);
2560 
2561  /*Free ressources:*/
2562  xDelete<IssmDouble>(values);
2563  xDelete<int>(doflist);
2564 }
2565 /*}}}*/
2566 void Penta::InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int enum_type){/*{{{*/
2567 
2568  const int numdof = NUMVERTICES;
2569  const int numdof2d = NUMVERTICES2D;
2570 
2571  IssmDouble values[numdof];
2572  int* doflist = NULL;
2573  Penta *penta = NULL;
2574 
2575  /*If not on bed, return*/
2576  if (!IsOnBase()) return;
2577 
2578  /*Get dof list: */
2580 
2581  /*Use the dof list to index into the solution vector and extrude it */
2582  for(int i=0;i<numdof2d;i++){
2583  values[i] =solution[doflist[i]];
2584  values[i+numdof2d]=values[i];
2585  if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
2586  if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in solution vector");
2587  }
2588 
2589  /*Start looping over all elements above current element and update all inputs*/
2590  penta=this;
2591  for(;;){
2592  /*Add input to the element: */
2593  penta->AddInput2(enum_type,values,P1Enum);
2594 
2595  /*Stop if we have reached the surface*/
2596  if (penta->IsOnSurface()) break;
2597 
2598  /* get upper Penta*/
2599  penta=penta->GetUpperPenta(); _assert_(penta->Id()!=this->id);
2600  }
2601 
2602  /*Free ressources:*/
2603  xDelete<int>(doflist);
2604 }
2605 /*}}}*/
2606 void Penta::InputUpdateFromVector(IssmDouble* vector, int name, int type){/*{{{*/
2607 
2608  const int numdof = NUMVERTICES;
2609  int *doflist = NULL;
2610  IssmDouble values[numdof];
2611  int lidlist[NUMVERTICES];
2612 
2613  GetVerticesLidList(&lidlist[0]);
2614 
2615  /*Check that name is an element input*/
2616  if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
2617 
2618  switch(type){
2619  case VertexLIdEnum:
2620  for (int i=0;i<NUMVERTICES;i++){
2621  values[i]=vector[this->vertices[i]->Lid()];
2622  }
2623  /*update input*/
2624  inputs2->SetPentaInput(name,P1Enum,NUMVERTICES,lidlist,values);
2625  return;
2626 
2627  case VertexPIdEnum:
2628  for (int i=0;i<NUMVERTICES;i++){
2629  values[i]=vector[this->vertices[i]->Pid()];
2630  }
2631  /*update input*/
2632  inputs2->SetPentaInput(name,P1Enum,NUMVERTICES,lidlist,values);
2633  return;
2634 
2635  case VertexSIdEnum:
2636  for (int i=0;i<NUMVERTICES;i++){
2637  values[i]=vector[this->vertices[i]->Sid()];
2638  }
2639  /*update input*/
2640  inputs2->SetPentaInput(name,P1Enum,NUMVERTICES,lidlist,values);
2641  return;
2642 
2643  case NodesEnum:
2644  /*Get dof list: */
2646 
2647  /*Use the dof list to index into the vector: */
2648  for(int i=0;i<numdof;i++){
2649  values[i]=vector[doflist[i]];
2650  if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
2651  if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in solution vector");
2652  }
2653  /*Add input to the element: */
2654  inputs2->SetPentaInput(name,P1Enum,NUMVERTICES,lidlist,values);
2655 
2656  /*Free ressources:*/
2657  xDelete<int>(doflist);
2658  return;
2659 
2660  case NodeSIdEnum:
2661  for(int i=0;i<NUMVERTICES;i++){
2662  values[i]=vector[nodes[i]->Sid()];
2663  if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
2664  if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in solution vector");
2665  }
2666  /*Add input to the element: */
2667  inputs2->SetPentaInput(name,P1Enum,NUMVERTICES,lidlist,values);
2668 
2669  /*Free ressources:*/
2670  xDelete<int>(doflist);
2671  return;
2672 
2673  default:
2674  _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
2675  }
2676 }
2677 /*}}}*/
2678 bool Penta::IsIcefront(void){/*{{{*/
2679 
2680  bool isicefront;
2681  int i,nrice;
2682  IssmDouble ls[NUMVERTICES];
2683 
2684  /*Retrieve all inputs and parameters*/
2686 
2687  /* If only one vertex has ice, there is an ice front here */
2688  isicefront=false;
2689  if(IsIceInElement()){
2690  nrice=0;
2691  for(i=0;i<NUMVERTICES2D;i++)
2692  if(ls[i]<0.) nrice++;
2693  if(nrice==1) isicefront= true;
2694  }
2695  return isicefront;
2696 }/*}}}*/
2698 
2699  int i;
2700  bool shelf=false;
2701 
2702  for(i=0;i<NUMVERTICES;i++){
2703  if (flags[vertices[i]->Pid()]<0.){
2704  shelf=true;
2705  break;
2706  }
2707  }
2708  return shelf;
2709 }
2710 /*}}}*/
2711 bool Penta::IsZeroLevelset(int levelset_enum){/*{{{*/
2712 
2713  bool iszerols;
2714  IssmDouble ls[NUMVERTICES];
2715 
2716  /*Retrieve all inputs and parameters*/
2717  Element::GetInputListOnVertices(&ls[0],levelset_enum);
2718 
2719  /*If the level set has always same sign, there is no ice front here*/
2720  iszerols = false;
2721  if(IsIceInElement()){
2722  if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){
2723  iszerols = true;
2724  }
2725  }
2726  return iszerols;
2727 }
2728 /*}}}*/
2729 void Penta::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
2730 
2731  _assert_(gauss->Enum()==GaussPentaEnum);
2732  this->GetJacobianDeterminant(pJdet,xyz_list,(GaussPenta*)gauss);
2733 
2734 }
2735 /*}}}*/
2736 void Penta::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){/*{{{*/
2737 
2738  _assert_(gauss->Enum()==GaussPentaEnum);
2739  this->GetTriaJacobianDeterminant(pJdet,xyz_list_base,(GaussPenta*)gauss);
2740 
2741 }
2742 /*}}}*/
2743 void Penta::JacobianDeterminantLine(IssmDouble* pJdet,IssmDouble* xyz_list_line,Gauss* gauss){/*{{{*/
2744 
2745  _assert_(gauss->Enum()==GaussPentaEnum);
2746  this->GetSegmentJacobianDeterminant(pJdet,xyz_list_line,(GaussPenta*)gauss);
2747 
2748 }
2749 /*}}}*/
2750 void Penta::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list_quad,Gauss* gauss){/*{{{*/
2751 
2752  _assert_(gauss->Enum()==GaussPentaEnum);
2753  this->GetQuadJacobianDeterminant(pJdet,xyz_list_quad,(GaussPenta*)gauss);
2754 
2755 }
2756 /*}}}*/
2757 void Penta::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){/*{{{*/
2758 
2759  _assert_(gauss->Enum()==GaussPentaEnum);
2760  this->GetTriaJacobianDeterminant(pJdet,xyz_list_top,(GaussPenta*)gauss);
2761 
2762 }
2763 /*}}}*/
2765 
2766  IssmDouble mass_flux=0;
2767 
2768  if(!IsOnBase()) return mass_flux;
2769 
2770  /*Depth Averaging Vx and Vy*/
2773 
2774  /*Spawn Tria element from the base of the Penta: */
2775  Tria* tria=(Tria*)SpawnTria(0,1,2);
2776  mass_flux=tria->MassFlux(segment);
2777  delete tria->material; delete tria;
2778 
2779  /*clean up and return*/
2780  return mass_flux;
2781 }
2782 /*}}}*/
2784 
2785  IssmDouble mass_flux=0;
2786 
2787  if(!IsOnBase()) return mass_flux;
2788 
2789  /*Depth Averaging Vx and Vy*/
2792 
2793  /*Spawn Tria element from the base of the Penta: */
2794  Tria* tria=(Tria*)SpawnTria(0,1,2);
2795  mass_flux=tria->MassFlux(x1,y1,x2,y2,segment_id);
2796  delete tria->material; delete tria;
2797 
2798  /*clean up and return*/
2799  return mass_flux;
2800 }
2801 /*}}}*/
2803  /*Return the minimum lenght of the nine egdes of the penta*/
2804 
2805  int i,node0,node1;
2806  int edges[9][2]={{0,1},{0,2},{1,2},{3,4},{3,5},{4,5},{0,3},{1,4},{2,5}}; //list of the nine edges
2807  IssmDouble length;
2808  IssmDouble minlength=-1;
2809 
2810  for(i=0;i<9;i++){
2811  /*Find the two nodes for this edge*/
2812  node0=edges[i][0];
2813  node1=edges[i][1];
2814 
2815  /*Compute the length of this edge and compare it to the minimal length*/
2816  length=sqrt(pow(xyz_list[node0*3+0]-xyz_list[node1*3+0],2)+pow(xyz_list[node0*3+1]-xyz_list[node1*3+1],2)+pow(xyz_list[node0*3+2]-xyz_list[node1*3+2],2));
2817  if(length<minlength || minlength<0) minlength=length;
2818  }
2819 
2820  return minlength;
2821 }
2822 /*}}}*/
2823 Gauss* Penta::NewGauss(void){/*{{{*/
2824  return new GaussPenta();
2825 }
2826 /*}}}*/
2827 Gauss* Penta::NewGauss(int order){/*{{{*/
2828  return new GaussPenta(order,order);
2829 }
2830 /*}}}*/
2831 Gauss* Penta::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){/*{{{*/
2832 
2833  IssmDouble area_coordinates[4][3];
2834 
2835  GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,4);
2836 
2837  return new GaussPenta(area_coordinates,order_horiz,order_vert);
2838 }
2839 /*}}}*/
2840 Gauss* Penta::NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){/*{{{*/
2841  return new GaussPenta(point1,fraction1,fraction2,mainlyfloating,order);
2842 }
2843 /*}}}*/
2844 Gauss* Penta::NewGaussBase(int order){/*{{{*/
2845  return new GaussPenta(0,1,2,order);
2846 }
2847 /*}}}*/
2848 Gauss* Penta::NewGaussBase(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz){/*{{{*/
2849 
2850  IssmDouble area_coordinates[2][3];
2851 
2852  GetAreaCoordinates(&area_coordinates[0][0],xyz_list_front,xyz_list,2);
2853 
2854  return new GaussPenta(area_coordinates,order_horiz);
2855 }
2856 /*}}}*/
2857 Gauss* Penta::NewGaussLine(int vertex1,int vertex2,int order){/*{{{*/
2858  return new GaussPenta(vertex1,vertex2,order);
2859 }
2860 /*}}}*/
2861 Gauss* Penta::NewGaussTop(int order){/*{{{*/
2862  return new GaussPenta(3,4,5,order);
2863 }
2864 /*}}}*/
2865 void Penta::NodalFunctions(IssmDouble* basis, Gauss* gauss){/*{{{*/
2866 
2867  _assert_(gauss->Enum()==GaussPentaEnum);
2868  this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->element_type);
2869 
2870 }
2871 /*}}}*/
2872 void Penta::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
2873 
2874  _assert_(gauss->Enum()==GaussPentaEnum);
2875  this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussPenta*)gauss,this->element_type);
2876 
2877 }
2878 /*}}}*/
2880 
2881  _assert_(gauss->Enum()==GaussPentaEnum);
2882  this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussPenta*)gauss,this->VelocityInterpolation());
2883 
2884 }
2885 /*}}}*/
2886 void Penta::NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
2887 
2888  _assert_(gauss->Enum()==GaussPentaEnum);
2889  this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussPenta*)gauss,P1bubbleEnum);
2890 
2891 }
2892 /*}}}*/
2893 void Penta::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){/*{{{*/
2894 
2895  _assert_(gauss->Enum()==GaussPentaEnum);
2896  this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->PressureInterpolation());
2897 
2898 }
2899 /*}}}*/
2900 void Penta::NodalFunctionsP1(IssmDouble* basis, Gauss* gauss){/*{{{*/
2901 
2902  _assert_(gauss->Enum()==GaussPentaEnum);
2903  this->GetNodalFunctions(basis,(GaussPenta*)gauss,P1Enum);
2904 
2905 }
2906 /*}}}*/
2907 void Penta::NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
2908 
2909  _assert_(gauss->Enum()==GaussPentaEnum);
2910  this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussPenta*)gauss,P1Enum);
2911 
2912 }
2913 /*}}}*/
2914 void Penta::NodalFunctionsP2(IssmDouble* basis, Gauss* gauss){/*{{{*/
2915 
2916  _assert_(gauss->Enum()==GaussPentaEnum);
2917  this->GetNodalFunctions(basis,(GaussPenta*)gauss,P2Enum);
2918 
2919 }
2920 /*}}}*/
2921 void Penta::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){/*{{{*/
2922 
2923  _assert_(gauss->Enum()==GaussPentaEnum);
2924  this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->VelocityInterpolation());
2925 
2926 }
2927 /*}}}*/
2928 void Penta::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){/*{{{*/
2929 
2930  _assert_(gauss->Enum()==GaussPentaEnum);
2931  this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->TensorInterpolation());
2932 
2933 }
2934 /*}}}*/
2935 int Penta::NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){/*{{{*/
2936 
2937  int i;
2938  int found=0;
2939  IssmDouble value;
2940  GaussPenta* gauss=NULL;
2941 
2942  /*First, serarch the input: */
2943  Input2* data=this->GetInput2(natureofdataenum);
2944 
2945  /*figure out if we have the vertex id: */
2946  found=0;
2947  for(i=0;i<NUMVERTICES;i++){
2948  if(index==vertices[i]->Id()){
2949  /*Do we have natureofdataenum in our inputs? :*/
2950  if(data){
2951  /*ok, we are good. retrieve value of input at vertex :*/
2952  gauss=new GaussPenta(); gauss->GaussVertex(i);
2953  data->GetInputValue(&value,gauss);
2954  found=1;
2955  break;
2956  }
2957  }
2958  }
2959 
2960  delete gauss;
2961  if(found)*pvalue=value;
2962  return found;
2963 }
2964 /*}}}*/
2965 void Penta::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){/*{{{*/
2966 
2967  IssmDouble v13[3],v23[3];
2968  IssmDouble normal[3];
2969  IssmDouble normal_norm;
2970 
2971  for(int i=0;i<3;i++){
2972  v13[i]=xyz_list[0*3+i]-xyz_list[2*3+i];
2973  v23[i]=xyz_list[1*3+i]-xyz_list[2*3+i];
2974  }
2975 
2976  normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
2977  normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
2978  normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
2979  normal_norm=sqrt(normal[0]*normal[0]+ normal[1]*normal[1]+ normal[2]*normal[2]);
2980 
2981  /*Bed normal is opposite to surface normal*/
2982  bed_normal[0]=-normal[0]/normal_norm;
2983  bed_normal[1]=-normal[1]/normal_norm;
2984  bed_normal[2]=-normal[2]/normal_norm;
2985 }
2986 /*}}}*/
2987 void Penta::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){/*{{{*/
2988 
2989  /*Build unit outward pointing vector*/
2990  IssmDouble AB[3];
2991  IssmDouble AC[3];
2992  IssmDouble norm;
2993 
2994  AB[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
2995  AB[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
2996  AB[2]=xyz_list[1*3+2] - xyz_list[0*3+2];
2997  AC[0]=xyz_list[2*3+0] - xyz_list[0*3+0];
2998  AC[1]=xyz_list[2*3+1] - xyz_list[0*3+1];
2999  AC[2]=xyz_list[2*3+2] - xyz_list[0*3+2];
3000 
3001  cross(normal,AB,AC);
3002  norm=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
3003 
3004  for(int i=0;i<3;i++) normal[i]=normal[i]/norm;
3005 }
3006 /*}}}*/
3007 void Penta::NormalSectionBase(IssmDouble* normal,IssmDouble* xyz_list){/*{{{*/
3008 
3009  /*Build unit outward pointing vector*/
3010  IssmDouble vector[2];
3011  IssmDouble norm;
3012 
3013  vector[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
3014  vector[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
3015 
3016  norm=sqrt(vector[0]*vector[0] + vector[1]*vector[1]);
3017 
3018  normal[0]= + vector[1]/norm;
3019  normal[1]= - vector[0]/norm;
3020 }
3021 /*}}}*/
3022 void Penta::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){/*{{{*/
3023 
3024  int i;
3025  IssmDouble v13[3],v23[3];
3026  IssmDouble normal[3];
3027  IssmDouble normal_norm;
3028 
3029  for (i=0;i<3;i++){
3030  v13[i]=xyz_list[0*3+i]-xyz_list[2*3+i];
3031  v23[i]=xyz_list[1*3+i]-xyz_list[2*3+i];
3032  }
3033 
3034  normal[0]=v13[1]*v23[2]-v13[2]*v23[1];
3035  normal[1]=v13[2]*v23[0]-v13[0]*v23[2];
3036  normal[2]=v13[0]*v23[1]-v13[1]*v23[0];
3037  normal_norm=sqrt(normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]);
3038 
3039  top_normal[0]=normal[0]/normal_norm;
3040  top_normal[1]=normal[1]/normal_norm;
3041  top_normal[2]=normal[2]/normal_norm;
3042 }
3043 /*}}}*/
3046 }
3047 /*}}}*/
3050 }
3051 /*}}}*/
3052 int Penta::ObjectEnum(void){/*{{{*/
3053 
3054  return PentaEnum;
3055 
3056 }
3057 /*}}}*/
3058 void Penta::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){/*{{{*/
3059 
3061  IssmDouble bed_hydro;
3062  IssmDouble rho_water,rho_ice,density;
3063 
3064  /*material parameters: */
3066  rho_ice=FindParam(MaterialsRhoIceEnum);
3067  density=rho_ice/rho_water;
3071 
3072  /*go through vertices, and figure out which ones are on the ice sheet, and want to unground: */
3073  for(int i=0;i<NUMVERTICES;i++){
3074  /*Find if grounded vertices want to start floating*/
3075  if (gl[i]>0.){
3076  bed_hydro=-density*h[i];
3077  if(bed_hydro>r[i]){
3078  /*Vertex that could potentially unground, flag it*/
3079  potential_ungrounding->SetValue(vertices[i]->Pid(),1,INS_VAL);
3080  }
3081  }
3082  }
3083 }
3084 /*}}}*/
3087 }
3088 /*}}}*/
3090 
3091  int analysis_type;
3092  parameters->FindParam(&analysis_type,AnalysisTypeEnum);
3093 
3094  if(pe){
3095  if(analysis_type==StressbalanceAnalysisEnum){
3096  if(this->element_type==MINIcondensedEnum){
3097  int approximation;
3098  this->GetInput2Value(&approximation,ApproximationEnum);
3099  if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
3100  //Do nothing, condensation already done in PVectorCoupling
3101  }
3102  else{
3103  int indices[3]={18,19,20};
3104  pe->StaticCondensation(Ke,3,&indices[0]);
3105  }
3106  }
3107  else if(this->element_type==P1bubblecondensedEnum){
3109  int offset = 0;
3110  for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
3111  int* indices=xNew<int>(size);
3112  for(int i=0;i<size;i++) indices[i] = offset+i;
3113  pe->StaticCondensation(Ke,size,indices);
3114  xDelete<int>(indices);
3115  }
3116  }
3117  }
3118 
3119  if(Ke){
3120  if(analysis_type==StressbalanceAnalysisEnum){
3121  int approximation;
3122  this->GetInput2Value(&approximation,ApproximationEnum);
3123  if(approximation==HOFSApproximationEnum || approximation==SSAFSApproximationEnum){
3124  //Do nothing condensatino already done for Stokes part
3125  }
3126  else{
3127  if(this->element_type==MINIcondensedEnum){
3128  int indices[3]={18,19,20};
3129  Ke->StaticCondensation(3,&indices[0]);
3130  }
3131  else if(this->element_type==P1bubblecondensedEnum){
3133  int offset = 0;
3134  for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);
3135  int* indices=xNew<int>(size);
3136  for(int i=0;i<size;i++) indices[i] = offset+i;
3137  Ke->StaticCondensation(size,indices);
3138  xDelete<int>(indices);
3139  }
3140  }
3141  }
3142  }
3143 }
3144 /*}}}*/
3146 
3147  int approximation;
3148  int numindices;
3149  int *indices = NULL;
3150  IssmDouble slopex,slopey,groundedice;
3151  IssmDouble xz_plane[6];
3152  IssmDouble* vertexapproximation= NULL;
3153 
3154  /*For FS only: we want the CS to be tangential to the bedrock*/
3155  this->GetInput2Value(&approximation,ApproximationEnum);
3156  if(!IsOnBase() || (approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum)) return;
3157 
3158  /*Get number of nodes for velocity only and base*/
3159  BasalNodeIndices(&numindices,&indices,this->VelocityInterpolation());
3160 
3161  /*Get inputs*/
3162  Input2* slopex_input=this->GetInput2(BedSlopeXEnum); _assert_(slopex_input);
3163  Input2* slopey_input=this->GetInput2(BedSlopeYEnum); _assert_(slopey_input);
3164  Input2* groundedicelevelset_input=this->GetInput2(MaskOceanLevelsetEnum); _assert_(groundedicelevelset_input);
3165 
3166  /*Loop over basal nodes and update their CS*/
3167  GaussPenta* gauss = new GaussPenta();
3168  for(int i=0;i<numindices;i++){//FIXME
3169  gauss->GaussNode(this->VelocityInterpolation(),indices[i]);
3170 
3171  slopex_input->GetInputValue(&slopex,gauss);
3172  slopey_input->GetInputValue(&slopey,gauss);
3173  groundedicelevelset_input->GetInputValue(&groundedice,gauss);
3174 
3175  /*New X axis New Z axis*/
3176  xz_plane[0]=1.; xz_plane[3]=-slopex;
3177  xz_plane[1]=0.; xz_plane[4]=-slopey;
3178  xz_plane[2]=slopex; xz_plane[5]=1.;
3179 
3180  if(groundedice>=0){
3181  if(this->nodes[indices[i]]->GetApproximation()==FSvelocityEnum){
3182  this->nodes[indices[i]]->DofInSSet(2); //vz
3183  }
3184  else if(this->nodes[indices[i]]->GetApproximation()==SSAFSApproximationEnum || this->nodes[indices[i]]->GetApproximation()==HOFSApproximationEnum){
3185  this->nodes[indices[i]]->DofInSSet(4); //vz
3186  }
3187  else _error_("Flow equation approximation"<<EnumToStringx(this->nodes[indices[i]]->GetApproximation())<<" not supported yet");
3188  }
3189  else{
3190  if(this->nodes[indices[i]]->GetApproximation()==FSvelocityEnum){
3191  this->nodes[indices[i]]->DofInFSet(2); //vz
3192  }
3193  else if(this->nodes[indices[i]]->GetApproximation()==SSAFSApproximationEnum || this->nodes[indices[i]]->GetApproximation()==HOFSApproximationEnum){
3194  this->nodes[indices[i]]->DofInFSet(4); //vz
3195  }
3196  else _error_("Flow equation approximation"<<EnumToStringx(this->nodes[indices[i]]->GetApproximation())<<" not supported yet");
3197  }
3198 
3199  XZvectorsToCoordinateSystem(&this->nodes[indices[i]]->coord_system[0][0],&xz_plane[0]);
3200  }
3201 
3202  /*cleanup*/
3203  xDelete<int>(indices);
3204  delete gauss;
3205 }
3206 /*}}}*/
3207 void Penta::ResetHooks(){/*{{{*/
3208 
3209  if(this->nodes) xDelete<Node*>(this->nodes);
3210  this->nodes=NULL;
3211  this->vertices=NULL;
3212  this->material=NULL;
3213  this->verticalneighbors=NULL;
3214  this->parameters=NULL;
3215 
3216  //deal with ElementHook mother class
3217  for(int i=0;i<this->numanalyses;i++) if(this->hnodes[i]) this->hnodes[i]->reset();
3218  this->hvertices->reset();
3219  this->hmaterial->reset();
3220  if(this->hneighbors) this->hneighbors->reset();
3221 
3222 }
3223 /*}}}*/
3225 
3226  if(!this->IsOnBase()) return;
3227 
3228  IssmDouble A, B, alpha, beta;
3229  IssmDouble bed,qsg,qsg_basin,TF,yts;
3230  int numbasins;
3231  IssmDouble basinid[NUMVERTICES];
3232  IssmDouble* basin_icefront_area=NULL;
3233 
3234  /* Coefficients */
3235  A = 3e-4;
3236  B = 0.15;
3237  alpha = 0.39;
3238  beta = 1.18;
3239 
3240  /*Get inputs*/
3241  Input2* bed_input = this->GetInput2(BedEnum); _assert_(bed_input);
3242  Input2* qsg_input = this->GetInput2(FrontalForcingsSubglacialDischargeEnum); _assert_(qsg_input);
3243  Input2* TF_input = this->GetInput2(FrontalForcingsThermalForcingEnum); _assert_(TF_input);
3245 
3246  this->FindParam(&yts, ConstantsYtsEnum);
3248  this->parameters->FindParam(&basin_icefront_area,&numbasins,FrontalForcingsBasinIcefrontAreaEnum);
3249 
3250  IssmDouble meltrates[NUMVERTICES2D]; //frontal melt-rate
3251 
3252  /* Start looping on the number of vertices: */
3253  GaussPenta* gauss=new GaussPenta();
3254  for(int iv=0;iv<NUMVERTICES2D;iv++){
3255  gauss->GaussVertex(iv);
3256 
3257  /* Get variables */
3258  bed_input->GetInputValue(&bed,gauss);
3259  qsg_input->GetInputValue(&qsg,gauss);
3260  TF_input->GetInputValue(&TF,gauss);
3261 
3262  if(basinid[iv]==0 || basin_icefront_area[reCast<int>(basinid[iv])-1]==0.) meltrates[iv]=0.;
3263  else{
3264  /* change the unit of qsg (m^3/d -> m/d) with ice front area */
3265  qsg_basin=qsg/basin_icefront_area[reCast<int>(basinid[iv])-1];
3266 
3267  /* calculate melt rates */
3268  meltrates[iv]=((A*max(-bed,0.)*pow(max(qsg_basin,0.),alpha)+B)*pow(max(TF,0.),beta))/86400; //[m/s]
3269  }
3270 
3271  if(xIsNan<IssmDouble>(meltrates[iv])) _error_("NaN found in vector");
3272  if(xIsInf<IssmDouble>(meltrates[iv])) _error_("Inf found in vector");
3273  }
3274 
3275  /*Add input*/
3276  this->AddInput2(CalvingMeltingrateEnum,&meltrates[0],P1Enum);
3277 
3279 
3280  /*Cleanup and return*/
3281  xDelete<IssmDouble>(basin_icefront_area);
3282  delete gauss;
3283 }
3284 /*}}}*/
3285 void Penta::SetElementInput(int enum_in,IssmDouble value){/*{{{*/
3286 
3287  this->SetElementInput(this->inputs2,enum_in,value);
3288 
3289 }
3290 /*}}}*/
3291 void Penta::SetElementInput(Inputs2* inputs2,int enum_in,IssmDouble value){/*{{{*/
3292 
3293  _assert_(inputs2);
3294  inputs2->SetPentaInput(enum_in,P0Enum,this->lid,value);
3295 
3296 }
3297 /*}}}*/
3298 void Penta::SetElementInput(Inputs2* inputs2,int numindices,int* indices,IssmDouble* values,int enum_in){/*{{{*/
3299 
3300  _assert_(inputs2);
3301  inputs2->SetPentaInput(enum_in,P1Enum,numindices,indices,values);
3302 
3303 }
3304 /*}}}*/
3305 void Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N, int M){/*{{{*/
3306 
3307  IssmDouble values[NUMVERTICES];
3308  int vertexpidlist[NUMVERTICES],control_init;
3309 
3310  /*Specific case for depth averaged quantities*/
3311  control_init=control_enum;
3312  if(control_enum==MaterialsRheologyBbarEnum){
3313  control_enum=MaterialsRheologyBEnum;
3314  if(!IsOnBase()) return;
3315  }
3316  if(control_enum==DamageDbarEnum){
3317  control_enum=DamageDEnum;
3318  if(!IsOnBase()) return;
3319  }
3320 
3321  /*Get out if this is not an element input*/
3322  if(!IsInputEnum(control_enum)) return;
3323 
3324  /*Prepare index list*/
3325  GradientIndexing(&vertexpidlist[0],control_index);
3326 
3327  /*Get values on vertices*/
3328  for(int i=0;i<NUMVERTICES;i++){
3329  values[i]=vector[vertexpidlist[i]];
3330  }
3331  _error_("not implemented");
3332  //Input* new_input = new PentaInput(control_enum,values,P1Enum);
3333  Input2* input=(Input2*)this->GetInput2(control_enum); _assert_(input);
3334  if(input->ObjectEnum()!=ControlInputEnum){
3335  _error_("input " << EnumToStringx(control_enum) << " is not a ControlInput");
3336  }
3337 
3338  //((ControlInput*)input)->SetInput(new_input);
3339 
3340  if(control_init==MaterialsRheologyBbarEnum){
3341  this->InputExtrude(control_enum,-1);
3342  }
3343  if(control_init==DamageDbarEnum){
3344  this->InputExtrude(control_enum,-1);
3345  }
3346 }
3347 /*}}}*/
3348 void Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){/*{{{*/
3349 
3350  IssmDouble values[NUMVERTICES];
3351  int lidlist[NUMVERTICES];
3352  int idlist[NUMVERTICES],control_init;
3353 
3354  /*Specific case for depth averaged quantities*/
3355  control_init=control_enum;
3356  if(control_enum==MaterialsRheologyBbarEnum){
3357  control_enum=MaterialsRheologyBEnum;
3358  if(!IsOnBase()) return;
3359  }
3360  if(control_enum==DamageDbarEnum){
3361  control_enum=DamageDEnum;
3362  if(!IsOnBase()) return;
3363  }
3364 
3365  /*Get Domain type*/
3366  int domaintype;
3367  parameters->FindParam(&domaintype,DomainTypeEnum);
3368 
3369  /*Specific case for depth averaged quantities*/
3370  if(domaintype==Domain2DverticalEnum){
3371  if(control_enum==MaterialsRheologyBbarEnum){
3372  control_enum=MaterialsRheologyBEnum;
3373  if(!IsOnBase()) return;
3374  }
3375  if(control_enum==DamageDbarEnum){
3376  control_enum=DamageDEnum;
3377  if(!IsOnBase()) return;
3378  }
3379  }
3380 
3381  /*Get out if this is not an element input*/
3382  if(!IsInputEnum(control_enum)) return;
3383 
3384  /*prepare index list*/
3385  this->GetVerticesLidList(&lidlist[0]);
3386  GradientIndexing(&idlist[0],control_index);
3387 
3388  /*Get values on vertices*/
3389  for(int i=0;i<NUMVERTICES;i++){
3390  values[i]=vector[idlist[i]];
3391  }
3392 
3393  /*Set Input*/
3394  ElementInput2* input=this->inputs2->GetControlInput2Data(control_enum,"value"); _assert_(input);
3395  input->SetInput(P1Enum,NUMVERTICES,&lidlist[0],&values[0]);
3396  if(control_init==MaterialsRheologyBbarEnum){
3397  this->ControlInputExtrude(control_enum,-1);
3398  }
3399  if(control_init==DamageDbarEnum){
3400  this->ControlInputExtrude(control_enum,-1);
3401  }
3402 }
3403 /*}}}*/
3404 void Penta::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){/*{{{*/
3405 
3406  /*go into parameters and get the analysis_counter: */
3407  int analysis_counter;
3408  parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
3409 
3410  /*Get Element type*/
3411  this->element_type=this->element_type_list[analysis_counter];
3412 
3413  /*Pick up nodes*/
3414  if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
3415  else this->nodes=NULL;
3416 
3417 }
3418 /*}}}*/
3419 void Penta::SetTemporaryElementType(int element_type_in){/*{{{*/
3420  this->element_type=element_type_in;
3421 }
3422 /*}}}*/
3424 
3425  _assert_(this->IsOnBase());
3426 
3427  switch(this->material->ObjectEnum()){
3428  case MaticeEnum:
3432  break;
3433  case MatestarEnum:
3437  break;
3438  default:
3439  _error_("not supported yet");
3440  }
3445 
3446  Tria* tria=(Tria*)SpawnTria(0,1,2);
3447 
3448  return tria;
3449 }
3450 /*}}}*/
3452 
3453  _assert_(this->IsOnSurface());
3454 
3455  Tria* tria=(Tria*)SpawnTria(3,4,5);
3456 
3457  return tria;
3458 }
3459 /*}}}*/
3460 Tria* Penta::SpawnTria(int index1,int index2,int index3){/*{{{*/
3461 
3462  int analysis_counter;
3463 
3464  /*go into parameters and get the analysis_counter: */
3465  this->parameters->FindParam(&analysis_counter,AnalysisCounterEnum);
3466 
3467  /*Create Tria*/
3468  Tria* tria=new Tria();
3469  tria->id=this->id;
3470  tria->sid=this->sid;
3471  tria->lid=this->lid;
3472  tria->parameters=this->parameters;
3473  tria->inputs2=this->inputs2;
3474  tria->element_type=P1Enum; //Only P1 CG for now (TO BE CHANGED)
3475  this->SpawnTriaHook(xDynamicCast<ElementHook*>(tria),index1,index2,index3);
3476 
3477  if(index1==0 && index2==1 && index3==2){
3478  tria->iscollapsed = 1;
3479  }
3480  else if(index1==3 && index2==4 && index3==5){
3481  tria->iscollapsed = 2;
3482  }
3483 
3484  /*Spawn material*/
3485  tria->material=(Material*)this->material->copy2(tria);
3486 
3487  /*recover nodes, material*/
3488  tria->nodes=(Node**)tria->hnodes[analysis_counter]->deliverp();
3489  tria->vertices=(Vertex**)tria->hvertices->deliverp();
3490 
3491  /*Return new Tria*/
3492  return tria;
3493 }
3494 /*}}}*/
3496  /*Compute stabilization parameter*/
3497  /*kappa=thermalconductivity/(rho_ice*heatcapacity) for thermal model*/
3498  /*kappa=enthalpydiffusionparameter for enthalpy model*/
3499 
3500  IssmDouble normu;
3501  IssmDouble tau_parameter;
3502 
3503  normu=pow(pow(u,2)+pow(v,2)+pow(w,2),0.5);
3504  if(normu*diameter/(3*2*kappa)<1){
3505  tau_parameter=pow(diameter,2)/(3*2*2*kappa);
3506  }
3507  else tau_parameter=diameter/(2*normu);
3508 
3509  return tau_parameter;
3510 }/*}}}*/
3512  /*Compute stabilization parameter*/
3513  /*kappa=thermalconductivity/(rho_ice*heatcapacity) for thermal model*/
3514  /*kappa=enthalpydiffusionparameter for enthalpy model*/
3515 
3516  IssmDouble normu,hk,C,area,p;
3517 
3518  /* compute tau for the horizontal direction */
3519  p=2.; C=3.;
3520  normu=pow(pow(u,p)+pow(v,p)+pow(w,p),1./p);
3521  hk=sqrt(pow(hx,2)+pow(hy,2));
3522 
3523  if(normu*hk/(C*2*kappa)<1){
3524  tau_parameter_anisotropic[0]=pow(hk,2)/(C*2*2*kappa);
3525  }
3526  else tau_parameter_anisotropic[0]=hk/(2*normu);
3527 
3528  /* compute tau for the vertical direction */
3529  hk=hz;
3530  if(normu*hk/(C*2*kappa)<1){
3531  tau_parameter_anisotropic[1]=pow(hk,2)/(C*2*2*kappa);
3532  }
3533  else{
3534  tau_parameter_anisotropic[1]=hk/(2*normu);
3535  }
3536 }
3537 /*}}}*/
3539 
3540  IssmDouble *xyz_list = NULL;
3541  IssmDouble epsilon[6];
3542  GaussPenta* gauss=NULL;
3543  IssmDouble vx,vy,vel;
3544  IssmDouble strainxx;
3545  IssmDouble strainxy;
3546  IssmDouble strainyy;
3547  IssmDouble strainparallel[NUMVERTICES];
3548 
3549  /* Get node coordinates and dof list: */
3550  this->GetVerticesCoordinates(&xyz_list);
3551 
3552  /*Retrieve all inputs we will need*/
3553  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
3554  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
3555  Input2* vz_input=this->GetInput2(VzEnum); _assert_(vz_input);
3556 
3557  /* Start looping on the number of vertices: */
3558  gauss=new GaussPenta();
3559  for (int iv=0;iv<NUMVERTICES;iv++){
3560  gauss->GaussVertex(iv);
3561 
3562  /* Get the value we need*/
3563  vx_input->GetInputValue(&vx,gauss);
3564  vy_input->GetInputValue(&vy,gauss);
3565  vel=vx*vx+vy*vy;
3566 
3567  /*Compute strain rate and viscosity: */
3568  this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
3569  strainxx=epsilon[0];
3570  strainyy=epsilon[1];
3571  strainxy=epsilon[3];
3572 
3573  /*strainparallel= Strain rate along the ice flow direction */
3574  strainparallel[iv]=(vx*vx*(strainxx)+vy*vy*(strainyy)+2*vy*vx*strainxy)/(vel+1.e-14);
3575  }
3576 
3577  /*Add input*/
3578  this->AddInput2(StrainRateparallelEnum,&strainparallel[0],P1DGEnum);
3579 
3580  /*Clean up and return*/
3581  delete gauss;
3582  xDelete<IssmDouble>(xyz_list);
3583 }
3584 /*}}}*/
3586 
3587  IssmDouble *xyz_list = NULL;
3588  IssmDouble epsilon[6];
3589  GaussPenta* gauss=NULL;
3590  IssmDouble vx,vy,vel;
3591  IssmDouble strainxx;
3592  IssmDouble strainxy;
3593  IssmDouble strainyy;
3594  IssmDouble strainperpendicular[NUMVERTICES];
3595 
3596  /* Get node coordinates and dof list: */
3597  this->GetVerticesCoordinates(&xyz_list);
3598 
3599  /*Retrieve all inputs we will need*/
3600  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
3601  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
3602  Input2* vz_input=this->GetInput2(VzEnum); _assert_(vz_input);
3603 
3604  /* Start looping on the number of vertices: */
3605  gauss=new GaussPenta();
3606  for (int iv=0;iv<NUMVERTICES;iv++){
3607  gauss->GaussVertex(iv);
3608 
3609  /* Get the value we need*/
3610  vx_input->GetInputValue(&vx,gauss);
3611  vy_input->GetInputValue(&vy,gauss);
3612  vel=vx*vx+vy*vy;
3613 
3614  /*Compute strain rate and viscosity: */
3615  this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
3616  strainxx=epsilon[0];
3617  strainyy=epsilon[1];
3618  strainxy=epsilon[3];
3619 
3620  /*strainperpendicular= Strain rate perpendicular to the ice flow direction */
3621  strainperpendicular[iv]=(vx*vx*(strainyy)+vy*vy*(strainxx)-2*vy*vx*strainxy)/(vel+1.e-14);
3622  }
3623 
3624  /*Add input*/
3625  this->AddInput2(StrainRateperpendicularEnum,&strainperpendicular[0],P1DGEnum);
3626 
3627  /*Clean up and return*/
3628  delete gauss;
3629  xDelete<IssmDouble>(xyz_list);
3630 }
3631 /*}}}*/
3633 
3634  /* Check if we are on the base */
3635  if(!IsOnBase()) return;
3636 
3637  IssmDouble ki[6]={0.};
3638  IssmDouble const_grav=9.81;
3639  IssmDouble rho_ice=900;
3640  IssmDouble rho_water=1000;
3641  IssmDouble Jdet[3];
3642  IssmDouble pressure,vx,vy,vel,deviaxx,deviaxy,deviayy,water_depth,prof,stress_xx,thickness;
3643 
3644  Penta* penta=this;
3645  for(;;){
3646 
3647  IssmDouble xyz_list[NUMVERTICES][3];
3648  /* Get node coordinates and dof list: */
3649  ::GetVerticesCoordinates(&xyz_list[0][0],penta->vertices,NUMVERTICES);
3650 
3652  Jdet[0]=(xyz_list[3][2]-xyz_list[0][2])*0.5;
3653  Jdet[1]=(xyz_list[4][2]-xyz_list[1][2])*0.5;
3654  Jdet[2]=(xyz_list[5][2]-xyz_list[2][2])*0.5;
3655 
3656  /*Retrieve all inputs we will need*/
3657  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
3658  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
3659  Input2* vel_input=this->GetInput2(VelEnum); _assert_(vel_input);
3660  Input2* pressure_input=this->GetInput2(PressureEnum); _assert_(pressure_input);
3661  Input2* deviaxx_input=this->GetInput2(DeviatoricStressxxEnum); _assert_(deviaxx_input);
3662  Input2* deviaxy_input=this->GetInput2(DeviatoricStressxyEnum); _assert_(deviaxy_input);
3663  Input2* deviayy_input=this->GetInput2(DeviatoricStressyyEnum); _assert_(deviayy_input);
3664  Input2* surface_input=this->GetInput2(SurfaceEnum); _assert_(surface_input);
3665  Input2* thickness_input=this->GetInput2(ThicknessEnum); _assert_(thickness_input);
3666 
3667  /* Start looping on the number of 2D vertices: */
3668  for(int ig=0;ig<3;ig++){
3669  GaussPenta* gauss=new GaussPenta(ig,3+ig,11);
3670  for (int iv=gauss->begin();iv<gauss->end();iv++){
3671  gauss->GaussPoint(iv);
3672 
3673  /* Get the value we need*/
3674  pressure_input->GetInputValue(&pressure,gauss);
3675  vx_input->GetInputValue(&vx,gauss);
3676  vy_input->GetInputValue(&vy,gauss);
3677  vel_input->GetInputValue(&vel,gauss);
3678  deviaxx_input->GetInputValue(&deviaxx,gauss);
3679  deviaxy_input->GetInputValue(&deviaxy,gauss);
3680  deviayy_input->GetInputValue(&deviayy,gauss);
3681  surface_input->GetInputValue(&water_depth,gauss);
3682  thickness_input->GetInputValue(&thickness,gauss);
3683  prof=water_depth-penta->GetZcoord(&xyz_list[0][0],gauss);
3684 
3685  /*stress_xx= Deviatoric stress along the ice flow direction plus cryostatic pressure */
3686  stress_xx=(vx*vx*(deviaxx)+vy*vy*(deviayy)+2*vy*vx*deviaxy)/(vel*vel+1.e-6);
3687 
3688  if(prof<water_depth&prof<thickness){
3689  /* Compute the local stress intensity factor*/
3690  ki[ig]+=Jdet[ig]*gauss->weight*stress_xx*StressIntensityIntegralWeight(prof,min(water_depth,thickness),thickness);
3691  }
3692  }
3693  delete gauss;
3694  }
3695 
3696  /*Stop if we have reached the surface/base*/
3697  if(penta->IsOnSurface()) break;
3698 
3699  /*get upper Penta*/
3700  penta=penta->GetUpperPenta();
3701  _assert_(penta->Id()!=this->id);
3702  }
3703 
3704  /*Add input*/
3707 }
3708 /*}}}*/
3710 
3711  int approximation;
3712  IssmDouble S;
3713  Tria* tria=NULL;
3714 
3715  /*retrieve inputs :*/
3716  this->GetInput2Value(&approximation,ApproximationEnum);
3717 
3718  /*If on water, return 0: */
3719  if(!IsIceInElement())return 0;
3720 
3721  /*Bail out if this element if:
3722  * -> Non SSA not on the surface
3723  * -> SSA (2d model) and not on bed) */
3724  if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
3725  return 0;
3726  }
3727  else if (approximation==SSAApproximationEnum){
3728 
3729  /*This element should be collapsed into a tria element at its base. Create this tria element,
3730  * and compute SurfaceArea*/
3731  tria=(Tria*)SpawnTria(0,1,2);
3732  S=tria->SurfaceArea();
3733  delete tria->material; delete tria;
3734  return S;
3735  }
3736  else{
3737 
3738  tria=(Tria*)SpawnTria(3,4,5);
3739  S=tria->SurfaceArea();
3740  delete tria->material; delete tria;
3741  return S;
3742  }
3743 }
3744 /*}}}*/
3746 
3747  /*intermediary: */
3748  IssmDouble C;
3749  IssmDouble xyz_list[NUMVERTICES][3];
3750 
3751  /*get CFL coefficient:*/
3753 
3754  /*Get for Vx and Vy, the max of abs value: */
3755  Input2* vx_input = this->GetInput2(VxEnum); _assert_(vx_input);
3756  Input2* vy_input = this->GetInput2(VyEnum); _assert_(vy_input);
3757  Input2* vz_input = this->GetInput2(VzEnum); _assert_(vz_input);
3758  IssmDouble maxabsvx = vx_input->GetInputMaxAbs();
3759  IssmDouble maxabsvy = vy_input->GetInputMaxAbs();
3760  IssmDouble maxabsvz = vz_input->GetInputMaxAbs();
3761 
3762  /* Get node coordinates and dof list: */
3764 
3765  IssmDouble minx=xyz_list[0][0];
3766  IssmDouble maxx=xyz_list[0][0];
3767  IssmDouble miny=xyz_list[0][1];
3768  IssmDouble maxy=xyz_list[0][1];
3769  IssmDouble minz=xyz_list[0][2];
3770  IssmDouble maxz=xyz_list[0][2];
3771 
3772  for(int i=1;i<NUMVERTICES;i++){
3773  if(xyz_list[i][0]<minx) minx=xyz_list[i][0];
3774  if(xyz_list[i][0]>maxx) maxx=xyz_list[i][0];
3775  if(xyz_list[i][1]<miny) miny=xyz_list[i][1];
3776  if(xyz_list[i][1]>maxy) maxy=xyz_list[i][1];
3777  if(xyz_list[i][2]<minz) minz=xyz_list[i][2];
3778  if(xyz_list[i][2]>maxz) maxz=xyz_list[i][2];
3779  }
3780  IssmDouble dx=maxx-minx;
3781  IssmDouble dy=maxy-miny;
3782  IssmDouble dz=maxz-minz;
3783 
3784  /*CFL criterion: */
3785  IssmDouble dt = C/(maxabsvx/dx+maxabsvy/dy+maxabsvz/dz);
3786 
3787  return dt;
3788 }/*}}}*/
3790 
3791  /*Make sure there is an ice front here*/
3792  if(!IsIceInElement() || !IsZeroLevelset(MaskIceLevelsetEnum) || !IsOnBase()) return 0;
3793 
3794  /*Scaled not implemented yet...*/
3795  _assert_(!scaled);
3796 
3797  int domaintype,index1,index2;
3798  const IssmPDouble epsilon = 1.e-15;
3799  IssmDouble s1,s2;
3800  IssmDouble gl[NUMVERTICES];
3801  IssmDouble xyz_front[2][3];
3802 
3803  IssmDouble *xyz_list = NULL;
3804  this->GetVerticesCoordinates(&xyz_list);
3805 
3806  /*Recover parameters and values*/
3808 
3809  /*Be sure that values are not zero*/
3810  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
3811  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
3812  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
3813 
3814  int pt1 = 0;
3815  int pt2 = 1;
3816  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
3817 
3818  /*Portion of the segments*/
3819  s1=gl[2]/(gl[2]-gl[1]);
3820  s2=gl[2]/(gl[2]-gl[0]);
3821  if(gl[2]<0.){
3822  pt1 = 1; pt2 = 0;
3823  }
3824  xyz_front[pt2][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
3825  xyz_front[pt2][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
3826  xyz_front[pt2][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
3827  xyz_front[pt1][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
3828  xyz_front[pt1][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
3829  xyz_front[pt1][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
3830  }
3831  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
3832 
3833  /*Portion of the segments*/
3834  s1=gl[0]/(gl[0]-gl[1]);
3835  s2=gl[0]/(gl[0]-gl[2]);
3836  if(gl[0]<0.){
3837  pt1 = 1; pt2 = 0;
3838  }
3839 
3840  xyz_front[pt1][0]=xyz_list[3*0+0]+s1*(xyz_list[3*1+0]-xyz_list[3*0+0]);
3841  xyz_front[pt1][1]=xyz_list[3*0+1]+s1*(xyz_list[3*1+1]-xyz_list[3*0+1]);
3842  xyz_front[pt1][2]=xyz_list[3*0+2]+s1*(xyz_list[3*1+2]-xyz_list[3*0+2]);
3843  xyz_front[pt2][0]=xyz_list[3*0+0]+s2*(xyz_list[3*2+0]-xyz_list[3*0+0]);
3844  xyz_front[pt2][1]=xyz_list[3*0+1]+s2*(xyz_list[3*2+1]-xyz_list[3*0+1]);
3845  xyz_front[pt2][2]=xyz_list[3*0+2]+s2*(xyz_list[3*2+2]-xyz_list[3*0+2]);
3846  }
3847  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
3848 
3849  /*Portion of the segments*/
3850  s1=gl[1]/(gl[1]-gl[0]);
3851  s2=gl[1]/(gl[1]-gl[2]);
3852  if(gl[1]<0.){
3853  pt1 = 1; pt2 = 0;
3854  }
3855 
3856  xyz_front[pt2][0]=xyz_list[3*1+0]+s1*(xyz_list[3*0+0]-xyz_list[3*1+0]);
3857  xyz_front[pt2][1]=xyz_list[3*1+1]+s1*(xyz_list[3*0+1]-xyz_list[3*1+1]);
3858  xyz_front[pt2][2]=xyz_list[3*1+2]+s1*(xyz_list[3*0+2]-xyz_list[3*1+2]);
3859  xyz_front[pt1][0]=xyz_list[3*1+0]+s2*(xyz_list[3*2+0]-xyz_list[3*1+0]);
3860  xyz_front[pt1][1]=xyz_list[3*1+1]+s2*(xyz_list[3*2+1]-xyz_list[3*1+1]);
3861  xyz_front[pt1][2]=xyz_list[3*1+2]+s2*(xyz_list[3*2+2]-xyz_list[3*1+2]);
3862  }
3863  else{
3864  _error_("case not possible");
3865  }
3866 
3867 
3868  /*Some checks in debugging mode*/
3869  _assert_(s1>=0 && s1<=1.);
3870  _assert_(s2>=0 && s2<=1.);
3871 
3872  /*Get normal vector*/
3873  IssmDouble normal[3];
3874  this->NormalSectionBase(&normal[0],&xyz_front[0][0]);
3875  normal[0] = -normal[0];
3876  normal[1] = -normal[1];
3877 
3878  /*Get inputs*/
3879  IssmDouble flux = 0.;
3880  IssmDouble calvingratex,calvingratey,thickness,Jdet;
3882  Input2* thickness_input=this->GetInput2(ThicknessEnum); _assert_(thickness_input);
3883  Input2* calvingratex_input=NULL;
3884  Input2* calvingratey_input=NULL;
3885  calvingratex_input=this->GetInput2(CalvingratexEnum); _assert_(calvingratex_input);
3886  calvingratey_input=this->GetInput2(CalvingrateyEnum); _assert_(calvingratey_input);
3887 
3888  /*Start looping on Gaussian points*/
3889  Gauss* gauss=this->NewGaussBase(xyz_list,&xyz_front[0][0],3);
3890  for(int ig=gauss->begin();ig<gauss->end();ig++){
3891 
3892  gauss->GaussPoint(ig);
3893  thickness_input->GetInputValue(&thickness,gauss);
3894  calvingratex_input->GetInputValue(&calvingratex,gauss);
3895  calvingratey_input->GetInputValue(&calvingratey,gauss);
3896  this->JacobianDeterminantLine(&Jdet,&xyz_front[0][0],gauss);
3897 
3898  flux += rho_ice*Jdet*gauss->weight*thickness*(calvingratex*normal[0] + calvingratey*normal[1]);
3899  }
3900 
3901  /*Clean up and return*/
3902  delete gauss;
3903  return flux;
3904 
3905 }
3906 /*}}}*/
3908 
3909  /*Make sure there is an ice front here*/
3910  if(!IsIceInElement() || !IsZeroLevelset(MaskIceLevelsetEnum) || !IsOnBase()) return 0;
3911 
3912  /*Scaled not implemented yet...*/
3913  _assert_(!scaled);
3914 
3915  int domaintype,index1,index2;
3916  const IssmPDouble epsilon = 1.e-15;
3917  IssmDouble s1,s2;
3918  IssmDouble gl[NUMVERTICES];
3919  IssmDouble xyz_front[2][3];
3920 
3921  IssmDouble *xyz_list = NULL;
3922  this->GetVerticesCoordinates(&xyz_list);
3923 
3924  /*Recover parameters and values*/
3926 
3927  /*Be sure that values are not zero*/
3928  if(gl[0]==0.) gl[0]=gl[0]+epsilon;
3929  if(gl[1]==0.) gl[1]=gl[1]+epsilon;
3930  if(gl[2]==0.) gl[2]=gl[2]+epsilon;
3931 
3932  int pt1 = 0;
3933  int pt2 = 1;
3934  if(gl[0]*gl[1]>0){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
3935 
3936  /*Portion of the segments*/
3937  s1=gl[2]/(gl[2]-gl[1]);
3938  s2=gl[2]/(gl[2]-gl[0]);
3939  if(gl[2]<0.){
3940  pt1 = 1; pt2 = 0;
3941  }
3942  xyz_front[pt2][0]=xyz_list[3*2+0]+s1*(xyz_list[3*1+0]-xyz_list[3*2+0]);
3943  xyz_front[pt2][1]=xyz_list[3*2+1]+s1*(xyz_list[3*1+1]-xyz_list[3*2+1]);
3944  xyz_front[pt2][2]=xyz_list[3*2+2]+s1*(xyz_list[3*1+2]-xyz_list[3*2+2]);
3945  xyz_front[pt1][0]=xyz_list[3*2+0]+s2*(xyz_list[3*0+0]-xyz_list[3*2+0]);
3946  xyz_front[pt1][1]=xyz_list[3*2+1]+s2*(xyz_list[3*0+1]-xyz_list[3*2+1]);
3947  xyz_front[pt1][2]=xyz_list[3*2+2]+s2*(xyz_list[3*0+2]-xyz_list[3*2+2]);
3948  }
3949  else if(gl[1]*gl[2]>0){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
3950 
3951  /*Portion of the segments*/
3952  s1=gl[0]/(gl[0]-gl[1]);
3953  s2=gl[0]/(gl[0]-gl[2]);
3954  if(gl[0]<0.){
3955  pt1 = 1; pt2 = 0;
3956  }
3957 
3958  xyz_front[pt1][0]=xyz_list[3*0+0]+s1*(xyz_list[3*1+0]-xyz_list[3*0+0]);
3959  xyz_front[pt1][1]=xyz_list[3*0+1]+s1*(xyz_list[3*1+1]-xyz_list[3*0+1]);
3960  xyz_front[pt1][2]=xyz_list[3*0+2]+s1*(xyz_list[3*1+2]-xyz_list[3*0+2]);
3961  xyz_front[pt2][0]=xyz_list[3*0+0]+s2*(xyz_list[3*2+0]-xyz_list[3*0+0]);
3962  xyz_front[pt2][1]=xyz_list[3*0+1]+s2*(xyz_list[3*2+1]-xyz_list[3*0+1]);
3963  xyz_front[pt2][2]=xyz_list[3*0+2]+s2*(xyz_list[3*2+2]-xyz_list[3*0+2]);
3964  }
3965  else if(gl[0]*gl[2]>0){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
3966 
3967  /*Portion of the segments*/
3968  s1=gl[1]/(gl[1]-gl[0]);
3969  s2=gl[1]/(gl[1]-gl[2]);
3970  if(gl[1]<0.){
3971  pt1 = 1; pt2 = 0;
3972  }
3973 
3974  xyz_front[pt2][0]=xyz_list[3*1+0]+s1*(xyz_list[3*0+0]-xyz_list[3*1+0]);
3975  xyz_front[pt2][1]=xyz_list[3*1+1]+s1*(xyz_list[3*0+1]-xyz_list[3*1+1]);
3976  xyz_front[pt2][2]=xyz_list[3*1+2]+s1*(xyz_list[3*0+2]-xyz_list[3*1+2]);
3977  xyz_front[pt1][0]=xyz_list[3*1+0]+s2*(xyz_list[3*2+0]-xyz_list[3*1+0]);
3978  xyz_front[pt1][1]=xyz_list[3*1+1]+s2*(xyz_list[3*2+1]-xyz_list[3*1+1]);
3979  xyz_front[pt1][2]=xyz_list[3*1+2]+s2*(xyz_list[3*2+2]-xyz_list[3*1+2]);
3980  }
3981  else{
3982  _error_("case not possible");
3983  }
3984 
3985 
3986  /*Some checks in debugging mode*/
3987  _assert_(s1>=0 && s1<=1.);
3988  _assert_(s2>=0 && s2<=1.);
3989 
3990  /*Get normal vector*/
3991  IssmDouble normal[3];
3992  this->NormalSectionBase(&normal[0],&xyz_front[0][0]);
3993  normal[0] = -normal[0];
3994  normal[1] = -normal[1];
3995 
3998 
3999  /*Get inputs*/
4000  IssmDouble flux = 0.;
4001  IssmDouble calvingratex,calvingratey,vx,vy,vel,meltingrate,meltingratex,meltingratey,thickness,Jdet;
4003  Input2* thickness_input=this->GetInput2(ThicknessEnum); _assert_(thickness_input);
4004  Input2* calvingratex_input=NULL;
4005  Input2* calvingratey_input=NULL;
4006  Input2* vx_input=NULL;
4007  Input2* vy_input=NULL;
4008  Input2* meltingrate_input=NULL;
4009  calvingratex_input=this->GetInput2(CalvingratexEnum); _assert_(calvingratex_input);
4010  calvingratey_input=this->GetInput2(CalvingrateyEnum); _assert_(calvingratey_input);
4011  vx_input=this->GetInput2(VxAverageEnum); _assert_(vx_input);
4012  vy_input=this->GetInput2(VyAverageEnum); _assert_(vy_input);
4013  meltingrate_input=this->GetInput2(CalvingMeltingrateEnum); _assert_(meltingrate_input);
4014 
4015  /*Start looping on Gaussian points*/
4016  Gauss* gauss=this->NewGaussBase(xyz_list,&xyz_front[0][0],3);
4017  for(int ig=gauss->begin();ig<gauss->end();ig++){
4018 
4019  gauss->GaussPoint(ig);
4020  thickness_input->GetInputValue(&thickness,gauss);
4021  calvingratex_input->GetInputValue(&calvingratex,gauss);
4022  calvingratey_input->GetInputValue(&calvingratey,gauss);
4023  vx_input->GetInputValue(&vx,gauss);
4024  vy_input->GetInputValue(&vy,gauss);
4025  vel=vx*vx+vy*vy;
4026  meltingrate_input->GetInputValue(&meltingrate,gauss);
4027  meltingratex=meltingrate*vx/(sqrt(vel)+1.e-14);
4028  meltingratey=meltingrate*vy/(sqrt(vel)+1.e-14);
4029  this->JacobianDeterminantLine(&Jdet,&xyz_front[0][0],gauss);
4030 
4031  flux += rho_ice*Jdet*gauss->weight*thickness*((calvingratex+meltingratex)*normal[0] + (calvingratey+meltingratey)*normal[1]);
4032  }
4033 
4034  /*Clean up and return*/
4035  delete gauss;
4036  return flux;
4037 
4038 }
4039 /*}}}*/
4041 
4042  /*The fbmb[kg yr-1] of one element is area[m2] * melting_rate [kg m^-2 yr^-1]*/
4043  int point1;
4044  bool mainlyfloating;
4045  IssmDouble fbmb=0;
4046  IssmDouble rho_ice,fraction1,fraction2,floatingmelt,Jdet,scalefactor;
4047  IssmDouble Total_Fbmb=0;
4048  IssmDouble xyz_list[NUMVERTICES][3];
4049  Gauss* gauss = NULL;
4050 
4051  if(!IsIceInElement() || !IsOnBase())return 0;
4052 
4053  /*Get material parameters :*/
4054  rho_ice=FindParam(MaterialsRhoIceEnum);
4055  Input2* floatingmelt_input = this->GetInput2(BasalforcingsFloatingiceMeltingRateEnum); _assert_(floatingmelt_input);
4056  Input2* gllevelset_input = this->GetInput2(MaskOceanLevelsetEnum); _assert_(gllevelset_input);
4057  Input2* scalefactor_input = NULL;
4058  if(scaled==true){
4059  scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
4060  }
4062 
4063  this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
4064  /* Start looping on the number of gaussian points: */
4065  gauss = this->NewGauss(point1,fraction1,fraction2,1-mainlyfloating,3);
4066  for(int ig=gauss->begin();ig<gauss->end();ig++){
4067 
4068  gauss->GaussPoint(ig);
4069  this->JacobianDeterminantBase(&Jdet,&xyz_list[0][0],gauss);
4070  floatingmelt_input->GetInputValue(&floatingmelt,gauss);
4071  if(scaled==true){
4072  scalefactor_input->GetInputValue(&scalefactor,gauss);
4073  }
4074  else scalefactor=1;
4075  fbmb+=floatingmelt*Jdet*gauss->weight*scalefactor;
4076  }
4077 
4078  Total_Fbmb=rho_ice*fbmb; // from volume to mass
4079 
4080  /*Return: */
4081  delete gauss;
4082  return Total_Fbmb;
4083 }
4084 /*}}}*/
4086 
4087  /*The gbmb[kg yr-1] of one element is area[m2] * gounded melting rate [kg m^-2 yr^-1]*/
4088  int point1;
4089  bool mainlyfloating;
4090  IssmDouble gbmb=0;
4091  IssmDouble rho_ice,fraction1,fraction2,groundedmelt,Jdet,scalefactor;
4092  IssmDouble Total_Gbmb=0;
4093  IssmDouble xyz_list[NUMVERTICES][3];
4094  Gauss* gauss = NULL;
4095 
4096  if(!IsIceInElement() || !IsOnBase())return 0;
4097 
4098  /*Get material parameters :*/
4099  rho_ice=FindParam(MaterialsRhoIceEnum);
4100  Input2* groundedmelt_input = this->GetInput2(BasalforcingsGroundediceMeltingRateEnum); _assert_(groundedmelt_input);
4101  Input2* gllevelset_input = this->GetInput2(MaskOceanLevelsetEnum); _assert_(gllevelset_input);
4102  Input2* scalefactor_input = NULL;
4103  if(scaled==true){
4104  scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
4105  }
4107 
4108  this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
4109  /* Start looping on the number of gaussian points: */
4110  gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,3);
4111  for(int ig=gauss->begin();ig<gauss->end();ig++){
4112 
4113  gauss->GaussPoint(ig);
4114  this->JacobianDeterminantBase(&Jdet,&xyz_list[0][0],gauss);
4115  groundedmelt_input->GetInputValue(&groundedmelt,gauss);
4116  if(scaled==true){
4117  scalefactor_input->GetInputValue(&scalefactor,gauss);
4118  }
4119  else scalefactor=1;
4120  gbmb+=groundedmelt*Jdet*gauss->weight*scalefactor;
4121  }
4122 
4123  Total_Gbmb=rho_ice*gbmb; // from volume to mass
4124 
4125  /*Return: */
4126  delete gauss;
4127  return Total_Gbmb;
4128 }
4129 /*}}}*/
4130 IssmDouble Penta::TotalSmb(bool scaled){/*{{{*/
4131 
4132  /*The smb[Gt yr-1] of one element is area[m2] * smb [ m ice yr^-1] * rho_ice [kg m-3] / 1e+10^12 */
4133  IssmDouble base,smb,rho_ice,scalefactor;
4134  IssmDouble Total_Smb=0;
4135  IssmDouble xyz_list[NUMVERTICES][3];
4136 
4137  /*Get material parameters :*/
4138  rho_ice=FindParam(MaterialsRhoIceEnum);
4139 
4140  if(!IsIceInElement() || !IsOnSurface()) return 0.;
4141 
4143 
4144  /*First calculate the area of the base (cross section triangle)
4145  * http://en.wikipedia.org/wiki/Triangle
4146  * base = 1/2 abs((xA-xC)(yB-yA)-(xA-xB)(yC-yA))*/
4147  base = 1./2. * fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1]));
4148 
4149  /*Now get the average SMB over the element*/
4150  Input2* smb_input = this->GetInput2(SmbMassBalanceEnum); _assert_(smb_input);
4151 
4152  smb_input->GetInputAverage(&smb);
4153  if(scaled==true){
4154  Input2* scalefactor_input = this->GetInput2(MeshScaleFactorEnum); _assert_(scalefactor_input);
4155  scalefactor_input->GetInputAverage(&scalefactor);// average scalefactor on element
4156  }
4157  else{
4158  scalefactor=1.;
4159  }
4160  Total_Smb=rho_ice*base*smb*scalefactor;// smb on element in kg s-1
4161 
4162  /*Return: */
4163  return Total_Smb;
4164 }
4165 /*}}}*/
4166 void Penta::Update(Inputs2* inputs2,int index,IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){ /*{{{*/
4167 
4168  /*Intermediaries*/
4169  int i;
4170  int penta_vertex_ids[6];
4171  IssmDouble nodeinputs[6];
4172  IssmDouble yts;
4173  bool dakota_analysis;
4174  int numnodes;
4175  int* penta_node_ids = NULL;
4176 
4177  /*Fetch parameters: */
4178  iomodel->FindConstant(&yts,"md.constants.yts");
4179  iomodel->FindConstant(&dakota_analysis,"md.qmu.isdakota");
4180 
4181  /*Checks if debuging*/
4182  _assert_(iomodel->elements);
4183  _assert_(index==this->sid);
4184 
4185  /*Recover element type*/
4186  this->element_type_list[analysis_counter]=finiteelement_type;
4187 
4188  /*Recover vertices ids needed to initialize inputs*/
4189  for(i=0;i<6;i++) penta_vertex_ids[i]=iomodel->elements[6*index+i]; //ids for vertices are in the elements array from Matlab
4190 
4191  /*Recover nodes ids needed to initialize the node hook.*/
4192  switch(finiteelement_type){
4193  case P1Enum:
4194  numnodes = 6;
4195  penta_node_ids = xNew<int>(numnodes);
4196  penta_node_ids[0]=iomodel->elements[6*index+0];
4197  penta_node_ids[1]=iomodel->elements[6*index+1];
4198  penta_node_ids[2]=iomodel->elements[6*index+2];
4199  penta_node_ids[3]=iomodel->elements[6*index+3];
4200  penta_node_ids[4]=iomodel->elements[6*index+4];
4201  penta_node_ids[5]=iomodel->elements[6*index+5];
4202  break;
4204  numnodes = 7;
4205  penta_node_ids = xNew<int>(numnodes);
4206  penta_node_ids[0]=iomodel->elements[6*index+0];
4207  penta_node_ids[1]=iomodel->elements[6*index+1];
4208  penta_node_ids[2]=iomodel->elements[6*index+2];
4209  penta_node_ids[3]=iomodel->elements[6*index+3];
4210  penta_node_ids[4]=iomodel->elements[6*index+4];
4211  penta_node_ids[5]=iomodel->elements[6*index+5];
4212  penta_node_ids[6]=iomodel->numberofvertices+index+1;
4213  break;
4214  case P1xP2Enum:
4215  numnodes = 9;
4216  penta_node_ids = xNew<int>(numnodes);
4217  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4218  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4219  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4220  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4221  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4222  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4223  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoverticaledgeconnectivity[3*index+0]+1;
4224  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoverticaledgeconnectivity[3*index+1]+1;
4225  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoverticaledgeconnectivity[3*index+2]+1;
4226  break;
4227  case P1xP3Enum:
4228  numnodes = 12;
4229  penta_node_ids = xNew<int>(numnodes);
4230  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4231  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4232  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4233  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4234  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4235  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4236  penta_node_ids[ 6]=iomodel->numberofvertices+2*iomodel->elementtoverticaledgeconnectivity[3*index+0]+1;
4237  penta_node_ids[ 7]=iomodel->numberofvertices+2*iomodel->elementtoverticaledgeconnectivity[3*index+1]+1;
4238  penta_node_ids[ 8]=iomodel->numberofvertices+2*iomodel->elementtoverticaledgeconnectivity[3*index+2]+1;
4239  penta_node_ids[ 9]=iomodel->numberofvertices+2*iomodel->elementtoverticaledgeconnectivity[3*index+0]+2;
4240  penta_node_ids[10]=iomodel->numberofvertices+2*iomodel->elementtoverticaledgeconnectivity[3*index+1]+2;
4241  penta_node_ids[11]=iomodel->numberofvertices+2*iomodel->elementtoverticaledgeconnectivity[3*index+2]+2;
4242  break;
4243  case P2xP1Enum:
4244  numnodes = 12;
4245  penta_node_ids = xNew<int>(numnodes);
4246  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4247  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4248  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4249  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4250  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4251  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4252  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtohorizontaledgeconnectivity[6*index+0]+1;
4253  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtohorizontaledgeconnectivity[6*index+1]+1;
4254  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtohorizontaledgeconnectivity[6*index+2]+1;
4255  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtohorizontaledgeconnectivity[6*index+3]+1;
4256  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtohorizontaledgeconnectivity[6*index+4]+1;
4257  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtohorizontaledgeconnectivity[6*index+5]+1;
4258  break;
4259  case P1xP4Enum:
4260  numnodes = 15;
4261  penta_node_ids = xNew<int>(numnodes);
4262  penta_node_ids[ 0]=iomodel->elements[6*index+0]; /*Vertex 1*/
4263  penta_node_ids[ 1]=iomodel->elements[6*index+1]; /*Vertex 2*/
4264  penta_node_ids[ 2]=iomodel->elements[6*index+2]; /*Vertex 3*/
4265  penta_node_ids[ 3]=iomodel->elements[6*index+3]; /*Vertex 4*/
4266  penta_node_ids[ 4]=iomodel->elements[6*index+4]; /*Vertex 5*/
4267  penta_node_ids[ 5]=iomodel->elements[6*index+5]; /*Vertex 6*/
4268  penta_node_ids[ 6]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+0]+1; /*mid vertical edge 1*/
4269  penta_node_ids[ 7]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+1]+1; /*mid vertical edge 2*/
4270  penta_node_ids[ 8]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+2]+1; /*mid vertical edge 3*/
4271  penta_node_ids[ 9]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+0]+2; /* 1/4 vertical edge 1*/
4272  penta_node_ids[10]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+1]+2; /* 1/4 vertical edge 2*/
4273  penta_node_ids[11]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+2]+2; /* 1/4 vertical edge 3*/
4274  penta_node_ids[12]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+0]+3; /* 3/4 vertical edge 1*/
4275  penta_node_ids[13]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+1]+3; /* 3/4 vertical edge 2*/
4276  penta_node_ids[14]=iomodel->numberofvertices+3*iomodel->elementtoverticaledgeconnectivity[3*index+2]+3; /* 3/4 vertical edge 3*/
4277  break;
4278  case P2xP4Enum:
4279  numnodes = 30;
4280  penta_node_ids = xNew<int>(numnodes);
4281  penta_node_ids[ 0]=iomodel->elements[6*index+0]; /*Vertex 1*/
4282  penta_node_ids[ 1]=iomodel->elements[6*index+1]; /*Vertex 2*/
4283  penta_node_ids[ 2]=iomodel->elements[6*index+2]; /*Vertex 3*/
4284  penta_node_ids[ 3]=iomodel->elements[6*index+3]; /*Vertex 4*/
4285  penta_node_ids[ 4]=iomodel->elements[6*index+4]; /*Vertex 5*/
4286  penta_node_ids[ 5]=iomodel->elements[6*index+5]; /*Vertex 6*/
4287  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1; /*mid vertical edge 1*/
4288  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1; /*mid vertical edge 2*/
4289  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1; /*mid vertical edge 3*/
4290  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1; /*mid basal edge 1*/
4291  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1; /*mid basal edge 2*/
4292  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1; /*mid basal edge 3*/
4293  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1; /*mid top edge 1*/
4294  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1; /*mid top edge 2*/
4295  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1; /*mid top edge 3*/
4296  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+0]+1; /* 1/4 vertical edge 1*/
4297  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+1]+1; /* 1/4 vertical edge 2*/
4298  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+2]+1; /* 1/4 vertical edge 3*/
4299  penta_node_ids[18]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+0]+2; /* 3/4 vertical edge 1*/
4300  penta_node_ids[19]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+1]+2; /* 3/4 vertical edge 2*/
4301  penta_node_ids[20]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+2]+2; /* 3/4 vertical edge 3*/
4302  penta_node_ids[21]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+0]+1; /* 1/4 vertical face 1*/
4303  penta_node_ids[22]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+1]+1; /* 1/4 vertical face 2*/
4304  penta_node_ids[23]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+2]+1; /* 1/4 vertical face 3*/
4305  penta_node_ids[24]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+0]+2; /* 2/4 vertical face 1*/
4306  penta_node_ids[25]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+1]+2; /* 2/4 vertical face 2*/
4307  penta_node_ids[26]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+2]+2; /* 2/4 vertical face 3*/
4308  penta_node_ids[27]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+0]+3; /* 3/4 vertical face 1*/
4309  penta_node_ids[28]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+1]+3; /* 3/4 vertical face 2*/
4310  penta_node_ids[29]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+2]+3; /* 3/4 vertical face 3*/
4311  break;
4312  case P2Enum:
4313  numnodes = 18;
4314  penta_node_ids = xNew<int>(numnodes);
4315  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4316  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4317  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4318  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4319  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4320  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4321  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1;
4322  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1;
4323  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
4324  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1;
4325  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1;
4326  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1;
4327  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1;
4328  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
4329  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
4330  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtoverticalfaceconnectivity[3*index+0]+1;
4331  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtoverticalfaceconnectivity[3*index+1]+1;
4332  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtoverticalfaceconnectivity[3*index+2]+1;
4333  break;
4335  numnodes = 19;
4336  penta_node_ids = xNew<int>(numnodes);
4337  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4338  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4339  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4340  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4341  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4342  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4343  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1;
4344  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1;
4345  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
4346  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1;
4347  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1;
4348  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1;
4349  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1;
4350  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
4351  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
4352  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+2]+1;
4353  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+3]+1;
4354  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+4]+1;
4355  penta_node_ids[18]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+index+1;
4356  break;
4357  case P1P1Enum: case P1P1GLSEnum:
4358  numnodes = 12;
4359  penta_node_ids = xNew<int>(numnodes);
4360  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4361  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4362  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4363  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4364  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4365  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4366 
4367  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elements[6*index+0];
4368  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elements[6*index+1];
4369  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elements[6*index+2];
4370  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elements[6*index+3];
4371  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elements[6*index+4];
4372  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elements[6*index+5];
4373  break;
4374  case MINIEnum: case MINIcondensedEnum:
4375  numnodes = 13;
4376  penta_node_ids = xNew<int>(numnodes);
4377  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4378  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4379  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4380  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4381  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4382  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4383  penta_node_ids[ 6]=iomodel->numberofvertices+index+1;
4384 
4385  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[6*index+0];
4386  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[6*index+1];
4387  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[6*index+2];
4388  penta_node_ids[10]=iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[6*index+3];
4389  penta_node_ids[11]=iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[6*index+4];
4390  penta_node_ids[12]=iomodel->numberofvertices+iomodel->numberofelements+iomodel->elements[6*index+5];
4391  break;
4392  case TaylorHoodEnum:
4393  numnodes = 24;
4394  penta_node_ids = xNew<int>(numnodes);
4395  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4396  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4397  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4398  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4399  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4400  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4401  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1;
4402  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1;
4403  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
4404  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1;
4405  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1;
4406  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1;
4407  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1;
4408  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
4409  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
4410  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtoverticalfaceconnectivity[3*index+0]+1;
4411  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtoverticalfaceconnectivity[3*index+1]+1;
4412  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtoverticalfaceconnectivity[3*index+2]+1;
4413 
4414  penta_node_ids[18]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberofverticalfaces+iomodel->elements[6*index+0];
4415  penta_node_ids[19]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberofverticalfaces+iomodel->elements[6*index+1];
4416  penta_node_ids[20]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberofverticalfaces+iomodel->elements[6*index+2];
4417  penta_node_ids[21]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberofverticalfaces+iomodel->elements[6*index+3];
4418  penta_node_ids[22]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberofverticalfaces+iomodel->elements[6*index+4];
4419  penta_node_ids[23]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberofverticalfaces+iomodel->elements[6*index+5];
4420  break;
4421  case LATaylorHoodEnum:
4422  numnodes = 18;
4423  penta_node_ids = xNew<int>(numnodes);
4424  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4425  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4426  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4427  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4428  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4429  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4430  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1;
4431  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1;
4432  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
4433  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1;
4434  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1;
4435  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1;
4436  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1;
4437  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
4438  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
4439  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+2]+1;
4440  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+3]+1;
4441  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+4]+1;
4442  break;
4443  case OneLayerP4zEnum:
4444  numnodes = 30+6;
4445  penta_node_ids = xNew<int>(numnodes);
4446  penta_node_ids[ 0]=iomodel->elements[6*index+0]; /*Vertex 1*/
4447  penta_node_ids[ 1]=iomodel->elements[6*index+1]; /*Vertex 2*/
4448  penta_node_ids[ 2]=iomodel->elements[6*index+2]; /*Vertex 3*/
4449  penta_node_ids[ 3]=iomodel->elements[6*index+3]; /*Vertex 4*/
4450  penta_node_ids[ 4]=iomodel->elements[6*index+4]; /*Vertex 5*/
4451  penta_node_ids[ 5]=iomodel->elements[6*index+5]; /*Vertex 6*/
4452  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1; /*mid vertical edge 1*/
4453  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1; /*mid vertical edge 2*/
4454  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1; /*mid vertical edge 3*/
4455  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1; /*mid basal edge 1*/
4456  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1; /*mid basal edge 2*/
4457  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1; /*mid basal edge 3*/
4458  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1; /*mid top edge 1*/
4459  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1; /*mid top edge 2*/
4460  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1; /*mid top edge 3*/
4461  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+0]+1; /* 1/4 vertical edge 1*/
4462  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+1]+1; /* 1/4 vertical edge 2*/
4463  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+2]+1; /* 1/4 vertical edge 3*/
4464  penta_node_ids[18]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+0]+2; /* 3/4 vertical edge 1*/
4465  penta_node_ids[19]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+1]+2; /* 3/4 vertical edge 2*/
4466  penta_node_ids[20]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->elementtoverticaledgeconnectivity[3*index+2]+2; /* 3/4 vertical edge 3*/
4467  penta_node_ids[21]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+0]+1; /* 1/4 vertical face 1*/
4468  penta_node_ids[22]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+1]+1; /* 1/4 vertical face 2*/
4469  penta_node_ids[23]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+2]+1; /* 1/4 vertical face 3*/
4470  penta_node_ids[24]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+0]+2; /* 2/4 vertical face 1*/
4471  penta_node_ids[25]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+1]+2; /* 2/4 vertical face 2*/
4472  penta_node_ids[26]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+2]+2; /* 2/4 vertical face 3*/
4473  penta_node_ids[27]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+0]+3; /* 3/4 vertical face 1*/
4474  penta_node_ids[28]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+1]+3; /* 3/4 vertical face 2*/
4475  penta_node_ids[29]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->elementtoverticalfaceconnectivity[3*index+2]+3; /* 3/4 vertical face 3*/
4476 
4477  penta_node_ids[30]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->numberofverticalfaces+iomodel->elements[6*index+0];
4478  penta_node_ids[31]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->numberofverticalfaces+iomodel->elements[6*index+1];
4479  penta_node_ids[32]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->numberofverticalfaces+iomodel->elements[6*index+2];
4480  penta_node_ids[33]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->numberofverticalfaces+iomodel->elements[6*index+3];
4481  penta_node_ids[34]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->numberofverticalfaces+iomodel->elements[6*index+4];
4482  penta_node_ids[35]=iomodel->numberofvertices+iomodel->numberofedges+2*iomodel->numberofverticaledges+3*iomodel->numberofverticalfaces+iomodel->elements[6*index+5];
4483  break;
4484  case CrouzeixRaviartEnum:
4485  numnodes = 25;
4486  penta_node_ids = xNew<int>(numnodes);
4487  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4488  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4489  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4490  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4491  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4492  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4493  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1;
4494  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1;
4495  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
4496  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1;
4497  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1;
4498  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1;
4499  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1;
4500  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
4501  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
4502  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+2]+1;
4503  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+3]+1;
4504  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+4]+1;
4505  penta_node_ids[18]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+index+1;
4506 
4507  penta_node_ids[19]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->numberofelements+6*index+1;
4508  penta_node_ids[20]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->numberofelements+6*index+2;
4509  penta_node_ids[21]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->numberofelements+6*index+3;
4510  penta_node_ids[22]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->numberofelements+6*index+4;
4511  penta_node_ids[23]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->numberofelements+6*index+5;
4512  penta_node_ids[24]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+iomodel->numberofelements+6*index+6;
4513  break;
4514  case LACrouzeixRaviartEnum:
4515  numnodes = 19;
4516  penta_node_ids = xNew<int>(numnodes);
4517  penta_node_ids[ 0]=iomodel->elements[6*index+0];
4518  penta_node_ids[ 1]=iomodel->elements[6*index+1];
4519  penta_node_ids[ 2]=iomodel->elements[6*index+2];
4520  penta_node_ids[ 3]=iomodel->elements[6*index+3];
4521  penta_node_ids[ 4]=iomodel->elements[6*index+4];
4522  penta_node_ids[ 5]=iomodel->elements[6*index+5];
4523  penta_node_ids[ 6]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+0]+1;
4524  penta_node_ids[ 7]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+1]+1;
4525  penta_node_ids[ 8]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+2]+1;
4526  penta_node_ids[ 9]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+3]+1;
4527  penta_node_ids[10]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+4]+1;
4528  penta_node_ids[11]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+5]+1;
4529  penta_node_ids[12]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+6]+1;
4530  penta_node_ids[13]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+7]+1;
4531  penta_node_ids[14]=iomodel->numberofvertices+iomodel->elementtoedgeconnectivity[9*index+8]+1;
4532  penta_node_ids[15]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+2]+1;
4533  penta_node_ids[16]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+3]+1;
4534  penta_node_ids[17]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->elementtofaceconnectivity[5*index+4]+1;
4535  penta_node_ids[18]=iomodel->numberofvertices+iomodel->numberofedges+iomodel->numberoffaces+index+1;
4536  break;
4537  default:
4538  _error_("Finite element "<<EnumToStringx(finiteelement_type)<<" not supported yet");
4539  }
4540 
4541  /*hooks: */
4542  this->SetHookNodes(penta_node_ids,numnodes,analysis_counter); this->nodes=NULL;
4543  xDelete<int>(penta_node_ids);
4544 
4545  /*Defaults if not provided in iomodel*/
4546  switch(analysis_type){
4547 
4549  _assert_(iomodel->Data("md.flowequation.element_equation"));
4550 
4551  if((IoCodeToEnumElementEquation(reCast<int>(iomodel->Data("md.flowequation.element_equation")[index])))==HOFSApproximationEnum){
4552  int vertexlids[NUMVERTICES];
4553  for(i=0;i<NUMVERTICES;i++) vertexlids[i]=iomodel->my_vertices_lids[penta_vertex_ids[i]-1];
4554  /*Create VzHO and VzFS Enums*/
4555  if(iomodel->Data("md.initialization.vz") && iomodel->Data("md.flowequation.borderFS")){
4556  for(i=0;i<6;i++) nodeinputs[i]=iomodel->Data("md.initialization.vz")[penta_vertex_ids[i]-1]*iomodel->Data("md.flowequation.borderFS")[penta_vertex_ids[i]-1];
4557  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzFSEnum);
4558  for(i=0;i<6;i++) nodeinputs[i]=iomodel->Data("md.initialization.vz")[penta_vertex_ids[i]-1]*(1-iomodel->Data("md.flowequation.borderFS")[penta_vertex_ids[i]-1]);
4559  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzHOEnum);
4560  }
4561  else{
4562  for(i=0;i<6;i++)nodeinputs[i]=0;
4563  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzFSEnum);
4564  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzHOEnum);
4565  }
4566  }
4567  if((IoCodeToEnumElementEquation(reCast<int>(iomodel->Data("md.flowequation.element_equation")[index])))==SSAFSApproximationEnum){
4568  int vertexlids[NUMVERTICES];
4569  for(i=0;i<NUMVERTICES;i++) vertexlids[i]=iomodel->my_vertices_lids[penta_vertex_ids[i]-1];
4570  /*Create VzSSA and VzFS Enums*/
4571  if(iomodel->Data("md.initialization.vz") && iomodel->Data("md.flowequation.borderFS")){
4572  for(i=0;i<6;i++) nodeinputs[i]=iomodel->Data("md.initialization.vz")[penta_vertex_ids[i]-1]*iomodel->Data("md.flowequation.borderFS")[penta_vertex_ids[i]-1];
4573  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzFSEnum);
4574  for(i=0;i<6;i++) nodeinputs[i]=iomodel->Data("md.initialization.vz")[penta_vertex_ids[i]-1]*(1-iomodel->Data("md.flowequation.borderFS")[penta_vertex_ids[i]-1]);
4575  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzSSAEnum);
4576  }
4577  else{
4578  for(i=0;i<6;i++)nodeinputs[i]=0;
4579  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzFSEnum);
4580  this->SetElementInput(inputs2,NUMVERTICES,vertexlids,nodeinputs,VzSSAEnum);
4581  }
4582  }
4583  break;
4584  default:
4585  /*No update for other solution types*/
4586  break;
4587  }
4588 }
4589 /*}}}*/
4591 
4592  if(!IsOnBase()) return;
4593 
4594  int extrusioninput;
4595  IssmDouble value,isonbase;
4596 
4597  this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
4598  Input2* input = this->GetInput2(extrusioninput); _assert_(extrusioninput);
4599  Input2* onbase = this->GetInput2(MeshVertexonbaseEnum); _assert_(onbase);
4600 
4601  GaussPenta* gauss=new GaussPenta();
4602  for(int iv=0;iv<this->NumberofNodes(this->element_type);iv++){
4603  gauss->GaussNode(this->element_type,iv);
4604  onbase->GetInputValue(&isonbase,gauss);
4605  if(isonbase==1.){
4606  input->GetInputValue(&value,gauss);
4607  this->nodes[iv]->ApplyConstraint(0,value);
4608  }
4609  }
4610  delete gauss;
4611 
4612 }
4613 /*}}}*/
4615 
4616  if(!IsOnSurface()) return;
4617 
4618  int extrusioninput;
4619  int indices[3]={3,4,5};
4620  IssmDouble value;
4621 
4622  this->parameters->FindParam(&extrusioninput,InputToExtrudeEnum);
4623  Input2* input = this->GetInput2(extrusioninput); _assert_(extrusioninput);
4624 
4625  GaussPenta* gauss=new GaussPenta();
4626  for(int i=0;i<3;i++){
4627  gauss->GaussNode(P1Enum,indices[i]);
4628  input->GetInputValue(&value,gauss);
4629  this->nodes[indices[i]]->ApplyConstraint(0,value);
4630  }
4631  delete gauss;
4632 
4633 }
4634 /*}}}*/
4635 int Penta::UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){/*{{{*/
4636 
4637  int i;
4638  int nflipped=0;
4639 
4640  /*Go through nodes, and whoever is on the potential_ungrounding, ends up in nodes_on_iceshelf: */
4641  for(i=0;i<NUMVERTICES;i++){
4642  if (reCast<bool,IssmDouble>(vertices_potentially_ungrounding[vertices[i]->Pid()])){
4643  vec_nodes_on_iceshelf->SetValue(vertices[i]->Pid(),-1.,INS_VAL);
4644 
4645  /*If node was not on ice shelf, we flipped*/
4646  if(nodes_on_iceshelf[vertices[i]->Pid()]>=0.){
4647  nflipped++;
4648  }
4649  }
4650  }
4651  return nflipped;
4652 }
4653 /*}}}*/
4654 void Penta::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
4655  PentaRef::GetInputDerivativeValue(dvalue,values,xyz_list,gauss,P1Enum);
4656 }
4657 /*}}}*/
4658 void Penta::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){/*{{{*/
4659  PentaRef::GetInputValue(pvalue,values,gauss,P1Enum);
4660 }
4661 /*}}}*/
4664 }
4665 /*}}}*/
4666 int Penta::VertexConnectivity(int vertexindex){/*{{{*/
4667  _assert_(this->vertices);
4668  return this->vertices[vertexindex]->Connectivity();
4669 }
4670 /*}}}*/
4671 void Penta::VerticalSegmentIndices(int** pindices,int* pnumseg){/*{{{*/
4672 
4673  /*output*/
4674  int *indices = xNew<int>(3*2);
4675  indices[0*2 + 0] = 0; indices[0*2 + 1] = 3;
4676  indices[1*2 + 0] = 1; indices[1*2 + 1] = 4;
4677  indices[2*2 + 0] = 2; indices[2*2 + 1] = 5;
4678 
4679  /*Assign output pointers*/
4680  *pindices = indices;
4681  *pnumseg = 3;
4682 }
4683 /*}}}*/
4684 void Penta::VerticalSegmentIndicesBase(int** pindices,int* pnumseg){/*{{{*/
4685 
4686  PentaRef::VerticalSegmentIndicesBase(pindices,pnumseg,this->GetElementType());
4687 
4688  return;
4689 }
4690 /*}}}*/
4691 void Penta::ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input,Input2* vz_input){/*{{{*/
4692 
4693  /*Intermediaries*/
4694  IssmDouble phi;
4695  IssmDouble viscosity;
4696  IssmDouble epsilon[6];
4697 
4698  _assert_(gauss->Enum()==GaussPentaEnum);
4699  this->StrainRateFS(&epsilon[0],xyz_list,(GaussPenta*)gauss,vx_input,vy_input,vz_input);
4700  this->material->ViscosityFS(&viscosity,3,xyz_list,(GaussPenta*)gauss,vx_input,vy_input,vz_input);
4701  GetPhi(&phi,&epsilon[0],viscosity);
4702 
4703  /*Assign output pointer*/
4704  *pphi = phi;
4705 }
4706 /*}}}*/
4707 
4708 #ifdef _HAVE_GIA_
4709 void Penta::GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x,IssmDouble* y){/*{{{*/
4710  _error_("GIA deflection not implemented yet!");
4711 }
4712 /*}}}*/
4713 #endif
4714 
4715 #ifdef _HAVE_DAKOTA_
4716 void Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/
4717 
4718  /*Check that name is an element input*/
4719  if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
4720  TransientInput2* transientinput = inputs2->GetTransientInput(name);
4721 
4722  switch(type){
4723 
4724  case VertexEnum:
4725 
4726  /*Get LID lists once for all*/
4727  IssmDouble values[NUMVERTICES];
4728  int lidlist[NUMVERTICES];
4729  this->GetVerticesLidList(&lidlist[0]);
4730 
4731  /*Create transient input: */
4732  for(int t=0;t<ncols;t++){ //ncols is the number of times
4733 
4734  /*create input values: */
4735  for(int i=0;i<6;i++){
4736  int row=this->vertices[i]->Sid();
4737  values[i]=matrix[ncols*row+t];
4738  }
4739 
4740  /*time:*/
4741  IssmDouble time=matrix[(nrows-1)*ncols+t];
4742 
4743  transientinput->AddPentaTimeInput(t,NUMVERTICES,&lidlist[0],&values[0],P1Enum);
4744  }
4745  break;
4746 
4747  case ElementEnum:
4748  /*Get value for the element: */
4749  for(int t=0;t<ncols;t++){ //ncols is the number of times
4750  IssmDouble value=matrix[ncols*(this->Sid())+t];
4751  IssmDouble time=matrix[(nrows-1)*ncols+t];
4752  transientinput->AddPentaTimeInput(t,1,&(this->lid),&value,P0Enum);
4753  }
4754  break;
4755 
4756  default:
4757  _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
4758  }
4759 
4760 }
4761 /*}}}*/
4762 void Penta::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){/*{{{*/
4763 
4764  int i,j;
4765 
4766  /*Check that name is an element input*/
4767  if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
4768 
4769  switch(type){
4770 
4771  case VertexEnum:
4772 
4773  /*New PentaInput*/
4774  IssmDouble values[6];
4775 
4776  /*Get values on the 6 vertices*/
4777  for (i=0;i<6;i++){
4778  values[i]=vector[this->vertices[i]->Sid()]; //careful, vector of values here is not parallel distributed, but serial distributed (from a serial Dakota core!)
4779  }
4780 
4781  /*Branch on the specified type of update: */
4782  switch(name){
4783  case ThicknessEnum:
4784  /*Update thickness + surface: assume bed is constant. On ice shelves, takes hydrostatic equilibrium*/
4785  IssmDouble thickness[6];
4786  IssmDouble thickness_init[6];
4787  IssmDouble hydrostatic_ratio[6];
4788  IssmDouble surface[6];
4789  IssmDouble bed[6];
4790 
4791  /*retrieve inputs: */
4792  Element::GetInputListOnVertices(&thickness_init[0],ThicknessEnum);
4796 
4797  /*build new thickness: */
4798 // for(j=0;j<6;j++)thickness[j]=values[j];
4799 
4800  /*build new bed and surface: */
4801  if (this->IsFloating()){
4802  /*hydrostatic equilibrium: */
4803  IssmDouble rho_ice,rho_water,di;
4804  rho_ice=this->FindParam(MaterialsRhoIceEnum);
4805  rho_water=this->FindParam(MaterialsRhoSeawaterEnum);
4806 
4807  di=rho_ice/rho_water;
4808 
4809  /*build new thickness: */
4810  for (j=0; j<6; j++) {
4811  /* for observed/interpolated/hydrostatic thickness, remove scaling from any hydrostatic thickness */
4812  if (hydrostatic_ratio[j] >= 0.)
4813  thickness[j]=values[j]-(values[j]/thickness_init[j]-1.)*hydrostatic_ratio[j]*surface[j]/(1.-di);
4814  /* for minimum thickness, don't scale */
4815  else
4816  thickness[j]=thickness_init[j];
4817 
4818  /* check the computed thickness and update bed */
4819  if (thickness[j] < 0.)
4820  thickness[j]=1./(1.-di);
4821  bed[j]=surface[j]-thickness[j];
4822  }
4823 
4824 // for(j=0;j<6;j++){
4825 // surface[j]=(1-di)*thickness[j];
4826 // bed[j]=-di*thickness[j];
4827 // }
4828  }
4829  else{
4830  /*build new thickness: */
4831  for (j=0; j<6; j++) {
4832  /* for observed thickness, use scaled value */
4833  if(hydrostatic_ratio[j] >= 0.)
4834  thickness[j]=values[j];
4835  /* for minimum thickness, don't scale */
4836  else
4837  thickness[j]=thickness_init[j];
4838  }
4839 
4840  /*update bed on grounded ice: */
4841 // for(j=0;j<6;j++)surface[j]=bed[j]+thickness[j];
4842  for(j=0;j<6;j++)bed[j]=surface[j]-thickness[j];
4843  }
4844 
4845  /*Add new inputs: */
4846  this->AddInput2(ThicknessEnum,thickness,P1Enum);
4847  this->AddInput2(BaseEnum,bed,P1Enum);
4848  this->AddInput2(SurfaceEnum,surface,P1Enum);
4849  break;
4850 
4851  default:
4852  this->AddInput2(name,values,P1Enum);
4853  }
4854  break;
4855 
4856  case ElementEnum:
4857  IssmDouble value;
4858  /*Get value for the element: */
4859  value=vector[this->Sid()]; //careful, vector of values here is not parallel distributed, but serial distributed (from a serial Dakota core!)
4860  this->AddInput2(name,&value,P0Enum);
4861  break;
4862 
4863  default:
4864  _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
4865  }
4866 
4867 }
4868 /*}}}*/
4869 #endif
Penta::DatasetInputExtrude
void DatasetInputExtrude(int enum_type, int start)
Definition: Penta.cpp:2324
Tria::iscollapsed
int iscollapsed
Definition: Tria.h:32
Penta::GetAreaCoordinates
void GetAreaCoordinates(IssmDouble *area_coordinates, IssmDouble *xyz_zero, IssmDouble *xyz_list, int numpoints)
Definition: Penta.cpp:1190
Penta::CalvingMeltingFluxLevelset
void CalvingMeltingFluxLevelset()
Definition: Penta.cpp:539
ElementInput2::SetInput
virtual void SetInput(int interp_in, int row, IssmDouble value_in)=0
Element::GetVerticesConnectivityList
void GetVerticesConnectivityList(int *connectivitylist)
Definition: Element.cpp:1440
Penta::GetGroundedPart
void GetGroundedPart(int *point1, IssmDouble *fraction1, IssmDouble *fraction2, bool *mainlyfloating)
Definition: Penta.cpp:1258
Element::lid
int lid
Definition: Element.h:46
CrouzeixRaviartEnum
@ CrouzeixRaviartEnum
Definition: EnumDefinitions.h:1023
BaseEnum
@ BaseEnum
Definition: EnumDefinitions.h:495
Vertices
Declaration of Vertices class.
Definition: Vertices.h:15
StressTensorxxEnum
@ StressTensorxxEnum
Definition: EnumDefinitions.h:811
ElementVector::StaticCondensation
void StaticCondensation(ElementMatrix *Ke, int numindices, int *indices)
Definition: ElementVector.cpp:266
Penta::PotentialUngrounding
void PotentialUngrounding(Vector< IssmDouble > *potential_sheet_ungrounding)
Definition: Penta.cpp:3058
CalvingStressThresholdGroundediceEnum
@ CalvingStressThresholdGroundediceEnum
Definition: EnumDefinitions.h:506
SmbMassBalanceEnum
@ SmbMassBalanceEnum
Definition: EnumDefinitions.h:748
ElementInput2::Serve
virtual void Serve(int numindices, int *indices)=0
DeviatoricStressxzEnum
@ DeviatoricStressxzEnum
Definition: EnumDefinitions.h:526
Penta::NodalFunctionsTensor
void NodalFunctionsTensor(IssmDouble *basis, Gauss *gauss)
Definition: Penta.cpp:2928
_assert_
#define _assert_(ignore)
Definition: exceptions.h:37
GaussPenta::GaussPoint
void GaussPoint(int ig)
Definition: GaussPenta.cpp:569
GaussPenta::GaussVertex
void GaussVertex(int iv)
Definition: GaussPenta.cpp:785
Penta::SetTemporaryElementType
void SetTemporaryElementType(int element_type_in)
Definition: Penta.cpp:3419
IssmDouble
double IssmDouble
Definition: types.h:37
Penta::DatasetInputCreate
void DatasetInputCreate(IssmDouble *array, int M, int N, int *individual_enums, int num_inputs, Inputs2 *inputs2, IoModel *iomodel, int input_enum)
Definition: Penta.cpp:228
HOApproximationEnum
@ HOApproximationEnum
Definition: EnumDefinitions.h:1095
Element::IsOnBase
bool IsOnBase()
Definition: Element.cpp:1984
Nodes
Declaration of Nodes class.
Definition: Nodes.h:19
Penta::GetVerticesCoordinatesTop
void GetVerticesCoordinatesTop(IssmDouble **pxyz_list)
Definition: Penta.cpp:1909
MaterialsRheologyEsbarEnum
@ MaterialsRheologyEsbarEnum
Definition: EnumDefinitions.h:650
DatasetInput2
Definition: DatasetInput2.h:14
Penta::MinEdgeLength
IssmDouble MinEdgeLength(IssmDouble *xyz_list)
Definition: Penta.cpp:2802
FrontalForcingsBasinIcefrontAreaEnum
@ FrontalForcingsBasinIcefrontAreaEnum
Definition: EnumDefinitions.h:152
Element::GetDofList
void GetDofList(int **pdoflist, int approximation_enum, int setenum)
Definition: Element.cpp:961
PentaInput2::GetInterpolation
int GetInterpolation()
Definition: PentaInput2.cpp:266
Penta::TotalFloatingBmb
IssmDouble TotalFloatingBmb(bool scaled)
Definition: Penta.cpp:4040
Penta::VerticalSegmentIndices
void VerticalSegmentIndices(int **pindices, int *pnumseg)
Definition: Penta.cpp:4671
Penta::NewGaussLine
Gauss * NewGaussLine(int vertex1, int vertex2, int order)
Definition: Penta.cpp:2857
Element::FindParam
void FindParam(bool *pvalue, int paramenum)
Definition: Element.cpp:933
ElementHook::SetHookNodes
void SetHookNodes(int *node_ids, int numnodes, int analysis_counter)
Definition: ElementHook.cpp:188
StressbalanceAnalysisEnum
@ StressbalanceAnalysisEnum
Definition: EnumDefinitions.h:1285
Penta::GetDatasetInput2
DatasetInput2 * GetDatasetInput2(int inputenum)
Definition: Penta.cpp:1651
CalvingMeltingFluxLevelsetEnum
@ CalvingMeltingFluxLevelsetEnum
Definition: EnumDefinitions.h:513
IoModel::elementtohorizontaledgeconnectivity
int * elementtohorizontaledgeconnectivity
Definition: IoModel.h:85
DeviatoricStressyzEnum
@ DeviatoricStressyzEnum
Definition: EnumDefinitions.h:528
Vertex::Pid
int Pid(void)
Definition: Vertex.cpp:164
MaterialsRheologyEcEnum
@ MaterialsRheologyEcEnum
Definition: EnumDefinitions.h:647
IoModel::elementtofaceconnectivity
int * elementtofaceconnectivity
Definition: IoModel.h:86
Penta::ObjectEnum
int ObjectEnum()
Definition: Penta.cpp:3052
Penta::GetVerticesCoordinatesBase
void GetVerticesCoordinatesBase(IssmDouble **pxyz_list)
Definition: Penta.cpp:1900
MaskOceanLevelsetEnum
@ MaskOceanLevelsetEnum
Definition: EnumDefinitions.h:640
Penta::SpawnTria
Tria * SpawnTria(int index1, int index2, int index3)
Definition: Penta.cpp:3460
Penta::NodalFunctionsP1Derivatives
void NodalFunctionsP1Derivatives(IssmDouble *dbasis, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2907
Hook::deliverp
Object ** deliverp(void)
Definition: Hook.cpp:187
Parameters
Declaration of Parameters class.
Definition: Parameters.h:18
SSAHOApproximationEnum
@ SSAHOApproximationEnum
Definition: EnumDefinitions.h:1257
MaskIceLevelsetEnum
@ MaskIceLevelsetEnum
Definition: EnumDefinitions.h:641
Penta::NodalFunctionsDerivatives
void NodalFunctionsDerivatives(IssmDouble *dbasis, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2872
Material::IsEnhanced
virtual bool IsEnhanced()=0
Penta::JacobianDeterminantTop
void JacobianDeterminantTop(IssmDouble *pJdet, IssmDouble *xyz_list_base, Gauss *gauss)
Definition: Penta.cpp:2757
StressbalanceFSreconditioningEnum
@ StressbalanceFSreconditioningEnum
Definition: EnumDefinitions.h:405
ADD_VAL
@ ADD_VAL
Definition: toolkitsenums.h:14
Penta::NumberofNodesVelocity
int NumberofNodesVelocity(void)
Definition: Penta.cpp:3048
MARSHALLING_ENUM
#define MARSHALLING_ENUM(EN)
Definition: Marshalling.h:14
CalvinglevermannCoeffEnum
@ CalvinglevermannCoeffEnum
Definition: EnumDefinitions.h:507
Gauss::end
virtual int end(void)=0
DeviatoricStressxxEnum
@ DeviatoricStressxxEnum
Definition: EnumDefinitions.h:524
PentaInput2::SetInput
void SetInput(int interp_in, int row, IssmDouble value_in)
Definition: PentaInput2.cpp:154
MINIEnum
@ MINIEnum
Definition: EnumDefinitions.h:1156
IoModel::my_vertices_lids
int * my_vertices_lids
Definition: IoModel.h:73
Penta::InputDepthAverageAtBase
void InputDepthAverageAtBase(int enum_type, int average_enum_type)
Definition: Penta.cpp:2254
BedEnum
@ BedEnum
Definition: EnumDefinitions.h:499
Penta::NewGaussBase
Gauss * NewGaussBase(IssmDouble *xyz_list, IssmDouble *xyz_list_front, int order_horiz)
Definition: Penta.cpp:2848
IoCodeToEnumElementEquation
int IoCodeToEnumElementEquation(int enum_in)
Definition: IoCodeConversions.cpp:311
P0Enum
@ P0Enum
Definition: EnumDefinitions.h:661
TransientInput2
Definition: TransientInput2.h:13
MaterialsRheologyEbarEnum
@ MaterialsRheologyEbarEnum
Definition: EnumDefinitions.h:646
Element::StrainRateFS
void StrainRateFS(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input)
Definition: Element.cpp:4055
Penta::FiniteElement
int FiniteElement(void)
Definition: Penta.cpp:1075
Penta::NodalFunctionsPressure
void NodalFunctionsPressure(IssmDouble *basis, Gauss *gauss)
Definition: Penta.cpp:2893
Penta::JacobianDeterminantSurface
void JacobianDeterminantSurface(IssmDouble *pJdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2750
MeshVertexonbaseEnum
@ MeshVertexonbaseEnum
Definition: EnumDefinitions.h:653
Penta::IcefrontMassFluxLevelset
IssmDouble IcefrontMassFluxLevelset(bool scaled)
Definition: Penta.cpp:2068
Penta::CalvingRateLevermann
void CalvingRateLevermann()
Definition: Penta.cpp:363
Material::copy2
virtual Material * copy2(Element *element)=0
Elements
Declaration of Elements class.
Definition: Elements.h:17
ControlInput2Enum
@ ControlInput2Enum
Definition: EnumDefinitions.h:1018
Penta::AverageOntoPartition
void AverageOntoPartition(Vector< IssmDouble > *partition_contributions, Vector< IssmDouble > *partition_areas, IssmDouble *vertex_response, IssmDouble *qmu_part)
Definition: Penta.cpp:260
StressTensorzzEnum
@ StressTensorzzEnum
Definition: EnumDefinitions.h:816
Penta::ComputeStressTensor
void ComputeStressTensor()
Definition: Penta.cpp:819
PressureEnum
@ PressureEnum
Definition: EnumDefinitions.h:664
MaterialsRhoIceEnum
@ MaterialsRhoIceEnum
Definition: EnumDefinitions.h:264
Penta::SpawnBasalElement
Element * SpawnBasalElement(void)
Definition: Penta.cpp:3423
Penta::GetBasalElement
Element * GetBasalElement(void)
Definition: Penta.cpp:1225
Penta::ControlInputSetGradient
void ControlInputSetGradient(IssmDouble *gradient, int enum_type, int control_index, int offset, int N, int M)
Definition: Penta.cpp:901
IoModel::numberoffaces
int numberoffaces
Definition: IoModel.h:97
P1DGEnum
@ P1DGEnum
Definition: EnumDefinitions.h:1215
Penta::MassFlux
IssmDouble MassFlux(IssmDouble *segment)
Definition: Penta.cpp:2764
Element::vertices
Vertex ** vertices
Definition: Element.h:49
Material
Definition: Material.h:21
Penta::InputUpdateFromSolutionOneDof
void InputUpdateFromSolutionOneDof(IssmDouble *solutiong, int enum_type)
Definition: Penta.cpp:2539
NUMVERTICES
#define NUMVERTICES
Definition: Penta.cpp:22
TransientInputEnum
@ TransientInputEnum
Definition: EnumDefinitions.h:1314
StressIntensityIntegralWeight
IssmDouble StressIntensityIntegralWeight(IssmDouble depth, IssmDouble water_depth, IssmDouble thickness)
Definition: StressIntensityIntegralWeight.cpp:9
AnalysisCounterEnum
@ AnalysisCounterEnum
Definition: EnumDefinitions.h:35
VzFSEnum
@ VzFSEnum
Definition: EnumDefinitions.h:854
PentaInput2::Serve
void Serve(int numindices, int *indices)
Definition: PentaInput2.cpp:208
P2xP1Enum
@ P2xP1Enum
Definition: EnumDefinitions.h:1226
Element::GetZcoord
IssmDouble GetZcoord(IssmDouble *xyz_list, Gauss *gauss)
Definition: Element.cpp:1494
Penta::JacobianDeterminant
void JacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2729
PentaRef::VerticalSegmentIndicesBase
void VerticalSegmentIndicesBase(int **pindices, int *pnumseg, int finiteelement)
Definition: PentaRef.cpp:1125
VertexLIdEnum
@ VertexLIdEnum
Definition: EnumDefinitions.h:1323
Penta::UpdateConstraintsExtrudeFromBase
void UpdateConstraintsExtrudeFromBase(void)
Definition: Penta.cpp:4590
FrontalForcingsThermalForcingEnum
@ FrontalForcingsThermalForcingEnum
Definition: EnumDefinitions.h:587
Penta::ElementSizes
void ElementSizes(IssmDouble *hx, IssmDouble *hy, IssmDouble *hz)
Definition: Penta.cpp:1049
BedSlopeXEnum
@ BedSlopeXEnum
Definition: EnumDefinitions.h:500
NUMVERTICES2D
#define NUMVERTICES2D
Definition: Penta.cpp:23
P1bubblecondensedEnum
@ P1bubblecondensedEnum
Definition: EnumDefinitions.h:1219
Penta::GetUpperPenta
Penta * GetUpperPenta(void)
Definition: Penta.cpp:1813
ConstantsYtsEnum
@ ConstantsYtsEnum
Definition: EnumDefinitions.h:104
PentaRef::VelocityInterpolation
int VelocityInterpolation(int fe_stokes)
Definition: PentaRef.cpp:1335
MaterialsRheologyNEnum
@ MaterialsRheologyNEnum
Definition: EnumDefinitions.h:651
Element::IsFloating
bool IsFloating()
Definition: Element.cpp:1987
Vertex::Lid
int Lid(void)
Definition: Vertex.cpp:166
DeviatoricStressxyEnum
@ DeviatoricStressxyEnum
Definition: EnumDefinitions.h:525
Element::Sid
int Sid()
Definition: Element.cpp:3578
Penta::GetLowerPenta
Penta * GetLowerPenta(void)
Definition: Penta.cpp:1707
Penta::ValueP1DerivativesOnGauss
void ValueP1DerivativesOnGauss(IssmDouble *dvalue, IssmDouble *values, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:4654
PentaInputEnum
@ PentaInputEnum
Definition: EnumDefinitions.h:1232
Penta::IsIcefront
bool IsIcefront(void)
Definition: Penta.cpp:2678
Material::IsDamage
virtual bool IsDamage()=0
Penta::BasalNodeIndices
void BasalNodeIndices(int *pnumindices, int **pindices, int finiteelement)
Definition: Penta.cpp:254
StressTensorxyEnum
@ StressTensorxyEnum
Definition: EnumDefinitions.h:812
Penta::VertexConnectivity
int VertexConnectivity(int vertexindex)
Definition: Penta.cpp:4666
Element::isonbase
bool isonbase
Definition: Element.h:53
Inputs2::SetPentaDatasetInput
void SetPentaDatasetInput(int enum_in, int id, int interpolation, int numindices, int *indices, IssmDouble *values)
Definition: Inputs2.cpp:862
FSApproximationEnum
@ FSApproximationEnum
Definition: EnumDefinitions.h:1060
StrainRateperpendicularEnum
@ StrainRateperpendicularEnum
Definition: EnumDefinitions.h:803
Tria::MassFlux
IssmDouble MassFlux(IssmDouble *segment)
Definition: Tria.cpp:3433
VyEnum
@ VyEnum
Definition: EnumDefinitions.h:850
ElementHook
Definition: ElementHook.h:11
Penta
Definition: Penta.h:29
Hook::reset
void reset(void)
Definition: Hook.cpp:211
Penta::NodalValue
int NodalValue(IssmDouble *pvalue, int index, int natureofdataenum)
Definition: Penta.cpp:2935
Input2::GetInputMaxAbs
virtual IssmDouble GetInputMaxAbs(void)
Definition: Input2.h:35
VzSSAEnum
@ VzSSAEnum
Definition: EnumDefinitions.h:857
Input2::ChangeEnum
void ChangeEnum(int newenumtype)
Definition: Input2.h:26
Penta::StabilizationParameterAnisotropic
void StabilizationParameterAnisotropic(IssmDouble *tau_parameter_anisotropic, IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble hx, IssmDouble hy, IssmDouble hz, IssmDouble kappa)
Definition: Penta.cpp:3511
CalvingMeltingrateEnum
@ CalvingMeltingrateEnum
Definition: EnumDefinitions.h:504
Penta::NumberofNodesPressure
int NumberofNodesPressure(void)
Definition: Penta.cpp:3044
ElementHook::hmaterial
Hook * hmaterial
Definition: ElementHook.h:17
ElementInput2
Definition: ElementInput2.h:7
MaterialsRheologyBbarEnum
@ MaterialsRheologyBbarEnum
Definition: EnumDefinitions.h:644
PentaRef::GetNodalFunctionsDerivatives
void GetNodalFunctionsDerivatives(IssmDouble *dbasis, IssmDouble *xyz_list, Gauss *gauss, int finiteelement)
Definition: PentaRef.cpp:466
Element::nodes
Node ** nodes
Definition: Element.h:48
Element
Definition: Element.h:41
DeviatoricStresszzEnum
@ DeviatoricStresszzEnum
Definition: EnumDefinitions.h:529
Penta::NewGaussTop
Gauss * NewGaussTop(int order)
Definition: Penta.cpp:2861
IoModel::numberofvertices
int numberofvertices
Definition: IoModel.h:99
Penta::IceVolumeAboveFloatation
IssmDouble IceVolumeAboveFloatation(bool scaled)
Definition: Penta.cpp:2218
P1Enum
@ P1Enum
Definition: EnumDefinitions.h:662
Penta::JacobianDeterminantBase
void JacobianDeterminantBase(IssmDouble *pJdet, IssmDouble *xyz_list_base, Gauss *gauss)
Definition: Penta.cpp:2736
Penta::~Penta
~Penta()
Definition: Penta.cpp:26
ElementMatrix::StaticCondensation
void StaticCondensation(int numindices, int *indices)
Definition: ElementMatrix.cpp:524
GaussPenta::begin
int begin(void)
Definition: GaussPenta.cpp:476
TaylorHoodEnum
@ TaylorHoodEnum
Definition: EnumDefinitions.h:1299
Element::GetPhi
void GetPhi(IssmDouble *phi, IssmDouble *epsilon, IssmDouble viscosity)
Definition: Element.cpp:1244
Penta::verticalneighbors
Penta ** verticalneighbors
Definition: Penta.h:33
CalvingrateyEnum
@ CalvingrateyEnum
Definition: EnumDefinitions.h:511
Penta::Configure
void Configure(Elements *elements, Loads *loads, Nodes *nodes, Vertices *vertices, Materials *materials, Parameters *parameters, Inputs2 *inputs2in)
Definition: Penta.cpp:872
Penta::GetInput2
Input2 * GetInput2(int enumtype)
Definition: Penta.cpp:1557
LATaylorHoodEnum
@ LATaylorHoodEnum
Definition: EnumDefinitions.h:1139
Penta::UpdatePotentialUngrounding
int UpdatePotentialUngrounding(IssmDouble *potential_sheet_ungrounding, Vector< IssmDouble > *vec_nodes_on_iceshelf, IssmDouble *nodes_on_iceshelf)
Definition: Penta.cpp:4635
Penta::GroundedArea
IssmDouble GroundedArea(bool scaled)
Definition: Penta.cpp:1918
VzHOEnum
@ VzHOEnum
Definition: EnumDefinitions.h:855
IoModel::numberofelements
int numberofelements
Definition: IoModel.h:96
Object
Definition: Object.h:13
PentaRef::NumberofNodes
int NumberofNodes(int finiteelement)
Definition: PentaRef.cpp:1216
Penta::ControlToVectors
void ControlToVectors(Vector< IssmPDouble > *vector_control, Vector< IssmPDouble > *vector_gradient, int control_enum)
Definition: Penta.cpp:948
ConstantsGEnum
@ ConstantsGEnum
Definition: EnumDefinitions.h:102
Hook::delivers
Object * delivers(void)
Definition: Hook.cpp:191
VertexSIdEnum
@ VertexSIdEnum
Definition: EnumDefinitions.h:1325
BasalforcingsGroundediceMeltingRateEnum
@ BasalforcingsGroundediceMeltingRateEnum
Definition: EnumDefinitions.h:478
IoModel::elementtoverticaledgeconnectivity
int * elementtoverticaledgeconnectivity
Definition: IoModel.h:84
InputToExtrudeEnum
@ InputToExtrudeEnum
Definition: EnumDefinitions.h:205
Element::inputs2
Inputs2 * inputs2
Definition: Element.h:47
Penta::CalvingFluxLevelset
void CalvingFluxLevelset()
Definition: Penta.cpp:417
NoneApproximationEnum
@ NoneApproximationEnum
Definition: EnumDefinitions.h:1201
Materials
Declaration of Materials class.
Definition: Materials.h:16
Element::id
int id
Definition: Element.h:44
CalvingratexAverageEnum
@ CalvingratexAverageEnum
Definition: EnumDefinitions.h:508
Penta::GetVectorFromControlInputs
void GetVectorFromControlInputs(Vector< IssmDouble > *gradient, int control_enum, int control_index, const char *data)
Definition: Penta.cpp:1822
Element::sid
int sid
Definition: Element.h:45
Penta::InputExtrude
void InputExtrude(int enum_type, int start)
Definition: Penta.cpp:2463
Penta::StressIntensityFactor
void StressIntensityFactor()
Definition: Penta.cpp:3632
Vector::SetValues
void SetValues(int ssize, int *list, doubletype *values, InsMode mode)
Definition: Vector.h:153
DomainTypeEnum
@ DomainTypeEnum
Definition: EnumDefinitions.h:124
Inputs2::SetPentaInput
void SetPentaInput(int enum_in, int interpolation, int row, IssmDouble values)
Definition: Inputs2.cpp:887
VxAverageEnum
@ VxAverageEnum
Definition: EnumDefinitions.h:845
Penta::SetCurrentConfiguration
void SetCurrentConfiguration(Elements *elements, Loads *loads, Nodes *nodes, Materials *materials, Parameters *parameters)
Definition: Penta.cpp:3404
Penta::SpawnTopElement
Element * SpawnTopElement(void)
Definition: Penta.cpp:3451
Penta::NormalSection
void NormalSection(IssmDouble *normal, IssmDouble *xyz_list)
Definition: Penta.cpp:2987
MatestarEnum
@ MatestarEnum
Definition: EnumDefinitions.h:1168
Penta::GetNumberOfVertices
int GetNumberOfVertices(void)
Definition: Penta.cpp:1809
Element::Id
int Id()
Definition: Element.cpp:1620
Penta::ElementResponse
void ElementResponse(IssmDouble *presponse, int response_enum)
Definition: Penta.cpp:1022
Penta::NodalFunctionsVelocity
void NodalFunctionsVelocity(IssmDouble *basis, Gauss *gauss)
Definition: Penta.cpp:2921
ApproximationEnum
@ ApproximationEnum
Definition: EnumDefinitions.h:470
FrontalForcingsNumberofBasinsEnum
@ FrontalForcingsNumberofBasinsEnum
Definition: EnumDefinitions.h:153
TimesteppingCflCoefficientEnum
@ TimesteppingCflCoefficientEnum
Definition: EnumDefinitions.h:428
Penta::ValueP1OnGauss
void ValueP1OnGauss(IssmDouble *pvalue, IssmDouble *values, Gauss *gauss)
Definition: Penta.cpp:4658
VzEnum
@ VzEnum
Definition: EnumDefinitions.h:853
Material::GetDbar
virtual IssmDouble GetDbar(Gauss *gauss)=0
EnumToStringx
const char * EnumToStringx(int enum_in)
Definition: EnumToStringx.cpp:15
Hook
Definition: Hook.h:16
OneLayerP4zEnum
@ OneLayerP4zEnum
Definition: EnumDefinitions.h:1208
DeviatoricStressyyEnum
@ DeviatoricStressyyEnum
Definition: EnumDefinitions.h:527
Element::element_type_list
int * element_type_list
Definition: Element.h:55
GaussPenta
Definition: GaussPenta.h:13
Hook::configure
void configure(DataSet *dataset)
Definition: Hook.cpp:145
ElementHook::InitHookNeighbors
void InitHookNeighbors(int *element_ids)
Definition: ElementHook.cpp:184
Penta::SurfaceArea
IssmDouble SurfaceArea(void)
Definition: Penta.cpp:3709
NodesEnum
@ NodesEnum
Definition: EnumDefinitions.h:275
PentaInput2::copy
Input2 * copy()
Definition: PentaInput2.cpp:73
GsetEnum
@ GsetEnum
Definition: EnumDefinitions.h:1093
Penta::VelocityInterpolation
int VelocityInterpolation()
Definition: Penta.cpp:4662
Penta::TotalGroundedBmb
IssmDouble TotalGroundedBmb(bool scaled)
Definition: Penta.cpp:4085
Penta::TotalCalvingMeltingFluxLevelset
IssmDouble TotalCalvingMeltingFluxLevelset(bool scaled)
Definition: Penta.cpp:3907
IoModel::elementtoedgeconnectivity
int * elementtoedgeconnectivity
Definition: IoModel.h:83
Matrix2x2Eigen
void Matrix2x2Eigen(IssmDouble *plambda1, IssmDouble *plambda2, IssmDouble *pvx, IssmDouble *pvy, IssmDouble a11, IssmDouble a21, IssmDouble a22)
Definition: MatrixUtils.cpp:348
BasalforcingsFloatingiceMeltingRateEnum
@ BasalforcingsFloatingiceMeltingRateEnum
Definition: EnumDefinitions.h:476
ElementEnum
@ ElementEnum
Definition: EnumDefinitions.h:1049
alpha
IssmDouble alpha(IssmDouble x, IssmDouble y, IssmDouble z, int testid)
Definition: fsanalyticals.cpp:221
IoModel::FindConstant
void FindConstant(bool *pvalue, const char *constant_name)
Definition: IoModel.cpp:2362
DamageDEnum
@ DamageDEnum
Definition: EnumDefinitions.h:516
P2bubbleEnum
@ P2bubbleEnum
Definition: EnumDefinitions.h:1224
Penta::ReduceMatrices
void ReduceMatrices(ElementMatrix *Ke, ElementVector *pe)
Definition: Penta.cpp:3089
Element::GetInput2Value
void GetInput2Value(bool *pvalue, int enum_type)
Definition: Element.cpp:1185
P2xP4Enum
@ P2xP4Enum
Definition: EnumDefinitions.h:1227
Material::ViscosityFS
virtual void ViscosityFS(IssmDouble *pviscosity, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input)=0
Penta::SetElementInput
void SetElementInput(int enum_in, IssmDouble values)
Definition: Penta.cpp:3285
MARSHALLING
#define MARSHALLING(FIELD)
Definition: Marshalling.h:29
Element::GetVerticesCoordinates
void GetVerticesCoordinates(IssmDouble **xyz_list)
Definition: Element.cpp:1446
DatasetInput2::GetPentaInputByOffset
PentaInput2 * GetPentaInputByOffset(int i)
Definition: DatasetInput2.cpp:237
Penta::StabilizationParameter
IssmDouble StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa)
Definition: Penta.cpp:3495
StressTensoryyEnum
@ StressTensoryyEnum
Definition: EnumDefinitions.h:814
Inputs2::SetPentaControlInput
void SetPentaControlInput(int enum_in, int layout, int interpolation, int id, int numindices, int *indices, IssmDouble *values, IssmDouble *values_min, IssmDouble *values_max)
Definition: Inputs2.cpp:824
Penta::GetInputListOnNodes
void GetInputListOnNodes(IssmDouble *pvalue, Input2 *input, IssmDouble default_value)
Definition: Penta.cpp:1629
P1P1Enum
@ P1P1Enum
Definition: EnumDefinitions.h:1216
Penta::GetBasalPenta
Penta * GetBasalPenta(void)
Definition: Penta.cpp:1232
Penta::copy
Object * copy()
Definition: Penta.cpp:82
MINIcondensedEnum
@ MINIcondensedEnum
Definition: EnumDefinitions.h:1157
GeometryHydrostaticRatioEnum
@ GeometryHydrostaticRatioEnum
Definition: EnumDefinitions.h:588
SigmaVMEnum
@ SigmaVMEnum
Definition: EnumDefinitions.h:705
INS_VAL
@ INS_VAL
Definition: toolkitsenums.h:14
Penta::ControlInputExtrude
void ControlInputExtrude(int enum_type, int start)
Definition: Penta.cpp:2382
Penta::IsZeroLevelset
bool IsZeroLevelset(int levelset_enum)
Definition: Penta.cpp:2711
ElementInput2::GetInterpolation
virtual int GetInterpolation()=0
Penta::TotalSmb
IssmDouble TotalSmb(bool scaled)
Definition: Penta.cpp:4130
SurfaceEnum
@ SurfaceEnum
Definition: EnumDefinitions.h:823
MaterialsRheologyEEnum
@ MaterialsRheologyEEnum
Definition: EnumDefinitions.h:645
Gauss::Enum
virtual int Enum(void)=0
Penta::Penta
Penta()
Definition: Penta.h:36
PentaInput2
Definition: PentaInput2.h:8
Inputs2
Declaration of Inputs class.
Definition: Inputs2.h:23
MaterialsRheologyEsEnum
@ MaterialsRheologyEsEnum
Definition: EnumDefinitions.h:649
Penta::CreateInputTimeAverage
void CreateInputTimeAverage(int transientinput_enum, int averagedinput_enum, IssmDouble start_time, IssmDouble end_time, int averaging_method)
Definition: Penta.cpp:1010
Domain3DEnum
@ Domain3DEnum
Definition: EnumDefinitions.h:536
MaterialsRhoSeawaterEnum
@ MaterialsRhoSeawaterEnum
Definition: EnumDefinitions.h:265
Penta::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: Penta.cpp:143
PentaRef::GetInputDerivativeValue
void GetInputDerivativeValue(IssmDouble *pvalues, IssmDouble *plist, IssmDouble *xyz_list, Gauss *gauss, int finiteelement)
Definition: PentaRef.cpp:131
Penta::IsNodeOnShelfFromFlags
bool IsNodeOnShelfFromFlags(IssmDouble *flags)
Definition: Penta.cpp:2697
Hook::copy
Object * copy(void)
Definition: Hook.cpp:61
FSvelocityEnum
@ FSvelocityEnum
Definition: EnumDefinitions.h:1063
IsInputEnum
bool IsInputEnum(int enum_in)
Definition: EnumToStringx.cpp:1368
P1bubbleEnum
@ P1bubbleEnum
Definition: EnumDefinitions.h:1218
TransientInput2::GetPentaInput
PentaInput2 * GetPentaInput()
Definition: TransientInput2.cpp:321
Inputs2::GetPentaInput
PentaInput2 * GetPentaInput(int enum_type)
Definition: Inputs2.cpp:363
SSAFSApproximationEnum
@ SSAFSApproximationEnum
Definition: EnumDefinitions.h:1256
Penta::GetLevelsetIntersectionBase
void GetLevelsetIntersectionBase(int **pindices, int *pnumiceverts, IssmDouble *fraction, int levelset_enum, IssmDouble level)
Definition: Penta.cpp:1716
ElementHook::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: ElementHook.cpp:67
TransientInput2::AddPentaTimeInput
void AddPentaTimeInput(IssmDouble time, int numindices, int *indices, IssmDouble *values_in, int interp_in)
Definition: TransientInput2.cpp:180
DamageDbarEnum
@ DamageDbarEnum
Definition: EnumDefinitions.h:518
Object::ObjectEnum
virtual int ObjectEnum()=0
Vertex::Connectivity
int Connectivity(void)
Definition: Vertex.cpp:138
Penta::NodalFunctionsP2
void NodalFunctionsP2(IssmDouble *basis, Gauss *gauss)
Definition: Penta.cpp:2914
StrainRateparallelEnum
@ StrainRateparallelEnum
Definition: EnumDefinitions.h:802
Input2
Definition: Input2.h:18
Element::GetDofListLocal
void GetDofListLocal(int **pdoflist, int approximation_enum, int setenum)
Definition: Element.cpp:984
VertexEnum
@ VertexEnum
Definition: EnumDefinitions.h:1322
Element::GetVerticesSidList
void GetVerticesSidList(int *sidlist)
Definition: Element.cpp:1456
Penta::ViscousHeating
void ViscousHeating(IssmDouble *pphi, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input)
Definition: Penta.cpp:4691
DeviatoricStresseffectiveEnum
@ DeviatoricStresseffectiveEnum
Definition: EnumDefinitions.h:523
PentaRef::PressureInterpolation
int PressureInterpolation(int fe_stokes)
Definition: PentaRef.cpp:1248
VertexPIdEnum
@ VertexPIdEnum
Definition: EnumDefinitions.h:1324
DatasetInput2::GetNumIds
int GetNumIds() const
Definition: DatasetInput2.h:24
PentaRef::GetQuadJacobianDeterminant
void GetQuadJacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: PentaRef.cpp:1065
Penta::GetNumberOfNodes
int GetNumberOfNodes(void)
Definition: Penta.cpp:1801
Penta::NormalTop
void NormalTop(IssmDouble *bed_normal, IssmDouble *xyz_list)
Definition: Penta.cpp:3022
SealevelEnum
@ SealevelEnum
Definition: EnumDefinitions.h:675
Gauss::GaussVertex
virtual void GaussVertex(int iv)=0
cross
void cross(IssmDouble *result, IssmDouble *vector1, IssmDouble *vector2)
Definition: cross.cpp:13
Inputs2::GetControlInput2Data
ElementInput2 * GetControlInput2Data(int enum_type, const char *data)
Definition: Inputs2.cpp:423
PentaRef::BasalNodeIndices
void BasalNodeIndices(int *pnumindices, int **pindices, int finiteelement)
Definition: PentaRef.cpp:40
CalvingFluxLevelsetEnum
@ CalvingFluxLevelsetEnum
Definition: EnumDefinitions.h:512
Inputs2::GetTransientInput
TransientInput2 * GetTransientInput(int enum_type)
Definition: Inputs2.cpp:406
PentaRef::GetTriaJacobianDeterminant
void GetTriaJacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: PentaRef.cpp:1106
Penta::ResetHooks
void ResetHooks()
Definition: Penta.cpp:3207
Penta::ComputeBasalStress
void ComputeBasalStress(void)
Definition: Penta.cpp:673
Material::GetBbar
virtual IssmDouble GetBbar(Gauss *gauss)=0
LACrouzeixRaviartEnum
@ LACrouzeixRaviartEnum
Definition: EnumDefinitions.h:1138
Element::IsIceInElement
bool IsIceInElement()
Definition: Element.cpp:2021
IoModel::Data
IssmDouble * Data(const char *data_name)
Definition: IoModel.cpp:437
Penta::NormalBase
void NormalBase(IssmDouble *bed_normal, IssmDouble *xyz_list)
Definition: Penta.cpp:2965
Penta::NodalFunctionsP1
void NodalFunctionsP1(IssmDouble *basis, Gauss *gauss)
Definition: Penta.cpp:2900
PentaInput2Enum
@ PentaInput2Enum
Definition: EnumDefinitions.h:1125
Loads
Declaration of Loads class.
Definition: Loads.h:16
Penta::NodalFunctionsMINIDerivatives
void NodalFunctionsMINIDerivatives(IssmDouble *dbasis, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2886
Node
Definition: Node.h:23
Penta::ComputeDeviatoricStressTensor
void ComputeDeviatoricStressTensor()
Definition: Penta.cpp:761
Tria::SurfaceArea
IssmDouble SurfaceArea(void)
Definition: Tria.cpp:4192
Node::Sid
int Sid(void)
Definition: Node.cpp:622
ElementInput2::ObjectEnum
virtual int ObjectEnum()=0
StressIntensityFactorEnum
@ StressIntensityFactorEnum
Definition: EnumDefinitions.h:1284
Penta::ResetFSBasalBoundaryCondition
void ResetFSBasalBoundaryCondition(void)
Definition: Penta.cpp:3145
CalvingStressThresholdFloatingiceEnum
@ CalvingStressThresholdFloatingiceEnum
Definition: EnumDefinitions.h:505
_error_
#define _error_(StreamArgs)
Definition: exceptions.h:49
ElementHook::hvertices
Hook * hvertices
Definition: ElementHook.h:16
Tria
Definition: Tria.h:29
MeshScaleFactorEnum
@ MeshScaleFactorEnum
Definition: EnumDefinitions.h:652
Node::DofInFSet
void DofInFSet(int dof)
Definition: Node.cpp:694
XZvectorsToCoordinateSystem
void XZvectorsToCoordinateSystem(IssmDouble *T, IssmDouble *xzvectors)
Definition: XZvectorsToCoordinateSystem.cpp:8
PentaRef::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: PentaRef.h:31
Penta::SetControlInputsFromVector
void SetControlInputsFromVector(IssmDouble *vector, int control_enum, int control_index, int offset, int N, int M)
Definition: Penta.cpp:3305
Penta::FloatingArea
IssmDouble FloatingArea(bool scaled)
Definition: Penta.cpp:1079
MaterialsRheologyBEnum
@ MaterialsRheologyBEnum
Definition: EnumDefinitions.h:643
Element::parameters
Parameters * parameters
Definition: Element.h:51
Penta::GetIcefrontCoordinates
void GetIcefrontCoordinates(IssmDouble **pxyz_front, IssmDouble *xyz_list, int levelsetenum)
Definition: Penta.cpp:1515
IoModel::numberofverticalfaces
int numberofverticalfaces
Definition: IoModel.h:98
Penta::StrainRateparallel
void StrainRateparallel()
Definition: Penta.cpp:3538
Inputs2::SetTriaControlInputGradient
void SetTriaControlInputGradient(int enum_in, int interpolation, int numindices, int *indices, IssmDouble *values)
Definition: Inputs2.cpp:717
Gauss::begin
virtual int begin(void)=0
VxEnum
@ VxEnum
Definition: EnumDefinitions.h:846
Penta::TimeAdapt
IssmDouble TimeAdapt()
Definition: Penta.cpp:3745
Node::DofInSSet
void DofInSSet(int dof)
Definition: Node.cpp:709
IoModel::numberofverticaledges
int numberofverticaledges
Definition: IoModel.h:94
min
IssmDouble min(IssmDouble a, IssmDouble b)
Definition: extrema.cpp:14
Penta::InputUpdateFromVector
void InputUpdateFromVector(IssmDouble *vector, int name, int type)
Definition: Penta.cpp:2606
Penta::GetInputListOnVertices
void GetInputListOnVertices(IssmDouble *pvalue, Input2 *input, IssmDouble default_value)
Definition: Penta.cpp:1611
Penta::GetVertexIndex
int GetVertexIndex(Vertex *vertex)
Definition: Penta.cpp:1792
P2bubblecondensedEnum
@ P2bubblecondensedEnum
Definition: EnumDefinitions.h:1225
PentaEnum
@ PentaEnum
Definition: EnumDefinitions.h:1231
GaussPenta::GaussNode
void GaussNode(int finitelement, int iv)
Definition: GaussPenta.cpp:583
CalvingCalvingrateEnum
@ CalvingCalvingrateEnum
Definition: EnumDefinitions.h:502
Penta::GetIcefrontArea
IssmDouble GetIcefrontArea()
Definition: Penta.cpp:1414
ElementInput2::GetInputInterpolationType
int GetInputInterpolationType()
Definition: ElementInput2.cpp:32
Penta::TensorInterpolation
int TensorInterpolation()
Definition: Penta.h:182
Gauss::GaussPoint
virtual void GaussPoint(int ig)=0
PentaRef::GetJacobianDeterminant
void GetJacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: PentaRef.cpp:250
NodeSIdEnum
@ NodeSIdEnum
Definition: EnumDefinitions.h:1200
StressTensorxzEnum
@ StressTensorxzEnum
Definition: EnumDefinitions.h:813
Penta::FSContactMigration
void FSContactMigration(Vector< IssmDouble > *vertex_sigmann, Vector< IssmDouble > *vertex_waterpressure)
Definition: Penta.cpp:1108
Penta::NodalFunctions
void NodalFunctions(IssmDouble *basis, Gauss *gauss)
Definition: Penta.cpp:2865
Penta::NormalSectionBase
void NormalSectionBase(IssmDouble *normal, IssmDouble *xyz_list)
Definition: Penta.cpp:3007
VyAverageEnum
@ VyAverageEnum
Definition: EnumDefinitions.h:849
Penta::CalvingRateVonmises
void CalvingRateVonmises()
Definition: Penta.cpp:264
ElementHook::hneighbors
Hook * hneighbors
Definition: ElementHook.h:18
HOFSApproximationEnum
@ HOFSApproximationEnum
Definition: EnumDefinitions.h:1096
Parameters::FindParam
void FindParam(bool *pinteger, int enum_type)
Definition: Parameters.cpp:262
ThicknessEnum
@ ThicknessEnum
Definition: EnumDefinitions.h:840
ElementInput2::element_values
IssmDouble * element_values
Definition: ElementInput2.h:18
ControlInputEnum
@ ControlInputEnum
Definition: EnumDefinitions.h:1017
Penta::StrainRateperpendicular
void StrainRateperpendicular()
Definition: Penta.cpp:3585
Penta::Update
void Update(Inputs2 *inputs, int index, IoModel *iomodel, int analysis_counter, int analysis_type, int finitelement)
Definition: Penta.cpp:4166
Element::GetNodeIndex
int GetNodeIndex(Node *node)
Definition: Element.cpp:1212
Penta::GetElementType
int GetElementType(void)
Definition: Penta.cpp:1252
SSAApproximationEnum
@ SSAApproximationEnum
Definition: EnumDefinitions.h:1255
FrontalForcingsBasinIdEnum
@ FrontalForcingsBasinIdEnum
Definition: EnumDefinitions.h:585
P2Enum
@ P2Enum
Definition: EnumDefinitions.h:1223
AnalysisTypeEnum
@ AnalysisTypeEnum
Definition: EnumDefinitions.h:36
VelEnum
@ VelEnum
Definition: EnumDefinitions.h:844
Penta::RignotMeltParameterization
void RignotMeltParameterization()
Definition: Penta.cpp:3224
Inputs2::GetDatasetInput2
DatasetInput2 * GetDatasetInput2(int enum_type)
Definition: Inputs2.cpp:438
Penta::GroundinglineMassFlux
IssmDouble GroundinglineMassFlux(bool scaled)
Definition: Penta.cpp:1946
Penta::GetInputValue
void GetInputValue(IssmDouble *pvalue, Vertex *vertex, int enumtype)
Definition: Penta.cpp:1693
ElementHook::hnodes
Hook ** hnodes
Definition: ElementHook.h:15
Node::ApplyConstraint
void ApplyConstraint(int dof, IssmDouble value)
Definition: Node.cpp:646
ElementVector
Definition: ElementVector.h:20
IoModel::elements
int * elements
Definition: IoModel.h:79
Element::StrainRateSSA
void StrainRateSSA(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:4138
Element::MarshallElement
void MarshallElement(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction, int numanalyses)
Definition: Element.cpp:2222
MaticeEnum
@ MaticeEnum
Definition: EnumDefinitions.h:1169
Input2::GetInputValue
virtual void GetInputValue(IssmDouble *pvalue, Gauss *gauss)
Definition: Input2.h:38
Vertex
Definition: Vertex.h:19
Gauss::weight
IssmDouble weight
Definition: Gauss.h:11
P1P1GLSEnum
@ P1P1GLSEnum
Definition: EnumDefinitions.h:1217
Element::IsOnSurface
bool IsOnSurface()
Definition: Element.cpp:1981
IoModel
Definition: IoModel.h:48
ElementHook::SpawnTriaHook
void SpawnTriaHook(ElementHook *triahook, int index1, int index2, int index3)
Definition: ElementHook.cpp:217
MaterialsRheologyEcbarEnum
@ MaterialsRheologyEcbarEnum
Definition: EnumDefinitions.h:648
P1xP4Enum
@ P1xP4Enum
Definition: EnumDefinitions.h:1222
max
IssmDouble max(IssmDouble a, IssmDouble b)
Definition: extrema.cpp:24
IoModel::elementtoverticalfaceconnectivity
int * elementtoverticalfaceconnectivity
Definition: IoModel.h:87
Penta::AddInput2
void AddInput2(int input_enum, IssmDouble *values, int interpolation_enum)
Definition: Penta.cpp:185
IssmPDouble
IssmDouble IssmPDouble
Definition: types.h:38
PentaRef::GetInputValue
void GetInputValue(IssmDouble *pvalue, IssmDouble *plist, Gauss *gauss, int finiteelement)
Definition: PentaRef.cpp:169
P1xP3Enum
@ P1xP3Enum
Definition: EnumDefinitions.h:1221
Element::GetInputListOnVertices
void GetInputListOnVertices(IssmDouble *pvalue, int enumtype)
Definition: Element.cpp:1131
Penta::NewGauss
Gauss * NewGauss(void)
Definition: Penta.cpp:2823
Penta::InputUpdateFromSolutionOneDofCollapsed
void InputUpdateFromSolutionOneDofCollapsed(IssmDouble *solutiong, int enum_type)
Definition: Penta.cpp:2566
Domain2DverticalEnum
@ Domain2DverticalEnum
Definition: EnumDefinitions.h:535
Penta::UpdateConstraintsExtrudeFromTop
void UpdateConstraintsExtrudeFromTop(void)
Definition: Penta.cpp:4614
ElementMatrix
Definition: ElementMatrix.h:19
FrontalForcingsSubglacialDischargeEnum
@ FrontalForcingsSubglacialDischargeEnum
Definition: EnumDefinitions.h:586
Penta::NodalFunctionsDerivativesVelocity
void NodalFunctionsDerivativesVelocity(IssmDouble *dbasis, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2879
Inputs2::AddInput
void AddInput(Input2 *in_input)
Definition: Inputs2.cpp:147
Vector< IssmDouble >
Element::GradientIndexing
void GradientIndexing(int *indexing, int control_index)
Definition: Element.cpp:1510
Penta::TotalCalvingFluxLevelset
IssmDouble TotalCalvingFluxLevelset(bool scaled)
Definition: Penta.cpp:3789
CalvingrateyAverageEnum
@ CalvingrateyAverageEnum
Definition: EnumDefinitions.h:510
Input2::GetInputAverage
virtual void GetInputAverage(IssmDouble *pvalue)
Definition: Input2.h:33
Penta::InputUpdateFromIoModel
void InputUpdateFromIoModel(int index, IoModel *iomodel)
Definition: Penta.cpp:2512
Element::isonsurface
bool isonsurface
Definition: Element.h:52
Penta::IceVolume
IssmDouble IceVolume(bool scaled)
Definition: Penta.cpp:2190
Penta::VerticalSegmentIndicesBase
void VerticalSegmentIndicesBase(int **pindices, int *pnumseg)
Definition: Penta.cpp:4684
Penta::JacobianDeterminantLine
void JacobianDeterminantLine(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: Penta.cpp:2743
Element::element_type
int element_type
Definition: Element.h:56
Node::GetNumberOfDofs
int GetNumberOfDofs(int approximation_enum, int setenum)
Definition: Node.cpp:741
Penta::AddBasalInput2
void AddBasalInput2(int input_enum, IssmDouble *values, int interpolation_enum)
Definition: Penta.cpp:162
Gauss
Definition: Gauss.h:8
Element::material
Material * material
Definition: Element.h:50
Penta::CreateDistanceInputFromSegmentlist
void CreateDistanceInputFromSegmentlist(IssmDouble *distances, int distanceenum)
Definition: Penta.cpp:984
CalvingratexEnum
@ CalvingratexEnum
Definition: EnumDefinitions.h:509
Penta::PressureInterpolation
int PressureInterpolation()
Definition: Penta.cpp:3085
Element::GetVerticesLidList
void GetVerticesLidList(int *lidlist)
Definition: Element.cpp:1426
Penta::GetGroundedPortion
IssmDouble GetGroundedPortion(IssmDouble *xyz_list)
Definition: Penta.cpp:1312
Vector::SetValue
void SetValue(int dof, doubletype value, InsMode mode)
Definition: Vector.h:163
GetNumberOfDofs
int GetNumberOfDofs(Node **nodes, int numnodes, int setenum, int approximation)
Definition: Node.cpp:1129
BedSlopeYEnum
@ BedSlopeYEnum
Definition: EnumDefinitions.h:501
Vertex::Sid
int Sid(void)
Definition: Vertex.cpp:168
P1xP2Enum
@ P1xP2Enum
Definition: EnumDefinitions.h:1220
PentaRef::GetNodalFunctions
void GetNodalFunctions(IssmDouble *basis, Gauss *gauss, int finiteelement)
Definition: PentaRef.cpp:276
PentaRef::GetSegmentJacobianDeterminant
void GetSegmentJacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)
Definition: PentaRef.cpp:1090
IoModel::numberofedges
int numberofedges
Definition: IoModel.h:93
StressTensoryzEnum
@ StressTensoryzEnum
Definition: EnumDefinitions.h:815
GaussPentaEnum
@ GaussPentaEnum
Definition: EnumDefinitions.h:1078
ElementInput2::GetInputValue
virtual void GetInputValue(IssmDouble *pvalue, Gauss *gauss)=0
ElementHook::numanalyses
int numanalyses
Definition: ElementHook.h:14
Penta::AddControlInput
void AddControlInput(int input_enum, Inputs2 *inputs2, IoModel *iomodel, IssmDouble *values, IssmDouble *values_min, IssmDouble *values_max, int interpolation_enum, int id)
Definition: Penta.cpp:206