Ice Sheet System Model  4.18
Code documentation
Element.cpp
Go to the documentation of this file.
1 
4 /*Headers:*/
5 /*{{{*/
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #else
9 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
10 #endif
11 #include <math.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include "../classes.h"
15 #include "../../shared/shared.h"
16 #include "../../modules/SurfaceMassBalancex/SurfaceMassBalancex.h"
17 #include "../Inputs2/BoolInput2.h"
18 #include "../Inputs2/TransientInput2.h"
19 #include "../Inputs2/ElementInput2.h"
20 #include "../Inputs2/PentaInput2.h"
21 #include "../Inputs2/DatasetInput2.h"
22 #include "../Inputs2/ArrayInput2.h"
23 /*}}}*/
24 #define MAXVERTICES 6 /*Maximum number of vertices per element, currently Penta, to avoid dynamic mem allocation*/
25 
26 #ifdef _HAVE_SEMIC_
27 /* SEMIC prototype {{{*/
28 extern "C" void run_semic_(IssmDouble *sf_in, IssmDouble *rf_in, IssmDouble *swd_in, IssmDouble *lwd_in, IssmDouble *wind_in, IssmDouble *sp_in, IssmDouble *rhoa_in,
29  IssmDouble *qq_in, IssmDouble *tt_in, IssmDouble *tsurf_out, IssmDouble *smb_out, IssmDouble *saccu_out, IssmDouble *smelt_out);
30 #endif
31 // _HAVE_SEMIC_
32 /*}}}*/
33 /*Constructors/destructor/copy*/
35  this->id = -1;
36  this->sid = -1;
37  this->lid = -1;
38  this->inputs2 = NULL;
39  this->nodes = NULL;
40  this->vertices = NULL;
41  this->material = NULL;
42  this->parameters = NULL;
43  this->element_type_list=NULL;
44 }/*}}}*/
46  xDelete<int>(element_type_list);
47 }
48 /*}}}*/
49 
50 /*Other*/
51 bool Element::AnyFSet(){/*{{{*/
52 
53  /*Fetch number of nodes and dof for this finite element*/
54  int numnodes = this->GetNumberOfNodes();
55 
56  for(int i=0;i<numnodes;i++){
57  if(nodes[i]->fsize) return true;
58  }
59  return false;
60 }/*}}}*/
62 
63  /*Intermediaries*/
64  IssmDouble vx,vy,vz,vmag;
65  IssmDouble dvx[3],dvy[3],dvz[3],dvmag[3];
66  IssmDouble eps[3][3],epseff,epsprime;
67  int dim;
68  IssmDouble *xyz_list = NULL;
69 
70  /*Retrieve all inputs we will be needing: */
71  this->GetVerticesCoordinates(&xyz_list);
73  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
74  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
75  Input2* vz_input=NULL;
76  if(dim==3){vz_input=this->GetInput2(VzEnum); _assert_(vz_input);}
77 
78  /*Allocate arrays*/
79  const int NUM_VERTICES = this->GetNumberOfVertices();
80 
81  IssmDouble* lambdas = xNew<IssmDouble>(NUM_VERTICES);
82 
83  /* Start looping on the number of vertices: */
84  Gauss* gauss=this->NewGauss();
85  for (int iv=0;iv<NUM_VERTICES;iv++){
86  gauss->GaussVertex(iv);
87 
88  /*Get velocity derivatives in all directions*/
89  _assert_(dim>1);
90  _assert_(vx_input);
91  vx_input->GetInputValue(&vx,gauss);
92  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
93  _assert_(vy_input);
94  vy_input->GetInputValue(&vy,gauss);
95  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
96  if(dim==3){
97  _assert_(vz_input);
98  vz_input->GetInputValue(&vz,gauss);
99  vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
100  }
101  else{
102  vz = 0.;
103  dvz[0] = 0.; dvz[1] = 0.; dvz[2] = 0.;
104  dvx[2]= 0.;
105  dvy[2]= 0.;
106  }
107  /*Calculate velocity magnitude and its derivative*/
108  vmag = sqrt(vx*vx+vy*vy+vz*vz);
109  if(vmag<1e-12){
110  vmag=1e-12;
111  dvmag[0]=0;
112  dvmag[1]=0;
113  dvmag[2]=0;
114  }
115  else{
116  dvmag[0]=1./(2*sqrt(vmag))*(2*vx*dvx[0]+2*vy*dvy[0]+2*vz*dvz[0]);
117  dvmag[1]=1./(2*sqrt(vmag))*(2*vx*dvx[1]+2*vy*dvy[1]+2*vz*dvz[1]);
118  dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]);
119  }
120  /*Build strain rate tensor*/
121  eps[0][0] = dvx[0]; eps[0][1] = .5*(dvx[1]+dvy[0]); eps[0][2] = .5*(dvx[2]+dvz[0]);
122  eps[1][0] = .5*(dvx[1]+dvy[0]); eps[1][1] = dvy[1]; eps[1][2] = .5*(dvy[2]+dvz[1]);
123  eps[2][0] = .5*(dvx[2]+dvz[0]); eps[2][1] = .5*(dvy[2]+dvz[1]); eps[2][2] = dvz[2];
124 
125  /*effective strain rate*/
126  epseff = 0.;
127  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
128  epseff = sqrt(eps[0][0]*eps[0][0] + eps[1][1]*eps[1][1] + eps[0][1]*eps[0][1] + eps[0][2]*eps[0][2] + eps[1][2]*eps[1][2] + eps[0][0]*eps[1][1]);
129 
130  EstarStrainrateQuantities(&epsprime,vx,vy,vz,vmag,&dvx[0],&dvy[0],&dvz[0],&dvmag[0]);
131  lambdas[iv]=EstarLambdaS(epseff,epsprime);
132  }
133 
134  /*Add Stress tensor components into inputs*/
135  this->AddInput2(LambdaSEnum,lambdas,P1Enum);
136 
137  /*Clean up and return*/
138  delete gauss;
139  xDelete<IssmDouble>(xyz_list);
140  xDelete<IssmDouble>(lambdas);
141 
142 }
143 /*}}}*/
145 
146  IssmDouble *xyz_list=NULL;
147  IssmDouble eps_xx,eps_xy,eps_yy,eps_xz,eps_yz,eps_zz,eps_eff;
148  IssmDouble epsmin=1.e-27;
149  IssmDouble eps_0,kappa,sigma_0,B,D,n,envelopeD;
150  int dim,counter=0;
151  IssmDouble k1,k2,threshold=1.e-12;
152 
153  /* Retrieve parameters */
154  this->GetVerticesCoordinates(&xyz_list);
155  this->ComputeStrainRate();
159 
160  /* Retrieve inputs */
161  Input2* eps_xx_input=this->GetInput2(StrainRatexxEnum); _assert_(eps_xx_input);
162  Input2* eps_yy_input=this->GetInput2(StrainRateyyEnum); _assert_(eps_yy_input);
163  Input2* eps_xy_input=this->GetInput2(StrainRatexyEnum); _assert_(eps_xy_input);
164  Input2* eps_xz_input=NULL;
165  Input2* eps_yz_input=NULL;
166  Input2* eps_zz_input=NULL;
167  if(dim==3){
168  eps_xz_input=this->GetInput2(StrainRatexzEnum); _assert_(eps_xz_input);
169  eps_yz_input=this->GetInput2(StrainRateyzEnum); _assert_(eps_yz_input);
170  eps_zz_input=this->GetInput2(StrainRatezzEnum); _assert_(eps_zz_input);
171  }
172 
173  /* Fetch number of nodes and allocate output*/
174  int numnodes = this->GetNumberOfNodes();
175  IssmDouble* newD = xNew<IssmDouble>(numnodes);
176 
177  /* Retrieve domain-dependent inputs */
178  Input2* n_input=this->GetInput2(MaterialsRheologyNEnum); _assert_(n_input);
179  Input2* damage_input = NULL;
180  Input2* B_input = NULL;
181  int domaintype;
182  parameters->FindParam(&domaintype,DomainTypeEnum);
183  if(domaintype==Domain2DhorizontalEnum){
184  damage_input = this->GetInput2(DamageDbarOldEnum); _assert_(damage_input);
185  B_input=this->GetInput2(MaterialsRheologyBbarEnum); _assert_(B_input);
186  }
187  else{
188  damage_input = this->GetInput2(DamageDOldEnum); _assert_(damage_input);
189  B_input=this->GetInput2(MaterialsRheologyBEnum); _assert_(B_input);
190  }
191 
192  /* Start looping on the number of nodes: */
193  Gauss* gauss=this->NewGauss();
194  for (int i=0;i<numnodes;i++){
195  gauss->GaussNode(this->GetElementType(),i);
196 
197  eps_xx_input->GetInputValue(&eps_xx,gauss);
198  eps_yy_input->GetInputValue(&eps_yy,gauss);
199  eps_xy_input->GetInputValue(&eps_xy,gauss);
200  if(dim==3){
201  eps_xz_input->GetInputValue(&eps_xz,gauss);
202  eps_yz_input->GetInputValue(&eps_yz,gauss);
203  eps_zz_input->GetInputValue(&eps_zz,gauss);
204  }
205  else{eps_xz=0; eps_yz=0; eps_zz=0;}
206 
207  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
208  eps_eff=sqrt(eps_xx*eps_xx+eps_yy*eps_yy+eps_xy*eps_xy+eps_xz*eps_xz+eps_yz*eps_yz+eps_xx*eps_yy+epsmin*epsmin);
209 
210  B_input->GetInputValue(&B,gauss);
211  n_input->GetInputValue(&n,gauss);
212  damage_input->GetInputValue(&D,gauss);
213 
214  /* Compute threshold strain rate from threshold stress */
215  eps_0=pow(sigma_0/B,n);
216 
217  if(eps_eff>eps_0){
218  /* Compute damage on envelope curve for existing level of effective strain rate */
219  envelopeD=1.-pow(eps_0/eps_eff,1./n)*exp(-(eps_eff-eps_0)/(eps_0*(kappa-1.)));
220 
221  if(envelopeD>D){
222  newD[i]=envelopeD;
223  }
224  else newD[i]=D;
225  }
226  else newD[i]=D;
227  }
228 
229  /* Add new damage input to DamageEnum and NewDamageEnum */
230  this->AddInput2(NewDamageEnum,newD,P1DGEnum);
231  if(domaintype==Domain2DhorizontalEnum){
232  this->AddInput2(DamageDbarEnum,newD,this->GetElementType());
233  }
234  else{
235  this->AddInput2(DamageDEnum,newD,this->GetElementType());
236  }
237 
238  /*Clean up and return*/
239  xDelete<IssmDouble>(xyz_list);
240  xDelete<IssmDouble>(newD);
241  delete gauss;
242 
243 }/*}}}*/
245 
246  int dim;
247  IssmDouble *xyz_list = NULL;
248  IssmDouble epsilon[6];
249 
250  /*Retrieve all inputs we will be needing: */
251  this->GetVerticesCoordinates(&xyz_list);
253  Input2* vx_input=this->GetInput2(VxEnum); _assert_(vx_input);
254  Input2* vy_input=this->GetInput2(VyEnum); _assert_(vy_input);
255  Input2* vz_input=NULL;
256  if(dim==3){vz_input=this->GetInput2(VzEnum); _assert_(vz_input);}
257 
258  /*Allocate arrays*/
259  const int NUM_VERTICES = this->GetNumberOfVertices();
260 
261  IssmDouble* eps_xx = xNew<IssmDouble>(NUM_VERTICES);
262  IssmDouble* eps_yy = xNew<IssmDouble>(NUM_VERTICES);
263  IssmDouble* eps_zz = xNew<IssmDouble>(NUM_VERTICES);
264  IssmDouble* eps_xy = xNew<IssmDouble>(NUM_VERTICES);
265  IssmDouble* eps_xz = xNew<IssmDouble>(NUM_VERTICES);
266  IssmDouble* eps_yz = xNew<IssmDouble>(NUM_VERTICES);
267  IssmDouble* eps_ef = xNew<IssmDouble>(NUM_VERTICES);
268 
269  /* Start looping on the number of vertices: */
270  Gauss* gauss=this->NewGauss();
271  for (int iv=0;iv<NUM_VERTICES;iv++){
272  gauss->GaussVertex(iv);
273 
274  /*Compute strain rate viscosity and pressure: */
275  if(dim==2)
276  this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
277  else
278  this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
279 
280  if(dim==2){
281  /* epsilon=[exx,eyy,exy];*/
282  eps_xx[iv]=epsilon[0];
283  eps_yy[iv]=epsilon[1];
284  eps_xy[iv]=epsilon[2];
285  /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
286  eps_ef[iv] = 1./sqrt(2.)*sqrt(epsilon[0]*epsilon[0] + epsilon[1]*epsilon[1] + 2.*epsilon[2]*epsilon[2]);
287  }
288  else{
289  /*epsilon=[exx eyy ezz exy exz eyz]*/
290  eps_xx[iv]=epsilon[0];
291  eps_yy[iv]=epsilon[1];
292  eps_zz[iv]=epsilon[2];
293  eps_xy[iv]=epsilon[3];
294  eps_xz[iv]=epsilon[4];
295  eps_yz[iv]=epsilon[5];
296  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
297  eps_ef[iv] = sqrt(epsilon[0]*epsilon[0] + epsilon[1]*epsilon[1] + epsilon[3]*epsilon[3] + epsilon[4]*epsilon[4] + epsilon[5]*epsilon[5] + epsilon[0]*epsilon[1]);
298  }
299  }
300 
301  /*Add Stress tensor components into inputs*/
302  this->AddInput2(StrainRatexxEnum,eps_xx,P1Enum);
303  this->AddInput2(StrainRatexyEnum,eps_xy,P1Enum);
304  this->AddInput2(StrainRatexzEnum,eps_xz,P1Enum);
305  this->AddInput2(StrainRateyyEnum,eps_yy,P1Enum);
306  this->AddInput2(StrainRateyzEnum,eps_yz,P1Enum);
307  this->AddInput2(StrainRatezzEnum,eps_zz,P1Enum);
309 
310  /*Clean up and return*/
311  delete gauss;
312  xDelete<IssmDouble>(xyz_list);
313  xDelete<IssmDouble>(eps_xx);
314  xDelete<IssmDouble>(eps_yy);
315  xDelete<IssmDouble>(eps_zz);
316  xDelete<IssmDouble>(eps_xy);
317  xDelete<IssmDouble>(eps_xz);
318  xDelete<IssmDouble>(eps_yz);
319  xDelete<IssmDouble>(eps_ef);
320 
321 }
322 /*}}}*/
323 void Element::CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
324 
325  int i,counter;
326  int numdofs = 0;
327  IssmDouble norm;
328  IssmDouble *transform = NULL;
329  IssmDouble coord_system[3][3];
330 
331  /*Some checks in debugging mode*/
332  _assert_(numnodes && nodes_list);
333 
334  /*Get total number of dofs*/
335  for(i=0;i<numnodes;i++){
336  switch(cs_array[i]){
337  case PressureEnum: numdofs+=1; break;
338  case XYEnum: numdofs+=2; break;
339  case XYZEnum: numdofs+=3; break;
340  default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
341  }
342  }
343 
344  /*Allocate and initialize transform matrix*/
345  transform=xNew<IssmDouble>(numdofs*numdofs);
346  for(i=0;i<numdofs*numdofs;i++) transform[i]=0.0;
347 
348  /*Create transform matrix for all nodes (x,y for 2d and x,y,z for 3d). It is a block matrix
349  *for 3 nodes:
350 
351  * | T1 0 0 |
352  * Q = | 0 T2 0 |
353  * | 0 0 T3|
354  *
355  * Where T1 is the transform matrix for node 1. It is a simple copy of the coordinate system
356  * associated to this node*/
357  counter=0;
358  for(i=0;i<numnodes;i++){
359  nodes_list[i]->GetCoordinateSystem(&coord_system[0][0]);
360  switch(cs_array[i]){
361  case PressureEnum:
362  /*DO NOT change anything*/
363  transform[(numdofs)*(counter) + counter] = 1.;
364  counter+=1;
365  break;
366  case XYEnum:
367  /*We remove the z component, we need to renormalize x and y: x=[x1 x2 0] y=[-x2 x1 0]*/
368  norm = sqrt( coord_system[0][0]*coord_system[0][0] + coord_system[1][0]*coord_system[1][0]); _assert_(norm>1.e-4);
369  transform[(numdofs)*(counter+0) + counter+0] = coord_system[0][0]/norm;
370  transform[(numdofs)*(counter+0) + counter+1] = - coord_system[1][0]/norm;
371  transform[(numdofs)*(counter+1) + counter+0] = coord_system[1][0]/norm;
372  transform[(numdofs)*(counter+1) + counter+1] = coord_system[0][0]/norm;
373  counter+=2;
374  break;
375  case XYZEnum:
376  /*The 3 coordinates are changed (x,y,z)*/
377  transform[(numdofs)*(counter+0) + counter+0] = coord_system[0][0];
378  transform[(numdofs)*(counter+0) + counter+1] = coord_system[0][1];
379  transform[(numdofs)*(counter+0) + counter+2] = coord_system[0][2];
380  transform[(numdofs)*(counter+1) + counter+0] = coord_system[1][0];
381  transform[(numdofs)*(counter+1) + counter+1] = coord_system[1][1];
382  transform[(numdofs)*(counter+1) + counter+2] = coord_system[1][2];
383  transform[(numdofs)*(counter+2) + counter+0] = coord_system[2][0];
384  transform[(numdofs)*(counter+2) + counter+1] = coord_system[2][1];
385  transform[(numdofs)*(counter+2) + counter+2] = coord_system[2][2];
386  counter+=3;
387  break;
388  default:
389  _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
390  }
391  }
392 
393  /*Assign output pointer*/
394  *ptransform=transform;
395 }
396 /*}}}*/
397 void Element::DeepEcho(void){/*{{{*/
398 
399  _printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
400  _printf_(" id : "<<this->id <<"\n");
401  _printf_(" sid: "<<this->sid<<"\n");
402  _printf_(" lid: "<<this->lid<<"\n");
403  if(vertices){
404  const int NUM_VERTICES = this->GetNumberOfVertices();
405  for(int i=0;i<NUM_VERTICES;i++) vertices[i]->Echo();
406  }
407  else _printf_("vertices = NULL\n");
408 
409  if(nodes){
410  int numnodes = this->GetNumberOfNodes();
411  for(int i=0;i<numnodes;i++) nodes[i]->DeepEcho();
412  }
413  else _printf_("nodes = NULL\n");
414 
415  if (material) material->DeepEcho();
416  else _printf_("material = NULL\n");
417 
418  _printf_(" parameters\n");
420  else _printf_("parameters = NULL\n");
421 
422  _printf_(" inputs\n");
423  if(inputs2) inputs2->DeepEcho();
424  else _printf_("inputs2=NULL\n");
425 
426  return;
427 }
428 /*}}}*/
429 void Element::DeleteMaterials(void){/*{{{*/
430  delete this->material;
431 }/*}}}*/
433 
434  /*Are we on the base? If not, return*/
435  if(!IsOnBase()) return;
436 
437  const int NUM_VERTICES = this->GetNumberOfVertices();
438  const int NUM_VERTICES_MONTHS_PER_YEAR = NUM_VERTICES * 12;
439 
440  int i;
441  int* vertexlids=xNew<int>(NUM_VERTICES);
442  IssmDouble* monthlytemperatures=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
443  IssmDouble* monthlyprec=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
444  IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
445  IssmDouble* TemperaturesLgm=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
446  IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
447  IssmDouble* tmp=xNew<IssmDouble>(NUM_VERTICES);
448 
449  /*Recover parameters*/
450  IssmDouble time,yts,finaltime;
451  this->parameters->FindParam(&time,TimeEnum);
454  this->GetVerticesLidList(vertexlids);
455  IssmDouble time_yr=floor(time/yts)*yts;
456 
457  /*Recover present day temperature and precipitation*/
461 
462  /*loop over vertices: */
463  Gauss* gauss=this->NewGauss();
464  for(int month=0;month<12;month++){
465  for(int iv=0;iv<NUM_VERTICES;iv++){
466  gauss->GaussVertex(iv);
467  dinput1->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month);
468  dinput2->GetInputValue(&TemperaturesLgm[iv*12+month],gauss,month);
469  dinput3->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month);
470 
471  PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;
472  }
473  }
474 
475  /*Recover delta18o and Delta18oSurface at present day, lgm and at time t*/
476  IssmDouble Delta18oPresent,Delta18oLgm,Delta18oTime;
477  IssmDouble Delta18oSurfacePresent,Delta18oSurfaceLgm,Delta18oSurfaceTime;
478  this->parameters->FindParam(&Delta18oPresent,SmbDelta18oEnum,finaltime);
479  this->parameters->FindParam(&Delta18oLgm,SmbDelta18oEnum,(finaltime-(21000*yts)));
480  this->parameters->FindParam(&Delta18oTime,SmbDelta18oEnum,time);
481  this->parameters->FindParam(&Delta18oSurfacePresent,SmbDelta18oSurfaceEnum,finaltime);
482  this->parameters->FindParam(&Delta18oSurfaceLgm,SmbDelta18oSurfaceEnum,(finaltime-(21000*yts)));
483  this->parameters->FindParam(&Delta18oSurfaceTime,SmbDelta18oSurfaceEnum,time);
484 
485  /*Compute the temperature and precipitation*/
486  for(int iv=0;iv<NUM_VERTICES;iv++){
487  ComputeDelta18oTemperaturePrecipitation(Delta18oSurfacePresent, Delta18oSurfaceLgm, Delta18oSurfaceTime,
488  Delta18oPresent, Delta18oLgm, Delta18oTime,
489  &PrecipitationsPresentday[iv*12],
490  &TemperaturesLgm[iv*12], &TemperaturesPresentday[iv*12],
491  &monthlytemperatures[iv*12], &monthlyprec[iv*12]);
492  }
493 
494  /*Update inputs*/
495  for (int imonth=0;imonth<12;imonth++) {
496  for(i=0;i<NUM_VERTICES;i++) tmp[i]=monthlytemperatures[i*12+imonth];
497  switch(this->ObjectEnum()){
498  case TriaEnum: this->inputs2->SetTriaDatasetInput(SmbMonthlytemperaturesEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
499  case PentaEnum: this->inputs2->SetPentaDatasetInput(SmbMonthlytemperaturesEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
500  default: _error_("Not implemented yet");
501  }
502  for(i=0;i<NUM_VERTICES;i++) tmp[i]=monthlyprec[i*12+imonth]/yts;
503  switch(this->ObjectEnum()){
504  case TriaEnum: this->inputs2->SetTriaDatasetInput(SmbPrecipitationEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
505  case PentaEnum: this->inputs2->SetPentaDatasetInput(SmbPrecipitationEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
506  default: _error_("Not implemented yet");
507  }
508  }
509 
510  switch(this->ObjectEnum()){
511  case TriaEnum: break;
512  case PentaEnum:
513  case TetraEnum:
516  break;
517  default: _error_("Not implemented yet");
518  }
519 
520  /*clean-up*/
521  delete gauss;
522  xDelete<IssmDouble>(monthlytemperatures);
523  xDelete<IssmDouble>(monthlyprec);
524  xDelete<IssmDouble>(TemperaturesPresentday);
525  xDelete<IssmDouble>(TemperaturesLgm);
526  xDelete<IssmDouble>(PrecipitationsPresentday);
527  xDelete<IssmDouble>(tmp);
528  xDelete<int>(vertexlids);
529 
530 } /*}}}*/
532  /*Are we on the base? If not, return*/
533  if(!IsOnBase()) return;
534 
535  const int NUM_VERTICES = this->GetNumberOfVertices();
536  const int NUM_VERTICES_MONTHS_PER_YEAR = NUM_VERTICES * 12;
537 
538  int i,offset;
539  int* vertexlids=xNew<int>(NUM_VERTICES);
540  IssmDouble* monthlytemperatures=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
541  IssmDouble* monthlyprec=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
542  IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
543  IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
544  IssmDouble* TemperaturesReconstructed=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
545  IssmDouble* PrecipitationsReconstructed=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
546  IssmDouble* tmp=xNew<IssmDouble>(NUM_VERTICES);
547  IssmDouble Delta18oTime;
548  IssmDouble f;
549  IssmDouble time,yts,time_yr,month,time_climt,time_climp,del_clim;
550  this->parameters->FindParam(&time,TimeEnum);
552  this->parameters->FindParam(&f,SmbFEnum);
553  this->GetVerticesLidList(vertexlids);
554  time_yr=floor(time/yts)*yts;
555  time_climt=ceil(time/yts + 1e-10)*yts;
556  time_climp=ceil(time/yts + 1e-10)*yts;
557 
558  /*Get some pdd parameters*/
559  bool isTemperatureScaled,isPrecipScaled;
560  IssmDouble dpermil=this->FindParam(SmbDpermilEnum);
561  this->parameters->FindParam(&isTemperatureScaled,SmbIstemperaturescaledEnum);
562  this->parameters->FindParam(&isPrecipScaled,SmbIsprecipscaledEnum);
563 
564  /*Recover present day temperature and precipitation*/
565  DatasetInput2 *dinput3 = NULL;
566  DatasetInput2 *dinput4 = NULL;
567  int offset_t,offset_p,N;
568  if(!isTemperatureScaled){
569  IssmDouble* time_temp_scaled = NULL;
571  if(!binary_search(&offset_t,time_climt,time_temp_scaled,N)) _error_("time not sorted?");
572  if(offset_t<0) offset_t=0;
573  xDelete<IssmDouble>(time_temp_scaled);
575  }
576  if(!isPrecipScaled){
577  IssmDouble* time_precip_scaled = NULL;
579  if(!binary_search(&offset_p,time_climt,time_precip_scaled,N)) _error_("time not sorted?");
580  if(offset_p<0) offset_p=0;
581  xDelete<IssmDouble>(time_precip_scaled);
583  }
584 
585  /*Get present day temp and precip (monthly)*/
588 
589  /*loop over vertices: */
590  Gauss* gauss=this->NewGauss();
591  for(int month=0;month<12;month++) {
592  for(int iv=0;iv<NUM_VERTICES;iv++) {
593  gauss->GaussVertex(iv);
594  dinput1->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month);
595  dinput2->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month);
596  PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;
597 
598  if(!isTemperatureScaled){
599  dinput3->GetInputValue(&TemperaturesReconstructed[iv*12+month],gauss,offset_t*12+month);
600  }
601  if(!isPrecipScaled){
602  dinput4->GetInputValue(&PrecipitationsReconstructed[iv*12+month],gauss,offset_p*12+month);
603  PrecipitationsReconstructed[iv*12+month]=PrecipitationsReconstructed[iv*12+month]*yts;
604  }
605  }
606  }
607 
608  /*Recover interpolation parameters at time t*/
609  this->parameters->FindParam(&Delta18oTime,SmbDelta18oEnum,time);
610 
611  /*Compute the temperature and precipitation*/
612  for(int iv=0;iv<NUM_VERTICES;iv++){
613  ComputeD18OTemperaturePrecipitationFromPD(Delta18oTime,dpermil,isTemperatureScaled,isPrecipScaled,
614  f,&PrecipitationsPresentday[iv*12], &TemperaturesPresentday[iv*12],
615  &PrecipitationsReconstructed[iv*12], &TemperaturesReconstructed[iv*12],
616  &monthlytemperatures[iv*12], &monthlyprec[iv*12]);
617  }
618 
619  /*Update inputs*/
620  for (int imonth=0;imonth<12;imonth++) {
621  for(i=0;i<NUM_VERTICES;i++) tmp[i]=monthlytemperatures[i*12+imonth];
622  switch(this->ObjectEnum()){
623  case TriaEnum: this->inputs2->SetTriaDatasetInput(SmbMonthlytemperaturesEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
624  case PentaEnum: this->inputs2->SetPentaDatasetInput(SmbMonthlytemperaturesEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
625  default: _error_("Not implemented yet");
626  }
627  for(i=0;i<NUM_VERTICES;i++) tmp[i]=monthlyprec[i*12+imonth]/yts;
628  switch(this->ObjectEnum()){
629  case TriaEnum: this->inputs2->SetTriaDatasetInput(SmbPrecipitationEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
630  case PentaEnum: this->inputs2->SetPentaDatasetInput(SmbPrecipitationEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
631  default: _error_("Not implemented yet");
632  }
633  }
634 
635  switch(this->ObjectEnum()){
636  case TriaEnum: break;
637  case PentaEnum:
638  case TetraEnum:
641  break;
642  default: _error_("Not implemented yet");
643  }
644 
645  /*clean-up*/
646  delete gauss;
647  xDelete<IssmDouble>(monthlytemperatures);
648  xDelete<IssmDouble>(monthlyprec);
649  xDelete<IssmDouble>(TemperaturesPresentday);
650  xDelete<IssmDouble>(PrecipitationsPresentday);
651  xDelete<IssmDouble>(TemperaturesReconstructed);
652  xDelete<IssmDouble>(PrecipitationsReconstructed);
653  xDelete<IssmDouble>(tmp);
654  xDelete<int>(vertexlids);
655 
656 } /*}}}*/
658 
659  /*Are we on the base? If not, return*/
660  if(!IsOnBase()) return;
661  const int NUM_VERTICES = this->GetNumberOfVertices();
662 
663  int i;
664  IssmDouble accuref, runoffref; //reference values at given altitude
665  IssmDouble accualti, runoffalti; //reference altitudes
666  IssmDouble accugrad, runoffgrad; //gradients from reference altitude
667  IssmDouble rho_water, rho_ice;
668  IssmDouble time;
669 
670  IssmDouble* smb = xNew<IssmDouble>(NUM_VERTICES);
671  IssmDouble* surf = xNew<IssmDouble>(NUM_VERTICES);
672  IssmDouble* accu = xNew<IssmDouble>(NUM_VERTICES);
673  IssmDouble* runoff = xNew<IssmDouble>(NUM_VERTICES);
674 
675  /*Get material parameters :*/
676  rho_water=this->FindParam(MaterialsRhoSeawaterEnum);
677  rho_ice=this->FindParam(MaterialsRhoIceEnum);
678 
679  /*Recover parameters*/
680  parameters->FindParam(&time,TimeEnum);
683  parameters->FindParam(&runoffalti,SmbRunoffaltiEnum);
684  parameters->FindParam(&runoffgrad,SmbRunoffgradEnum);
685 
686  /*Recover reference values at current time*/
687  parameters->FindParam(&accuref,SmbAccurefEnum,time);
688  parameters->FindParam(&runoffref,SmbRunoffrefEnum,time);
689 
690  /*Recover surface elevation*/
692 
693  /*Compute the temperature and precipitation*/
694  for(int iv=0;iv<NUM_VERTICES;iv++){
695  accu[iv]=max(0.,(accuref+(surf[iv]-accualti)*accugrad));
696  runoff[iv]=max(0.,(runoffref+(surf[iv]-runoffalti)*runoffgrad));
697  smb[iv]=(accu[iv]-runoff[iv])*rho_ice/rho_water;
698  }
699 
700  switch(this->ObjectEnum()){
701  case TriaEnum:
703  this->AddInput2(SmbRunoffSubstepEnum,&runoff[0],P1Enum);
704  break;
705  case PentaEnum:
707  this->AddInput2(SmbRunoffSubstepEnum,&runoff[0],P1Enum);
710  break;
711  default: _error_("Not implemented yet");
712  }
713  /*clean-up*/
714  xDelete<IssmDouble>(surf);
715  xDelete<IssmDouble>(accu);
716  xDelete<IssmDouble>(runoff);
717  xDelete<IssmDouble>(smb);
718 }
719 /*}}}*/
721  /*Compute element divergence*/
722 
723  /*Intermediaries*/
724  int dim;
725  IssmDouble Jdet;
726  IssmDouble divergence=0.;
727  IssmDouble dvx[3],dvy[3],dvz[3];
728  IssmDouble *xyz_list = NULL;
729 
730  /*Get inputs and parameters*/
731  this->FindParam(&dim,DomainDimensionEnum);
732  Input2* vx_input = this->GetInput2(VxEnum); _assert_(vx_input);
733  Input2* vy_input = this->GetInput2(VyEnum); _assert_(vy_input);
734  Input2* vz_input = NULL;
735  if(dim==3){
736  vz_input = this->GetInput2(VzEnum); _assert_(vz_input);
737  }
738  this->GetVerticesCoordinates(&xyz_list);
739 
740  Gauss* gauss=this->NewGauss(5);
741  for(int ig=gauss->begin();ig<gauss->end();ig++){
742  gauss->GaussPoint(ig);
743  this->JacobianDeterminant(&Jdet,xyz_list,gauss);
744 
745  /*Get strain rate assuming that epsilon has been allocated*/
746  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
747  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
748  if(dim==2){
749  divergence += (dvx[0]+dvy[1])*gauss->weight*Jdet;
750  }
751  else{
752  vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
753  divergence += (dvx[0]+dvy[1]+dvz[2])*gauss->weight*Jdet;
754  }
755 
756  }
757 
758  /*Clean up and return*/
759  xDelete<IssmDouble>(xyz_list);
760  delete gauss;
761  return divergence;
762 }/*}}}*/
763 void Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input,Input2* vz_input){/*{{{*/
764 
765  /*Intermediaries*/
766  int materialstype;
767  IssmDouble dmudB;
768  IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz]; */
769  IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */
770  IssmDouble eps_eff;
771  IssmDouble eps0=1.e-27;
772 
773  if(dim==3){
774  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
775  this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);
776  eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[5]*epsilon3d[5] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
777  }
778  else{
779  /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
780  this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
781  eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);
782  }
783  /*Get viscosity*/
784  materialstype=this->material->ObjectEnum();
785  switch(materialstype){
786  case MaticeEnum:
787  material->GetViscosity_B(&dmudB,eps_eff,gauss);
788  break;
789  case MatestarEnum:
790  material->ViscosityBFS(&dmudB,dim,xyz_list,gauss,vx_input,vy_input,vz_input,eps_eff);
791  break;
792  default: _error_("not supported");
793  }
794 
795  /*Assign output pointer*/
796  *pdmudB=dmudB;
797 
798 }
799 /*}}}*/
800 void Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
801 
802  /*Intermediaries*/
803  int materialstype;
804  IssmDouble dmudB;
805  IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz]; */
806  IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy]; */
807  IssmDouble eps_eff;
808  IssmDouble eps0=1.e-27;
809 
810  if(dim==3){
811  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
812  this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
813  eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[2]*epsilon3d[2] + epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
814  }
815  else{
816  /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
817  this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
818  eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0);
819  }
820  /*Get viscosity*/
821  materialstype=this->material->ObjectEnum();
822  switch(materialstype){
823  case MaticeEnum:
824  material->GetViscosity_B(&dmudB,eps_eff,gauss);
825  break;
826  case MatestarEnum:
827  material->ViscosityBHO(&dmudB,dim,xyz_list,gauss,vx_input,vy_input,eps_eff);
828  break;
829  default: _error_("not supported");
830  }
831 
832  /*Assign output pointer*/
833  *pdmudB=dmudB;
834 
835 }
836 /*}}}*/
837 void Element::dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
838 
839  /*Intermediaries*/
840  int materialstype;
841  IssmDouble dmudB;
842  IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */
843  IssmDouble epsilon1d; /* epsilon=[exx]; */
844  IssmDouble eps_eff;
845 
846  if(dim==2){
847  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
848  this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
849  eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
850  }
851  else{
852  /* eps_eff^2 = 1/2 exx^2*/
853  this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
854  eps_eff = sqrt(epsilon1d*epsilon1d/2.);
855  }
856 
857  /*Get viscosity*/
858  materialstype=this->material->ObjectEnum();
859  switch(materialstype){
860  case MaticeEnum:
861  material->GetViscosity_B(&dmudB,eps_eff,gauss);
862  break;
863  case MatestarEnum:
864  material->ViscosityBSSA(&dmudB,dim,xyz_list,gauss,vx_input,vy_input,eps_eff);
865  break;
866  default: _error_("not supported");
867  }
868 
869  /*Assign output pointer*/
870  *pdmudB=dmudB;
871 
872 }
873 /*}}}*/
874 void Element::dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
875 
876  /*Intermediaries*/
877  IssmDouble dmudB;
878  IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */
879  IssmDouble epsilon1d; /* epsilon=[exx]; */
880  IssmDouble eps_eff;
881 
882  if(dim==2){
883  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
884  this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
885  eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
886  }
887  else{
888  /* eps_eff^2 = 1/2 exx^2*/
889  this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
890  eps_eff = sqrt(epsilon1d*epsilon1d/2.);
891  }
892 
893  /*Get viscosity*/
894  material->GetViscosity_D(&dmudB,eps_eff,gauss);
895 
896  /*Assign output pointer*/
897  *pdmudB=dmudB;
898 
899 }
900 /*}}}*/
901 void Element::Echo(void){/*{{{*/
902  _printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
903  _printf_(" id : "<<this->id <<"\n");
904  _printf_(" sid: "<<this->sid<<"\n");
905  _printf_(" lid: "<<this->lid<<"\n");
906  if(vertices){
907  const int NUM_VERTICES = this->GetNumberOfVertices();
908  for(int i=0;i<NUM_VERTICES;i++) vertices[i]->Echo();
909  }
910  else _printf_("vertices = NULL\n");
911 
912  if(nodes){
913  int numnodes = this->GetNumberOfNodes();
914  for(int i=0;i<numnodes;i++) {
915  _printf_("nodes[" << i << "] = " << nodes[i]);
916  nodes[i]->Echo();
917  }
918  }
919  else _printf_("nodes = NULL\n");
920 
921  if (material) material->Echo();
922  else _printf_("material = NULL\n");
923 
924  _printf_(" parameters\n");
925  if (parameters) parameters->Echo();
926  else _printf_("parameters = NULL\n");
927 
928  _printf_(" inputs\n");
929  if (inputs2) inputs2->Echo();
930  else _printf_("inputs2=NULL\n");
931 }
932 /*}}}*/
933 void Element::FindParam(bool* pvalue,int paramenum){/*{{{*/
934  this->parameters->FindParam(pvalue,paramenum);
935 }/*}}}*/
936 void Element::FindParam(int* pvalue,int paramenum){/*{{{*/
937  this->parameters->FindParam(pvalue,paramenum);
938 }/*}}}*/
939 void Element::FindParam(IssmDouble* pvalue,int paramenum){/*{{{*/
940  this->parameters->FindParam(pvalue,paramenum);
941 }/*}}}*/
942 IssmDouble Element::FindParam(int paramenum){/*{{{*/
943  return this->parameters->FindParam(paramenum);
944 }/*}}}*/
945 void Element::FindParam(int** pvalues,int* psize,int paramenum){/*{{{*/
946  this->parameters->FindParam(pvalues,psize,paramenum);
947 }/*}}}*/
948 IssmDouble Element::FloatingArea(IssmDouble* mask, bool scaled){/*{{{*/
949 
950  /*Retrieve values of the mask defining the element: */
951  for(int i=0;i<this->GetNumberOfVertices();i++){
952  if(mask[this->vertices[i]->Sid()]<=0.){
953  return 0.;
954  }
955  }
956 
957  /*Return: */
958  return this->FloatingArea(scaled);
959 }
960 /*}}}*/
961 void Element::GetDofList(int** pdoflist,int approximation_enum,int setenum){/*{{{*/
962 
963  /*Fetch number of nodes and dof for this finite element*/
964  int numnodes = this->GetNumberOfNodes();
965 
966  /*First, figure out size of doflist and create it: */
967  int numberofdofs=0;
968  for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
969 
970  /*Allocate output*/
971  int* doflist=xNew<int>(numberofdofs);
972 
973  /*Populate: */
974  int count=0;
975  for(int i=0;i<numnodes;i++){
976  nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
977  count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
978  }
979 
980  /*Assign output pointers:*/
981  *pdoflist=doflist;
982 }
983 /*}}}*/
984 void Element::GetDofListLocal(int** pdoflist,int approximation_enum,int setenum){/*{{{*/
985 
986  /*Fetch number of nodes and dof for this finite element*/
987  int numnodes = this->GetNumberOfNodes();
988 
989  /*First, figure out size of doflist and create it: */
990  int numberofdofs=0;
991  for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
992 
993  /*Allocate output*/
994  int* doflist=xNew<int>(numberofdofs);
995 
996  /*Populate: */
997  int count=0;
998  for(int i=0;i<numnodes;i++){
999  nodes[i]->GetDofListLocal(doflist+count,approximation_enum,setenum);
1000  count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
1001  }
1002 
1003  /*Assign output pointers:*/
1004  *pdoflist=doflist;
1005 }
1006 /*}}}*/
1007 void Element::GetDofListPressure(int** pdoflist,int setenum){/*{{{*/
1008 
1009  /*Fetch number of nodes and dof for this finite element*/
1010  int vnumnodes = this->NumberofNodesVelocity();
1011  int pnumnodes = this->NumberofNodesPressure();
1012 
1013  /*First, figure out size of doflist and create it: */
1014  int numberofdofs=0;
1015  for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
1016 
1017  /*Allocate output*/
1018  int* doflist=xNew<int>(numberofdofs);
1019 
1020  /*Populate: */
1021  int count=0;
1022  for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
1023  nodes[i]->GetDofList(doflist+count,FSApproximationEnum,setenum);
1024  count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
1025  }
1026 
1027  /*Assign output pointers:*/
1028  *pdoflist=doflist;
1029 }
1030 /*}}}*/
1031 void Element::GetDofListVelocity(int** pdoflist,int setenum){/*{{{*/
1032 
1033  /*Fetch number of nodes and dof for this finite element*/
1034  int numnodes = this->NumberofNodesVelocity();
1035 
1036  /*First, figure out size of doflist and create it: */
1037  int numberofdofs=0;
1038  for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
1039 
1040  /*Allocate output*/
1041  int* doflist=xNew<int>(numberofdofs);
1042 
1043  /*Populate: */
1044  int count=0;
1045  for(int i=0;i<numnodes;i++){
1046  nodes[i]->GetDofList(doflist+count,FSvelocityEnum,setenum);
1047  count+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
1048  }
1049 
1050  /*Assign output pointers:*/
1051  *pdoflist=doflist;
1052 }
1053 /*}}}*/
1054 void Element::GetDofListLocalPressure(int** pdoflist,int setenum){/*{{{*/
1055 
1056  /*Fetch number of nodes and dof for this finite element*/
1057  int vnumnodes = this->NumberofNodesVelocity();
1058  int pnumnodes = this->NumberofNodesPressure();
1059 
1060  /*First, figure out size of doflist and create it: */
1061  int numberofdofs=0;
1062  for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
1063 
1064  /*Allocate output*/
1065  int* doflist=xNew<int>(numberofdofs);
1066 
1067  /*Populate: */
1068  int count=0;
1069  for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
1070  nodes[i]->GetDofListLocal(doflist+count,FSApproximationEnum,setenum);
1071  count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
1072  }
1073 
1074  /*Assign output pointers:*/
1075  *pdoflist=doflist;
1076 }
1077 /*}}}*/
1078 void Element::GetDofListLocalVelocity(int** pdoflist,int setenum){/*{{{*/
1079 
1080  /*Fetch number of nodes and dof for this finite element*/
1081  int numnodes = this->NumberofNodesVelocity();
1082 
1083  /*First, figure out size of doflist and create it: */
1084  int numberofdofs=0;
1085  for(int i=0;i<numnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
1086 
1087  /*Allocate output*/
1088  int* doflist=xNew<int>(numberofdofs);
1089 
1090  /*Populate: */
1091  int count=0;
1092  for(int i=0;i<numnodes;i++){
1093  nodes[i]->GetDofListLocal(doflist+count,FSvelocityEnum,setenum);
1094  count+=nodes[i]->GetNumberOfDofs(FSvelocityEnum,setenum);
1095  }
1096 
1097  /*Assign output pointers:*/
1098  *pdoflist=doflist;
1099 }
1100 /*}}}*/
1101 void Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
1102  Input2 *input = this->GetInput2(enumtype);
1103  this->GetInputListOnNodes(pvalue,input,defaultvalue);
1104 }
1105 /*}}}*/
1106 void Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){/*{{{*/
1107 
1108  Input2 *input = this->GetInput2(enumtype);
1109  if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
1110  this->GetInputListOnNodes(pvalue,input,0.);
1111 
1112 }
1113 /*}}}*/
1114 void Element::GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype){/*{{{*/
1115 
1116  _assert_(pvalue);
1117 
1118  int numnodes = this->NumberofNodesVelocity();
1119  Input2 *input = this->GetInput2(enumtype);
1120  if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
1121 
1122  /* Start looping on the number of vertices: */
1123  Gauss* gauss=this->NewGauss();
1124  for(int iv=0;iv<numnodes;iv++){
1125  gauss->GaussNode(this->VelocityInterpolation(),iv);
1126  input->GetInputValue(&pvalue[iv],gauss);
1127  }
1128  delete gauss;
1129 }
1130 /*}}}*/
1131 void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){/*{{{*/
1132 
1133  /*Recover input*/
1134  Input2* input2=this->GetInput2(enumtype);
1135  if(!input2) _error_("input "<<EnumToStringx(enumtype)<<" not found in element");
1136  this->GetInputListOnVertices(pvalue,input2,0.);
1137 }
1138 /*}}}*/
1139 void Element::GetInputListOnVerticesAtTime(IssmDouble* pvalue, int enumtype, IssmDouble time){/*{{{*/
1140 
1141  /*Recover input*/
1142  Input2* input=this->GetInput2(enumtype,time);
1143  if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
1144  this->GetInputListOnVertices(pvalue,input,0.);
1145 }
1146 /*}}}*/
1147 void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
1148  Input2* input=this->GetInput2(enumtype);
1149  this->GetInputListOnVertices(pvalue,input,defaultvalue);
1150 }
1151 /*}}}*/
1153 
1154  /*Get number of nodes for this element*/
1155  int numnodes = this->GetNumberOfNodes();
1156 
1157  /*Some checks to avoid segmentation faults*/
1158  _assert_(ug);
1159  _assert_(numnodes>0);
1160  _assert_(nodes);
1161 
1162  /*Get element minimum/maximum*/
1163  IssmDouble input_min = ug[nodes[0]->GetDof(0,GsetEnum)];
1164  IssmDouble input_max = input_min;
1165  for(int i=1;i<numnodes;i++){
1166  if(ug[nodes[i]->GetDof(0,GsetEnum)] < input_min) input_min = ug[nodes[i]->GetDof(0,GsetEnum)];
1167  if(ug[nodes[i]->GetDof(0,GsetEnum)] > input_max) input_max = ug[nodes[i]->GetDof(0,GsetEnum)];
1168  }
1169 
1170  /*Second loop to reassign min and max with local extrema*/
1171  for(int i=0;i<numnodes;i++){
1172  if(min[nodes[i]->GetDof(0,GsetEnum)]>input_min) min[nodes[i]->GetDof(0,GsetEnum)] = input_min;
1173  if(max[nodes[i]->GetDof(0,GsetEnum)]<input_max) max[nodes[i]->GetDof(0,GsetEnum)] = input_max;
1174  }
1175 }
1176 /*}}}*/
1177 void Element::GetInputValue(bool* pvalue,int inputenum){/*{{{*/
1178 
1179  this->inputs2->GetInputValue(pvalue,inputenum,this->lid);
1180 
1181 }/*}}}*/
1182 void Element::GetInputValue(int* pvalue,int inputenum){/*{{{*/
1183  this->inputs2->GetInputValue(pvalue,inputenum,this->lid);
1184 }/*}}}*/
1185 void Element::GetInput2Value(bool* pvalue,int inputenum){/*{{{*/
1186 
1187  this->inputs2->GetInputValue(pvalue,inputenum,this->lid);
1188 
1189 }/*}}}*/
1190 void Element::GetInput2Value(int* pvalue,int inputenum){/*{{{*/
1191 
1192  this->inputs2->GetInputValue(pvalue,inputenum,this->lid);
1193 
1194 }/*}}}*/
1195 void Element::GetInput2Value(IssmDouble* pvalue,int inputenum){/*{{{*/
1196 
1197  this->inputs2->GetInputValue(pvalue,inputenum,this->lid);
1198 
1199 }/*}}}*/
1200 void Element::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int inputenum){/*{{{*/
1201 
1202  Input2* input=this->GetInput2(inputenum);
1203  if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
1204  input->GetInputValue(pvalue,gauss);
1205 
1206 }/*}}}*/
1207 Node* Element::GetNode(int nodeindex){/*{{{*/
1208  _assert_(nodeindex>=0);
1209  _assert_(nodeindex<this->GetNumberOfNodes(this->element_type));
1210  return this->nodes[nodeindex];
1211 }/*}}}*/
1212 int Element::GetNodeIndex(Node* node){/*{{{*/
1213 
1214  _assert_(this->nodes);
1215  int numnodes = this->GetNumberOfNodes(this->element_type);
1216 
1217  for(int i=0;i<numnodes;i++){
1218  if(node==nodes[i]) return i;
1219  }
1220  _error_("Node provided not found among element nodes");
1221 
1222 }
1223 /*}}}*/
1224 void Element::GetNodesLidList(int* lidlist){/*{{{*/
1225 
1226  _assert_(lidlist);
1227  _assert_(nodes);
1228  int numnodes = this->GetNumberOfNodes();
1229  for(int i=0;i<numnodes;i++){
1230  lidlist[i]=nodes[i]->Lid();
1231  }
1232 }
1233 /*}}}*/
1234 void Element::GetNodesSidList(int* sidlist){/*{{{*/
1235 
1236  _assert_(sidlist);
1237  _assert_(nodes);
1238  int numnodes = this->GetNumberOfNodes();
1239  for(int i=0;i<numnodes;i++){
1240  sidlist[i]=nodes[i]->Sid();
1241  }
1242 }
1243 /*}}}*/
1244 void Element::GetPhi(IssmDouble* phi, IssmDouble* epsilon, IssmDouble viscosity){/*{{{*/
1245  /*Compute deformational heating from epsilon and viscosity */
1246 
1247  IssmDouble epsilon_matrix[3][3];
1248  IssmDouble epsilon_eff;
1249  IssmDouble epsilon_sqr[3][3];
1250 
1251  /* Build epsilon matrix */
1252  epsilon_matrix[0][0]=epsilon[0];
1253  epsilon_matrix[1][0]=epsilon[3];
1254  epsilon_matrix[2][0]=epsilon[4];
1255  epsilon_matrix[0][1]=epsilon[3];
1256  epsilon_matrix[1][1]=epsilon[1];
1257  epsilon_matrix[2][1]=epsilon[5];
1258  epsilon_matrix[0][2]=epsilon[4];
1259  epsilon_matrix[1][2]=epsilon[5];
1260  epsilon_matrix[2][2]=epsilon[2];
1261 
1262  /* Effective value of epsilon_matrix */
1263  epsilon_sqr[0][0]=epsilon_matrix[0][0]*epsilon_matrix[0][0];
1264  epsilon_sqr[1][0]=epsilon_matrix[1][0]*epsilon_matrix[1][0];
1265  epsilon_sqr[2][0]=epsilon_matrix[2][0]*epsilon_matrix[2][0];
1266  epsilon_sqr[0][1]=epsilon_matrix[0][1]*epsilon_matrix[0][1];
1267  epsilon_sqr[1][1]=epsilon_matrix[1][1]*epsilon_matrix[1][1];
1268  epsilon_sqr[2][1]=epsilon_matrix[2][1]*epsilon_matrix[2][1];
1269  epsilon_sqr[0][2]=epsilon_matrix[0][2]*epsilon_matrix[0][2];
1270  epsilon_sqr[1][2]=epsilon_matrix[1][2]*epsilon_matrix[1][2];
1271  epsilon_sqr[2][2]=epsilon_matrix[2][2]*epsilon_matrix[2][2];
1272  epsilon_eff=1/sqrt(2.)*sqrt(epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]);
1273 
1274  /*Phi = Tr(sigma * eps)
1275  * = Tr(sigma'* eps)
1276  * = 2 * eps_eff * sigma'_eff
1277  * = 4 * mu * eps_eff ^2*/
1278  *phi=4.*epsilon_eff*epsilon_eff*viscosity;
1279 }
1280 /*}}}*/
1281 void Element::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){/*{{{*/
1282 
1283  int *doflist = NULL;
1284  IssmDouble value;
1285 
1286  /*Fetch number of nodes for this finite element*/
1287  int numnodes = this->GetNumberOfNodes();
1288 
1289  /*Fetch dof list and allocate solution vector*/
1291  IssmDouble* values = xNew<IssmDouble>(numnodes);
1292 
1293  /*Get inputs*/
1294  Input2* enum_input=this->GetInput2(enum_type); _assert_(enum_input);
1295 
1296  /*Ok, we have the values, fill in the array: */
1297  Gauss* gauss=this->NewGauss();
1298  for(int i=0;i<numnodes;i++){
1299  gauss->GaussNode(this->element_type,i);
1300 
1301  enum_input->GetInputValue(&value,gauss);
1302  values[i]=value;
1303  }
1304 
1305  solution->SetValues(numnodes,doflist,values,INS_VAL);
1306 
1307  /*Free ressources:*/
1308  xDelete<int>(doflist);
1309  xDelete<IssmDouble>(values);
1310  delete gauss;
1311 }
1312 /*}}}*/
1313 /* void Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){/\*{{{*\/ */
1314 
1315 /* /\*Fetch number vertices for this element and allocate arrays*\/ */
1316 /* const int NUM_VERTICES = this->GetNumberOfVertices(); */
1317 /* int* vertexpidlist = xNew<int>(NUM_VERTICES); */
1318 /* IssmDouble* values = xNew<IssmDouble>(NUM_VERTICES); */
1319 
1320 /* /\*Fill in values*\/ */
1321 /* this->GetVerticesPidList(vertexpidlist); */
1322 /* this->GetInputListOnVertices(values,input_enum); */
1323 /* vector->SetValues(NUM_VERTICES,vertexpidlist,values,INS_VAL); */
1324 
1325 /* /\*Clean up*\/ */
1326 /* xDelete<int>(vertexpidlist); */
1327 /* xDelete<IssmDouble>(values); */
1328 
1329 /* } */
1330 /* /\*}}}*\/ */
1331 void Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum,int type){/*{{{*/
1332 
1333  /*Fetch number vertices for this element and allocate arrays*/
1334  const int NUM_VERTICES = this->GetNumberOfVertices();
1335 
1336  int numnodes = this->GetNumberOfNodes();
1337  int* doflist = NULL;
1338  IssmDouble value;
1339  IssmDouble* values = NULL;
1340  Input2* input = NULL;
1341 
1342  switch(type){
1343  case ElementSIdEnum:
1344  input=this->GetInput2(input_enum); _assert_(input);
1345  input->GetInputAverage(&value);
1346  vector->SetValue(this->sid,value,INS_VAL);
1347  break;
1348  case VertexPIdEnum:
1349  doflist = xNew<int>(NUM_VERTICES);
1350  values = xNew<IssmDouble>(NUM_VERTICES);
1351  /*Fill in values*/
1352  this->GetVerticesPidList(doflist);
1353  this->GetInputListOnVertices(values,input_enum);
1354  vector->SetValues(NUM_VERTICES,doflist,values,INS_VAL);
1355  break;
1356  case VertexSIdEnum:
1357  doflist = xNew<int>(NUM_VERTICES);
1358  values = xNew<IssmDouble>(NUM_VERTICES);
1359  /*Fill in values*/
1360  this->GetVerticesSidList(doflist);
1361  this->GetInputListOnVertices(values,input_enum);
1362  vector->SetValues(NUM_VERTICES,doflist,values,INS_VAL);
1363  break;
1364  case NodesEnum:
1365  doflist = xNew<int>(numnodes);
1366  values = xNew<IssmDouble>(numnodes);
1367  /*Fill in values*/
1368  this->GetInputListOnNodes(values,input_enum);
1369  this->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
1370  vector->SetValues(numnodes,doflist,values,INS_VAL);
1371  break;
1372  case NodeSIdEnum:
1373  doflist = xNew<int>(numnodes);
1374  values = xNew<IssmDouble>(numnodes);
1375  /*Fill in values*/
1376  this->GetNodesSidList(doflist);
1377  this->GetInputListOnNodes(values,input_enum);
1378  vector->SetValues(numnodes,doflist,values,INS_VAL);
1379  break;
1380  default:
1381  _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
1382  }
1383 
1384  /*Clean up*/
1385  xDelete<int>(doflist);
1386  xDelete<IssmDouble>(values);
1387 
1388 }
1389 /*}}}*/
1390 void Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum,int type, IssmDouble time){/*{{{*/
1391 
1392  /*Fetch number vertices for this element and allocate arrays*/
1393  const int NUM_VERTICES = this->GetNumberOfVertices();
1394 
1395  int numnodes = this->GetNumberOfNodes();
1396  int* doflist = NULL;
1397  IssmDouble* values = NULL;
1398 
1399  switch(type){
1400  case VertexPIdEnum:
1401  doflist = xNew<int>(NUM_VERTICES);
1402  values = xNew<IssmDouble>(NUM_VERTICES);
1403  /*Fill in values*/
1404  this->GetVerticesPidList(doflist);
1405  this->GetInputListOnVerticesAtTime(values,input_enum,time);
1406  vector->SetValues(NUM_VERTICES,doflist,values,INS_VAL);
1407  break;
1408  case VertexSIdEnum:
1409  doflist = xNew<int>(NUM_VERTICES);
1410  values = xNew<IssmDouble>(NUM_VERTICES);
1411  /*Fill in values*/
1412  this->GetVerticesSidList(doflist);
1413  this->GetInputListOnVerticesAtTime(values,input_enum,time);
1414  vector->SetValues(NUM_VERTICES,doflist,values,INS_VAL);
1415  break;
1416  default:
1417  _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
1418  }
1419 
1420  /*Clean up*/
1421  xDelete<int>(doflist);
1422  xDelete<IssmDouble>(values);
1423 
1424 }
1425 /*}}}*/
1426 void Element::GetVerticesLidList(int* lidlist){/*{{{*/
1427 
1428  const int NUM_VERTICES = this->GetNumberOfVertices();
1429  for(int i=0;i<NUM_VERTICES;i++) lidlist[i]=vertices[i]->Lid();
1430 
1431 }
1432 /*}}}*/
1433 void Element::GetVerticesPidList(int* pidlist){/*{{{*/
1434 
1435  const int NUM_VERTICES = this->GetNumberOfVertices();
1436  for(int i=0;i<NUM_VERTICES;i++) pidlist[i]=vertices[i]->Pid();
1437 
1438 }
1439 /*}}}*/
1440 void Element::GetVerticesConnectivityList(int* connectivity){/*{{{*/
1441 
1442  const int NUM_VERTICES = this->GetNumberOfVertices();
1443  for(int i=0;i<NUM_VERTICES;i++) connectivity[i]=this->vertices[i]->Connectivity();
1444 }
1445 /*}}}*/
1447 
1448  const int NUM_VERTICES = this->GetNumberOfVertices();
1449 
1450  IssmDouble* xyz_list = xNew<IssmDouble>(NUM_VERTICES*3);
1451  ::GetVerticesCoordinates(xyz_list,this->vertices,NUM_VERTICES);
1452 
1453  *pxyz_list = xyz_list;
1454 
1455 }/*}}}*/
1456 void Element::GetVerticesSidList(int* sidlist){/*{{{*/
1457 
1458  const int NUM_VERTICES = this->GetNumberOfVertices();
1459  for(int i=0;i<NUM_VERTICES;i++) sidlist[i]=this->vertices[i]->Sid();
1460 }
1461 /*}}}*/
1463 
1464  /*output*/
1465  IssmDouble x;
1466 
1467  /*Create list of x*/
1468  const int NUM_VERTICES = this->GetNumberOfVertices();
1469 
1470  IssmDouble* x_list = xNew<IssmDouble>(NUM_VERTICES);
1471 
1472  for(int i=0;i<NUM_VERTICES;i++) x_list[i]=xyz_list[i*3+0];
1473  ValueP1OnGauss(&x,x_list,gauss);
1474 
1475  xDelete<IssmDouble>(x_list);
1476  return x;
1477 }/*}}}*/
1479 
1480  /*output*/
1481  IssmDouble y;
1482 
1483  /*Create list of y*/
1484  const int NUM_VERTICES = this->GetNumberOfVertices();
1485 
1486  IssmDouble* y_list = xNew<IssmDouble>(NUM_VERTICES);
1487 
1488  for(int i=0;i<NUM_VERTICES;i++) y_list[i]=xyz_list[i*3+1];
1489  ValueP1OnGauss(&y,y_list,gauss);
1490 
1491  xDelete<IssmDouble>(y_list);
1492  return y;
1493 }/*}}}*/
1495 
1496  /*output*/
1497  IssmDouble z;
1498 
1499  /*Create list of z*/
1500  const int NUM_VERTICES = this->GetNumberOfVertices();
1501 
1502  IssmDouble* z_list = xNew<IssmDouble>(NUM_VERTICES);
1503 
1504  for(int i=0;i<NUM_VERTICES;i++) z_list[i]=xyz_list[i*3+2];
1505  ValueP1OnGauss(&z,z_list,gauss);
1506 
1507  xDelete<IssmDouble>(z_list);
1508  return z;
1509 }/*}}}*/
1510 void Element::GradientIndexing(int* indexing,int control_index){/*{{{*/
1511 
1512  /*Get number of controls*/
1513  int num_controls;
1514  bool isautodiff;
1517 
1518  /*Get number of vertices*/
1519  const int NUM_VERTICES = this->GetNumberOfVertices();
1520  if(isautodiff){
1521  int* N=NULL;
1522  int* M=NULL;
1523  int start = 0;
1526  if(control_index>0) {
1527  for(int n=0;n<control_index;n++){
1528  start+=N[n]*M[n];
1529  }
1530  }
1531 
1532  for(int n=0;n<N[control_index];n++){
1533  for(int i=0;i<NUM_VERTICES;i++){
1534  indexing[i+n*NUM_VERTICES]=this->vertices[i]->Sid() + start + n*M[control_index];
1535  }
1536  }
1537  }
1538  else{
1539  int M;
1541  /*get gradient indices*/
1542  for(int i=0;i<NUM_VERTICES;i++){
1543  indexing[i]=this->vertices[i]->Sid() + (control_index)*M;
1544  }
1545  }
1546 }
1547 /*}}}*/
1548 IssmDouble Element::GroundedArea(IssmDouble* mask, bool scaled){/*{{{*/
1549 
1550  /*Retrieve values of the mask defining the element: */
1551  for(int i=0;i<this->GetNumberOfVertices();i++){
1552  if(mask[this->vertices[i]->Sid()]<=0.){
1553  return 0.;
1554  }
1555  }
1556 
1557  /*Return: */
1558  return this->GroundedArea(scaled);
1559 }
1560 /*}}}*/
1562  Input2* input=this->GetInput2(MeshVertexonbaseEnum); _assert_(input);
1563  return (input->GetInputMax()>0.);
1564 }/*}}}*/
1566  Input2* input=this->GetInput2(MeshVertexonsurfaceEnum); _assert_(input);
1567  return (input->GetInputMax()>0.);
1568 }/*}}}*/
1569 IssmDouble Element::IceMass(bool scaled){/*{{{*/
1570 
1571  IssmDouble rho_ice;
1572 
1573  if(!IsIceInElement())return 0.; //do not contribute to the volume of the ice!
1574 
1575  /*recover ice density: */
1576  rho_ice=FindParam(MaterialsRhoIceEnum);
1577 
1578  return rho_ice*this->IceVolume(scaled);
1579 }
1580 /*}}}*/
1581 IssmDouble Element::IceMass(IssmDouble* mask, bool scaled){/*{{{*/
1582 
1583  /*Retrieve values of the mask defining the element: */
1584  for(int i=0;i<this->GetNumberOfVertices();i++){
1585  if(mask[this->vertices[i]->Sid()]<=0.){
1586  return 0.;
1587  }
1588  }
1589 
1590  /*Return: */
1591  return this->IceMass(scaled);
1592 }
1593 /*}}}*/
1594 IssmDouble Element::IceVolume(IssmDouble* mask, bool scaled){/*{{{*/
1595 
1596  /*Retrieve values of the mask defining the element: */
1597  for(int i=0;i<this->GetNumberOfVertices();i++){
1598  if(mask[this->vertices[i]->Sid()]<=0.){
1599  return 0.;
1600  }
1601  }
1602 
1603  /*Return: */
1604  return this->IceVolume(scaled);
1605 }
1606 /*}}}*/
1608 
1609  /*Retrieve values of the mask defining the element: */
1610  for(int i=0;i<this->GetNumberOfVertices();i++){
1611  if(mask[this->vertices[i]->Sid()]<=0.){
1612  return 0.;
1613  }
1614  }
1615 
1616  /*Return: */
1617  return this->IceVolumeAboveFloatation(scaled);
1618 }
1619 /*}}}*/
1620 int Element::Id(){/*{{{*/
1621 
1622  return this->id;
1623 
1624 }
1625 /*}}}*/
1626 void Element::InputCreate(IssmDouble* vector,Inputs2* inputs2,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){/*{{{*/
1627 
1628  /*Intermediaries*/
1629  int i,t;
1630 
1631  /*Branch on type of vector: nodal or elementary: */
1632  if(vector_type==1){ //nodal vector
1633 
1634  const int NUM_VERTICES = this->GetNumberOfVertices();
1635 
1636  int *vertexids = xNew<int>(NUM_VERTICES);
1637  int *vertexlids = xNew<int>(NUM_VERTICES);
1638  IssmDouble *values = xNew<IssmDouble>(NUM_VERTICES);
1639 
1640  /*Recover vertices ids needed to initialize inputs*/
1641  _assert_(iomodel->elements);
1642  for(i=0;i<NUM_VERTICES;i++){
1643  vertexids[i] =reCast<int>(iomodel->elements[NUM_VERTICES*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
1644  vertexlids[i]=iomodel->my_vertices_lids[vertexids[i]-1];
1645  }
1646 
1647  /*Are we in transient or static? */
1648  if(M==1){
1649  values[0]=vector[0];
1650  this->SetElementInput(inputs2,vector_enum,vector[0]);
1651  }
1652  else if(M==iomodel->numberofvertices){
1653  for(i=0;i<NUM_VERTICES;i++) values[i]=vector[vertexids[i]-1];
1654  this->SetElementInput(inputs2,NUM_VERTICES,vertexlids,values,vector_enum);
1655  }
1656  else if(M==iomodel->numberofvertices+1){
1657  /*create transient input: */
1658  IssmDouble* times = xNew<IssmDouble>(N);
1659  for(t=0;t<N;t++) times[t] = vector[(M-1)*N+t];
1660  inputs2->SetTransientInput(vector_enum,times,N);
1661  TransientInput2* transientinput = inputs2->GetTransientInput(vector_enum);
1662  for(t=0;t<N;t++){
1663  for(i=0;i<NUM_VERTICES;i++) values[i]=vector[N*(vertexids[i]-1)+t];
1664  switch(this->ObjectEnum()){
1665  case TriaEnum: transientinput->AddTriaTimeInput( t,NUM_VERTICES,vertexlids,values,P1Enum); break;
1666  case PentaEnum: transientinput->AddPentaTimeInput(t,NUM_VERTICES,vertexlids,values,P1Enum); break;
1667  default: _error_("Not implemented yet");
1668  }
1669  }
1670  xDelete<IssmDouble>(times);
1671  }
1672  else if(M==iomodel->numberofelements){
1673 
1674  /*This is a Patch!*/
1675  xDelete<IssmDouble>(values);
1676  values = xNew<IssmDouble>(N);
1677  for(int j=0;j<N;j++) values[j]=vector[this->Sid()*N+j];
1678 
1679  if (N==this->GetNumberOfNodes(P1Enum)){
1680  this->SetElementInput(inputs2,NUM_VERTICES,vertexlids,values,vector_enum);
1681  }
1682  else if(N==this->GetNumberOfNodes(P0Enum)){
1683  this->SetElementInput(inputs2,vector_enum,values[0]);
1684  }
1685  else if(N==this->GetNumberOfNodes(P1xP2Enum)){ _assert_(this->ObjectEnum()==PentaEnum);
1686  inputs2->SetPentaInput(vector_enum,P1xP2Enum,this->lid,N,values);
1687  }
1688  else if(N==this->GetNumberOfNodes(P1xP3Enum)){ _assert_(this->ObjectEnum()==PentaEnum);
1689  inputs2->SetPentaInput(vector_enum,P1xP3Enum,this->lid,N,values);
1690  }
1691  else{
1692  _error_("Patch interpolation not supported yet");
1693  }
1694 
1695  }
1696  else{
1697  _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
1698  }
1699 
1700  xDelete<IssmDouble>(values);
1701  xDelete<int>(vertexids);
1702  xDelete<int>(vertexlids);
1703  }
1704  else if(vector_type==2){ //element vector
1705 
1706  IssmDouble value;
1707 
1708  /*Are we in transient or static? */
1709  if(M==iomodel->numberofelements){
1710  if (code==5){ //boolean
1711  this->SetBoolInput(inputs2,vector_enum,reCast<bool>(vector[this->Sid()]));
1712  }
1713  else if (code==6){ //integer
1714  this->SetIntInput(inputs2,vector_enum,reCast<int>(vector[this->Sid()]));
1715  }
1716  else if (code==7){ //IssmDouble
1717  this->SetElementInput(inputs2,vector_enum,vector[this->Sid()]);
1718  }
1719  else _error_("could not recognize nature of vector from code " << code);
1720  }
1721  else if(M==iomodel->numberofelements+1){
1722  /*create transient input: */
1723  IssmDouble* times = xNew<IssmDouble>(N);
1724  for(t=0;t<N;t++) times[t] = vector[(M-1)*N+t];
1725  inputs2->SetTransientInput(vector_enum,times,N);
1726  TransientInput2* transientinput = inputs2->GetTransientInput(vector_enum);
1727  for(t=0;t<N;t++){
1728  value=vector[N*this->Sid()+t];
1729  switch(this->ObjectEnum()){
1730  case TriaEnum: transientinput->AddTriaTimeInput( t,1,&(this->lid),&value,P0Enum); break;
1731  case PentaEnum: transientinput->AddPentaTimeInput(t,1,&(this->lid),&value,P0Enum); break;
1732  default: _error_("Not implemented yet");
1733  }
1734  }
1735  xDelete<IssmDouble>(times);
1736  }
1737  else _error_("element vector is either numberofelements or numberofelements+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
1738  }
1739  else if(vector_type==3){ //Double array matrix
1740 
1741  /*For right now we are static */
1742  if(M==iomodel->numberofelements){
1743  IssmDouble* layers = xNewZeroInit<IssmDouble>(N);
1744  for(t=0;t<N;t++) layers[t] = vector[N*this->Sid()+t];
1745  inputs2->SetArrayInput(vector_enum,this->lid,layers,N);
1746  xDelete<IssmDouble>(layers);
1747  }
1748  else _error_("element vector is either numberofelements or numberofelements+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
1749  }
1750  else _error_("Cannot add input for vector type " << vector_type << " (not supported)");
1751 }
1752 /*}}}*/
1753 void Element::ControlInputCreate(IssmDouble* vector,IssmDouble* min_vector,IssmDouble* max_vector,Inputs2* inputs2,IoModel* iomodel,int M,int N,IssmDouble scale,int input_enum,int id){/*{{{*/
1754 
1755  /*Intermediaries*/
1756  const int numvertices = this->GetNumberOfVertices();
1757 
1758  int *vertexids = xNew<int>(numvertices);
1759  IssmDouble *values = xNew<IssmDouble>(numvertices);
1760  IssmDouble *values_min = xNew<IssmDouble>(numvertices);
1761  IssmDouble *values_max = xNew<IssmDouble>(numvertices);
1762 
1763  /*Some sanity checks*/
1764  _assert_(vector);
1765  _assert_(min_vector);
1766  _assert_(max_vector);
1767 
1768  /*Recover vertices ids needed to initialize inputs*/
1769  _assert_(iomodel->elements);
1770  for(int i=0;i<numvertices;i++){
1771  vertexids[i]=reCast<int>(iomodel->elements[numvertices*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
1772  }
1773 
1774  /*Are we in transient or static? */
1775  if(M==iomodel->numberofvertices && N==1){
1776  for(int i=0;i<numvertices;i++){
1777  values[i] = vector[vertexids[i]-1];
1778  values_min[i] = scale*min_vector[vertexids[i]-1];
1779  values_max[i] = scale*max_vector[vertexids[i]-1];
1780  }
1781  this->AddControlInput(input_enum,inputs2,iomodel,values,values_min,values_max,P1Enum,id);
1782  }
1783 
1784  else if(M==iomodel->numberofvertices+1 && N>1){
1785  _error_("not supported tet");
1787  //IssmDouble* times = xNew<IssmDouble>(N);
1788  //for(int t=0;t<N;t++) times[t] = vector[(M-1)*N+t];
1790  //TransientInput* values_input=new TransientInput(input_enum,times,N);
1791  //TransientInput* mins_input = new TransientInput(ControlInputMinsEnum,times,N);
1792  //TransientInput* maxs_input = new TransientInput(ControlInputMaxsEnum,times,N);
1793  //TransientInput* grad_input = new TransientInput(ControlInputGradEnum);
1794  //for(int t=0;t<N;t++){
1795  // for(int i=0;i<numvertices;i++){
1796  // values[i]=vector[N*(vertexids[i]-1)+t];
1797  // values_min[i] = min_vector[N*(vertexids[i]-1)+t];
1798  // values_max[i] = max_vector[N*(vertexids[i]-1)+t];
1799  // }
1800  // switch(this->ObjectEnum()){
1801  // case TriaEnum:
1802  // values_input->AddTimeInput(new TriaInput(input_enum,values,P1Enum));
1803  // mins_input->AddTimeInput(new TriaInput(ControlInputMinsEnum,values_min,P1Enum));
1804  // maxs_input->AddTimeInput(new TriaInput(ControlInputMaxsEnum,values_max,P1Enum));
1805  // break;
1806  // case PentaEnum:
1807  // values_input->AddTimeInput(new PentaInput(input_enum,values,P1Enum));
1808  // mins_input->AddTimeInput(new PentaInput(ControlInputMinsEnum,values_min,P1Enum));
1809  // maxs_input->AddTimeInput(new PentaInput(ControlInputMaxsEnum,values_max,P1Enum));
1810  // break;
1811  // case TetraEnum:
1812  // values_input->AddTimeInput(new TetraInput(input_enum,values,P1Enum));
1813  // mins_input->AddTimeInput(new TetraInput(ControlInputMinsEnum,values_min,P1Enum));
1814  // maxs_input->AddTimeInput(new TetraInput(ControlInputMaxsEnum,values_max,P1Enum));
1815  // break;
1816  // default: _error_("Not implemented yet");
1817  // }
1818  //}
1819  //this->inputs->AddInput(new ControlInput(input_enum,TransientInputEnum,values_input,mins_input,maxs_input,grad_input,P1Enum,id));
1820  //xDelete<IssmDouble>(times);
1821  }
1822  else _error_("not currently supported type of M and N attempted");
1823 
1824  /*clean up*/
1825  xDelete<IssmDouble>(values);
1826  xDelete<IssmDouble>(values_min);
1827  xDelete<IssmDouble>(values_max);
1828  xDelete<int>(vertexids);
1829 }
1830 /*}}}*/
1831 void Element::DatasetInputAdd(int enum_type,IssmDouble* vector,Inputs2* inputs2,IoModel* iomodel,int M,int N,int vector_type,int input_enum,int code,int input_id){/*{{{*/
1832  /*enum_type: the name of the DatasetInput (eg Outputdefinition1)
1833  * vector: information being stored (eg observations)
1834  * vector_type: is if by element or by vertex
1835  * input_enum: is the name of the vector being stored
1836  * code: what type of data is in the vector (booleans, ints, doubles)
1837  */
1838 
1839  /*Intermediaries*/
1840  int i,t;
1841 
1842  /*Branch on type of vector: nodal or elementary: */
1843  if(vector_type==1){ //nodal vector
1844 
1845  const int NUM_VERTICES = this->GetNumberOfVertices();
1846 
1847  int *vertexids = xNew<int>(NUM_VERTICES);
1848  int *vertexlids = xNew<int>(NUM_VERTICES);
1849  IssmDouble *values = xNew<IssmDouble>(NUM_VERTICES);
1850 
1851  /*Recover vertices ids needed to initialize inputs*/
1852  _assert_(iomodel->elements);
1853  for(i=0;i<NUM_VERTICES;i++){
1854  vertexids[i] =reCast<int>(iomodel->elements[NUM_VERTICES*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
1855  vertexlids[i]=iomodel->my_vertices_lids[vertexids[i]-1];
1856  }
1857 
1858  /*Are we in transient or static? */
1859  if(M==1){
1860  values[0]=vector[0];
1861  //this->AddInput2(vector_enum,values,P0Enum);
1862  _error_("not implemented yet");
1863  }
1864  else if(M==iomodel->numberofvertices){
1865  for(i=0;i<NUM_VERTICES;i++) values[i]=vector[vertexids[i]-1];
1866  switch(this->ObjectEnum()){
1867  case TriaEnum: inputs2->SetTriaDatasetInput(enum_type,input_id,P1Enum,NUM_VERTICES,vertexlids,values); break;
1868  case PentaEnum: inputs2->SetPentaDatasetInput(enum_type,input_id,P1Enum,NUM_VERTICES,vertexlids,values); break;
1869  default: _error_("Not implemented yet for "<<this->ObjectEnum());
1870  }
1871  }
1872  else if(M==iomodel->numberofvertices+1){
1873  /*create transient input: */
1874  IssmDouble* times = xNew<IssmDouble>(N);
1875  for(t=0;t<N;t++) times[t] = vector[(M-1)*N+t];
1876  TransientInput2* transientinput = inputs2->SetDatasetTransientInput(enum_type,input_id,times,N);
1877  for(t=0;t<N;t++){
1878  for(i=0;i<NUM_VERTICES;i++) values[i]=vector[N*(vertexids[i]-1)+t];
1879  switch(this->ObjectEnum()){
1880  case TriaEnum: transientinput->AddTriaTimeInput( t,NUM_VERTICES,vertexlids,values,P1Enum); break;
1881  case PentaEnum: transientinput->AddPentaTimeInput(t,NUM_VERTICES,vertexlids,values,P1Enum); break;
1882  default: _error_("Not implemented yet");
1883  }
1884  }
1885  xDelete<IssmDouble>(times);
1886  }
1887  else{
1888  _error_("not implemented yet (M="<<M<<")");
1889  }
1890 
1891  xDelete<IssmDouble>(values);
1892  xDelete<int>(vertexids);
1893  xDelete<int>(vertexlids);
1894  }
1895  else if(vector_type==2){ //element vector
1896  _error_("not supported");
1897 
1898  IssmDouble value;
1899 
1900  /*Are we in transient or static? */
1901  if(M==iomodel->numberofelements){
1902  if (code==5){ //boolean
1903  _error_("not implemented");
1904  //datasetinput->AddInput(new BoolInput(input_enum,reCast<bool>(vector[this->Sid()])),input_id);
1905  }
1906  else if (code==6){ //integer
1907  _error_("not implemented");
1908  //datasetinput->AddInput(new IntInput(input_enum,reCast<int>(vector[this->Sid()])),input_id);
1909  }
1910  else if (code==7){ //IssmDouble
1911  _error_("not implemented");
1912  //datasetinput->AddInput(new DoubleInput(input_enum,vector[this->Sid()]),input_id);
1913  }
1914  else _error_("could not recognize nature of vector from code " << code);
1915  }
1916  else if(M==iomodel->numberofelements+1){
1917  _error_("not supported");
1919  //IssmDouble* times = xNew<IssmDouble>(N);
1920  //for(t=0;t<N;t++) times[t] = vector[(M-1)*N+t];
1921  //TransientInput* transientinput=new TransientInput(input_enum,times,N);
1922  //TriaInput* bof=NULL;
1923  //for(t=0;t<N;t++){
1924  // value=vector[N*this->Sid()+t];
1925  // switch(this->ObjectEnum()){
1926  // case TriaEnum: transientinput->AddTimeInput(new TriaInput( input_enum,&value,P0Enum)); break;
1927  // case PentaEnum: transientinput->AddTimeInput(new PentaInput(input_enum,&value,P0Enum)); break;
1928  // case TetraEnum: transientinput->AddTimeInput(new TetraInput(input_enum,&value,P0Enum)); break;
1929  // default: _error_("Not implemented yet");
1930  // }
1931  //}
1932  //xDelete<IssmDouble>(times);
1933  }
1934  else _error_("element vector is either numberofelements or numberofelements+1 long. Field provided (" << EnumToStringx(input_enum) << ") is " << M << " long");
1935  }
1936  else if(vector_type==3){ //element vector
1937  _error_("not supported");
1938 
1940  //if(M==iomodel->numberofelements){
1941  // /*create transient input: */
1942  // IssmDouble* layers = xNewZeroInit<IssmDouble>(N);;
1943  // for(t=0;t<N;t++) layers[t] = vector[N*this->Sid()+t];
1944  // DoubleArrayInput* arrayinput=new DoubleArrayInput(input_enum,layers,N);
1945  // xDelete<IssmDouble>(layers);
1946  //}
1947  //else _error_("element vector is either numberofelements or numberofelements+1 long. Field provided (" << EnumToStringx(input_enum) << ") is " << M << " long");
1948  }
1949  else{
1950  _error_("Cannot add input for vector type " << vector_type << " (not supported)");
1951  }
1952 }
1953 /*}}}*/
1954 void Element::InputUpdateFromConstant(int constant, int name){/*{{{*/
1955 
1956  /*Check that name is an element input*/
1957  if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
1958 
1959  /*update input*/
1960  this->SetIntInput(this->inputs2,name,constant);
1961 }
1962 /*}}}*/
1963 void Element::InputUpdateFromConstant(IssmDouble constant, int name){/*{{{*/
1964 
1965  /*Check that name is an element input*/
1966  if(!IsInputEnum(name)) return;
1967 
1968  /*update input*/
1969  this->SetElementInput(name,constant);
1970 }
1971 /*}}}*/
1972 void Element::InputUpdateFromConstant(bool constant, int name){/*{{{*/
1973 
1974  /*Check that name is an element input*/
1975  if(!IsInputEnum(name)) return;
1976 
1977  /*update input*/
1978  this->SetBoolInput(this->inputs2,name,constant);
1979 }
1980 /*}}}*/
1981 bool Element::IsOnSurface(){/*{{{*/
1982  return this->isonsurface;
1983 }/*}}}*/
1984 bool Element::IsOnBase(){/*{{{*/
1985  return this->isonbase;
1986 }/*}}}*/
1987 bool Element::IsFloating(){/*{{{*/
1988 
1989  bool shelf;
1990  int migration_style;
1991  parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
1992 
1993  Input2* input = this->GetInput2(MaskOceanLevelsetEnum); _assert_(input);
1994 
1995  if(migration_style==SubelementMigrationEnum){ //Floating if all nodes are floating
1996  if(input->GetInputMax() <= 0.) shelf=true;
1997  else shelf=false;
1998  }
1999  else if(migration_style==ContactEnum){
2000  if(input->GetInputMin() < 0.) shelf=true;
2001  else shelf=false;
2002  }
2003  else if(migration_style==NoneEnum || migration_style==AggressiveMigrationEnum || migration_style==SoftMigrationEnum || migration_style==GroundingOnlyEnum){ //Floating if all nodes are floating
2004  if(input->GetInputMin() > 0.) shelf=false;
2005  else shelf=true;
2006  }
2007  else _error_("migration_style not implemented yet");
2008 
2009  return shelf;
2010 }/*}}}*/
2011 bool Element::IsGrounded(){/*{{{*/
2012 
2013  Input2* input=this->GetInput2(MaskOceanLevelsetEnum); _assert_(input);
2014  if(input->GetInputMax() > 0.){
2015  return true;
2016  }
2017  else{
2018  return false;
2019  }
2020 }/*}}}*/
2022  Input2* input=this->GetInput2(MaskIceLevelsetEnum); _assert_(input);
2023  return (input->GetInputMin()<0.);
2024 }
2025 /*}}}*/
2027  Input2* input=this->GetInput2(MaskIceLevelsetEnum); _assert_(input);
2028  return (input->GetInputMax()<0.);
2029 }
2030 /*}}}*/
2032  Input2* input=this->GetInput2(MaskOceanLevelsetEnum); _assert_(input);
2033  return (input->GetInputMax()>0.);
2034 }
2035 /*}}}*/
2037  Input2* input=this->GetInput2(MaskOceanLevelsetEnum); _assert_(input);
2038  return (input->GetInputMin()<0.);
2039 }
2040 /*}}}*/
2042 
2043  if(!this->IsIceInElement() || !this->IsFloating() || !this->IsOnBase()) return;
2044 
2045  int basinid,num_basins,M,N;
2046  IssmDouble tf,gamma0,base,delta_t_basin,mean_tf_basin,absval,meltanomaly;
2047  bool islocal;
2048  IssmDouble* delta_t = NULL;
2049  IssmDouble* mean_tf = NULL;
2050  IssmDouble* depths = NULL;
2051 
2052  /*Allocate some arrays*/
2053  const int numvertices = this->GetNumberOfVertices();
2054  IssmDouble* basalmeltrate = xNew<IssmDouble>(numvertices);
2055 
2056  /*Get variables*/
2061 
2062  /*Hard code sea water density to be consistent with ISMIP6 documentation*/
2063  rhow = 1028.;
2064 
2065  /* Get parameters and inputs */
2069  this->parameters->FindParam(&delta_t,&M,BasalforcingsIsmip6DeltaTEnum); _assert_(M==num_basins);
2071  if(!islocal) {
2072  this->parameters->FindParam(&mean_tf,&N,BasalforcingsIsmip6AverageTfEnum); _assert_(N==num_basins);
2073  }
2074  Input2* tf_input = this->GetInput2(BasalforcingsIsmip6TfShelfEnum); _assert_(tf_input);
2075  Input2* meltanomaly_input = this->GetInput2(BasalforcingsIsmip6MeltAnomalyEnum); _assert_(meltanomaly_input);
2076  delta_t_basin = delta_t[basinid];
2077  if(!islocal) mean_tf_basin = mean_tf[basinid];
2078 
2079  /*Compute melt rate for Local and Nonlocal parameterizations*/
2080  Gauss* gauss=this->NewGauss();
2081  for(int i=0;i<numvertices;i++){
2082  gauss->GaussVertex(i);
2083  tf_input->GetInputValue(&tf,gauss);
2084  meltanomaly_input->GetInputValue(&meltanomaly,gauss);
2085  if(!islocal) {
2086  absval = mean_tf_basin+delta_t_basin;
2087  if (absval<0) {absval = -1.*absval;}
2088  basalmeltrate[i] = gamma0*pow((rhow*cp)/(rhoi*lf),2)*(tf+delta_t_basin)*absval + meltanomaly;
2089  }
2090  else{
2091  basalmeltrate[i] = gamma0*pow((rhow*cp)/(rhoi*lf),2)*pow(max(tf+delta_t_basin,0.),2) + meltanomaly;
2092  }
2093  }
2094 
2095  /*Return basal melt rate*/
2097 
2098  /*Cleanup and return*/
2099  delete gauss;
2100  xDelete<IssmDouble>(delta_t);
2101  xDelete<IssmDouble>(mean_tf);
2102  xDelete<IssmDouble>(depths);
2103  xDelete<IssmDouble>(basalmeltrate);
2104 
2105 }/*}}}*/
2107 
2108  const int NUM_VERTICES = this->GetNumberOfVertices();
2109 
2110  IssmDouble deepwaterel,upperwaterel,deepwatermelt,upperwatermelt;
2111  IssmDouble *base = xNew<IssmDouble>(NUM_VERTICES);
2112  IssmDouble *values = xNew<IssmDouble>(NUM_VERTICES);
2113  IssmDouble *perturbation = xNew<IssmDouble>(NUM_VERTICES);
2114  IssmDouble time;
2115 
2116  parameters->FindParam(&time,TimeEnum);
2121  _assert_(upperwaterel>deepwaterel);
2122 
2123  this->GetInputListOnVertices(base,BaseEnum);
2125  for(int i=0;i<NUM_VERTICES;i++){
2126  if(base[i]>=upperwaterel){
2127  values[i]=upperwatermelt;
2128  }
2129  else if (base[i]<deepwaterel){
2130  values[i]=deepwatermelt;
2131  }
2132  else{
2133  IssmDouble alpha = (base[i]-upperwaterel)/(deepwaterel-upperwaterel);
2134  values[i]=deepwatermelt*alpha+(1.-alpha)*upperwatermelt;
2135  }
2136 
2137  values[i]+=perturbation[i];
2138  }
2139 
2141  xDelete<IssmDouble>(base);
2142  xDelete<IssmDouble>(perturbation);
2143  xDelete<IssmDouble>(values);
2144 
2145 }/*}}}*/
2147 
2148  const int NUM_VERTICES = this->GetNumberOfVertices();
2149 
2150  IssmDouble *deepwatermelt = xNew<IssmDouble>(NUM_VERTICES);
2151  IssmDouble *deepwaterel = xNew<IssmDouble>(NUM_VERTICES);
2152  IssmDouble *upperwaterel = xNew<IssmDouble>(NUM_VERTICES);
2153  IssmDouble *base = xNew<IssmDouble>(NUM_VERTICES);
2154  IssmDouble *values = xNew<IssmDouble>(NUM_VERTICES);
2155 
2156  this->GetInputListOnVertices(base,BaseEnum);
2160 
2161  for(int i=0;i<NUM_VERTICES;i++){
2162  if(base[i]>upperwaterel[i]) values[i]=0;
2163  else if (base[i]<deepwaterel[i]) values[i]=deepwatermelt[i];
2164  else values[i]=deepwatermelt[i]*(base[i]-upperwaterel[i])/(deepwaterel[i]-upperwaterel[i]);
2165  }
2166 
2168  xDelete<IssmDouble>(base);
2169  xDelete<IssmDouble>(deepwaterel);
2170  xDelete<IssmDouble>(deepwatermelt);
2171  xDelete<IssmDouble>(upperwaterel);
2172  xDelete<IssmDouble>(values);
2173 
2174 }/*}}}*/
2176 
2177  const int NUM_VERTICES = this->GetNumberOfVertices();
2178  IssmDouble mantleconductivity,nusselt,dtbg,plumeradius,topplumedepth,bottomplumedepth,plumex,plumey;
2179  IssmDouble crustthickness,uppercrustthickness,uppercrustheat,lowercrustheat;
2180  IssmDouble crustheat,plumeheat,dt,middleplumedepth,a,e,eprime,A0,lambda,Alambda,dAlambda;
2181  IssmDouble x,y,z,c;
2182  IssmDouble* values = xNew<IssmDouble>(NUM_VERTICES);
2183  IssmDouble *xyz_list = NULL;
2184 
2197 
2198  this->GetVerticesCoordinates(&xyz_list);
2199  c=plumeradius;
2200  a=(bottomplumedepth-topplumedepth)/2.;
2201  e=pow(a*a-c*c,1./2.)/a;
2202  A0=(1-pow(e,2.))/pow(e,3.)*(1./2.*log((1+e)/(1-e))-e);
2203  for(int i=0;i<NUM_VERTICES;i++){
2204  y=xyz_list[i*3+0]-plumex;
2205  z=xyz_list[i*3+1]-plumey;
2206  x=-(a+topplumedepth+crustthickness);
2207  lambda=(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2)))))/2;
2208  dAlambda=(-8*a*pow(c,2)*x*(-2*pow(a,2)+2*pow(c,2)+sqrt(2)*sqrt((a-c)*(a+c))*sqrt(pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2))))))*(pow(a,4)*(pow(y,2)+pow(z,2))+pow(c,4)*(pow(y,2)+pow(z,2))+pow(pow(x,2)+pow(y,2)+pow(z,2),2)*(pow(x,2)+pow(y,2)+pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2)))))+pow(c,2)*(pow(x,4)-pow(x,2)*(pow(y,2)+pow(z,2))-(pow(y,2)+pow(z,2))*(2*pow(y,2)+2*pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2))))))+pow(a,2)*(-pow(x,4)+pow(x,2)*(pow(y,2)+pow(z,2))+(pow(y,2)+pow(z,2))*(-2*pow(c,2)+2*(pow(y,2)+pow(z,2))+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2))))))))/(sqrt((a-c)*(a+c))*sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2))))*pow(pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2)))),3.5)*pow(-(sqrt(2)*sqrt((a-c)*(a+c)))+sqrt(pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2))))),2)*(sqrt(2)*sqrt((a-c)*(a+c))+sqrt(pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2)+sqrt(pow(-pow(a,2)-pow(c,2)+pow(x,2)+pow(y,2)+pow(z,2),2)+4*(pow(c,2)*pow(x,2)+pow(a,2)*(-pow(c,2)+pow(y,2)+pow(z,2)))))));
2209  eprime=pow((a*a-plumeradius*plumeradius)/(a*a+lambda),1./2.);
2210  Alambda=(1.-e*e)/(e*e*e)*(1./2.*log((1.+eprime)/(1.-eprime))-eprime);
2211  dt=dtbg-(nusselt-1.)/(1.+A0*(nusselt-1.))*(Alambda*dtbg+x*dtbg*dAlambda);
2212  plumeheat=mantleconductivity*dt;
2213  crustheat=uppercrustheat*uppercrustthickness+lowercrustheat*(crustthickness-uppercrustthickness);
2214  values[i]=crustheat+plumeheat;
2215  }
2216 
2218  xDelete<IssmDouble>(xyz_list);
2219  xDelete<IssmDouble>(values);
2220 
2221 }/*}}}*/
2222 void Element::MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses){/*{{{*/
2223 
2224  _assert_(this);
2225  if(marshall_direction==MARSHALLING_BACKWARD){
2226  nodes = NULL;
2227  }
2228 
2230 
2231  MARSHALLING(id);
2232  MARSHALLING(sid);
2233  MARSHALLING(lid);
2235  MARSHALLING_DYNAMIC(element_type_list,int,numanalyses);
2236 }
2237 /*}}}*/
2238 void Element::MigrateGroundingLine(IssmDouble* phi_ungrounding){/*{{{*/
2239 
2240  const int NUM_VERTICES = this->GetNumberOfVertices();
2241  int i,migration_style;
2242  IssmDouble bed_hydro,yts;
2243  IssmDouble rho_water,rho_ice,density;
2244  IssmDouble* melting = xNew<IssmDouble>(NUM_VERTICES);
2245  IssmDouble* phi = xNew<IssmDouble>(NUM_VERTICES);
2246  IssmDouble* h = xNew<IssmDouble>(NUM_VERTICES);
2247  IssmDouble* s = xNew<IssmDouble>(NUM_VERTICES);
2248  IssmDouble* b = xNew<IssmDouble>(NUM_VERTICES);
2249  IssmDouble* r = xNew<IssmDouble>(NUM_VERTICES);
2250  IssmDouble* sl = xNew<IssmDouble>(NUM_VERTICES);
2251 
2252  /*Recover info at the vertices: */
2253  parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
2261  rho_water = FindParam(MaterialsRhoSeawaterEnum);
2262  rho_ice = FindParam(MaterialsRhoIceEnum);
2263  density = rho_ice/rho_water;
2264 
2265  /*go through vertices, and update inputs, considering them to be TriaVertex type: */
2266  for(i=0;i<NUM_VERTICES;i++){
2267  /* Contact FS*/
2268  if(migration_style == ContactEnum){
2269  phi[i]=phi_ungrounding[vertices[i]->Pid()];
2270  if(phi[i]>=0.) b[i]=r[i];
2271  }
2272  else if(migration_style == GroundingOnlyEnum && b[i]<r[i]) b[i]=r[i];
2273  /*Ice shelf: if bed below bathymetry, impose it at the bathymetry and update surface, elso do nothing */
2274  else if(phi[i]<=0.){
2275  if(b[i]<=r[i]){
2276  b[i] = r[i];
2277  s[i] = b[i]+h[i];
2278  }
2279  }
2280  /*Ice sheet: if hydrostatic bed above bathymetry, ice sheet starts to unground, elso do nothing */
2281  /*Change only if AggressiveMigration or if the ice sheet is in contact with the ocean*/
2282  else{ // phi>0
2283  bed_hydro=-density*h[i]+sl[i];
2284  if (bed_hydro>r[i]){
2285  /*Unground only if the element is connected to the ice shelf*/
2286  if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum){
2287  s[i] = (1-density)*h[i]+sl[i];
2288  b[i] = -density*h[i]+sl[i];
2289  }
2290  else if(migration_style==SoftMigrationEnum && phi_ungrounding[vertices[i]->Pid()]<0.){
2291  s[i] = (1-density)*h[i]+sl[i];
2292  b[i] = -density*h[i]+sl[i];
2293  }
2294  else{
2295  if(migration_style!=SoftMigrationEnum && migration_style!=ContactEnum && migration_style!=GroundingOnlyEnum) _error_("Error: migration should be Aggressive, Soft, Subelement, Contact or GroundingOnly");
2296  }
2297  }
2298  }
2299  }
2300 
2301  /*Recalculate phi*/
2302  for(i=0;i<NUM_VERTICES;i++){
2303  if(migration_style==SoftMigrationEnum){
2304  bed_hydro=-density*h[i]+sl[i];
2305  if(phi[i]<0. || bed_hydro<=r[i] || phi_ungrounding[vertices[i]->Pid()]<0.){
2306  phi[i]=h[i]+(r[i]-sl[i])/density;
2307  }
2308  }
2309  else if(migration_style!=ContactEnum) phi[i]=h[i]+(r[i]-sl[i])/density;
2310  else{
2311  /*do nothing*/
2312  }
2313  }
2314  this->AddInput2(MaskOceanLevelsetEnum,&phi[0],P1Enum);
2315 
2316  /*Update inputs*/
2317  this->AddInput2(SurfaceEnum,&s[0],P1Enum);
2318  this->AddInput2(BaseEnum,&b[0],P1Enum);
2319 
2320  /*Delete*/
2321  xDelete<IssmDouble>(melting);
2322  xDelete<IssmDouble>(phi);
2323  xDelete<IssmDouble>(r);
2324  xDelete<IssmDouble>(b);
2325  xDelete<IssmDouble>(s);
2326  xDelete<IssmDouble>(sl);
2327  xDelete<IssmDouble>(h);
2328 
2329 }
2330 /*}}}*/
2332  const int NUM_VERTICES = this->GetNumberOfVertices();
2333 
2334  IssmDouble meltratefactor,thresholdthickness,upperdepthmelt;
2335  IssmDouble* base = xNew<IssmDouble>(NUM_VERTICES);
2336  IssmDouble* bed = xNew<IssmDouble>(NUM_VERTICES);
2337  IssmDouble* values = xNew<IssmDouble>(NUM_VERTICES);
2338 
2342 
2343  this->GetInputListOnVertices(base,BaseEnum);
2344  this->GetInputListOnVertices(bed,BedEnum);
2345  for(int i=0;i<NUM_VERTICES;i++){
2346  if(base[i]>upperdepthmelt){
2347  values[i]=0;
2348  }
2349  else{
2350  values[i]=meltratefactor*tanh((base[i]-bed[i])/thresholdthickness)*(upperdepthmelt-base[i]);
2351  }
2352  }
2353 
2355  xDelete<IssmDouble>(base);
2356  xDelete<IssmDouble>(bed);
2357  xDelete<IssmDouble>(values);
2358 
2359 }/*}}}*/
2361 
2362  int numvertices = this->GetNumberOfVertices();
2363  IssmDouble meltratefactor,T_f,ocean_heat_flux;
2364  IssmDouble rho_water = this->FindParam(MaterialsRhoSeawaterEnum);
2365  IssmDouble rho_ice = this->FindParam(MaterialsRhoIceEnum);
2366  IssmDouble latentheat = this->FindParam(MaterialsLatentheatEnum);
2367  IssmDouble mixed_layer_capacity = this->FindParam(MaterialsMixedLayerCapacityEnum);
2368  IssmDouble thermal_exchange_vel = this->FindParam(MaterialsThermalExchangeVelocityEnum);
2369 
2370  IssmDouble* base = xNew<IssmDouble>(numvertices);
2371  IssmDouble* values = xNew<IssmDouble>(numvertices);
2372  IssmDouble* oceansalinity = xNew<IssmDouble>(numvertices);
2373  IssmDouble* oceantemp = xNew<IssmDouble>(numvertices);
2374 
2375  this->GetInputListOnVertices(base,BaseEnum);
2379 
2380  Gauss* gauss=this->NewGauss();
2381  for(int i=0;i<numvertices;i++){
2382  T_f=(0.0939 - 0.057 * oceansalinity[i] + 7.64e-4 * base[i]); //degC
2383 
2384  // compute ocean_heat_flux according to beckmann_goosse2003
2385  // positive, if T_oc > T_ice ==> heat flux FROM ocean TO ice
2386  ocean_heat_flux = meltratefactor * rho_water * mixed_layer_capacity * thermal_exchange_vel * (oceantemp[i] - T_f); // in W/m^2
2387 
2388  // shelfbmassflux is positive if ice is freezing on; here it is always negative:
2389  // same sign as ocean_heat_flux (positive if massflux FROM ice TO ocean)
2390  values[i] = ocean_heat_flux / (latentheat * rho_ice); // m s-1
2391  }
2392 
2394  xDelete<IssmDouble>(base);
2395  xDelete<IssmDouble>(values);
2396  xDelete<IssmDouble>(oceantemp);
2397  xDelete<IssmDouble>(oceansalinity);
2398  delete gauss;
2399 }/*}}}*/
2401  /*Are we on the base? If not, return*/
2402  if(!IsOnBase()) return;
2403 
2404  const int NUM_VERTICES = this->GetNumberOfVertices();
2405  const int NUM_VERTICES_MONTHS_PER_YEAR = NUM_VERTICES * 12;
2406 
2407  int i;
2408  int* vertexlids=xNew<int>(NUM_VERTICES);
2409  IssmDouble* monthlytemperatures=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2410  IssmDouble* monthlyprec=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2411  IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2412  IssmDouble* TemperaturesLgm=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2413  IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2414  IssmDouble* PrecipitationsLgm=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2415  IssmDouble* tmp=xNew<IssmDouble>(NUM_VERTICES);
2416  IssmDouble TdiffTime,PfacTime;
2417 
2418  /*Recover parameters*/
2419  IssmDouble time,yts,time_yr;
2420  this->parameters->FindParam(&time,TimeEnum);
2421  this->parameters->FindParam(&yts,ConstantsYtsEnum);
2422  this->GetVerticesLidList(vertexlids);
2423  time_yr=floor(time/yts)*yts;
2424 
2425  /*Recover present day temperature and precipitation*/
2430 
2431  /*loop over vertices: */
2432  Gauss* gauss=this->NewGauss();
2433  for(int month=0;month<12;month++) {
2434  for(int iv=0;iv<NUM_VERTICES;iv++) {
2435  gauss->GaussVertex(iv);
2436  dinput1->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month);
2437  dinput2->GetInputValue(&TemperaturesLgm[iv*12+month],gauss,month);
2438  dinput3->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month);
2439  dinput4->GetInputValue(&PrecipitationsLgm[iv*12+month],gauss,month);
2440 
2441  PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;
2442  PrecipitationsLgm[iv*12+month]=PrecipitationsLgm[iv*12+month]*yts;
2443  }
2444  }
2445 
2446  /*Recover interpolation parameters at time t*/
2447  this->parameters->FindParam(&TdiffTime,SmbTdiffEnum,time);
2448  this->parameters->FindParam(&PfacTime,SmbPfacEnum,time);
2449 
2450  /*Compute the temperature and precipitation*/
2451  for(int iv=0;iv<NUM_VERTICES;iv++){
2452  ComputeMungsmTemperaturePrecipitation(TdiffTime,PfacTime,
2453  &PrecipitationsLgm[iv*12],&PrecipitationsPresentday[iv*12],
2454  &TemperaturesLgm[iv*12], &TemperaturesPresentday[iv*12],
2455  &monthlytemperatures[iv*12], &monthlyprec[iv*12]);
2456  }
2457 
2458  /*Update inputs*/
2459  for (int imonth=0;imonth<12;imonth++) {
2460  for(i=0;i<NUM_VERTICES;i++) tmp[i]=monthlytemperatures[i*12+imonth];
2461  switch(this->ObjectEnum()){
2462  case TriaEnum: this->inputs2->SetTriaDatasetInput(SmbMonthlytemperaturesEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
2463  case PentaEnum: this->inputs2->SetPentaDatasetInput(SmbMonthlytemperaturesEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
2464  default: _error_("Not implemented yet");
2465  }
2466  for(i=0;i<NUM_VERTICES;i++) tmp[i]=monthlyprec[i*12+imonth]/yts;
2467  switch(this->ObjectEnum()){
2468  case TriaEnum: this->inputs2->SetTriaDatasetInput(SmbPrecipitationEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
2469  case PentaEnum: this->inputs2->SetPentaDatasetInput(SmbPrecipitationEnum,imonth,P1Enum,NUM_VERTICES,vertexlids,tmp); break;
2470  default: _error_("Not implemented yet");
2471  }
2472  }
2473 
2474  switch(this->ObjectEnum()){
2475  case TriaEnum: break;
2476  case PentaEnum:
2477  case TetraEnum:
2480  break;
2481  default: _error_("Not implemented yet");
2482  }
2483 
2484  /*clean-up*/
2485  delete gauss;
2486  xDelete<IssmDouble>(monthlytemperatures);
2487  xDelete<IssmDouble>(monthlyprec);
2488  xDelete<IssmDouble>(TemperaturesPresentday);
2489  xDelete<IssmDouble>(TemperaturesLgm);
2490  xDelete<IssmDouble>(PrecipitationsPresentday);
2491  xDelete<IssmDouble>(PrecipitationsLgm);
2492  xDelete<IssmDouble>(tmp);
2493  xDelete<int>(vertexlids);
2494 
2495 }
2496 /*}}}*/
2497 ElementMatrix* Element::NewElementMatrix(int approximation_enum){/*{{{*/
2498  return new ElementMatrix(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
2499 }
2500 /*}}}*/
2501 ElementMatrix* Element::NewElementMatrixCoupling(int number_nodes,int approximation_enum){/*{{{*/
2502  return new ElementMatrix(nodes,number_nodes,this->parameters,approximation_enum);
2503 }
2504 /*}}}*/
2505 ElementVector* Element::NewElementVector(int approximation_enum){/*{{{*/
2506  return new ElementVector(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
2507 }
2508 /*}}}*/
2509 void Element::PicoUpdateBoxid(int* max_boxid_basin_list){/*{{{*/
2510 
2511  if(!this->IsIceInElement() || !this->IsFloating()) return;
2512 
2513  int basin_id;
2514  IssmDouble dist_gl,dist_cf;
2515 
2517  IssmDouble boxid_max=reCast<IssmDouble>(max_boxid_basin_list[basin_id])+1.;
2518 
2519  Input2* dist_gl_input=this->GetInput2(DistanceToGroundinglineEnum); _assert_(dist_gl_input);
2520  Input2* dist_cf_input=this->GetInput2(DistanceToCalvingfrontEnum); _assert_(dist_cf_input);
2521 
2522  /*Get dist_gl and dist_cf at center of element*/
2523  Gauss* gauss=this->NewGauss(1); gauss->GaussPoint(0);
2524  dist_gl_input->GetInputValue(&dist_gl,gauss);
2525  dist_cf_input->GetInputValue(&dist_cf,gauss);
2526  delete gauss;
2527 
2528  /*Ensure values are positive for floating ice*/
2529  dist_gl = fabs(dist_gl);
2530  dist_cf = fabs(dist_cf);
2531 
2532  /*Compute relative distance to grounding line*/
2533  IssmDouble rel_dist_gl=dist_gl/(dist_gl+dist_cf);
2534 
2535  /*Assign box numbers based on rel_dist_gl*/
2536  int boxid = -1;
2537  for(IssmDouble i=0.;i<boxid_max;i++){
2538  IssmDouble lowbound = 1. -sqrt((boxid_max-i )/boxid_max);
2539  IssmDouble highbound = 1. -sqrt((boxid_max-i-1.)/boxid_max);
2540  if(rel_dist_gl>=lowbound && rel_dist_gl<=highbound){
2541  boxid=reCast<int>(i);
2542  break;
2543  }
2544  }
2545  if(boxid==-1) _error_("No boxid found for element " << this->Sid() << "!");
2546 
2547  this->SetIntInput(this->inputs2,BasalforcingsPicoBoxIdEnum, boxid);
2548 
2549 }/*}}}*/
2550 void Element::PicoUpdateBox(int loopboxid){/*{{{*/
2551 
2552  if(!this->IsIceInElement() || !this->IsFloating()) return;
2553 
2554  int boxid;
2556  if(loopboxid!=boxid) return;
2557 
2558  const int NUM_VERTICES = this->GetNumberOfVertices();
2559 
2560  int basinid, maxbox, num_basins, numnodes, M;
2561  IssmDouble gamma_T, overturning_coeff, thickness;
2562  IssmDouble pressure, T_star,p_coeff, q_coeff;
2563  bool isplume;
2564 
2565  /*Get variables*/
2568  IssmDouble earth_grav = this->FindParam(ConstantsGEnum);
2569  IssmDouble rho_star = 1033.; // kg/m^3
2570  IssmDouble nu = rhoi/rhow;
2571  IssmDouble latentheat = this->FindParam(MaterialsLatentheatEnum);
2573  IssmDouble lambda = latentheat/c_p_ocean;
2574  IssmDouble a = -0.0572; // K/psu
2575  IssmDouble b = 0.0788 + this->FindParam(MaterialsMeltingpointEnum); //K
2576  IssmDouble c = 7.77e-4;
2577  IssmDouble alpha = 7.5e-5; // 1/K
2578  IssmDouble Beta = 7.7e-4; // K
2579 
2580  /* Get non-box-specific parameters and inputs */
2586  Input2 *thickness_input = this->GetInput2(ThicknessEnum); _assert_(thickness_input);
2587  _assert_(basinid<=num_basins);
2588 
2589  IssmDouble* boxareas = NULL;
2590  this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum);
2591  _assert_(M==num_basins*maxbox);
2592 
2593  IssmDouble area_boxi = boxareas[basinid*maxbox+boxid];
2594  IssmDouble g1 = area_boxi*gamma_T;
2595 
2596  IssmDouble* basalmeltrates_shelf = xNew<IssmDouble>(NUM_VERTICES);
2597  IssmDouble* potential_pressure_melting_point = xNew<IssmDouble>(NUM_VERTICES);
2598  IssmDouble* Tocs = xNew<IssmDouble>(NUM_VERTICES);
2599  IssmDouble* Socs = xNew<IssmDouble>(NUM_VERTICES);
2600 
2601  /* First box calculations */
2602  if(boxid==0){
2603  /* Get box1 parameters and inputs */
2604  IssmDouble time, toc_farocean, soc_farocean;
2605  this->parameters->FindParam(&time,TimeEnum);
2606  this->parameters->FindParam(&toc_farocean, basinid, time, BasalforcingsPicoFarOceantemperatureEnum);
2607  this->parameters->FindParam(&soc_farocean, basinid, time, BasalforcingsPicoFarOceansalinityEnum);
2608  IssmDouble s1 = soc_farocean/(nu*lambda);
2609  IssmDouble* overturnings = xNew<IssmDouble>(NUM_VERTICES);
2610  Input2 *overturningC_input = this->GetInput2(BasalforcingsPicoOverturningCoeffEnum); _assert_(overturningC_input);
2611 
2612  /* Start looping on the number of verticies and calculate ocean vars */
2613  Gauss* gauss=this->NewGauss();
2614  for(int i=0;i<NUM_VERTICES;i++){
2615  gauss->GaussVertex(i);
2616  thickness_input->GetInputValue(&thickness,gauss);
2617  overturningC_input->GetInputValue(&overturning_coeff,gauss);
2618  pressure = (rhoi*earth_grav*1e-4)*thickness;
2619  T_star = a*soc_farocean+b-c*pressure-toc_farocean;
2620  p_coeff = g1/(overturning_coeff*rho_star*(Beta*s1-alpha));
2621  q_coeff = T_star*(g1/(overturning_coeff*rho_star*(Beta*s1-alpha)));
2622 
2623  /* To avoid negatives under the square root */
2624  if((0.25*pow(p_coeff,2)-q_coeff)<0) q_coeff = 0.25*p_coeff*p_coeff;
2625 
2626  Tocs[i] = toc_farocean-(-0.5*p_coeff+sqrt(0.25*pow(p_coeff,2)-q_coeff));
2627  Socs[i] = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Tocs[i]);
2628  potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;
2629  if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
2630  overturnings[i] = overturning_coeff*rho_star*(Beta*(soc_farocean-Socs[i])-alpha*(toc_farocean-Tocs[i]));
2631  }
2632 
2633  if(!isplume) this->AddInput2(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1DGEnum);
2637 
2638  /*Cleanup and return*/
2639  delete gauss;
2640  }
2641 
2642  /* Subsequent box calculations */
2643  else {
2644  /* Get subsequent box parameters and inputs */
2645  IssmDouble* toc_weighted_avg = NULL;
2646  IssmDouble* soc_weighted_avg = NULL;
2647  IssmDouble* overturning_weighted_avg = NULL;
2648  this->parameters->FindParam(&toc_weighted_avg,&num_basins,BasalforcingsPicoAverageTemperatureEnum);
2649  this->parameters->FindParam(&soc_weighted_avg,&num_basins,BasalforcingsPicoAverageSalinityEnum);
2650  this->parameters->FindParam(&overturning_weighted_avg,&num_basins,BasalforcingsPicoAverageOverturningEnum);
2651  IssmDouble mean_toc = toc_weighted_avg[basinid];
2652  IssmDouble mean_soc = soc_weighted_avg[basinid];
2653  IssmDouble mean_overturning = overturning_weighted_avg[basinid];
2654  IssmDouble g2 = g1/(nu*lambda);
2655 
2656  /* Start looping on the number of verticies and calculate ocean vars */
2657  Gauss* gauss=this->NewGauss();
2658  for(int i=0;i<NUM_VERTICES;i++){
2659  gauss->GaussVertex(i);
2660  thickness_input->GetInputValue(&thickness,gauss);
2661  pressure = (rhoi*earth_grav*1.e-4)*thickness;
2662  T_star = a*mean_soc+b-c*pressure-mean_toc;
2663  Tocs[i] = mean_toc+T_star*(g1/(mean_overturning+g1-g2*a*mean_soc));
2664  Socs[i] = mean_soc-mean_soc*((mean_toc-Tocs[i])/(nu*lambda));
2665  potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;
2666  if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
2667  }
2668 
2669  if(!isplume) this->AddInput2(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1DGEnum);
2672 
2673  /*Cleanup and return*/
2674  xDelete<IssmDouble>(toc_weighted_avg);
2675  xDelete<IssmDouble>(soc_weighted_avg);
2676  xDelete<IssmDouble>(overturning_weighted_avg);
2677  delete gauss;
2678  }
2679 
2680  /*Cleanup and return*/
2681  xDelete<IssmDouble>(boxareas);
2682 
2683 }/*}}}*/
2685 
2686  if(!this->IsIceInElement() || !this->IsFloating()) return;
2687 
2688  const int NUM_VERTICES = this->GetNumberOfVertices();
2689 
2690  IssmDouble E0, Cd, CdT, YT, lam1, lam2, lam3, M0, CdTS0, y1, y2, x0;
2691  IssmDouble Tf_gl, YTS, CdTS, G1, G2, G3, g_alpha, M, l, X_hat, M_hat;
2692  IssmDouble alpha, zgl, Toc, Soc, z_base, yts, slopex, slopey;
2693 
2694  /*Get variables*/
2695  E0 = 3.6e-2; //Entrainment coefficient
2696  Cd = 2.5e-3; //Drag coefficient
2697  CdT = 1.1e-3; //Turbulent heat exchange coefficient
2698  YT = CdT/sqrt(Cd); //Heat exchange coefficient
2699  lam1 = -5.73e-2; //Freezing point-salinity coefficient (degrees C)
2700  lam2 = 8.32e-2; //Freezing point offset (degrees C)
2701  lam3 = 7.61e-4; //Freezing point-depth coefficient (K m-1)
2702  M0 = 10.; //Melt-rate parameter (m yr-1 C-2)
2703  CdTS0 = 6e-4; //Heat exchange parameter
2704  y1 = 0.545; //Heat exchange parameter
2705  y2 = 3.5e-5; //Heat exchange parameter
2706  x0 = 0.56; //Dimentionless scaling factor
2707 
2708  /*Define arrays*/
2709  IssmDouble* basalmeltrates_shelf = xNew<IssmDouble>(NUM_VERTICES); //Basal melt-rate
2710 
2711  /*Polynomial coefficients*/
2712  IssmDouble p[12];
2713  p[0] = 0.1371330075095435;
2714  p[1] = 5.527656234709359E1;
2715  p[2] = -8.951812433987858E2;
2716  p[3] = 8.927093637594877E3;
2717  p[4] = -5.563863123811898E4;
2718  p[5] = 2.218596970948727E5;
2719  p[6] = -5.820015295669482E5;
2720  p[7] = 1.015475347943186E6;
2721  p[8] = -1.166290429178556E6;
2722  p[9] = 8.466870335320488E5;
2723  p[10] = -3.520598035764990E5;
2724  p[11] = 6.387953795485420E4;
2725 
2726  /*Get inputs*/
2727  Input2* zgl_input = this->GetInput2(GroundinglineHeightEnum); _assert_(zgl_input);
2728  Input2* toc_input = this->GetInput2(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(toc_input);
2729  Input2* soc_input = this->GetInput2(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(soc_input);
2730  Input2* base_input = this->GetInput2(BaseEnum); _assert_(base_input);
2731  Input2* baseslopex_input = this->GetInput2(BaseSlopeXEnum); _assert_(baseslopex_input);
2732  Input2* baseslopey_input = this->GetInput2(BaseSlopeYEnum); _assert_(baseslopey_input);
2733  this->FindParam(&yts, ConstantsYtsEnum);
2734 
2735  /*Loop over the number of vertices in this element*/
2736  Gauss* gauss=this->NewGauss();
2737  for(int i=0;i<NUM_VERTICES;i++){
2738  gauss->GaussVertex(i);
2739 
2740  /*Get inputs*/
2741  zgl_input->GetInputValue(&zgl,gauss);
2742  toc_input->GetInputValue(&Toc,gauss); //(K)
2743  soc_input->GetInputValue(&Soc,gauss);
2744  base_input->GetInputValue(&z_base,gauss);
2745  baseslopex_input->GetInputValue(&slopex,gauss);
2746  baseslopey_input->GetInputValue(&slopey,gauss);
2747 
2748  /*Compute ice shelf base slope (radians)*/
2749  alpha = atan(sqrt(slopex*slopex + slopey*slopey));
2750  if(alpha>=M_PI) alpha = M_PI - 0.001; //ensure sin(alpha) > 0 for meltrate calculations
2751 
2752  /*Make necessary conversions*/
2753  Toc = Toc-273.15;
2754  if(zgl>z_base) zgl=z_base;
2755 
2756  /*Low bound for Toc to ensure X_hat is between 0 and 1*/
2757  if(Toc<lam1*Soc+lam2) Toc=lam1*Soc+lam2;
2758 
2759  /*Compute parameters needed for melt-rate calculation*/
2760  Tf_gl = lam1*Soc+lam2+lam3*zgl; //Characteristic freezing point
2761  YTS = YT*(y1+y2*(((Toc-Tf_gl)*E0*sin(alpha))/(lam3*(CdTS0+E0*sin(alpha))))); //Effective heat exchange coefficient
2762  CdTS = sqrt(Cd)*YTS; //Heat exchange coefficient
2763  G1 = sqrt(sin(alpha)/(Cd+E0*sin(alpha))); //Geometric factor
2764  G2 = sqrt(CdTS/(CdTS+E0*sin(alpha))); //Geometric factor
2765  G3 = (E0*sin(alpha))/(CdTS+E0*sin(alpha)); //Geometric factor
2766  g_alpha = G1*G2*G3; //Melt scaling factor
2767  M = M0*g_alpha*pow((Toc-Tf_gl),2); //Melt-rate scale
2768  l = ((Toc-Tf_gl)*(x0*CdTS+E0*sin(alpha)))/(lam3*x0*(CdTS+E0*sin(alpha))); //Length scale
2769  X_hat = (z_base-zgl)/l; //Dimentionless coordinate system
2770 
2771  /*Compute polynomial fit*/
2772  M_hat = 0.; //Reset summation variable for each node
2773  for(int ii=0;ii<12;ii++) {
2774  M_hat += p[ii]*pow(X_hat,ii); //Polynomial fit
2775  }
2776 
2777  /*Compute melt-rate*/
2778  basalmeltrates_shelf[i] = (M*M_hat)/yts; //Basal melt-rate (m/s)
2779  }
2780 
2781  /*Save computed melt-rate*/
2782  this->AddInput2(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1DGEnum);
2783 
2784  /*Cleanup and return*/
2785  delete gauss;
2786 
2787 }/*}}}*/
2788 void Element::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm,bool ismungsm,bool issetpddfac){/*{{{*/
2789 
2790  const int NUM_VERTICES = this->GetNumberOfVertices();
2791  const int NUM_VERTICES_MONTHS_PER_YEAR = NUM_VERTICES * 12;
2792 
2793  int i,vertexlids[MAXVERTICES];
2794  IssmDouble* agd=xNew<IssmDouble>(NUM_VERTICES); // surface mass balance
2795  IssmDouble* melt=xNew<IssmDouble>(NUM_VERTICES); // surface mass balance
2796  IssmDouble* accu=xNew<IssmDouble>(NUM_VERTICES); // surface mass balance
2797  IssmDouble* monthlytemperatures=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2798  IssmDouble* monthlyprec=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2799  IssmDouble* yearlytemperatures=xNew<IssmDouble>(NUM_VERTICES); memset(yearlytemperatures, 0., NUM_VERTICES*sizeof(IssmDouble));
2800  IssmDouble* tmp=xNew<IssmDouble>(NUM_VERTICES);
2801  IssmDouble* h=xNew<IssmDouble>(NUM_VERTICES);
2802  IssmDouble* s=xNew<IssmDouble>(NUM_VERTICES);
2803  IssmDouble* s0p=xNew<IssmDouble>(NUM_VERTICES);
2804  IssmDouble* s0t=xNew<IssmDouble>(NUM_VERTICES);
2805  IssmDouble pddsnowfac = -1.;
2806  IssmDouble pddicefac = -1.;
2807  IssmDouble rho_water,rho_ice,desfac,rlaps,rlapslgm;
2808  IssmDouble PfacTime,TdiffTime,sealevTime;
2809  IssmDouble mavg=1./12.; //factor for monthly average
2810 
2811  /*Get vertex Lids for later*/
2812  this->GetVerticesLidList(&vertexlids[0]);
2813 
2814  /*Get material parameters :*/
2815  rho_water=this->FindParam(MaterialsRhoSeawaterEnum);
2816  rho_ice=this->FindParam(MaterialsRhoIceEnum);
2817 
2818  /*Get some pdd parameters*/
2819  desfac=this->FindParam(SmbDesfacEnum);
2820  rlaps=this->FindParam(SmbRlapsEnum);
2821  rlapslgm=this->FindParam(SmbRlapslgmEnum);
2822 
2823  IssmDouble time,yts,time_yr;
2824  this->parameters->FindParam(&time,TimeEnum);
2825  this->parameters->FindParam(&yts,ConstantsYtsEnum);
2826  time_yr=floor(time/yts)*yts;
2827 
2828  /*Get inputs*/
2830  DatasetInput2* dinput2=this->GetDatasetInput2(SmbPrecipitationEnum); _assert_(dinput2);
2831 
2832  /*loop over vertices: */
2833  Gauss* gauss=this->NewGauss();
2834  for(int month=0;month<12;month++) {
2835  /*Recover monthly temperatures and precipitation and compute the yearly mean temperatures*/
2836 
2837  for(int iv=0;iv<NUM_VERTICES;iv++) {
2838  gauss->GaussVertex(iv);
2839  dinput->GetInputValue(&monthlytemperatures[iv*12+month],gauss,month);
2840  // yearlytemperatures[iv]=yearlytemperatures[iv]+monthlytemperatures[iv*12+month]*mavg; // Has to be in Kelvin
2841  monthlytemperatures[iv*12+month]=monthlytemperatures[iv*12+month]-273.15; // conversion from Kelvin to celcius for PDD module
2842  dinput2->GetInputValue(&monthlyprec[iv*12+month],gauss,month);
2843  monthlyprec[iv*12+month]=monthlyprec[iv*12+month]*yts;
2844  }
2845  }
2846 
2847  /*Recover Pfac, Tdiff and sealev at time t:
2848  * This parameters are used to interpolate the temperature
2849  * and precipitaton between PD and LGM when ismungsm==1 */
2850  if (ismungsm==1){
2851  this->parameters->FindParam(&TdiffTime,SmbTdiffEnum,time);
2852  this->parameters->FindParam(&sealevTime,SmbSealevEnum,time);
2853  }
2854  else {
2855  TdiffTime=0;
2856  sealevTime=0;
2857  }
2858 
2859  /*Recover pdd factors at time t.
2860  * This parameter is set, if the user wants to define the
2861  * pdd factors regionally, if issetpddfac==1 in the d18opdd method */
2862  Input2* input = NULL;
2863  Input2* input2 = NULL;
2864  if(issetpddfac==1){
2865  input = this->GetInput2(SmbPddfacSnowEnum); _assert_(input);
2866  input2 = this->GetInput2(SmbPddfacIceEnum); _assert_(input2);
2867  }
2868 
2869  /*Recover info at the vertices: */
2874 
2875  /*measure the surface mass balance*/
2876  for(int iv = 0; iv<NUM_VERTICES; iv++){
2877  gauss->GaussVertex(iv);
2878  pddsnowfac=0.;
2879  pddicefac=0.;
2880  if(issetpddfac==1){
2881  input->GetInputValue(&pddsnowfac,gauss);
2882  input2->GetInputValue(&pddicefac,gauss);
2883  }
2884  agd[iv]=PddSurfaceMassBalance(&monthlytemperatures[iv*12], &monthlyprec[iv*12],
2885  pdds, pds, &melt[iv], &accu[iv], signorm, yts, h[iv], s[iv],
2886  desfac, s0t[iv], s0p[iv],rlaps,rlapslgm,TdiffTime,sealevTime,
2887  pddsnowfac,pddicefac,rho_water,rho_ice);
2888  /*Get yearlytemperatures */
2889  for(int month=0;month<12;month++) {
2890  yearlytemperatures[iv]=yearlytemperatures[iv]+(monthlytemperatures[iv*12+month]+273.15)*mavg; // Has to be in Kelvin
2891  }
2892  }
2893 
2894  /*Update inputs*/
2895  switch(this->ObjectEnum()){
2896  case TriaEnum:
2897  this->AddInput2(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum);
2898  this->AddInput2(SmbMassBalanceEnum,&agd[0],P1Enum);
2899  this->AddInput2(SmbAccumulationEnum,&accu[0],P1Enum);
2900  this->AddInput2(SmbMeltEnum,&melt[0],P1Enum);
2901  break;
2902  case PentaEnum:
2903  if(IsOnSurface()){
2904  /*Here, we want to change the BC of the thermal model, keep
2905  * the temperatures as they are for the base of the penta and
2906  * yse yearlytemperatures for the top*/
2907  PentaInput2* temp_input = xDynamicCast<PentaInput2*>(this->GetInput2(TemperatureEnum)); _assert_(temp_input);
2908  switch(temp_input->GetInputInterpolationType()){
2909  case P1Enum:
2910  temp_input->element_values[3] = yearlytemperatures[3];
2911  temp_input->element_values[4] = yearlytemperatures[4];
2912  temp_input->element_values[5] = yearlytemperatures[5];
2913  temp_input->SetInput(P1Enum,NUM_VERTICES,&vertexlids[0],temp_input->element_values);
2914  break;
2915  case P1xP2Enum:
2916  case P1xP3Enum:
2917  case P1xP4Enum:
2918  temp_input->element_values[3] = yearlytemperatures[3];
2919  temp_input->element_values[4] = yearlytemperatures[4];
2920  temp_input->element_values[5] = yearlytemperatures[5];
2921  temp_input->SetInput(temp_input->GetInputInterpolationType(),this->lid,this->GetNumberOfNodes(temp_input->GetInputInterpolationType()),temp_input->element_values);
2922  break;
2923  default:
2924  _error_("Interpolation "<<EnumToStringx(temp_input->GetInputInterpolationType())<<" not supported yet");
2925  }
2926 
2927  bool isenthalpy;
2928  this->parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
2929  if(isenthalpy){
2930  /*Convert that to enthalpy for the enthalpy model*/
2931  PentaInput2* enth_input = xDynamicCast<PentaInput2*>(this->GetInput2(EnthalpyEnum)); _assert_(enth_input);
2932  switch(enth_input->GetInputInterpolationType()){
2933  case P1Enum:
2934  ThermalToEnthalpy(&enth_input->element_values[3],yearlytemperatures[3],0.,0.);
2935  ThermalToEnthalpy(&enth_input->element_values[4],yearlytemperatures[4],0.,0.);
2936  ThermalToEnthalpy(&enth_input->element_values[5],yearlytemperatures[5],0.,0.);
2937  enth_input->SetInput(P1Enum,NUM_VERTICES,&vertexlids[0],enth_input->element_values);
2938  break;
2939  case P1xP2Enum:
2940  case P1xP3Enum:
2941  case P1xP4Enum:
2942  ThermalToEnthalpy(&enth_input->element_values[3],yearlytemperatures[3],0.,0.);
2943  ThermalToEnthalpy(&enth_input->element_values[4],yearlytemperatures[4],0.,0.);
2944  ThermalToEnthalpy(&enth_input->element_values[5],yearlytemperatures[5],0.,0.);
2945  enth_input->SetInput(enth_input->GetInputInterpolationType(),this->lid,this->GetNumberOfNodes(enth_input->GetInputInterpolationType()),enth_input->element_values);
2946  break;
2947  default:
2948  _error_("Interpolation "<<EnumToStringx(temp_input->GetInputInterpolationType())<<" not supported yet");
2949  }
2950  }
2951  }
2952  this->AddInput2(SmbMassBalanceEnum,&agd[0],P1Enum);
2953  this->AddInput2(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum);
2954  this->InputExtrude(TemperaturePDDEnum,-1);
2955  this->InputExtrude(SmbMassBalanceEnum,-1);
2956  break;
2957  default: _error_("Not implemented yet");
2958  }
2959 
2960  /*clean-up*/
2961  delete gauss;
2962  xDelete<IssmDouble>(monthlytemperatures);
2963  xDelete<IssmDouble>(monthlyprec);
2964  xDelete<IssmDouble>(agd);
2965  xDelete<IssmDouble>(melt);
2966  xDelete<IssmDouble>(accu);
2967  xDelete<IssmDouble>(yearlytemperatures);
2968  xDelete<IssmDouble>(h);
2969  xDelete<IssmDouble>(s);
2970  xDelete<IssmDouble>(s0t);
2971  xDelete<IssmDouble>(s0p);
2972  xDelete<IssmDouble>(tmp);
2973 }
2974 /*}}}*/
2975 void Element::PositiveDegreeDaySicopolis(bool isfirnwarming){/*{{{*/
2976 
2977  /* General FIXMEs: get Tmelting point, pddicefactor, pddsnowfactor, sigma from parameters/user input */
2978 
2979  const int NUM_VERTICES = this->GetNumberOfVertices();
2980  const int NUM_VERTICES_MONTHS_PER_YEAR = NUM_VERTICES * 12;
2981 
2982  int i,vertexlids[MAXVERTICES];;
2983  IssmDouble* smb=xNew<IssmDouble>(NUM_VERTICES); // surface mass balance
2984  IssmDouble* melt=xNew<IssmDouble>(NUM_VERTICES); // melting comp. of surface mass balance
2985  IssmDouble* accu=xNew<IssmDouble>(NUM_VERTICES); // accuumulation comp. of surface mass balance
2986  IssmDouble* melt_star=xNew<IssmDouble>(NUM_VERTICES);
2987  IssmDouble* monthlytemperatures=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2988  IssmDouble* monthlyprec=xNew<IssmDouble>(NUM_VERTICES_MONTHS_PER_YEAR);
2989  IssmDouble* yearlytemperatures=xNew<IssmDouble>(NUM_VERTICES); memset(yearlytemperatures, 0., NUM_VERTICES*sizeof(IssmDouble));
2990  IssmDouble* s=xNew<IssmDouble>(NUM_VERTICES); // actual surface height
2991  IssmDouble* s0p=xNew<IssmDouble>(NUM_VERTICES); // reference elevation for precip.
2992  IssmDouble* s0t=xNew<IssmDouble>(NUM_VERTICES); // reference elevation for temperature
2993  IssmDouble* smbcorr=xNew<IssmDouble>(NUM_VERTICES); // surface mass balance correction; will be added after pdd call
2994  IssmDouble* p_ampl=xNew<IssmDouble>(NUM_VERTICES); // precip anomaly
2995  IssmDouble* t_ampl=xNew<IssmDouble>(NUM_VERTICES); // remperature anomaly
2996  IssmDouble rho_water,rho_ice,desfac,rlaps;
2997  IssmDouble inv_twelve=1./12.; //factor for monthly average
2998  IssmDouble time,yts,time_yr;
2999 
3000  /*Get vertex Lids for later*/
3001  this->GetVerticesLidList(&vertexlids[0]);
3002 
3003  /*Get material parameters :*/
3004  rho_water=this->FindParam(MaterialsRhoSeawaterEnum);
3005  rho_ice=this->FindParam(MaterialsRhoIceEnum);
3006 
3007  /*Get parameters for height corrections*/
3008  desfac=this->FindParam(SmbDesfacEnum);
3009  rlaps=this->FindParam(SmbRlapsEnum);
3010 
3011  /* Get time */
3012  this->parameters->FindParam(&time,TimeEnum);
3013  this->parameters->FindParam(&yts,ConstantsYtsEnum);
3014  time_yr=floor(time/yts)*yts;
3015 
3016  /* Set parameters for finrnwarming */
3017  IssmDouble MU_0 = 9.7155; //Firn-warming correction, in (d*deg C)/(mm WE)
3018  IssmDouble mu = MU_0*(1000.0*86400.0)*(rho_ice/rho_water); // (d*deg C)/(mm WE) --> (s*deg C)/(m IE)
3019 
3020  /*Get inputs*/
3022  DatasetInput2* dinput2=this->GetDatasetInput2(SmbPrecipitationEnum); _assert_(dinput2);
3023 
3024  /*loop over vertices: */
3025  Gauss* gauss=this->NewGauss();
3026  for(int month=0;month<12;month++){
3027 
3028  for(int iv=0;iv<NUM_VERTICES;iv++){
3029  gauss->GaussVertex(iv);
3030  dinput->GetInputValue(&monthlytemperatures[iv*12+month],gauss,month);
3031  monthlytemperatures[iv*12+month]=monthlytemperatures[iv*12+month]-273.15; // conversion from Kelvin to celcius for PDD module
3032  dinput2->GetInputValue(&monthlyprec[iv*12+month],gauss,month);
3033  monthlyprec[iv*12+month]=monthlyprec[iv*12+month]*yts;
3034  }
3035  }
3036 
3037  /*Recover info at the vertices: */
3044 
3045  /*measure the surface mass balance*/
3046  for (int iv = 0; iv<NUM_VERTICES; iv++){
3047  smb[iv]=PddSurfaceMassBalanceSicopolis(&monthlytemperatures[iv*12], &monthlyprec[iv*12],
3048  &melt[iv], &accu[iv], &melt_star[iv], &t_ampl[iv], &p_ampl[iv], yts, s[iv],
3049  desfac, s0t[iv], s0p[iv],rlaps,rho_water,rho_ice);
3050 
3051  /* make correction */
3052  smb[iv] = smb[iv]+smbcorr[iv];
3053  /*Get yearlytemperatures */
3054  for(int month=0;month<12;month++) yearlytemperatures[iv]=yearlytemperatures[iv]+((monthlytemperatures[iv*12+month]+273.15)+t_ampl[iv])*inv_twelve; // Has to be in Kelvin
3055 
3056  if(isfirnwarming){
3057  if(melt_star[iv]>=melt[iv]){
3058  yearlytemperatures[iv]= yearlytemperatures[iv]+mu*(melt_star[iv]-melt[iv]);
3059  }
3060  else{
3061  yearlytemperatures[iv]= yearlytemperatures[iv];
3062  }
3063  }
3064  if (yearlytemperatures[iv]>273.15) yearlytemperatures[iv]=273.15;
3065  }
3066 
3067  switch(this->ObjectEnum()){
3068  case TriaEnum:
3069  //this->AddInput2(TemperatureEnum,&yearlytemperatures[0],P1Enum);
3070  this->AddInput2(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum);
3071  this->AddInput2(SmbMassBalanceEnum,&smb[0],P1Enum);
3072  this->AddInput2(SmbAccumulationEnum,&accu[0],P1Enum);
3073  this->AddInput2(SmbMeltEnum,&melt[0],P1Enum);
3074  break;
3075  case PentaEnum:
3076  bool isthermal;
3077  this->parameters->FindParam(&isthermal,TransientIsthermalEnum);
3078  if(isthermal){
3079  bool isenthalpy;
3080  this->parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
3081  if(IsOnSurface()){
3082  /*Here, we want to change the BC of the thermal model, keep
3083  * the temperatures as they are for the base of the penta and
3084  * use yearlytemperatures for the top*/
3085 
3086  /*FIXME: look at other function Element::PositiveDegreeDay and propagate change! Just assert for now*/
3087  PentaInput2* temp_input = xDynamicCast<PentaInput2*>(this->GetInput2(TemperatureEnum)); _assert_(temp_input);
3088  switch(temp_input->GetInputInterpolationType()){
3089  case P1Enum:
3090  temp_input->element_values[3] = yearlytemperatures[3];
3091  temp_input->element_values[4] = yearlytemperatures[4];
3092  temp_input->element_values[5] = yearlytemperatures[5];
3093  temp_input->SetInput(P1Enum,NUM_VERTICES,&vertexlids[0],temp_input->element_values);
3094  break;
3095  case P1DGEnum:
3096  case P1xP2Enum:
3097  case P1xP3Enum:
3098  case P1xP4Enum:
3099  temp_input->element_values[3] = yearlytemperatures[3];
3100  temp_input->element_values[4] = yearlytemperatures[4];
3101  temp_input->element_values[5] = yearlytemperatures[5];
3102  temp_input->SetInput(temp_input->GetInputInterpolationType(),this->lid,this->GetNumberOfNodes(temp_input->GetInputInterpolationType()),temp_input->element_values);
3103  break;
3104  default:
3105  _error_("Interpolation "<<EnumToStringx(temp_input->GetInputInterpolationType())<<" not supported yet");
3106  }
3107 
3108  if(isenthalpy){
3109  /*Convert that to enthalpy for the enthalpy model*/
3110  PentaInput2* enth_input = xDynamicCast<PentaInput2*>(this->GetInput2(EnthalpyEnum)); _assert_(enth_input);
3111  switch(enth_input->GetInputInterpolationType()){
3112  case P1Enum:
3113  ThermalToEnthalpy(&enth_input->element_values[3],yearlytemperatures[3],0.,0.);
3114  ThermalToEnthalpy(&enth_input->element_values[4],yearlytemperatures[4],0.,0.);
3115  ThermalToEnthalpy(&enth_input->element_values[5],yearlytemperatures[5],0.,0.);
3116  enth_input->SetInput(P1Enum,NUM_VERTICES,&vertexlids[0],enth_input->element_values);
3117  break;
3118  case P1DGEnum:
3119  case P1xP2Enum:
3120  case P1xP3Enum:
3121  case P1xP4Enum:
3122  ThermalToEnthalpy(&enth_input->element_values[3],yearlytemperatures[3],0.,0.);
3123  ThermalToEnthalpy(&enth_input->element_values[4],yearlytemperatures[4],0.,0.);
3124  ThermalToEnthalpy(&enth_input->element_values[5],yearlytemperatures[5],0.,0.);
3125  enth_input->SetInput(enth_input->GetInputInterpolationType(),this->lid,this->GetNumberOfNodes(enth_input->GetInputInterpolationType()),enth_input->element_values);
3126  break;
3127  default:
3128  _error_("Interpolation "<<EnumToStringx(temp_input->GetInputInterpolationType())<<" not supported yet");
3129  }
3130  }
3131  }
3132  }
3133  this->AddInput2(SmbMassBalanceEnum,&smb[0],P1Enum);
3134  this->AddInput2(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum);
3135  this->AddInput2(SmbAccumulationEnum,&accu[0],P1Enum);
3136  this->AddInput2(SmbMeltEnum,&melt[0],P1Enum);
3137  this->InputExtrude(TemperaturePDDEnum,-1);
3138  this->InputExtrude(SmbMassBalanceEnum,-1);
3140  this->InputExtrude(SmbMeltEnum,-1);
3141  break;
3142  default: _error_("Not implemented yet");
3143  }
3144 
3145  /*clean-up*/
3146  delete gauss;
3147  xDelete<IssmDouble>(monthlytemperatures);
3148  xDelete<IssmDouble>(monthlyprec);
3149  xDelete<IssmDouble>(smb);
3150  xDelete<IssmDouble>(melt);
3151  xDelete<IssmDouble>(accu);
3152  xDelete<IssmDouble>(yearlytemperatures);
3153  xDelete<IssmDouble>(s);
3154  xDelete<IssmDouble>(s0t);
3155  xDelete<IssmDouble>(s0p);
3156  xDelete<IssmDouble>(t_ampl);
3157  xDelete<IssmDouble>(p_ampl);
3158  xDelete<IssmDouble>(smbcorr);
3159  xDelete<IssmDouble>(melt_star);
3160 }
3161 /*}}}*/
3162 void Element::ResultInterpolation(int* pinterpolation,int* pnodesperelement,int* parray_size, int output_enum){/*{{{*/
3163 
3164  /*Some intputs need to be computed, even if they are already in inputs, they might not be up to date!*/
3165  switch(output_enum){
3166  case ViscousHeatingEnum: this->ViscousHeatingCreateInput(); break;
3168  case StressTensorxxEnum:
3169  case StressTensorxyEnum:
3170  case StressTensorxzEnum:
3171  case StressTensoryyEnum:
3172  case StressTensoryzEnum:
3173  case StressTensorzzEnum: this->ComputeStressTensor(); break;
3174  case StrainRatexxEnum:
3175  case StrainRatexyEnum:
3176  case StrainRatexzEnum:
3177  case StrainRateyyEnum:
3178  case StrainRateyzEnum:
3179  case StrainRatezzEnum:
3180  case StrainRateeffectiveEnum: this->ComputeStrainRate(); break;
3187  case DeviatoricStress1Enum:
3188  case DeviatoricStress2Enum:
3190  case EsaStrainratexxEnum:
3191  case EsaStrainratexyEnum:
3192  case EsaStrainrateyyEnum:
3194  case SigmaNNEnum: this->ComputeSigmaNN(); break;
3195  case LambdaSEnum: this->ComputeLambdaS(); break;
3196  case StressIntensityFactorEnum: this->StressIntensityFactor(); break;
3197  case CalvingratexEnum:
3198  case CalvingrateyEnum:
3200  this->StrainRateparallel();
3201  this->StrainRateperpendicular();
3202  int calvinglaw;
3203  this->FindParam(&calvinglaw,CalvingLawEnum);
3204  switch(calvinglaw){
3205  case DefaultCalvingEnum:
3206  //do nothing
3207  break;
3208  case CalvingLevermannEnum:
3209  this->CalvingRateLevermann();
3210  break;
3211  case CalvingVonmisesEnum:
3212  case CalvingDev2Enum:
3213  this->CalvingRateVonmises();
3214  break;
3216  this->CalvingCrevasseDepth();
3217  break;
3218  default:
3219  _error_("Calving law "<<EnumToStringx(calvinglaw)<<" not supported yet");
3220  }
3221  break;
3222  case CalvingFluxLevelsetEnum: this->CalvingFluxLevelset(); break;
3224  case StrainRateparallelEnum: this->StrainRateparallel(); break;
3226  case SurfaceCrevasseEnum: this->CalvingCrevasseDepth(); break;
3227  case SigmaVMEnum: this->CalvingRateVonmises(); break;
3229  }
3230 
3231  /*If this input is not already in Inputs, maybe it needs to be computed?*/
3232  switch(this->inputs2->GetInputObjectEnum(output_enum)){
3233  case TriaInput2Enum:
3234  case PentaInput2Enum:
3235  case TransientInput2Enum:{
3236  Input2* input2 = this->GetInput2(output_enum);
3237  if(!input2) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
3238  *pinterpolation = input2->GetResultInterpolation();
3239  *pnodesperelement = input2->GetResultNumberOfNodes();
3240  *parray_size = input2->GetResultArraySize();
3241  }
3242  break;
3243  case BoolInput2Enum:
3244  *pinterpolation = P0Enum;
3245  *pnodesperelement = 1;
3246  *parray_size = 1;
3247  break;
3248  case IntInput2Enum:
3249  *pinterpolation = P0Enum;
3250  *pnodesperelement = 1;
3251  *parray_size = 1;
3252  break;
3253  case ArrayInput2Enum:{
3254  int M;
3255  this->inputs2->GetArray(output_enum,this->lid,NULL,&M);
3256  *pinterpolation = P0ArrayEnum;
3257  *pnodesperelement = 1;
3258  *parray_size = M;
3259  }
3260  break;
3261  default:
3262  _error_("Input type \""<<EnumToStringx(this->inputs2->GetInputObjectEnum(output_enum))<<"\" not supported yet (While trying to return "<<EnumToStringx(output_enum)<<")");
3263  }
3264 
3265 
3266  /*Assign output pointer*/
3267 
3268  return;
3269 }/*}}}*/
3270 void Element::ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum){/*{{{*/
3271 
3272  /*Find input*/
3273  Input2* input=this->GetInput2(output_enum);
3274  if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
3275 
3276  /*Cast to ElementInput*/
3277  if(input->ObjectEnum()!=TriaInput2Enum && input->ObjectEnum()!=PentaInput2Enum){
3278  _error_("Input "<<EnumToStringx(output_enum)<<" is not an ElementInput2");
3279  }
3280  ElementInput2* element_input = xDynamicCast<ElementInput2*>(input);
3281 
3282  /*Get Number of nodes and make sure that it is the same as the one provided*/
3283  int numnodes = this->GetNumberOfNodes(element_input->GetInputInterpolationType());
3284  _assert_(numnodes==nodesperelement);
3285 
3286  /*Fill in arrays*/
3287  for(int i=0;i<numnodes;i++) values[this->sid*numnodes + i] = element_input->element_values[i];
3288 
3289 } /*}}}*/
3290 void Element::ResultToMatrix(IssmDouble* values,int ncols,int output_enum){/*{{{*/
3291 
3292  IssmDouble* array = NULL;
3293  int m;
3294  this->inputs2->GetArray(output_enum,this->lid,&array,&m);
3295  for(int i=0;i<m;i++) values[this->Sid()*ncols + i] = array[i];
3296  xDelete<IssmDouble>(array);
3297 
3298 } /*}}}*/
3299 void Element::ResultToVector(Vector<IssmDouble>* vector,int output_enum){/*{{{*/
3300 
3301  IssmDouble values[MAXVERTICES];
3302  int connectivity[MAXVERTICES];
3303  int sidlist[MAXVERTICES];
3304 
3305  switch(this->inputs2->GetInputObjectEnum(output_enum)){
3306  case TriaInput2Enum:
3307  case PentaInput2Enum:
3308  case TransientInput2Enum:{
3309 
3310  Input2* input2 = this->GetInput2(output_enum);
3311  if(!input2) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
3312 
3313  switch(input2->GetResultInterpolation()){
3314  case P0Enum:{
3315  IssmDouble value;
3316  bool bvalue;
3317  Gauss* gauss = this->NewGauss();
3318  input2->GetInputValue(&value,gauss);
3319  delete gauss;
3320  vector->SetValue(this->Sid(),value,INS_VAL);
3321  break;
3322  }
3323  case P1Enum:{
3324  const int NUM_VERTICES = this->GetNumberOfVertices();
3325 
3326 
3327 
3328  this->GetVerticesSidList(&sidlist[0]);
3329  this->GetVerticesConnectivityList(&connectivity[0]);
3330  this->GetInputListOnVertices(&values[0],output_enum);
3331  for(int i=0;i<NUM_VERTICES;i++) values[i] = values[i]/reCast<IssmDouble>(connectivity[i]);
3332  vector->SetValues(NUM_VERTICES,sidlist,values,ADD_VAL);
3333  break;
3334  }
3335  default:
3336  _error_("interpolation "<<EnumToStringx(input2->GetResultInterpolation())<<" not supported yet");
3337  }
3338  }
3339  break;
3340  case BoolInput2Enum:
3341  bool bvalue;
3342  this->GetInput2Value(&bvalue,output_enum);
3343  vector->SetValue(this->Sid(),reCast<IssmDouble>(bvalue),INS_VAL);
3344  break;
3345  case IntInput2Enum:
3346  int ivalue;
3347  this->GetInput2Value(&ivalue,output_enum);
3348  vector->SetValue(this->Sid(),reCast<IssmDouble>(ivalue),INS_VAL);
3349  break;
3350  default:
3351  _error_("Input type \""<<EnumToStringx(this->inputs2->GetInputObjectEnum(output_enum))<<"\" not supported yet");
3352  }
3353 
3354 } /*}}}*/
3355 void Element::SetBoolInput(Inputs2* inputs2,int enum_in,bool value){/*{{{*/
3356 
3357  _assert_(inputs2);
3358  inputs2->SetInput(enum_in,this->lid,value);
3359 
3360 }
3361 /*}}}*/
3362 void Element::SetIntInput(Inputs2* inputs2,int enum_in,int value){/*{{{*/
3363 
3364  _assert_(inputs2);
3365  inputs2->SetInput(enum_in,this->lid,value);
3366 
3367 }
3368 /*}}}*/
3369 void Element::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){/*{{{*/
3370 
3371  /*Intermediaries*/
3372  const int numnodes = this->GetNumberOfNodes();
3373 
3374  /*Output */
3375  int d_nz = 0;
3376  int o_nz = 0;
3377 
3378  /*Loop over all nodes*/
3379  for(int i=0;i<numnodes;i++){
3380 
3381  if(!flags[this->nodes[i]->Lid()]){
3382 
3383  /*flag current node so that no other element processes it*/
3384  flags[this->nodes[i]->Lid()]=true;
3385 
3386  int counter=0;
3387  while(flagsindices[counter]>=0) counter++;
3388  flagsindices[counter]=this->nodes[i]->Lid();
3389 
3390  /*if node is clone, we have an off-diagonal non-zero, else it is a diagonal non-zero*/
3391  switch(set2_enum){
3392  case FsetEnum:
3393  if(nodes[i]->fsize){
3394  if(this->nodes[i]->IsClone())
3395  o_nz += 1;
3396  else
3397  d_nz += 1;
3398  }
3399  break;
3400  case GsetEnum:
3401  if(nodes[i]->gsize){
3402  if(this->nodes[i]->IsClone())
3403  o_nz += 1;
3404  else
3405  d_nz += 1;
3406  }
3407  break;
3408  case SsetEnum:
3409  if(nodes[i]->ssize){
3410  if(this->nodes[i]->IsClone())
3411  o_nz += 1;
3412  else
3413  d_nz += 1;
3414  }
3415  break;
3416  default: _error_("not supported");
3417  }
3418  }
3419  }
3420 
3421  /*Special case: 2d/3d coupling, the node of this element might be connected
3422  *to the basal element*/
3423  int analysis_type,approximation,numlayers;
3424  parameters->FindParam(&analysis_type,AnalysisTypeEnum);
3425  if(analysis_type==StressbalanceAnalysisEnum){
3426  this->GetInput2Value(&approximation,ApproximationEnum);
3427  if(approximation==SSAHOApproximationEnum || approximation==SSAFSApproximationEnum){
3429  o_nz += numlayers*3;
3430  d_nz += numlayers*3;
3431  }
3432  }
3433 
3434  /*Assign output pointers: */
3435  *pd_nz=d_nz;
3436  *po_nz=o_nz;
3437 }
3438 /*}}}*/
3439 #ifdef _HAVE_SEMIC_
3440 void Element::SmbSemic(){/*{{{*/
3441 
3442  /*only compute SMB at the surface: */
3443  if (!IsOnSurface()) return;
3444 
3445  const int NUM_VERTICES = this->GetNumberOfVertices();
3446  const int NUM_VERTICES_DAYS_PER_YEAR = NUM_VERTICES * 365;
3447 
3448  IssmDouble* s=xNew<IssmDouble>(NUM_VERTICES);
3449  IssmDouble* s0gcm=xNew<IssmDouble>(NUM_VERTICES);
3450  IssmDouble* st=xNew<IssmDouble>(NUM_VERTICES);
3451 
3452  // daily forcing inputs
3453  IssmDouble* dailyrainfall=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3454  IssmDouble* dailysnowfall=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3455  IssmDouble* dailydlradiation=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3456  IssmDouble* dailydsradiation=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3457  IssmDouble* dailywindspeed=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3458  IssmDouble* dailypressure=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3459  IssmDouble* dailyairdensity=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3460  IssmDouble* dailyairhumidity=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3461  IssmDouble* dailytemperature=xNew<IssmDouble>(NUM_VERTICES_DAYS_PER_YEAR);
3462  // daily outputs
3463  IssmDouble* tsurf_out=xNew<IssmDouble>(NUM_VERTICES); memset(tsurf_out, 0., NUM_VERTICES*sizeof(IssmDouble));
3464  IssmDouble* smb_out=xNew<IssmDouble>(NUM_VERTICES); memset(smb_out, 0., NUM_VERTICES*sizeof(IssmDouble));
3465  IssmDouble* saccu_out=xNew<IssmDouble>(NUM_VERTICES); memset(saccu_out, 0., NUM_VERTICES*sizeof(IssmDouble));
3466  IssmDouble* smelt_out=xNew<IssmDouble>(NUM_VERTICES); memset(smelt_out, 0., NUM_VERTICES*sizeof(IssmDouble));
3467 
3468  IssmDouble rho_water,rho_ice,desfac,rlaps,rdl;
3469  IssmDouble time,yts,time_yr;
3470 
3471  /* Get time: */
3472  this->parameters->FindParam(&time,TimeEnum);
3473  this->parameters->FindParam(&yts,ConstantsYtsEnum);
3474  time_yr=floor(time/yts)*yts;
3475 
3476  /*Get material parameters :*/
3477  rho_water=this->FindParam(MaterialsRhoSeawaterEnum);
3478  rho_ice=this->FindParam(MaterialsRhoIceEnum);
3479  desfac=this->FindParam(SmbDesfacEnum);
3480  rlaps=this->FindParam(SmbRlapsEnum);
3481  rdl=this->FindParam(SmbRdlEnum);
3482 
3483  /* Recover info at the vertices: */
3486 
3487  /* loop over vertices and days */ //FIXME account for leap years (365 -> 366)
3488  Gauss* gauss=this->NewGauss();
3489  for (int iday = 0; iday < 365; iday++){
3490  /* Retrieve inputs: */
3491  Input2* dailysnowfall_input = this->GetInput2(SmbDailysnowfallEnum,time_yr+(iday+1)/365.*yts); _assert_(dailysnowfall_input);
3492  Input2* dailyrainfall_input = this->GetInput2(SmbDailyrainfallEnum,time_yr+(iday+1)/365.*yts); _assert_(dailyrainfall_input);
3493  Input2* dailydlradiation_input = this->GetInput2(SmbDailydlradiationEnum,time_yr+(iday+1)/365.*yts); _assert_(dailydlradiation_input);
3494  Input2* dailydsradiation_input = this->GetInput2(SmbDailydsradiationEnum,time_yr+(iday+1)/365.*yts); _assert_(dailydsradiation_input);
3495  Input2* dailywindspeed_input = this->GetInput2(SmbDailywindspeedEnum,time_yr+(iday+1)/365.*yts); _assert_(dailywindspeed_input);
3496  Input2* dailypressure_input = this->GetInput2(SmbDailypressureEnum,time_yr+(iday+1)/365.*yts); _assert_(dailypressure_input);
3497  Input2* dailyairdensity_input = this->GetInput2(SmbDailyairdensityEnum,time_yr+(iday+1)/365.*yts); _assert_(dailyairdensity_input);
3498  Input2* dailyairhumidity_input = this->GetInput2(SmbDailyairhumidityEnum,time_yr+(iday+1)/365.*yts); _assert_(dailyairhumidity_input);
3499  Input2* dailytemperature_input = this->GetInput2(SmbDailytemperatureEnum,time_yr+(iday+1)/365.*yts); _assert_(dailytemperature_input);
3500 
3501  for(int iv=0;iv<NUM_VERTICES;iv++){
3502  gauss->GaussVertex(iv);
3503  /* get forcing */
3504  dailyrainfall_input->GetInputValue(&dailyrainfall[iv*365+iday],gauss);
3505  dailysnowfall_input->GetInputValue(&dailysnowfall[iv*365+iday],gauss);
3506  dailydlradiation_input->GetInputValue(&dailydlradiation[iv*365+iday],gauss);
3507  dailydsradiation_input->GetInputValue(&dailydsradiation[iv*365+iday],gauss);
3508  dailywindspeed_input->GetInputValue(&dailywindspeed[iv*365+iday],gauss);
3509  dailypressure_input->GetInputValue(&dailypressure[iv*365+iday],gauss);
3510  dailyairdensity_input->GetInputValue(&dailyairdensity[iv*365+iday],gauss);
3511  dailyairhumidity_input->GetInputValue(&dailyairhumidity[iv*365+iday],gauss);
3512  dailytemperature_input->GetInputValue(&dailytemperature[iv*365+iday],gauss);
3513 
3514  /* Surface temperature correction */
3515  st[iv]=(s[iv]-s0gcm[iv])/1000.;
3516  dailytemperature[iv*365+iday]=dailytemperature[iv*365+iday]-rlaps *st[iv];
3517 
3518  /* Precipitation correction (Vizcaino et al. 2010) */
3519  if (s0gcm[iv] < 2000.0) {
3520  dailysnowfall[iv*365+iday] = dailysnowfall[iv*365+iday]*exp(desfac*(max(s[iv],2000.0)-2000.0));
3521  dailyrainfall[iv*365+iday] = dailyrainfall[iv*365+iday]*exp(desfac*(max(s[iv],2000.0)-2000.0));
3522  }else{
3523  dailysnowfall[iv*365+iday] = dailysnowfall[iv*365+iday]*exp(desfac*(max(s[iv],2000.0)-s0gcm[iv]));
3524  dailyrainfall[iv*365+iday] = dailyrainfall[iv*365+iday]*exp(desfac*(max(s[iv],2000.0)-s0gcm[iv]));
3525  }
3526 
3527  /* downward longwave radiation correction (Marty et al. 2002) */
3528  st[iv]=(s[iv]-s0gcm[iv])/1000.;
3529  dailydlradiation[iv*365+iday]=dailydlradiation[iv*365+iday]+rdl*st[iv];
3530  }
3531  }
3532 
3533  for (int iv = 0; iv<NUM_VERTICES; iv++){
3534  /* call semic */
3535  run_semic_(&dailysnowfall[iv*365], &dailyrainfall[iv*365], &dailydsradiation[iv*365], &dailydlradiation[iv*365],
3536  &dailywindspeed[iv*365], &dailypressure[iv*365], &dailyairdensity[iv*365], &dailyairhumidity[iv*365], &dailytemperature[iv*365],
3537  &tsurf_out[iv], &smb_out[iv], &saccu_out[iv], &smelt_out[iv]);
3538  }
3539 
3540  switch(this->ObjectEnum()){
3541  case TriaEnum:
3542  this->AddInput2(TemperatureSEMICEnum,&tsurf_out[0],P1Enum); // TODO add TemperatureSEMICEnum to EnumDefinitions
3543  this->AddInput2(SmbMassBalanceEnum,&smb_out[0],P1Enum);
3544  this->AddInput2(SmbAccumulationEnum,&saccu_out[0],P1Enum);
3545  this->AddInput2(SmbMeltEnum,&smelt_out[0],P1Enum);
3546  break;
3547  case PentaEnum:
3548  // TODO
3549  break;
3550  case TetraEnum:
3551  // TODO
3552  break;
3553  default: _error_("Not implemented yet");
3554  }
3555 
3556  /*clean-up*/
3557  delete gauss;
3558  xDelete<IssmDouble>(dailysnowfall);
3559  xDelete<IssmDouble>(dailyrainfall);
3560  xDelete<IssmDouble>(dailydlradiation);
3561  xDelete<IssmDouble>(dailydsradiation);
3562  xDelete<IssmDouble>(dailywindspeed);
3563  xDelete<IssmDouble>(dailypressure);
3564  xDelete<IssmDouble>(dailyairdensity);
3565  xDelete<IssmDouble>(dailyairhumidity);
3566  xDelete<IssmDouble>(dailypressure);
3567  xDelete<IssmDouble>(dailytemperature);
3568  xDelete<IssmDouble>(smb_out);
3569  xDelete<IssmDouble>(smelt_out);
3570  xDelete<IssmDouble>(saccu_out);
3571  xDelete<IssmDouble>(tsurf_out);
3572  xDelete<IssmDouble>(s);
3573  xDelete<IssmDouble>(st);
3574  xDelete<IssmDouble>(s0gcm);
3575 }
3576 /*}}}*/
3577 #endif // _HAVE_SEMIC_
3578 int Element::Sid(){/*{{{*/
3579 
3580  return this->sid;
3581 
3582 }
3583 /*}}}*/
3584 void Element::SmbGemb(IssmDouble timeinputs, int count){/*{{{*/
3585 
3586  /*only compute SMB at the surface: */
3587  if (!IsOnSurface()) return;
3588 
3589  /*Intermediary variables: {{{*/
3590  bool isinitialized;
3591  IssmDouble zTop=0.0;
3592  IssmDouble dzTop=0.0;
3593  IssmDouble zMax=0.0;
3594  IssmDouble zMin=0.0;
3595  IssmDouble zY=0.0;
3596  IssmDouble dzMin=0.0;
3597  IssmDouble Tmean=0.0;
3598  IssmDouble Vmean=0.0;
3599  IssmDouble C=0.0;
3600  IssmDouble Tz,Vz=0.0;
3601  IssmDouble yts;
3602  IssmDouble Ta=0.0;
3603  IssmDouble V=0.0;
3604  IssmDouble dlw=0.0;
3605  IssmDouble dsw=0.0;
3606  IssmDouble P=0.0;
3607  IssmDouble eAir=0.0;
3608  IssmDouble pAir=0.0;
3609  IssmDouble teValue=1.0;
3610  IssmDouble aValue=0.0;
3611  IssmDouble dt,time,smb_dt;
3612  int aIdx=0;
3613  int denIdx=0;
3614  int dsnowIdx=0;
3615  int swIdx=0;
3616  IssmDouble cldFrac,t0wet, t0dry, K;
3617  IssmDouble lhf=0.0;
3618  IssmDouble shf=0.0;
3619  IssmDouble dayEC=0.0;
3620  IssmDouble initMass=0.0;
3621  IssmDouble sumR=0.0;
3622  IssmDouble sumM=0.0;
3623  IssmDouble sumMsurf=0.0;
3624  IssmDouble sumEC=0.0;
3625  IssmDouble sumP=0.0;
3626  IssmDouble sumW=0.0;
3627  IssmDouble sumMassAdd=0.0;
3628  IssmDouble fac=0.0;
3629  IssmDouble sumMass=0.0;
3630  IssmDouble dMass=0.0;
3631  bool isgraingrowth,isalbedo,isshortwave,isthermal,isaccumulation,ismelt,isdensification,isturbulentflux;
3632  bool isclimatology=false;
3633  bool isconstrainsurfaceT=false;
3634  IssmDouble init_scaling=0.0;
3635  IssmDouble thermo_scaling=1.0;
3636  IssmDouble adThresh=1023.0;
3637  /*}}}*/
3638  /*Output variables:{{{ */
3639  IssmDouble* dz=NULL;
3640  IssmDouble* d = NULL;
3641  IssmDouble* re = NULL;
3642  IssmDouble* gdn = NULL;
3643  IssmDouble* gsp = NULL;
3644  IssmDouble EC = 0.0;
3645  IssmDouble ulw = 0.0;
3646  IssmDouble netSW=0.0;
3647  IssmDouble netLW=0.0;
3648  IssmDouble meanULW=0.0;
3649  IssmDouble meanLHF=0.0;
3650  IssmDouble meanSHF=0.0;
3651  IssmDouble* W = NULL;
3652  IssmDouble* a = NULL;
3653  IssmDouble* swf=NULL;
3654  IssmDouble* T = NULL;
3655  IssmDouble T_bottom = 0.0;
3656  IssmDouble M = 0.0;
3657  IssmDouble Msurf = 0.0;
3658  IssmDouble R = 0.0;
3659  IssmDouble mAdd = 0.0;
3660  IssmDouble dz_add = 0.0;
3661  IssmDouble* dzini=NULL;
3662  IssmDouble* dini = NULL;
3663  IssmDouble* reini = NULL;
3664  IssmDouble* gdnini = NULL;
3665  IssmDouble* gspini = NULL;
3666  IssmDouble* Wini = NULL;
3667  IssmDouble* aini = NULL;
3668  IssmDouble* Tini = NULL;
3669  int m=0;
3670  /*}}}*/
3671 
3672  /*Retrieve material properties and parameters:{{{ */
3677  parameters->FindParam(&time,TimeEnum); /*transient core time at which we run the smb core*/
3678  parameters->FindParam(&dt,TimesteppingTimeStepEnum); /*transient core time step*/
3680  parameters->FindParam(&smb_dt,SmbDtEnum); /*time period for the smb solution, usually smaller than the glaciological dt*/
3684  parameters->FindParam(&dsnowIdx,SmbDsnowIdxEnum);
3685  parameters->FindParam(&cldFrac,SmbCldFracEnum);
3689  parameters->FindParam(&isgraingrowth,SmbIsgraingrowthEnum);
3690  parameters->FindParam(&isalbedo,SmbIsalbedoEnum);
3691  parameters->FindParam(&isshortwave,SmbIsshortwaveEnum);
3692  parameters->FindParam(&isthermal,SmbIsthermalEnum);
3693  parameters->FindParam(&isaccumulation,SmbIsaccumulationEnum);
3695  parameters->FindParam(&isdensification,SmbIsdensificationEnum);
3696  parameters->FindParam(&isturbulentflux,SmbIsturbulentfluxEnum);
3697  parameters->FindParam(&isconstrainsurfaceT,SmbIsconstrainsurfaceTEnum);
3700  parameters->FindParam(&adThresh,SmbAdThreshEnum);
3701  /*}}}*/
3702  /*Retrieve inputs: {{{*/
3703  Input2 *zTop_input = this->GetInput2(SmbZTopEnum); _assert_(zTop_input);
3704  Input2 *dzTop_input = this->GetInput2(SmbDzTopEnum); _assert_(dzTop_input);
3705  Input2 *dzMin_input = this->GetInput2(SmbDzMinEnum); _assert_(dzMin_input);
3706  Input2 *zMax_input = this->GetInput2(SmbZMaxEnum); _assert_(zMax_input);
3707  Input2 *zMin_input = this->GetInput2(SmbZMinEnum); _assert_(zMin_input);
3708  Input2 *zY_input = this->GetInput2(SmbZYEnum); _assert_(zY_input);
3709  Input2 *Tmean_input = this->GetInput2(SmbTmeanEnum); _assert_(Tmean_input);
3710  Input2 *Vmean_input = this->GetInput2(SmbVmeanEnum); _assert_(Vmean_input);
3711  Input2 *C_input = this->GetInput2(SmbCEnum); _assert_(C_input);
3712  Input2 *Tz_input = this->GetInput2(SmbTzEnum); _assert_(Tz_input);
3713  Input2 *Vz_input = this->GetInput2(SmbVzEnum); _assert_(Vz_input);
3714  Input2 *EC_input = NULL;
3715 
3716  /*Retrieve input values:*/
3717  Gauss* gauss=this->NewGauss(1); gauss->GaussPoint(0);
3718 
3719  this->GetInputValue(&isinitialized,SmbIsInitializedEnum);
3720  zTop_input->GetInputValue(&zTop,gauss);
3721  dzTop_input->GetInputValue(&dzTop,gauss);
3722  dzMin_input->GetInputValue(&dzMin,gauss);
3723  zMax_input->GetInputValue(&zMax,gauss);
3724  zMin_input->GetInputValue(&zMin,gauss);
3725  zY_input->GetInputValue(&zY,gauss);
3726  Tmean_input->GetInputValue(&Tmean,gauss);
3727  Vmean_input->GetInputValue(&Vmean,gauss);
3728  C_input->GetInputValue(&C,gauss);
3729  Tz_input->GetInputValue(&Tz,gauss);
3730  Vz_input->GetInputValue(&Vz,gauss);
3731  /*}}}*/
3732 
3733  /*First, check that the initial structures have been setup in GEMB. If not, initialize profile variables: layer thickness dz, * density d, temperature T, etc. {{{*/
3734  if(!isinitialized){
3735  if(VerboseSmb() && this->Sid()==0)_printf0_("smb core: Initializing grid\n");
3736  //if(this->Sid()==1) for(int i=0;i<m;i++)_printf_("z[" << i << "]=" <<
3737  //dz[i] << "\n");
3738 
3739  this->inputs2->GetArray(SmbDziniEnum,this->lid,&dzini,&m);
3740  this->inputs2->GetArray(SmbDiniEnum,this->lid,&dini,&m);
3741  this->inputs2->GetArray(SmbReiniEnum,this->lid,&reini,&m);
3742  this->inputs2->GetArray(SmbGdniniEnum,this->lid,&gdnini,&m);
3743  this->inputs2->GetArray(SmbGspiniEnum,this->lid,&gspini,&m);
3744  this->inputs2->GetArray(SmbWiniEnum,this->lid,&Wini,&m);
3745  this->inputs2->GetArray(SmbAiniEnum,this->lid,&aini,&m);
3746  this->inputs2->GetArray(SmbTiniEnum,this->lid,&Tini,&m);
3747  EC_input = this->GetInput2(SmbECiniEnum); _assert_(EC_input);
3748  EC_input->GetInputAverage(&EC);
3749 
3750  /*Retrieve the correct value of m (without the zeroes at the end)*/
3751  this->GetInput2Value(&m,SmbSizeiniEnum);
3752 
3753  if(m==2){ //Snow properties are initialized with default values. Vertical grid has to be initialized too
3754  // if(VerboseSmb() && this->Sid()==0)_printf0_("Snow properties initialized w DEFAULT values\n");
3755 
3756  /*initialize profile variables:*/
3757  GembgridInitialize(&dz, &m, zTop, dzTop, zMax, zY);
3758 
3759  d = xNew<IssmDouble>(m); for(int i=0;i<m;i++)d[i]=dini[0]; //ice density [kg m-3]
3760  re = xNew<IssmDouble>(m); for(int i=0;i<m;i++)re[i]=reini[0]; //set grain size to old snow [mm]
3761  gdn = xNew<IssmDouble>(m); for(int i=0;i<m;i++)gdn[i]=gdnini[0]; //set grain dentricity to old snow
3762  gsp = xNew<IssmDouble>(m); for(int i=0;i<m;i++)gsp[i]=gspini[0]; //set grain sphericity to old snow
3763  W = xNew<IssmDouble>(m); for(int i=0;i<m;i++)W[i]=Wini[0]; //set water content to zero [kg m-2]
3764  a = xNew<IssmDouble>(m); for(int i=0;i<m;i++)a[i]=aini[0]; //set albedo equal to fresh snow [fraction]
3765  T = xNew<IssmDouble>(m); for(int i=0;i<m;i++)T[i]=Tmean; //set initial grid cell temperature to the annual mean temperature [K]
3766  /*/!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties)
3767  * because don't know Tmean yet when set default values.
3768  * Default value of 0C given in SMBgemb.m is overwritten here with value of Tmean*/
3769 
3770  //fixed lower temperature bounday condition - T is fixed
3771  T_bottom=T[m-1];
3772  }
3773  else{ //Retrieve snow properties from previous run. Need to provide values for all layers
3774  // if(VerboseSmb() && this->Sid()==0)_printf0_("Snow properties initialized w RESTART values\n");
3775 
3776  dz = xNew<IssmDouble>(m);for(int i=0;i<m;i++)dz[i]=dzini[i];
3777  d = xNew<IssmDouble>(m);for(int i=0;i<m;i++)d[i]=dini[i];
3778  re = xNew<IssmDouble>(m);for(int i=0;i<m;i++)re[i]=reini[i];
3779  gdn = xNew<IssmDouble>(m);for(int i=0;i<m;i++)gdn[i]=gdnini[i];
3780  gsp = xNew<IssmDouble>(m);for(int i=0;i<m;i++)gsp[i]=gspini[i];
3781  W = xNew<IssmDouble>(m);for(int i=0;i<m;i++)W[i]=Wini[i];
3782  a = xNew<IssmDouble>(m);for(int i=0;i<m;i++)a[i]=aini[i];
3783  T = xNew<IssmDouble>(m);for(int i=0;i<m;i++)T[i]=Tini[i];
3784 
3785  //fixed lower temperature bounday condition - T is fixed
3786  _assert_(m>0);
3787  T_bottom=T[m-1];
3788  }
3789 
3790  /*Flag the initialization:*/
3791  this->SetBoolInput(this->inputs2,SmbIsInitializedEnum,true);
3792  }
3793  else{
3794  /*Recover inputs: */
3795  this->inputs2->GetArray(SmbDzEnum,this->lid,&dz,&m);
3796  this->inputs2->GetArray(SmbDEnum,this->lid,&d,&m);
3797  this->inputs2->GetArray(SmbReEnum,this->lid,&re,&m);
3798  this->inputs2->GetArray(SmbGdnEnum,this->lid,&gdn,&m);
3799  this->inputs2->GetArray(SmbGspEnum,this->lid,&gsp,&m);
3800  this->inputs2->GetArray(SmbWEnum,this->lid,&W,&m);
3801  this->inputs2->GetArray(SmbAEnum,this->lid,&a,&m);
3802  this->inputs2->GetArray(SmbTEnum,this->lid,&T,&m);
3803  EC_input = this->GetInput2(SmbECDtEnum); _assert_(EC_input);
3804  EC_input->GetInputAverage(&EC);
3805 
3806  //fixed lower temperature bounday condition - T is fixed
3807  _assert_(m>0);
3808  T_bottom=T[m-1];
3809  } /*}}}*/
3810 
3811  // determine initial mass [kg]
3812  initMass=0; for(int i=0;i<m;i++) initMass += dz[i]*d[i] + W[i];
3813 
3814  // initialize cumulative variables
3815  sumR = 0; sumM = 0; sumEC = 0; sumP = 0; sumMassAdd = 0; sumMsurf = 0;
3816 
3817  //before starting loop, realize that the transient core runs this smb_core at time = time +deltaT.
3818  //go back to time - deltaT:
3819  time-=dt;
3820 
3821  if(VerboseSmb() && this->Sid()==0 && IssmComm::GetRank()==0)_printf0_("Time: t=" << setprecision(8) << timeinputs/365.0/24.0/3600.0 << " yr/" << (time+dt)/365.0/24.0/3600.0 << " yr" << setprecision(3) << " Step: " << count << "\n");
3822 
3823  /*Get daily accumulated inputs {{{*/
3824  if (count>1){
3825  Input2 *sumEC_input = this->GetInput2(SmbECEnum); _assert_(sumEC_input);
3826  Input2 *sumM_input = this->GetInput2(SmbMeltEnum); _assert_(sumM_input);
3827  Input2 *sumR_input = this->GetInput2(SmbRunoffEnum); _assert_(sumR_input);
3828  Input2 *sumP_input = this->GetInput2(SmbPrecipitationEnum); _assert_(sumP_input);
3829  Input2 *ULW_input = this->GetInput2(SmbMeanULWEnum); _assert_(ULW_input);
3830  Input2 *LW_input = this->GetInput2(SmbNetLWEnum); _assert_(LW_input);
3831  Input2 *SW_input = this->GetInput2(SmbNetSWEnum); _assert_(SW_input);
3832  Input2 *LHF_input = this->GetInput2(SmbMeanLHFEnum); _assert_(LHF_input);
3833  Input2 *SHF_input = this->GetInput2(SmbMeanSHFEnum); _assert_(SHF_input);
3834  Input2 *DzAdd_input = this->GetInput2(SmbDzAddEnum); _assert_(DzAdd_input);
3835  Input2 *MassAdd_input = this->GetInput2(SmbMAddEnum); _assert_(MassAdd_input);
3836  Input2 *InitMass_input = this->GetInput2(SmbMInitnum); _assert_(InitMass_input);
3837  Input2 *sumMsurf_input = this->GetInput2(SmbMSurfEnum); _assert_(sumMsurf_input);
3838 
3839  ULW_input->GetInputAverage(&meanULW);
3840  LW_input->GetInputAverage(&netLW);
3841  SW_input->GetInputAverage(&netSW);
3842  LHF_input->GetInputAverage(&meanLHF);
3843  SHF_input->GetInputAverage(&meanSHF);
3844  DzAdd_input->GetInputAverage(&dz_add);
3845  MassAdd_input->GetInputAverage(&sumMassAdd);
3846  sumMassAdd=sumMassAdd*dt;
3847  InitMass_input->GetInputAverage(&initMass);
3848  sumEC_input->GetInputAverage(&sumEC);
3849  sumEC=sumEC*dt*rho_ice;
3850  sumM_input->GetInputAverage(&sumM);
3851  sumM=sumM*dt*rho_ice;
3852  sumMsurf_input->GetInputAverage(&sumMsurf);
3853  sumMsurf=sumMsurf*dt*rho_ice;
3854  sumR_input->GetInputAverage(&sumR);
3855  sumR=sumR*dt*rho_ice;
3856  sumP_input->GetInputAverage(&sumP);
3857  sumP=sumP*dt*rho_ice;
3858  }
3859  /*}}}*/
3860 
3861  // Get time forcing inputs
3862  Input2 *Ta_input = this->GetInput2(SmbTaEnum,timeinputs); _assert_(Ta_input);
3863  Input2 *V_input = this->GetInput2(SmbVEnum,timeinputs); _assert_(V_input);
3864  Input2 *Dlwr_input= this->GetInput2(SmbDlwrfEnum,timeinputs); _assert_(Dlwr_input);
3865  Input2 *Dswr_input= this->GetInput2(SmbDswrfEnum,timeinputs); _assert_(Dswr_input);
3866  Input2 *P_input = this->GetInput2(SmbPEnum,timeinputs); _assert_(P_input);
3867  Input2 *eAir_input= this->GetInput2(SmbEAirEnum,timeinputs); _assert_(eAir_input);
3868  Input2 *pAir_input= this->GetInput2(SmbPAirEnum,timeinputs); _assert_(pAir_input);
3869  Input2 *teValue_input= this->GetInput2(SmbTeValueEnum,timeinputs); _assert_(teValue_input);
3870  Input2 *aValue_input= this->GetInput2(SmbAValueEnum,timeinputs); _assert_(aValue_input);
3871 
3872  /*extract daily data:{{{*/
3873  Ta_input->GetInputValue(&Ta,gauss);//screen level air temperature [K]
3874  V_input->GetInputValue(&V,gauss); //wind speed [m s-1]
3875  Dlwr_input->GetInputValue(&dlw,gauss); //downward longwave radiation flux [W m-2]
3876  Dswr_input->GetInputValue(&dsw,gauss); //downward shortwave radiation flux [W m-2]
3877  P_input->GetInputValue(&P,gauss); //precipitation [kg m-2]
3878  eAir_input->GetInputValue(&eAir,gauss); //screen level vapor pressure [Pa]
3879  pAir_input->GetInputValue(&pAir,gauss); // screen level air pressure [Pa]
3880  teValue_input->GetInputValue(&teValue,gauss); // Emissivity [0-1]
3881  aValue_input->GetInputValue(&aValue,gauss); // Albedo [0 1]
3882  //_printf_("Time: " << t << " Ta: " << Ta << " V: " << V << " dlw: " << dlw << " dsw: " << dsw << " P: " << P << " eAir: " << eAir << " pAir: " << pAir << "\n");
3883  /*}}}*/
3884 
3885  /*Snow grain metamorphism:*/
3886  if(isgraingrowth)grainGrowth(&re, &gdn, &gsp, T, dz, d, W, smb_dt, m, aIdx,this->Sid());
3887 
3888  /*Snow, firn and ice albedo:*/
3889  if(isalbedo)albedo(&a,aIdx,re,dz,d,cldFrac,aIce,aSnow,aValue,adThresh,T,W,P,EC,Msurf,t0wet,t0dry,K,smb_dt,rho_ice,m,this->Sid());
3890 
3891  /*Distribution of absorbed short wave radation with depth:*/
3892  if(isshortwave)shortwave(&swf, swIdx, aIdx, dsw, a[0], d, dz, re,rho_ice,m,this->Sid());
3893 
3894  /*Calculate net shortwave [W m-2]*/
3895  netSW = netSW + cellsum(swf,m)*smb_dt/dt;
3896 
3897  if(isconstrainsurfaceT){
3898  if (m>0) T[0]=Ta;
3899  if (m>1) T[1]=Ta;
3900  }
3901  /*Thermal profile computation:*/
3902  if(isthermal)thermo(&EC, &T, &ulw, dz, d, swf, dlw, Ta, V, eAir, pAir, teValue, W[0], smb_dt, m, Vz, Tz, thermo_scaling,rho_ice,this->Sid(),isconstrainsurfaceT);
3903 
3904  /*Change in thickness of top cell due to evaporation/condensation assuming same density as top cell.
3905  * need to fix this in case all or more of cell evaporates */
3906  dz[0] = dz[0] + EC / d[0];
3907 
3908  /*Add snow/rain to top grid cell adjusting cell depth, temperature and density*/
3909  if(isaccumulation)accumulation(&T, &dz, &d, &W, &a, &re, &gdn, &gsp, &m, aIdx, dsnowIdx, Tmean, Ta, P, dzMin, aSnow, C, V, Vmean, rho_ice,this->Sid());
3910 
3911  /*Calculate water production, M [kg m-2] resulting from snow/ice temperature exceeding 273.15 deg K
3912  * (> 0 deg C), runoff R [kg m-2] and resulting changes in density and determine wet compaction [m]*/
3913  if(ismelt)melt(&M, &Msurf, &R, &mAdd, &dz_add, &T, &d, &dz, &W, &a, &re, &gdn, &gsp, &m, dzMin, zMax, zMin, zTop, zY, rho_ice,this->Sid());
3914 
3915  /*Allow non-melt densification and determine compaction [m]*/
3916  if(isdensification)densification(&d,&dz, T, re, denIdx, C, smb_dt, Tmean,rho_ice,m,this->Sid());
3917 
3918  /*Calculate upward longwave radiation flux [W m-2] not used in energy balance. Calculated for every
3919  * sub-time step in thermo equations*/
3920  //ulw = 5.67E-8 * pow(T[0],4.0) * teValue; // + deltatest here
3921 
3922  /*Calculate net longwave [W m-2]*/
3923  meanULW = meanULW + ulw*smb_dt/dt;
3924  netLW = netLW + (dlw - ulw)*smb_dt/dt;
3925 
3926  /*Calculate turbulent heat fluxes [W m-2]*/
3927  if(isturbulentflux)turbulentFlux(&shf, &lhf, &dayEC, Ta, T[0], V, eAir, pAir, d[0], W[0], Vz, Tz,rho_ice,this->Sid());
3928 
3929  /*Verbose some results in debug mode: {{{*/
3930  if(VerboseSmb() && 0){
3931  _printf_("smb log: count[" << count << "] m[" << m << "] "
3932  << setprecision(16) << "T[" << cellsum(T,m) << "] "
3933  << "d[" << cellsum(d,m) << "] "
3934  << "dz[" << cellsum(dz,m) << "] "
3935  << "a[" << cellsum(a,m) << "] "
3936  << "W[" << cellsum(W,m) << "] "
3937  << "re[" << cellsum(re,m) << "] "
3938  << "gdn[" << cellsum(gdn,m) << "] "
3939  << "gsp[" << cellsum(gsp,m) << "] "
3940  << "swf[" << netSW << "] "
3941  << "lwf[" << netLW << "] "
3942  << "a[" << a << "] "
3943  << "te[" << teValue << "] "
3944  << "\n");
3945  } /*}}}*/
3946 
3947  meanLHF = meanLHF + lhf*smb_dt/dt;
3948  meanSHF = meanSHF + shf*smb_dt/dt;
3949 
3950  /*Sum component mass changes [kg m-2]*/
3951  sumMassAdd = mAdd + sumMassAdd;
3952  sumM = M + sumM;
3953  sumMsurf = Msurf + sumMsurf;
3954  sumR = R + sumR;
3955  sumW = cellsum(W,m);
3956  sumP = P + sumP;
3957  sumEC = sumEC + EC; // evap (-)/cond(+)
3958 
3959  /*Calculate total system mass:*/
3960  sumMass=0;
3961  fac=0;
3962  for(int i=0;i<m;i++){
3963  sumMass += dz[i]*d[i];
3964  if (d[i] > 0) fac += dz[i]*(rho_ice - fmin(d[i],rho_ice));
3965  }
3966 
3967  #if defined(_HAVE_AD_)
3968  /*we want to avoid the round operation at all cost. Not differentiable.*/
3969  _error_("not implemented yet");
3970  #else
3971  dMass = sumMass + sumR + sumW - sumP - sumEC - initMass - sumMassAdd;
3972  dMass = round(dMass * 100.0)/100.0;
3973 
3974  /*Check mass conservation:*/
3975  if (dMass != 0.0){
3976  _printf_("total system mass not conserved in MB function \n");
3977  }
3978  #endif
3979 
3980  /*Check bottom grid cell T is unchanged:*/
3981  if(VerboseSmb() && this->Sid()==0 && IssmComm::GetRank()==0){
3982  if (T[m-1]!=T_bottom) _printf_("T(end)~=T_bottom" << "\n");
3983  }
3984 
3985  /*Save generated inputs: */
3986  this->inputs2->SetArrayInput(SmbDzEnum,this->lid,dz,m);
3987  this->inputs2->SetArrayInput(SmbDEnum,this->lid,d,m);
3988  this->inputs2->SetArrayInput(SmbReEnum,this->lid,re,m);
3989  this->inputs2->SetArrayInput(SmbGdnEnum,this->lid,gdn,m);
3990  this->inputs2->SetArrayInput(SmbGspEnum,this->lid,gsp,m);
3991  this->inputs2->SetArrayInput(SmbTEnum,this->lid,T,m);
3992  this->inputs2->SetArrayInput(SmbWEnum,this->lid,W,m);
3993  this->inputs2->SetArrayInput(SmbAEnum,this->lid,a,m);
3994  this->SetElementInput(SmbECEnum,sumEC/dt/rho_ice);
3995  this->SetElementInput(SmbMassBalanceEnum,(sumP + sumEC -sumR)/dt/rho_ice);
3996  this->SetElementInput(SmbMeltEnum,sumM/dt/rho_ice);
3997  this->SetElementInput(SmbRunoffEnum,sumR/dt/rho_ice);
3998  this->SetElementInput(SmbPrecipitationEnum,sumP/dt/rho_ice);
3999  this->SetElementInput(SmbMeanULWEnum,meanULW);
4000  this->SetElementInput(SmbNetLWEnum,netLW);
4001  this->SetElementInput(SmbNetSWEnum,netSW);
4002  this->SetElementInput(SmbMeanLHFEnum,meanLHF);
4003  this->SetElementInput(SmbMeanSHFEnum,meanSHF);
4004  this->SetElementInput(SmbDzAddEnum,dz_add);
4005  this->SetElementInput(SmbMInitnum,initMass);
4006  this->SetElementInput(SmbMAddEnum,sumMassAdd/dt);
4007  this->SetElementInput(SmbMSurfEnum,sumMsurf/dt/rho_ice);
4008  this->SetElementInput(SmbWAddEnum,sumW/dt);
4009  this->SetElementInput(SmbFACEnum,fac/1000.); // output in meters
4010  this->SetElementInput(SmbECDtEnum,EC);
4011 
4012  /*Free allocations:{{{*/
4013  if(dz) xDelete<IssmDouble>(dz);
4014  if(d) xDelete<IssmDouble>(d);
4015  if(re) xDelete<IssmDouble>(re);
4016  if(gdn) xDelete<IssmDouble>(gdn);
4017  if(gsp) xDelete<IssmDouble>(gsp);
4018  if(W) xDelete<IssmDouble>(W);
4019  if(a) xDelete<IssmDouble>(a);
4020  if(T) xDelete<IssmDouble>(T);
4021  if(dzini) xDelete<IssmDouble>(dzini);
4022  if(dini) xDelete<IssmDouble>(dini);
4023  if(reini) xDelete<IssmDouble>(reini);
4024  if(gdnini) xDelete<IssmDouble>(gdnini);
4025  if(gspini) xDelete<IssmDouble>(gspini);
4026  if(Wini) xDelete<IssmDouble>(Wini);
4027  if(aini) xDelete<IssmDouble>(aini);
4028  if(Tini) xDelete<IssmDouble>(Tini);
4029  if(swf) xDelete<IssmDouble>(swf);
4030 
4031  delete gauss;
4032  /*}}}*/
4033 }
4034 /*}}}*/
4035 void Element::StrainRateESA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
4036 
4037  /*Intermediaries*/
4038  IssmDouble dvx[3];
4039  IssmDouble dvy[3];
4040 
4041  /*Check that both inputs have been found*/
4042  if(!vx_input || !vy_input){
4043  _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
4044  }
4045 
4046  /*Get strain rate assuming that epsilon has been allocated*/
4047  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
4048  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
4049  epsilon[0] = dvx[0]; // normal strain rate x-direction
4050  epsilon[1] = dvy[1]; // normal strain rate y-direction
4051  epsilon[2] = 0.5*(dvx[1] + dvy[0]); // shear strain rate
4052  epsilon[3] = 0.5*(dvx[1] - dvy[0]); // rotation rate
4053 
4054 }/*}}}*/
4055 void Element::StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input,Input2* vz_input){/*{{{*/
4056  /*Compute the 3d Strain Rate (6 components):
4057  *
4058  * epsilon=[exx eyy ezz exy exz eyz]
4059  */
4060 
4061  /*Intermediaries*/
4062  IssmDouble dvx[3];
4063  IssmDouble dvy[3];
4064  IssmDouble dvz[3];
4065 
4066  /*Check that both inputs have been found*/
4067  if (!vx_input || !vy_input || !vz_input){
4068  _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << ", vz: " << vz_input << "\n");
4069  }
4070 
4071  /*Get strain rate assuming that epsilon has been allocated*/
4072  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
4073  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
4074  vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
4075 
4076  epsilon[0] = dvx[0];
4077  epsilon[1] = dvy[1];
4078  epsilon[2] = dvz[2];
4079  epsilon[3] = 0.5*(dvx[1] + dvy[0]);
4080  epsilon[4] = 0.5*(dvx[2] + dvz[0]);
4081  epsilon[5] = 0.5*(dvy[2] + dvz[1]);
4082 
4083 }/*}}}*/
4084 void Element::StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
4085  /*Compute the 3d Blatter/HOStrain Rate (5 components):
4086  *
4087  * epsilon=[exx eyy exy exz eyz]
4088  *
4089  * with exz=1/2 du/dz
4090  * eyz=1/2 dv/dz
4091  *
4092  * the contribution of vz is neglected
4093  */
4094 
4095  /*Intermediaries*/
4096  IssmDouble dvx[3];
4097  IssmDouble dvy[3];
4098 
4099  /*Check that both inputs have been found*/
4100  if (!vx_input || !vy_input){
4101  _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
4102  }
4103 
4104  /*Get strain rate assuming that epsilon has been allocated*/
4105  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
4106  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
4107  epsilon[0] = dvx[0];
4108  epsilon[1] = dvy[1];
4109  epsilon[2] = 0.5*(dvx[1] + dvy[0]);
4110  epsilon[3] = 0.5*dvx[2];
4111  epsilon[4] = 0.5*dvy[2];
4112 
4113 }/*}}}*/
4114 void Element::StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
4115  /*Compute the 2d Blatter/HOStrain Rate (2 components):
4116  *
4117  * epsilon=[exx exz]
4118  *
4119  * with exz=1/2 du/dz
4120  *
4121  * the contribution of vz is neglected
4122  */
4123 
4124  /*Intermediaries*/
4125  IssmDouble dvx[3];
4126 
4127  /*Check that both inputs have been found*/
4128  if (!vx_input){
4129  _error_("Input missing. Here are the input pointers we have for vx: " << vx_input <<"\n");
4130  }
4131 
4132  /*Get strain rate assuming that epsilon has been allocated*/
4133  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
4134  epsilon[0] = dvx[0];
4135  epsilon[1] = 0.5*dvx[1];
4136 
4137 }/*}}}*/
4138 void Element::StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input,Input2* vy_input){/*{{{*/
4139 
4140  /*Intermediaries*/
4141  IssmDouble dvx[3];
4142  IssmDouble dvy[3];
4143 
4144  /*Check that both inputs have been found*/
4145  if(!vx_input || !vy_input){
4146  _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
4147  }
4148 
4149  /*Get strain rate assuming that epsilon has been allocated*/
4150  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
4151  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
4152  epsilon[0] = dvx[0];
4153  epsilon[1] = dvy[1];
4154  epsilon[2] = 0.5*(dvx[1] + dvy[0]);
4155 
4156 }/*}}}*/
4157 void Element::StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input2* vx_input){/*{{{*/
4158 
4159  /*Intermediaries*/
4160  IssmDouble dvx[3];
4161 
4162  /*Check that both inputs have been found*/
4163  if (!vx_input){
4164  _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << "\n");
4165  }
4166 
4167  /*Get strain rate assuming that epsilon has been allocated*/
4168  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
4169  *epsilon = dvx[0];
4170 
4171 }/*}}}*/
4173 
4174  /*Intermediaries*/
4175  IssmDouble *xyz_list = NULL;
4176  IssmDouble sigma_xx,sigma_yy,sigma_zz,sigma_xy,sigma_xz,sigma_yz;
4177  IssmDouble a,b,c,d,x[3],max;
4178  int dim,numroots;
4179 
4180  /*First: get stress tensor*/
4181  this->ComputeStressTensor();
4182 
4183  /*Get domain dimension*/
4184  this->FindParam(&dim,DomainDimensionEnum);
4185 
4186  /*Fetch number vertices and allocate memory*/
4187  const int NUM_VERTICES = this->GetNumberOfVertices();
4188 
4189  IssmDouble* maxprincipal = xNew<IssmDouble>(NUM_VERTICES);
4190 
4191  /*Retrieve all inputs and parameters*/
4192  this->GetVerticesCoordinatesBase(&xyz_list);
4193  Input2* sigma_xx_input = this->GetInput2(StressTensorxxEnum); _assert_(sigma_xx_input);
4194  Input2* sigma_yy_input = this->GetInput2(StressTensoryyEnum); _assert_(sigma_yy_input);
4195  Input2* sigma_xy_input = this->GetInput2(StressTensorxyEnum); _assert_(sigma_xy_input);
4196  Input2* sigma_xz_input = NULL;
4197  Input2* sigma_yz_input = NULL;
4198  Input2* sigma_zz_input = NULL;
4199  if(dim==3){
4200  sigma_xz_input = this->GetInput2(StressTensorxzEnum); _assert_(sigma_xz_input);
4201  sigma_yz_input = this->GetInput2(StressTensoryzEnum); _assert_(sigma_yz_input);
4202  sigma_zz_input = this->GetInput2(StressTensorzzEnum); _assert_(sigma_zz_input);
4203  }
4204 
4205  /*loop over vertices: */
4206  Gauss* gauss=this->NewGauss();
4207  for (int iv=0;iv<NUM_VERTICES;iv++){
4208  gauss->GaussVertex(iv);
4209 
4210  sigma_xx_input->GetInputValue(&sigma_xx,gauss);
4211  sigma_yy_input->GetInputValue(&sigma_yy,gauss);
4212  sigma_xy_input->GetInputValue(&sigma_xy,gauss);
4213  if(dim==3){
4214  sigma_xz_input->GetInputValue(&sigma_xz,gauss);
4215  sigma_yz_input->GetInputValue(&sigma_yz,gauss);
4216  sigma_zz_input->GetInputValue(&sigma_zz,gauss);
4217  }
4218 
4219  if(dim==2){
4220  a = 0.;
4221  b = 1.;
4222  c = -sigma_yy -sigma_xx;
4223  d = sigma_xx*sigma_yy - sigma_xy*sigma_xy;
4224  }
4225  else{
4226  a = -1.;
4227  b = sigma_xx+sigma_yy+sigma_zz;
4228  c = -sigma_xx*sigma_yy -sigma_xx*sigma_zz -sigma_yy*sigma_zz + sigma_xy*sigma_xy +sigma_xz*sigma_xz +sigma_yz*sigma_yz;
4229  d = sigma_xx*sigma_yy*sigma_zz - sigma_xx*sigma_yz*sigma_yz -sigma_yy*sigma_xz*sigma_xz - sigma_zz*sigma_xy*sigma_xy + 2.*sigma_xy*sigma_xz*sigma_yz;
4230  }
4231 
4232  /*Get roots of polynomials*/
4233  cubic(a,b,c,d,x,&numroots);
4234 
4235  /*Initialize maximum eigne value*/
4236  if(numroots>0){
4237  max = fabs(x[0]);
4238  }
4239  else{
4240  _error_("No eigen value found");
4241  }
4242 
4243  /*Get max*/
4244  for(int i=1;i<numroots;i++){
4245  if(fabs(x[i])>max) max = fabs(x[i]);
4246  }
4247 
4248  maxprincipal[iv]=max;
4249  }
4250 
4251  /*Create input*/
4252  this->AddInput2(StressMaxPrincipalEnum,maxprincipal,P1Enum);
4253 
4254  /*Clean up and return*/
4255  xDelete<IssmDouble>(maxprincipal);
4256  xDelete<IssmDouble>(xyz_list);
4257  delete gauss;
4258 }
4259 /*}}}*/
4261 
4262  /*Retrieve values of the mask defining the element: */
4263  for(int i=0;i<this->GetNumberOfVertices();i++){
4264  if(mask[this->vertices[i]->Sid()]<=0.){
4265  return 0.;
4266  }
4267  }
4268 
4269  /*Return: */
4270  return this->TotalFloatingBmb(scaled);
4271 }
4272 /*}}}*/
4274 
4275  /*Retrieve values of the mask defining the element: */
4276  for(int i=0;i<this->GetNumberOfVertices();i++){
4277  if(mask[this->vertices[i]->Sid()]<=0.){
4278  return 0.;
4279  }
4280  }
4281 
4282  /*Return: */
4283  return this->TotalGroundedBmb(scaled);
4284 }
4285 /*}}}*/
4286 IssmDouble Element::TotalSmb(IssmDouble* mask, bool scaled){/*{{{*/
4287 
4288  /*Retrieve values of the mask defining the element: */
4289  for(int i=0;i<this->GetNumberOfVertices();i++){
4290  if(mask[this->vertices[i]->Sid()]<=0.){
4291  return 0.;
4292  }
4293  }
4294 
4295  /*Return: */
4296  return this->TotalSmb(scaled);
4297 }
4298 /*}}}*/
4300 
4301  /*All nodes have the same Coordinate System*/
4302  int numnodes = this->GetNumberOfNodes();
4303  int* cs_array = xNew<int>(numnodes);
4304  for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
4305 
4306  /*Call core*/
4307  TransformInvStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
4308 
4309  /*Clean-up*/
4310  xDelete<int>(cs_array);
4311 }/*}}}*/
4312 void Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
4313 
4314  int i,j;
4315  int numdofs = 0;
4316  IssmDouble *transform = NULL;
4317  IssmDouble *values = NULL;
4318 
4319  /*Get total number of dofs*/
4320  for(i=0;i<numnodes;i++){
4321  switch(cs_array[i]){
4322  case PressureEnum: numdofs+=1; break;
4323  case XYEnum: numdofs+=2; break;
4324  case XYZEnum: numdofs+=3; break;
4325  default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
4326  }
4327  }
4328 
4329  /*Copy current stiffness matrix*/
4330  values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
4331  for(i=0;i<Ke->nrows;i++) for(j=0;j<Ke->ncols;j++) values[i*Ke->ncols+j]=Ke->values[i*Ke->ncols+j];
4332 
4333  /*Get Coordinate Systems transform matrix*/
4334  CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
4335 
4336  /*Transform matrix: R*Ke*R^T */
4337  TripleMultiply(transform,numdofs,numdofs,0,
4338  values,Ke->nrows,Ke->ncols,0,
4339  transform,numdofs,numdofs,1,
4340  &Ke->values[0],0);
4341 
4342  /*Free Matrix*/
4343  xDelete<IssmDouble>(transform);
4344  xDelete<IssmDouble>(values);
4345 }/*}}}*/
4346 void Element::TransformLoadVectorCoord(ElementVector* pe,int transformenum){/*{{{*/
4347 
4348  /*All nodes have the same Coordinate System*/
4349  int numnodes = this->GetNumberOfNodes();
4350  int* cs_array = xNew<int>(numnodes);
4351  for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
4352 
4353  /*Call core*/
4354  this->TransformLoadVectorCoord(pe,this->nodes,numnodes,cs_array);
4355 
4356  /*Clean-up*/
4357  xDelete<int>(cs_array);
4358 }/*}}}*/
4359 void Element::TransformLoadVectorCoord(ElementVector* pe,int* cs_array){/*{{{*/
4360 
4361  this->TransformLoadVectorCoord(pe,this->nodes,this->GetNumberOfNodes(),cs_array);
4362 
4363 }/*}}}*/
4364 void Element::TransformLoadVectorCoord(ElementVector* pe,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
4365 
4366  int i;
4367  int numdofs = 0;
4368  IssmDouble *transform = NULL;
4369  IssmDouble *values = NULL;
4370 
4371  /*Get total number of dofs*/
4372  for(i=0;i<numnodes;i++){
4373  switch(cs_array[i]){
4374  case PressureEnum: numdofs+=1; break;
4375  case XYEnum: numdofs+=2; break;
4376  case XYZEnum: numdofs+=3; break;
4377  default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
4378  }
4379  }
4380 
4381  /*Copy current load vector*/
4382  values=xNew<IssmDouble>(pe->nrows);
4383  for(i=0;i<pe->nrows;i++) values[i]=pe->values[i];
4384 
4385  /*Get Coordinate Systems transform matrix*/
4386  CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
4387 
4388  /*Transform matrix: R^T*pe */
4389  MatrixMultiply(transform,numdofs,numdofs,1,
4390  values,pe->nrows,1,0,
4391  &pe->values[0],0);
4392 
4393  /*Free Matrices*/
4394  xDelete<IssmDouble>(transform);
4395  xDelete<IssmDouble>(values);
4396 }/*}}}*/
4397 void Element::TransformSolutionCoord(IssmDouble* values,int transformenum){/*{{{*/
4398 
4399  /*All nodes have the same Coordinate System*/
4400  int numnodes = this->GetNumberOfNodes();
4401  int* cs_array = xNew<int>(numnodes);
4402  for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
4403 
4404  /*Call core*/
4405  this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
4406 
4407  /*Clean-up*/
4408  xDelete<int>(cs_array);
4409 }/*}}}*/
4410 void Element::TransformSolutionCoord(IssmDouble* values,int* transformenum_list){/*{{{*/
4411  this->TransformSolutionCoord(values,this->nodes,this->GetNumberOfNodes(),transformenum_list);
4412 }/*}}}*/
4413 void Element::TransformSolutionCoord(IssmDouble* values,int numnodes,int transformenum){/*{{{*/
4414 
4415  /*All nodes have the same Coordinate System*/
4416  int* cs_array = xNew<int>(numnodes);
4417  for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
4418 
4419  /*Call core*/
4420  this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
4421 
4422  /*Clean-up*/
4423  xDelete<int>(cs_array);
4424 }/*}}}*/
4425 void Element::TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array){/*{{{*/
4426  this->TransformSolutionCoord(solution,this->nodes,numnodes,cs_array);
4427 }/*}}}*/
4428 void Element::TransformSolutionCoord(IssmDouble* values,Node** nodes_list,int numnodes,int transformenum){/*{{{*/
4429  /*NOT NEEDED*/
4430  /*All nodes have the same Coordinate System*/
4431  int* cs_array = xNew<int>(numnodes);
4432  for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
4433 
4434  /*Call core*/
4435  this->TransformSolutionCoord(values,nodes_list,numnodes,cs_array);
4436 
4437  /*Clean-up*/
4438  xDelete<int>(cs_array);
4439 }/*}}}*/
4440 void Element::TransformSolutionCoord(IssmDouble* solution,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
4441 
4442  int i;
4443  int numdofs = 0;
4444  IssmDouble *transform = NULL;
4445  IssmDouble *values = NULL;
4446 
4447  /*Get total number of dofs*/
4448  for(i=0;i<numnodes;i++){
4449  switch(cs_array[i]){
4450  case PressureEnum: numdofs+=1; break;
4451  case XYEnum: numdofs+=2; break;
4452  case XYZEnum: numdofs+=3; break;
4453  default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
4454  }
4455  }
4456 
4457  /*Copy current solution vector*/
4458  values=xNew<IssmDouble>(numdofs);
4459  for(i=0;i<numdofs;i++) values[i]=solution[i];
4460 
4461  /*Get Coordinate Systems transform matrix*/
4462  CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
4463 
4464  /*Transform matrix: R*U */
4465  MatrixMultiply(transform,numdofs,numdofs,0,
4466  values,numdofs,1,0,
4467  &solution[0],0);
4468 
4469  /*Free Matrices*/
4470  xDelete<IssmDouble>(transform);
4471  xDelete<IssmDouble>(values);
4472 }/*}}}*/
4473 void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
4474 
4475  /*All nodes have the same Coordinate System*/
4476  int numnodes = this->GetNumberOfNodes();
4477  int* cs_array = xNew<int>(numnodes);
4478  for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
4479 
4480  /*Call core*/
4481  this->TransformStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
4482 
4483  /*Clean-up*/
4484  xDelete<int>(cs_array);
4485 }/*}}}*/
4486 void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* transformenum_list){/*{{{*/
4487  this->TransformStiffnessMatrixCoord(Ke,this->nodes,this->GetNumberOfNodes(),transformenum_list);
4488 }/*}}}*/
4489 void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
4490 
4491  int numdofs = 0;
4492  IssmDouble *transform = NULL;
4493  IssmDouble *values = NULL;
4494 
4495  /*Get total number of dofs*/
4496  for(int i=0;i<numnodes;i++){
4497  switch(cs_array[i]){
4498  case PressureEnum: numdofs+=1; break;
4499  case XYEnum: numdofs+=2; break;
4500  case XYZEnum: numdofs+=3; break;
4501  default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
4502  }
4503  }
4504 
4505  /*Copy current stiffness matrix*/
4506  values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
4507  for(int i=0;i<Ke->nrows*Ke->ncols;i++) values[i]=Ke->values[i];
4508 
4509  /*Get Coordinate Systems transform matrix*/
4510  CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
4511 
4512  /*Transform matrix: R^T*Ke*R */
4513  TripleMultiply(transform,numdofs,numdofs,1,
4514  values,Ke->nrows,Ke->ncols,0,
4515  transform,numdofs,numdofs,0,
4516  &Ke->values[0],0);
4517 
4518  /*Free Matrix*/
4519  xDelete<IssmDouble>(transform);
4520  xDelete<IssmDouble>(values);
4521 }/*}}}*/
4523 
4524  /*Intermediaries*/
4525  IssmDouble phi;
4526  IssmDouble thickness;
4527  IssmDouble *xyz_list = NULL;
4528 
4529  /*Fetch number vertices and allocate memory*/
4530  const int NUM_VERTICES = this->GetNumberOfVertices();
4531 
4532  IssmDouble* viscousheating = xNew<IssmDouble>(NUM_VERTICES);
4533 
4534  /*Retrieve all inputs and parameters*/
4535  this->GetVerticesCoordinates(&xyz_list);
4536  Input2* vx_input = this->GetInput2(VxEnum); _assert_(vx_input);
4537  Input2* vy_input = this->GetInput2(VyEnum); _assert_(vy_input);
4538  Input2* vz_input = this->GetInput2(VzEnum); _assert_(vz_input);
4539 
4540  /*loop over vertices: */
4541  Gauss* gauss=this->NewGauss();
4542  for (int iv=0;iv<NUM_VERTICES;iv++){
4543  gauss->GaussVertex(iv);
4544 
4545  this->ViscousHeating(&phi,xyz_list,gauss,vx_input,vy_input,vz_input);
4546 
4547  viscousheating[iv]=phi;
4548  }
4549 
4550  /*Create PentaVertex input, which will hold the basal friction:*/
4551  this->AddInput2(ViscousHeatingEnum,viscousheating,P1Enum);
4552 
4553  /*Clean up and return*/
4554  xDelete<IssmDouble>(viscousheating);
4555  xDelete<IssmDouble>(xyz_list);
4556  delete gauss;
4557 }
4558 /*}}}*/
4559 
4560 /*Enthalpy*/
4561 void Element::ThermalToEnthalpy(IssmDouble * penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure){/*{{{*/
4562 
4563  /*Ouput*/
4564  IssmDouble enthalpy;
4565 
4566  /*Get necessary parameters*/
4567  IssmDouble latentheat,referencetemperature,heatcapacity;
4569  parameters->FindParam(&referencetemperature,ConstantsReferencetemperatureEnum);
4571 
4572  if(temperature<TMeltingPoint(pressure)){
4573  enthalpy=heatcapacity*(temperature-referencetemperature);
4574  }
4575  else{
4576  enthalpy=PureIceEnthalpy(pressure)+latentheat*waterfraction;
4577  }
4578 
4579  /*Assign output pointers:*/
4580  *penthalpy=enthalpy;
4581 }
4582 /*}}}*/
4584 
4585  /*Get necessary parameters*/
4586  IssmDouble beta,meltingpoint;
4589 
4590  return meltingpoint-beta*pressure;
4591 }
4592 /*}}}*/
4593 void Element::EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
4594 
4595  /*Ouput*/
4596  IssmDouble temperature,waterfraction;
4597 
4598  /*Get necessary parameters*/
4599  IssmDouble latentheat,referencetemperature,heatcapacity;
4601  parameters->FindParam(&referencetemperature,ConstantsReferencetemperatureEnum);
4603 
4604  if(enthalpy<PureIceEnthalpy(pressure)){
4605  temperature=referencetemperature+enthalpy/heatcapacity;
4606  waterfraction=0.;
4607  }
4608  else{
4609  temperature=TMeltingPoint(pressure);
4610  waterfraction=(enthalpy-PureIceEnthalpy(pressure))/latentheat;
4611  }
4612 
4613  /*Assign output pointers:*/
4614  *pwaterfraction=waterfraction;
4615  *ptemperature=temperature;
4616 }
4617 /*}}}*/
4619 
4620  /*Get necessary parameters*/
4621  IssmDouble heatcapacity,thermalconductivity,temperateiceconductivity;
4623  parameters->FindParam(&thermalconductivity,MaterialsThermalconductivityEnum);
4624  parameters->FindParam(&temperateiceconductivity,MaterialsTemperateiceconductivityEnum);
4625 
4626  if(enthalpy<PureIceEnthalpy(pressure)){
4627  return thermalconductivity/heatcapacity;
4628  }
4629  else{
4630  return temperateiceconductivity/heatcapacity;
4631  }
4632 }
4633 /*}}}*/
4635 
4636  IssmDouble lambda; // fraction of cold ice
4637  IssmDouble kappa,kappa_c,kappa_t; //enthalpy conductivities
4638  IssmDouble Hc,Ht;
4639  IssmDouble* PIE = xNew<IssmDouble>(numvertices);
4640  IssmDouble* dHpmp = xNew<IssmDouble>(numvertices);
4641 
4642  for(int iv=0; iv<numvertices; iv++){
4643  PIE[iv]=PureIceEnthalpy(pressure[iv]);
4644  dHpmp[iv]=enthalpy[iv]-PIE[iv];
4645  }
4646 
4647  bool allequalsign=true;
4648  if(dHpmp[0]<0){
4649  for(int iv=1; iv<numvertices;iv++) allequalsign=(allequalsign && (dHpmp[iv]<0));
4650  }
4651  else{
4652  for(int iv=1; iv<numvertices;iv++) allequalsign=(allequalsign && (dHpmp[iv]>=0));
4653  }
4654 
4655  if(allequalsign){
4656  kappa=EnthalpyDiffusionParameter(enthalpy[0], pressure[0]);
4657  }
4658  else {
4659  /* return harmonic mean of thermal conductivities, weighted by fraction of cold/temperate ice,
4660  cf Patankar 1980, pp44 */
4661  kappa_c=EnthalpyDiffusionParameter(PureIceEnthalpy(0.)-1.,0.);
4662  kappa_t=EnthalpyDiffusionParameter(PureIceEnthalpy(0.)+1.,0.);
4663  Hc=0.; Ht=0.;
4664  for(int iv=0; iv<numvertices;iv++){
4665  if(enthalpy[iv]<PIE[iv])
4666  Hc+=(PIE[iv]-enthalpy[iv]);
4667  else
4668  Ht+=(enthalpy[iv]-PIE[iv]);
4669  }
4670  _assert_((Hc+Ht)>0.);
4671  lambda = Hc/(Hc+Ht);
4672  kappa = 1./(lambda/kappa_c + (1.-lambda)/kappa_t);
4673  }
4674 
4675  /*Clean up and return*/
4676  xDelete<IssmDouble>(PIE);
4677  xDelete<IssmDouble>(dHpmp);
4678  return kappa;
4679 }
4680 /*}}}*/
4682 
4683  /*Get necessary parameters*/
4684  IssmDouble referencetemperature,heatcapacity;
4685  parameters->FindParam(&referencetemperature,ConstantsReferencetemperatureEnum);
4687 
4688  return heatcapacity*(TMeltingPoint(pressure)-referencetemperature);
4689 }
4690 /*}}}*/
GroundingOnlyEnum
@ GroundingOnlyEnum
Definition: EnumDefinitions.h:1091
MaterialsThermalconductivityEnum
@ MaterialsThermalconductivityEnum
Definition: EnumDefinitions.h:268
Element::IsGrounded
bool IsGrounded()
Definition: Element.cpp:2011
Element::StrainRateESA
void StrainRateESA(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:4035
melt
void melt(IssmDouble *pM, IssmDouble *pMs, IssmDouble *pR, IssmDouble *pmAdd, IssmDouble *pdz_add, IssmDouble **pT, IssmDouble **pd, IssmDouble **pdz, IssmDouble **pW, IssmDouble **pa, IssmDouble **pre, IssmDouble **pgdn, IssmDouble **pgsp, int *pn, IssmDouble dzMin, IssmDouble zMax, IssmDouble zMin, IssmDouble zTop, IssmDouble zY, IssmDouble dIce, int sid)
Definition: Gembx.cpp:1374
SmbAIceEnum
@ SmbAIceEnum
Definition: EnumDefinitions.h:342
BasalforcingsPicoBasinIdEnum
@ BasalforcingsPicoBasinIdEnum
Definition: EnumDefinitions.h:486
DamageDOldEnum
@ DamageDOldEnum
Definition: EnumDefinitions.h:517
Element::TotalFloatingBmb
IssmDouble TotalFloatingBmb(IssmDouble *mask, bool scaled)
Definition: Element.cpp:4260
Element::GetVerticesConnectivityList
void GetVerticesConnectivityList(int *connectivitylist)
Definition: Element.cpp:1440
BasalforcingsOceanTempEnum
@ BasalforcingsOceanTempEnum
Definition: EnumDefinitions.h:485
Input2::GetResultArraySize
virtual int GetResultArraySize(void)
Definition: Input2.h:50
Element::TransformStiffnessMatrixCoord
void TransformStiffnessMatrixCoord(ElementMatrix *Ke, int cs_enum)
Definition: Element.cpp:4473
TimesteppingFinalTimeEnum
@ TimesteppingFinalTimeEnum
Definition: EnumDefinitions.h:430
SmbDEnum
@ SmbDEnum
Definition: EnumDefinitions.h:715
SmbRunoffSubstepEnum
@ SmbRunoffSubstepEnum
Definition: EnumDefinitions.h:773
NewDamageEnum
@ NewDamageEnum
Definition: EnumDefinitions.h:658
Element::lid
int lid
Definition: Element.h:46
SmbTemperaturesReconstructedEnum
@ SmbTemperaturesReconstructedEnum
Definition: EnumDefinitions.h:787
SmbIsalbedoEnum
@ SmbIsalbedoEnum
Definition: EnumDefinitions.h:362
BaseEnum
@ BaseEnum
Definition: EnumDefinitions.h:495
StressTensorxxEnum
@ StressTensorxxEnum
Definition: EnumDefinitions.h:811
Element::SetIntInput
void SetIntInput(Inputs2 *inputs2, int enum_in, int value)
Definition: Element.cpp:3362
Element::GetElementType
virtual int GetElementType(void)=0
SmbMassBalanceEnum
@ SmbMassBalanceEnum
Definition: EnumDefinitions.h:748
CalvingVonmisesEnum
@ CalvingVonmisesEnum
Definition: EnumDefinitions.h:1004
TransientInput2Enum
@ TransientInput2Enum
Definition: EnumDefinitions.h:1315
Element::DeepEcho
void DeepEcho()
Definition: Element.cpp:397
Element::ComputeStrainRate
void ComputeStrainRate()
Definition: Element.cpp:244
Element::GetInputListOnNodes
void GetInputListOnNodes(IssmDouble *pvalue, int enumtype)
Definition: Element.cpp:1106
EstarLambdaS
IssmDouble EstarLambdaS(IssmDouble epseff, IssmDouble epsprime_norm)
Definition: EstarComponents.cpp:118
DeviatoricStressxzEnum
@ DeviatoricStressxzEnum
Definition: EnumDefinitions.h:526
SmbZYEnum
@ SmbZYEnum
Definition: EnumDefinitions.h:800
_assert_
#define _assert_(ignore)
Definition: exceptions.h:37
SmbIsprecipscaledEnum
@ SmbIsprecipscaledEnum
Definition: EnumDefinitions.h:372
SmbS0tEnum
@ SmbS0tEnum
Definition: EnumDefinitions.h:777
SmbDtEnum
@ SmbDtEnum
Definition: EnumDefinitions.h:357
IssmDouble
double IssmDouble
Definition: types.h:37
Element::TransformSolutionCoord
void TransformSolutionCoord(IssmDouble *solution, int cs_enum)
Definition: Element.cpp:4397
SmbAccumulationEnum
@ SmbAccumulationEnum
Definition: EnumDefinitions.h:708
Element::IsOnBase
bool IsOnBase()
Definition: Element.cpp:1984
SmbIsturbulentfluxEnum
@ SmbIsturbulentfluxEnum
Definition: EnumDefinitions.h:377
grainGrowth
void grainGrowth(IssmDouble **pre, IssmDouble **pgdn, IssmDouble **pgsp, IssmDouble *T, IssmDouble *dz, IssmDouble *d, IssmDouble *W, IssmDouble smb_dt, int m, int aIdx, int sid)
Definition: Gembx.cpp:199
SmbReEnum
@ SmbReEnum
Definition: EnumDefinitions.h:769
SmbIsdensificationEnum
@ SmbIsdensificationEnum
Definition: EnumDefinitions.h:367
TetraEnum
@ TetraEnum
Definition: EnumDefinitions.h:1300
DatasetInput2
Definition: DatasetInput2.h:14
Element::GetDofList
void GetDofList(int **pdoflist, int approximation_enum, int setenum)
Definition: Element.cpp:961
SmbAEnum
@ SmbAEnum
Definition: EnumDefinitions.h:706
SmbAValueEnum
@ SmbAValueEnum
Definition: EnumDefinitions.h:707
SmbDailydsradiationEnum
@ SmbDailydsradiationEnum
Definition: EnumDefinitions.h:719
InversionNumControlParametersEnum
@ InversionNumControlParametersEnum
Definition: EnumDefinitions.h:223
Element::GetNumberOfNodes
virtual int GetNumberOfNodes(void)=0
SmbWiniEnum
@ SmbWiniEnum
Definition: EnumDefinitions.h:796
SmbSwIdxEnum
@ SmbSwIdxEnum
Definition: EnumDefinitions.h:390
GroundinglineMigrationEnum
@ GroundinglineMigrationEnum
Definition: EnumDefinitions.h:161
BasalforcingsIsmip6IsLocalEnum
@ BasalforcingsIsmip6IsLocalEnum
Definition: EnumDefinitions.h:69
ContactEnum
@ ContactEnum
Definition: EnumDefinitions.h:1014
_printf0_
#define _printf0_(StreamArgs)
Definition: Print.h:29
Element::FindParam
void FindParam(bool *pvalue, int paramenum)
Definition: Element.cpp:933
Element::SetBoolInput
void SetBoolInput(Inputs2 *inputs2, int enum_in, bool value)
Definition: Element.cpp:3355
BasalforcingsPicoAverageSalinityEnum
@ BasalforcingsPicoAverageSalinityEnum
Definition: EnumDefinitions.h:77
SmbReiniEnum
@ SmbReiniEnum
Definition: EnumDefinitions.h:771
SmbSealevEnum
@ SmbSealevEnum
Definition: EnumDefinitions.h:388
StressbalanceAnalysisEnum
@ StressbalanceAnalysisEnum
Definition: EnumDefinitions.h:1285
Element::dViscositydDSSA
void dViscositydDSSA(IssmDouble *pdmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:874
Element::DatasetInputExtrude
virtual void DatasetInputExtrude(int input_enum, int start)
Definition: Element.h:275
GroundinglineHeightEnum
@ GroundinglineHeightEnum
Definition: EnumDefinitions.h:596
CalvingMeltingFluxLevelsetEnum
@ CalvingMeltingFluxLevelsetEnum
Definition: EnumDefinitions.h:513
BasalforcingsThresholdThicknessEnum
@ BasalforcingsThresholdThicknessEnum
Definition: EnumDefinitions.h:89
DeviatoricStressyzEnum
@ DeviatoricStressyzEnum
Definition: EnumDefinitions.h:528
SmbT0dryEnum
@ SmbT0dryEnum
Definition: EnumDefinitions.h:391
SmbMeanULWEnum
@ SmbMeanULWEnum
Definition: EnumDefinitions.h:753
Material::GetViscosity_D
virtual void GetViscosity_D(IssmDouble *pviscosity, IssmDouble epseff, Gauss *gauss)=0
Element::PicoUpdateBoxid
void PicoUpdateBoxid(int *pmax_boxid_basin)
Definition: Element.cpp:2509
Element::HasNodeOnSurface
bool HasNodeOnSurface()
Definition: Element.cpp:1565
SoftMigrationEnum
@ SoftMigrationEnum
Definition: EnumDefinitions.h:1277
Vertex::Pid
int Pid(void)
Definition: Vertex.cpp:164
SmbTEnum
@ SmbTEnum
Definition: EnumDefinitions.h:781
_printf_
#define _printf_(StreamArgs)
Definition: Print.h:22
BasalforcingsPicoSubShelfOceanOverturningEnum
@ BasalforcingsPicoSubShelfOceanOverturningEnum
Definition: EnumDefinitions.h:489
SmbVEnum
@ SmbVEnum
Definition: EnumDefinitions.h:791
SmbTmeanEnum
@ SmbTmeanEnum
Definition: EnumDefinitions.h:789
Element::SmbGradCompParameterization
void SmbGradCompParameterization(void)
Definition: Element.cpp:657
SmbPAirEnum
@ SmbPAirEnum
Definition: EnumDefinitions.h:760
GembgridInitialize
void GembgridInitialize(IssmDouble **pdz, int *psize, IssmDouble zTop, IssmDouble dzTop, IssmDouble zMax, IssmDouble zY)
Definition: Gembx.cpp:87
MeshNumberoflayersEnum
@ MeshNumberoflayersEnum
Definition: EnumDefinitions.h:272
Node::GetDofListLocal
void GetDofListLocal(int *poutdoflist, int approximation_enum, int setenum)
Definition: Node.cpp:455
SmbFACEnum
@ SmbFACEnum
Definition: EnumDefinitions.h:739
SmbMSurfEnum
@ SmbMSurfEnum
Definition: EnumDefinitions.h:757
MaskOceanLevelsetEnum
@ MaskOceanLevelsetEnum
Definition: EnumDefinitions.h:640
SSAHOApproximationEnum
@ SSAHOApproximationEnum
Definition: EnumDefinitions.h:1257
SmbDzAddEnum
@ SmbDzAddEnum
Definition: EnumDefinitions.h:728
DeviatoricStress2Enum
@ DeviatoricStress2Enum
Definition: EnumDefinitions.h:531
MaskIceLevelsetEnum
@ MaskIceLevelsetEnum
Definition: EnumDefinitions.h:641
SmbDzTopEnum
@ SmbDzTopEnum
Definition: EnumDefinitions.h:731
TimeEnum
@ TimeEnum
Definition: EnumDefinitions.h:427
ADD_VAL
@ ADD_VAL
Definition: toolkitsenums.h:14
SmbECEnum
@ SmbECEnum
Definition: EnumDefinitions.h:734
SmbAccurefEnum
@ SmbAccurefEnum
Definition: EnumDefinitions.h:347
MaterialsRhoFreshwaterEnum
@ MaterialsRhoFreshwaterEnum
Definition: EnumDefinitions.h:263
MaterialsMeltingpointEnum
@ MaterialsMeltingpointEnum
Definition: EnumDefinitions.h:259
MARSHALLING_ENUM
#define MARSHALLING_ENUM(EN)
Definition: Marshalling.h:14
TimesteppingTimeStepEnum
@ TimesteppingTimeStepEnum
Definition: EnumDefinitions.h:433
Inputs2::Echo
void Echo(void)
Definition: Inputs2.cpp:73
SmbDiniEnum
@ SmbDiniEnum
Definition: EnumDefinitions.h:725
DeviatoricStressxxEnum
@ DeviatoricStressxxEnum
Definition: EnumDefinitions.h:524
PentaInput2::SetInput
void SetInput(int interp_in, int row, IssmDouble value_in)
Definition: PentaInput2.cpp:154
Element::TransformInvStiffnessMatrixCoord
void TransformInvStiffnessMatrixCoord(ElementMatrix *Ke, int cs_enum)
Definition: Element.cpp:4299
IoModel::my_vertices_lids
int * my_vertices_lids
Definition: IoModel.h:73
SmbZMaxEnum
@ SmbZMaxEnum
Definition: EnumDefinitions.h:797
BedEnum
@ BedEnum
Definition: EnumDefinitions.h:499
P0Enum
@ P0Enum
Definition: EnumDefinitions.h:661
TransientInput2
Definition: TransientInput2.h:13
Element::NewElementMatrixCoupling
ElementMatrix * NewElementMatrixCoupling(int number_nodes, int approximation_enum=NoneApproximationEnum)
Definition: Element.cpp:2501
EstarStrainrateQuantities
void EstarStrainrateQuantities(IssmDouble *pepsprime_norm, IssmDouble vx, IssmDouble vy, IssmDouble vz, IssmDouble vmag, IssmDouble *dvx, IssmDouble *dvy, IssmDouble *dvz, IssmDouble *dvmag)
Definition: EstarComponents.cpp:5
Element::IceVolumeAboveFloatation
IssmDouble IceVolumeAboveFloatation(IssmDouble *mask, bool scaled)
Definition: Element.cpp:1607
Element::dViscositydBHO
void dViscositydBHO(IssmDouble *pdmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:800
Element::StrainRateFS
void StrainRateFS(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input)
Definition: Element.cpp:4055
Element::CalvingRateVonmises
virtual void CalvingRateVonmises(void)
Definition: Element.h:221
SmbGdnEnum
@ SmbGdnEnum
Definition: EnumDefinitions.h:740
Element::ResultToVector
void ResultToVector(Vector< IssmDouble > *vector, int output_enum)
Definition: Element.cpp:3299
ElementVector::nrows
int nrows
Definition: ElementVector.h:23
SmbWEnum
@ SmbWEnum
Definition: EnumDefinitions.h:794
albedo
void albedo(IssmDouble **pa, int aIdx, IssmDouble *re, IssmDouble *dz, IssmDouble *d, IssmDouble cldFrac, IssmDouble aIce, IssmDouble aSnow, IssmDouble aValue, IssmDouble adThresh, IssmDouble *TK, IssmDouble *W, IssmDouble P, IssmDouble EC, IssmDouble Msurf, IssmDouble t0wet, IssmDouble t0dry, IssmDouble K, IssmDouble dt, IssmDouble dIce, int m, int sid)
Definition: Gembx.cpp:404
EsaRotationrateEnum
@ EsaRotationrateEnum
Definition: EnumDefinitions.h:562
MeshVertexonbaseEnum
@ MeshVertexonbaseEnum
Definition: EnumDefinitions.h:653
Element::MantlePlumeGeothermalFlux
void MantlePlumeGeothermalFlux()
Definition: Element.cpp:2175
BasalforcingsPicoGammaTEnum
@ BasalforcingsPicoGammaTEnum
Definition: EnumDefinitions.h:82
Element::EnthalpyDiffusionParameter
IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy, IssmDouble pressure)
Definition: Element.cpp:4618
BasalforcingsCrustthicknessEnum
@ BasalforcingsCrustthicknessEnum
Definition: EnumDefinitions.h:60
ViscousHeatingEnum
@ ViscousHeatingEnum
Definition: EnumDefinitions.h:1327
SmbAccugradEnum
@ SmbAccugradEnum
Definition: EnumDefinitions.h:346
SmbAiniEnum
@ SmbAiniEnum
Definition: EnumDefinitions.h:709
SmbPrecipitationsReconstructedYearsEnum
@ SmbPrecipitationsReconstructedYearsEnum
Definition: EnumDefinitions.h:396
StressTensorzzEnum
@ StressTensorzzEnum
Definition: EnumDefinitions.h:816
Element::TransformLoadVectorCoord
void TransformLoadVectorCoord(ElementVector *pe, int cs_enum)
Definition: Element.cpp:4346
CalvingCrevasseDepthEnum
@ CalvingCrevasseDepthEnum
Definition: EnumDefinitions.h:96
Element::GetDofListPressure
void GetDofListPressure(int **pdoflist, int setenum)
Definition: Element.cpp:1007
Element::PicoUpdateBox
void PicoUpdateBox(int loopboxid)
Definition: Element.cpp:2550
TripleMultiply
int TripleMultiply(IssmDouble *a, int nrowa, int ncola, int itrna, IssmDouble *b, int nrowb, int ncolb, int itrnb, IssmDouble *c, int nrowc, int ncolc, int itrnc, IssmDouble *d, int iaddd)
Definition: MatrixUtils.cpp:20
SsetEnum
@ SsetEnum
Definition: EnumDefinitions.h:1282
SmbDzEnum
@ SmbDzEnum
Definition: EnumDefinitions.h:729
MaterialsLatentheatEnum
@ MaterialsLatentheatEnum
Definition: EnumDefinitions.h:254
TemperaturePDDEnum
@ TemperaturePDDEnum
Definition: EnumDefinitions.h:832
PressureEnum
@ PressureEnum
Definition: EnumDefinitions.h:664
MaterialsRhoIceEnum
@ MaterialsRhoIceEnum
Definition: EnumDefinitions.h:264
BasalforcingsUppercrustheatEnum
@ BasalforcingsUppercrustheatEnum
Definition: EnumDefinitions.h:91
XYZEnum
@ XYZEnum
Definition: EnumDefinitions.h:1331
Element::GroundedArea
IssmDouble GroundedArea(IssmDouble *mask, bool scaled)
Definition: Element.cpp:1548
P1DGEnum
@ P1DGEnum
Definition: EnumDefinitions.h:1215
SmbDailytemperatureEnum
@ SmbDailytemperatureEnum
Definition: EnumDefinitions.h:723
ElementVector::values
IssmDouble * values
Definition: ElementVector.h:24
Element::vertices
Vertex ** vertices
Definition: Element.h:49
SmbDpermilEnum
@ SmbDpermilEnum
Definition: EnumDefinitions.h:351
Element::GetInputListOnVerticesAtTime
void GetInputListOnVerticesAtTime(IssmDouble *pvalue, int enumtype, IssmDouble time)
Definition: Element.cpp:1139
Element::StrainRateparallel
virtual void StrainRateparallel(void)=0
Element::GetZcoord
IssmDouble GetZcoord(IssmDouble *xyz_list, Gauss *gauss)
Definition: Element.cpp:1494
Gauss::GaussNode
virtual void GaussNode(int finitelement, int iv)=0
Element::GetNodesSidList
void GetNodesSidList(int *sidlist)
Definition: Element.cpp:1234
EnthalpyEnum
@ EnthalpyEnum
Definition: EnumDefinitions.h:551
ControlInputSizeMEnum
@ ControlInputSizeMEnum
Definition: EnumDefinitions.h:105
Element::PureIceEnthalpy
IssmDouble PureIceEnthalpy(IssmDouble pressure)
Definition: Element.cpp:4681
SmbPrecipitationsPresentdayEnum
@ SmbPrecipitationsPresentdayEnum
Definition: EnumDefinitions.h:767
ConstantsYtsEnum
@ ConstantsYtsEnum
Definition: EnumDefinitions.h:104
PddSurfaceMassBalance
IssmDouble PddSurfaceMassBalance(IssmDouble *monthlytemperatures, IssmDouble *monthlyprec, IssmDouble *pdds, IssmDouble *pds, IssmDouble *melt, IssmDouble *accu, IssmDouble signorm, IssmDouble yts, IssmDouble h, IssmDouble s, IssmDouble desfac, IssmDouble s0t, IssmDouble s0p, IssmDouble rlaps, IssmDouble rlapslgm, IssmDouble TdiffTime, IssmDouble sealevTime, IssmDouble pddsnowfac, IssmDouble pddicefac, IssmDouble rho_water, IssmDouble rho_ice)
Definition: PddSurfaceMassBalance.cpp:11
ElementMatrix::ncols
int ncols
Definition: ElementMatrix.h:24
MaterialsRheologyNEnum
@ MaterialsRheologyNEnum
Definition: EnumDefinitions.h:651
Element::IsFloating
bool IsFloating()
Definition: Element.cpp:1987
DeviatoricStressxyEnum
@ DeviatoricStressxyEnum
Definition: EnumDefinitions.h:525
Element::Sid
int Sid()
Definition: Element.cpp:3578
SmbTaEnum
@ SmbTaEnum
Definition: EnumDefinitions.h:782
Element::ResultToPatch
void ResultToPatch(IssmDouble *values, int nodesperelement, int output_enum)
Definition: Element.cpp:3270
BasalforcingsUpperwaterElevationEnum
@ BasalforcingsUpperwaterElevationEnum
Definition: EnumDefinitions.h:94
DatasetInput2::GetInputValue
void GetInputValue(IssmDouble *pvalue, Gauss *gauss, int index)
Definition: DatasetInput2.cpp:199
SmbGspiniEnum
@ SmbGspiniEnum
Definition: EnumDefinitions.h:743
SmbAdThreshEnum
@ SmbAdThreshEnum
Definition: EnumDefinitions.h:348
BasalforcingsIsmip6NumBasinsEnum
@ BasalforcingsIsmip6NumBasinsEnum
Definition: EnumDefinitions.h:70
BasalforcingsTopplumedepthEnum
@ BasalforcingsTopplumedepthEnum
Definition: EnumDefinitions.h:90
StressTensorxyEnum
@ StressTensorxyEnum
Definition: EnumDefinitions.h:812
Element::AddControlInput
virtual void AddControlInput(int input_enum, Inputs2 *inputs2, IoModel *iomodel, IssmDouble *values, IssmDouble *values_min, IssmDouble *values_max, int interpolation_enum, int id)
Definition: Element.h:217
SmbDzMinEnum
@ SmbDzMinEnum
Definition: EnumDefinitions.h:730
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
SmbZMinEnum
@ SmbZMinEnum
Definition: EnumDefinitions.h:798
FSApproximationEnum
@ FSApproximationEnum
Definition: EnumDefinitions.h:1060
StrainRateperpendicularEnum
@ StrainRateperpendicularEnum
Definition: EnumDefinitions.h:803
VyEnum
@ VyEnum
Definition: EnumDefinitions.h:850
SmbDsnowIdxEnum
@ SmbDsnowIdxEnum
Definition: EnumDefinitions.h:352
ConstantsReferencetemperatureEnum
@ ConstantsReferencetemperatureEnum
Definition: EnumDefinitions.h:103
BasalforcingsDeepwaterMeltingRateEnum
@ BasalforcingsDeepwaterMeltingRateEnum
Definition: EnumDefinitions.h:62
SmbTemperaturesAnomalyEnum
@ SmbTemperaturesAnomalyEnum
Definition: EnumDefinitions.h:784
Inputs2::SetArrayInput
void SetArrayInput(int enum_in, int row, IssmDouble *layers, int numlayers)
Definition: Inputs2.cpp:623
Element::ComputeNewDamage
void ComputeNewDamage()
Definition: Element.cpp:144
Element::FloatingArea
IssmDouble FloatingArea(IssmDouble *mask, bool scaled)
Definition: Element.cpp:948
BasalforcingsLowercrustheatEnum
@ BasalforcingsLowercrustheatEnum
Definition: EnumDefinitions.h:72
Material::ViscosityBFS
virtual void ViscosityBFS(IssmDouble *pmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input, IssmDouble epseff)=0
Material::ViscosityBHO
virtual void ViscosityBHO(IssmDouble *pmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, IssmDouble epseff)=0
EsaStrainrateyyEnum
@ EsaStrainrateyyEnum
Definition: EnumDefinitions.h:565
SmbGdniniEnum
@ SmbGdniniEnum
Definition: EnumDefinitions.h:741
CalvingLawEnum
@ CalvingLawEnum
Definition: EnumDefinitions.h:98
SmbDailyairdensityEnum
@ SmbDailyairdensityEnum
Definition: EnumDefinitions.h:716
Element::ThermalToEnthalpy
void ThermalToEnthalpy(IssmDouble *penthalpy, IssmDouble temperature, IssmDouble waterfraction, IssmDouble pressure)
Definition: Element.cpp:4561
Input2::GetInputMax
virtual IssmDouble GetInputMax(void)
Definition: Input2.h:34
SmbWAddEnum
@ SmbWAddEnum
Definition: EnumDefinitions.h:795
Input2::GetInputDerivativeValue
virtual void GetInputDerivativeValue(IssmDouble *derivativevalues, IssmDouble *xyz_list, Gauss *gauss)
Definition: Input2.h:37
SmbPddfacSnowEnum
@ SmbPddfacSnowEnum
Definition: EnumDefinitions.h:763
ElementInput2
Definition: ElementInput2.h:7
EsaStrainratexyEnum
@ EsaStrainratexyEnum
Definition: EnumDefinitions.h:564
MaterialsRheologyBbarEnum
@ MaterialsRheologyBbarEnum
Definition: EnumDefinitions.h:644
Element::GetDofListLocalPressure
void GetDofListLocalPressure(int **pdoflist, int setenum)
Definition: Element.cpp:1054
Element::StressIntensityFactor
virtual void StressIntensityFactor(void)=0
BasalforcingsPicoAverageTemperatureEnum
@ BasalforcingsPicoAverageTemperatureEnum
Definition: EnumDefinitions.h:78
Element::GetInput2
virtual Input2 * GetInput2(int inputenum)=0
Element::DeleteMaterials
void DeleteMaterials(void)
Definition: Element.cpp:429
ComputeMungsmTemperaturePrecipitation
void ComputeMungsmTemperaturePrecipitation(IssmDouble TdiffTime, IssmDouble PfacTime, IssmDouble *PrecipitationsLgm, IssmDouble *PrecipitationsPresentday, IssmDouble *TemperaturesLgm, IssmDouble *TemperaturesPresentday, IssmDouble *monthlytemperaturesout, IssmDouble *monthlyprecout)
Definition: ComputeMungsmTemperaturePrecipitation.cpp:11
MAXVERTICES
#define MAXVERTICES
Definition: Element.cpp:24
Element::nodes
Node ** nodes
Definition: Element.h:48
DeviatoricStresszzEnum
@ DeviatoricStresszzEnum
Definition: EnumDefinitions.h:529
MARSHALLING_DYNAMIC
#define MARSHALLING_DYNAMIC(FIELD, TYPE, SIZE)
Definition: Marshalling.h:61
Element::SetwiseNodeConnectivity
void SetwiseNodeConnectivity(int *d_nz, int *o_nz, Node *node, bool *flags, int *flagsindices, int set1_enum, int set2_enum)
Definition: Element.cpp:3369
Element::ValueP1OnGauss
virtual void ValueP1OnGauss(IssmDouble *pvalue, IssmDouble *values, Gauss *gauss)=0
BasalforcingsPicoNumBasinsEnum
@ BasalforcingsPicoNumBasinsEnum
Definition: EnumDefinitions.h:85
IoModel::numberofvertices
int numberofvertices
Definition: IoModel.h:99
P1Enum
@ P1Enum
Definition: EnumDefinitions.h:662
Element::SmbSemic
void SmbSemic()
SmbPEnum
@ SmbPEnum
Definition: EnumDefinitions.h:761
SmbS0pEnum
@ SmbS0pEnum
Definition: EnumDefinitions.h:776
SmbTeValueEnum
@ SmbTeValueEnum
Definition: EnumDefinitions.h:783
Element::GetDatasetInput2
virtual DatasetInput2 * GetDatasetInput2(int inputenum)
Definition: Element.h:250
Domain2DhorizontalEnum
@ Domain2DhorizontalEnum
Definition: EnumDefinitions.h:534
Element::~Element
~Element()
Definition: Element.cpp:45
Element::GetPhi
void GetPhi(IssmDouble *phi, IssmDouble *epsilon, IssmDouble viscosity)
Definition: Element.cpp:1244
Element::ComputeStressTensor
virtual void ComputeStressTensor(void)=0
Element::IsIceOnlyInElement
bool IsIceOnlyInElement()
Definition: Element.cpp:2026
Element::dViscositydBFS
void dViscositydBFS(IssmDouble *pdmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input)
Definition: Element.cpp:763
CalvingrateyEnum
@ CalvingrateyEnum
Definition: EnumDefinitions.h:511
SmbDailysnowfallEnum
@ SmbDailysnowfallEnum
Definition: EnumDefinitions.h:722
SmbIstemperaturescaledEnum
@ SmbIstemperaturescaledEnum
Definition: EnumDefinitions.h:375
Element::InputCreate
void InputCreate(IssmDouble *vector, Inputs2 *inputs2, IoModel *iomodel, int M, int N, int vector_type, int vector_enum, int code)
Definition: Element.cpp:1626
SmbS0gcmEnum
@ SmbS0gcmEnum
Definition: EnumDefinitions.h:775
Element::MismipFloatingiceMeltingRate
void MismipFloatingiceMeltingRate()
Definition: Element.cpp:2331
SmbDenIdxEnum
@ SmbDenIdxEnum
Definition: EnumDefinitions.h:356
SmbTemperaturesPresentdayEnum
@ SmbTemperaturesPresentdayEnum
Definition: EnumDefinitions.h:786
Element::NewElementVector
ElementVector * NewElementVector(int approximation_enum=NoneApproximationEnum)
Definition: Element.cpp:2505
IoModel::numberofelements
int numberofelements
Definition: IoModel.h:96
XYEnum
@ XYEnum
Definition: EnumDefinitions.h:1330
Element::SmbGemb
void SmbGemb(IssmDouble timeinputs, int count)
Definition: Element.cpp:3584
BasalforcingsNusseltEnum
@ BasalforcingsNusseltEnum
Definition: EnumDefinitions.h:75
Parameters::DeepEcho
void DeepEcho()
Definition: Parameters.cpp:99
SmbDailyrainfallEnum
@ SmbDailyrainfallEnum
Definition: EnumDefinitions.h:721
Element::Divergence
IssmDouble Divergence(void)
Definition: Element.cpp:720
BasalforcingsPerturbationMeltingRateEnum
@ BasalforcingsPerturbationMeltingRateEnum
Definition: EnumDefinitions.h:479
TriaInput2Enum
@ TriaInput2Enum
Definition: EnumDefinitions.h:1124
ConstantsGEnum
@ ConstantsGEnum
Definition: EnumDefinitions.h:102
VertexSIdEnum
@ VertexSIdEnum
Definition: EnumDefinitions.h:1325
Material::ViscosityBSSA
virtual void ViscosityBSSA(IssmDouble *pmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, IssmDouble epseff)=0
Element::Ismip6FloatingiceMeltingRate
void Ismip6FloatingiceMeltingRate()
Definition: Element.cpp:2041
Element::PositiveDegreeDay
void PositiveDegreeDay(IssmDouble *pdds, IssmDouble *pds, IssmDouble signorm, bool ismungsm, bool issetpddfac)
Definition: Element.cpp:2788
Element::inputs2
Inputs2 * inputs2
Definition: Element.h:47
NoneApproximationEnum
@ NoneApproximationEnum
Definition: EnumDefinitions.h:1201
Element::id
int id
Definition: Element.h:44
SmbVzEnum
@ SmbVzEnum
Definition: EnumDefinitions.h:793
SmbCEnum
@ SmbCEnum
Definition: EnumDefinitions.h:714
BasalforcingsPlumeyEnum
@ BasalforcingsPlumeyEnum
Definition: EnumDefinitions.h:88
Element::IceVolume
IssmDouble IceVolume(IssmDouble *mask, bool scaled)
Definition: Element.cpp:1594
Element::sid
int sid
Definition: Element.h:45
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
Element::AddInput2
virtual void AddInput2(int input_enum, IssmDouble *values, int interpolation_enum)
Definition: Element.h:216
MatestarEnum
@ MatestarEnum
Definition: EnumDefinitions.h:1168
Element::Id
int Id()
Definition: Element.cpp:1620
Element::NewGauss
virtual Gauss * NewGauss(void)=0
ApproximationEnum
@ ApproximationEnum
Definition: EnumDefinitions.h:470
SmbMassBalanceSubstepEnum
@ SmbMassBalanceSubstepEnum
Definition: EnumDefinitions.h:749
SmbAccualtiEnum
@ SmbAccualtiEnum
Definition: EnumDefinitions.h:345
Element::MungsmtpParameterization
void MungsmtpParameterization(void)
Definition: Element.cpp:2400
Element::dViscositydBSSA
void dViscositydBSSA(IssmDouble *pdmudB, int dim, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:837
DeviatoricStress1Enum
@ DeviatoricStress1Enum
Definition: EnumDefinitions.h:530
BasalforcingsIsmip6DeltaTEnum
@ BasalforcingsIsmip6DeltaTEnum
Definition: EnumDefinitions.h:67
BasalforcingsOceanSalinityEnum
@ BasalforcingsOceanSalinityEnum
Definition: EnumDefinitions.h:484
VzEnum
@ VzEnum
Definition: EnumDefinitions.h:853
SurfaceCrevasseEnum
@ SurfaceCrevasseEnum
Definition: EnumDefinitions.h:822
MaterialsThermalExchangeVelocityEnum
@ MaterialsThermalExchangeVelocityEnum
Definition: EnumDefinitions.h:267
EnumToStringx
const char * EnumToStringx(int enum_in)
Definition: EnumToStringx.cpp:15
DeviatoricStressyyEnum
@ DeviatoricStressyyEnum
Definition: EnumDefinitions.h:527
VerboseSmb
bool VerboseSmb(void)
Definition: Verbosity.cpp:30
MaterialsBetaEnum
@ MaterialsBetaEnum
Definition: EnumDefinitions.h:250
Element::element_type_list
int * element_type_list
Definition: Element.h:55
BasalforcingsPicoSubShelfOceanSalinityEnum
@ BasalforcingsPicoSubShelfOceanSalinityEnum
Definition: EnumDefinitions.h:490
SmbDelta18oEnum
@ SmbDelta18oEnum
Definition: EnumDefinitions.h:354
Element::CoordinateSystemTransform
void CoordinateSystemTransform(IssmDouble **ptransform, Node **nodes, int numnodes, int *cs_array)
Definition: Element.cpp:323
ThermalIsenthalpyEnum
@ ThermalIsenthalpyEnum
Definition: EnumDefinitions.h:417
NodesEnum
@ NodesEnum
Definition: EnumDefinitions.h:275
Element::PositiveDegreeDaySicopolis
void PositiveDegreeDaySicopolis(bool isfirnwarming)
Definition: Element.cpp:2975
DomainDimensionEnum
@ DomainDimensionEnum
Definition: EnumDefinitions.h:123
SmbRunoffrefEnum
@ SmbRunoffrefEnum
Definition: EnumDefinitions.h:387
SmbPddfacIceEnum
@ SmbPddfacIceEnum
Definition: EnumDefinitions.h:762
Element::ComputeSigmaNN
virtual void ComputeSigmaNN(void)=0
GsetEnum
@ GsetEnum
Definition: EnumDefinitions.h:1093
DistanceToCalvingfrontEnum
@ DistanceToCalvingfrontEnum
Definition: EnumDefinitions.h:532
SmbSmbCorrEnum
@ SmbSmbCorrEnum
Definition: EnumDefinitions.h:779
Inputs2::DeepEcho
void DeepEcho(void)
Definition: Inputs2.cpp:66
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
SmbTemperaturesLgmEnum
@ SmbTemperaturesLgmEnum
Definition: EnumDefinitions.h:785
Element::TotalSmb
IssmDouble TotalSmb(IssmDouble *mask, bool scaled)
Definition: Element.cpp:4286
DamageDEnum
@ DamageDEnum
Definition: EnumDefinitions.h:516
ElementSIdEnum
@ ElementSIdEnum
Definition: EnumDefinitions.h:1051
PddSurfaceMassBalanceSicopolis
IssmDouble PddSurfaceMassBalanceSicopolis(IssmDouble *monthlytemperatures, IssmDouble *monthlyprec, IssmDouble *melt, IssmDouble *accu, IssmDouble *melt_star, IssmDouble *t_ampl, IssmDouble *p_ampl, IssmDouble yts, IssmDouble s, IssmDouble desfac, IssmDouble s0t, IssmDouble s0p, IssmDouble rlaps, IssmDouble rho_water, IssmDouble rho_ice)
Definition: PddSurfaceMassBalanceSicopolis.cpp:10
StrainRateeffectiveEnum
@ StrainRateeffectiveEnum
Definition: EnumDefinitions.h:801
Element::GetInput2Value
void GetInput2Value(bool *pvalue, int enum_type)
Definition: Element.cpp:1185
SmbECiniEnum
@ SmbECiniEnum
Definition: EnumDefinitions.h:736
Element::BeckmannGoosseFloatingiceMeltingRate
void BeckmannGoosseFloatingiceMeltingRate()
Definition: Element.cpp:2360
SmbIsconstrainsurfaceTEnum
@ SmbIsconstrainsurfaceTEnum
Definition: EnumDefinitions.h:364
Element::ComputeEsaStrainAndVorticity
virtual void ComputeEsaStrainAndVorticity(void)=0
Element::Delta18opdParameterization
void Delta18opdParameterization(void)
Definition: Element.cpp:531
MARSHALLING
#define MARSHALLING(FIELD)
Definition: Marshalling.h:29
Element::StrainRateSSA1d
void StrainRateSSA1d(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input)
Definition: Element.cpp:4157
Element::GetVerticesCoordinates
void GetVerticesCoordinates(IssmDouble **xyz_list)
Definition: Element.cpp:1446
SmbGspEnum
@ SmbGspEnum
Definition: EnumDefinitions.h:742
MaterialsHeatcapacityEnum
@ MaterialsHeatcapacityEnum
Definition: EnumDefinitions.h:253
SmbIsgraingrowthEnum
@ SmbIsgraingrowthEnum
Definition: EnumDefinitions.h:369
Element::GetNode
Node * GetNode(int nodeindex)
Definition: Element.cpp:1207
Element::ResultToMatrix
void ResultToMatrix(IssmDouble *values, int ncols, int output_enum)
Definition: Element.cpp:3290
Element::ComputeLambdaS
void ComputeLambdaS(void)
Definition: Element.cpp:61
Element::GetVectorFromInputs
void GetVectorFromInputs(Vector< IssmDouble > *vector, int name_enum, int type)
Definition: Element.cpp:1331
StressTensoryyEnum
@ StressTensoryyEnum
Definition: EnumDefinitions.h:814
Object::DeepEcho
virtual void DeepEcho()=0
BasalforcingsPicoBoxAreaEnum
@ BasalforcingsPicoBoxAreaEnum
Definition: EnumDefinitions.h:79
BasalforcingsPicoBoxIdEnum
@ BasalforcingsPicoBoxIdEnum
Definition: EnumDefinitions.h:487
Input2::GetResultNumberOfNodes
virtual int GetResultNumberOfNodes(void)
Definition: Input2.h:52
BasalforcingsPicoOverturningCoeffEnum
@ BasalforcingsPicoOverturningCoeffEnum
Definition: EnumDefinitions.h:488
SmbPrecipitationsLgmEnum
@ SmbPrecipitationsLgmEnum
Definition: EnumDefinitions.h:766
SigmaVMEnum
@ SigmaVMEnum
Definition: EnumDefinitions.h:705
INS_VAL
@ INS_VAL
Definition: toolkitsenums.h:14
AutodiffIsautodiffEnum
@ AutodiffIsautodiffEnum
Definition: EnumDefinitions.h:50
Inputs2::GetArray
void GetArray(int enum_in, int row, IssmDouble **pvalues, int *pN)
Definition: Inputs2.cpp:485
shortwave
void shortwave(IssmDouble **pswf, int swIdx, int aIdx, IssmDouble dsw, IssmDouble as, IssmDouble *d, IssmDouble *dz, IssmDouble *re, IssmDouble dIce, int m, int sid)
Definition: Gembx.cpp:991
SurfaceEnum
@ SurfaceEnum
Definition: EnumDefinitions.h:823
cubic
int cubic(IssmDouble a, IssmDouble b, IssmDouble c, IssmDouble d, IssmDouble x[3], int *num)
Definition: cubic.cpp:21
Element::SpatialLinearFloatingiceMeltingRate
void SpatialLinearFloatingiceMeltingRate()
Definition: Element.cpp:2146
SmbIsaccumulationEnum
@ SmbIsaccumulationEnum
Definition: EnumDefinitions.h:361
PentaInput2
Definition: PentaInput2.h:8
Element::NumberofNodesPressure
virtual int NumberofNodesPressure(void)=0
Inputs2
Declaration of Inputs class.
Definition: Inputs2.h:23
BasalforcingsPlumexEnum
@ BasalforcingsPlumexEnum
Definition: EnumDefinitions.h:87
cellsum
IssmDouble cellsum(IssmDouble *cell, int m)
Definition: MatrixUtils.cpp:604
Element::InputExtrude
virtual void InputExtrude(int input_enum, int start)=0
BasalforcingsUpperwaterMeltingRateEnum
@ BasalforcingsUpperwaterMeltingRateEnum
Definition: EnumDefinitions.h:95
BaseSlopeXEnum
@ BaseSlopeXEnum
Definition: EnumDefinitions.h:497
BasalforcingsPicoFarOceantemperatureEnum
@ BasalforcingsPicoFarOceantemperatureEnum
Definition: EnumDefinitions.h:81
TransientIsthermalEnum
@ TransientIsthermalEnum
Definition: EnumDefinitions.h:455
MaterialsRhoSeawaterEnum
@ MaterialsRhoSeawaterEnum
Definition: EnumDefinitions.h:265
Element::ViscousHeatingCreateInput
void ViscousHeatingCreateInput(void)
Definition: Element.cpp:4522
thermo
void thermo(IssmDouble *pEC, IssmDouble **pT, IssmDouble *pulwrf, IssmDouble *dz, IssmDouble *d, IssmDouble *swf, IssmDouble dlwrf, IssmDouble Ta, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble teValue, IssmDouble Ws, IssmDouble dt0, int m, IssmDouble Vz, IssmDouble Tz, IssmDouble thermo_scaling, IssmDouble dIce, int sid, bool isconstrainsurfaceT)
Definition: Gembx.cpp:617
SmbECDtEnum
@ SmbECDtEnum
Definition: EnumDefinitions.h:735
FSvelocityEnum
@ FSvelocityEnum
Definition: EnumDefinitions.h:1063
IsInputEnum
bool IsInputEnum(int enum_in)
Definition: EnumToStringx.cpp:1368
SmbDswrfEnum
@ SmbDswrfEnum
Definition: EnumDefinitions.h:727
SSAFSApproximationEnum
@ SSAFSApproximationEnum
Definition: EnumDefinitions.h:1256
BasalforcingsIsmip6Gamma0Enum
@ BasalforcingsIsmip6Gamma0Enum
Definition: EnumDefinitions.h:68
Element::Echo
void Echo()
Definition: Element.cpp:901
DamageDbarOldEnum
@ DamageDbarOldEnum
Definition: EnumDefinitions.h:519
Node::GetDofList
void GetDofList(int *poutdoflist, int approximation_enum, int setenum)
Definition: Node.cpp:392
SmbPrecipitationsReconstructedEnum
@ SmbPrecipitationsReconstructedEnum
Definition: EnumDefinitions.h:768
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
SmbNetLWEnum
@ SmbNetLWEnum
Definition: EnumDefinitions.h:758
StrainRateparallelEnum
@ StrainRateparallelEnum
Definition: EnumDefinitions.h:802
BaseSlopeYEnum
@ BaseSlopeYEnum
Definition: EnumDefinitions.h:498
Input2
Definition: Input2.h:18
Element::GetDofListLocal
void GetDofListLocal(int **pdoflist, int approximation_enum, int setenum)
Definition: Element.cpp:984
SmbEAirEnum
@ SmbEAirEnum
Definition: EnumDefinitions.h:733
MARSHALLING_BACKWARD
@ MARSHALLING_BACKWARD
Definition: Marshalling.h:10
Element::GetVerticesSidList
void GetVerticesSidList(int *sidlist)
Definition: Element.cpp:1456
CalvingDev2Enum
@ CalvingDev2Enum
Definition: EnumDefinitions.h:1001
DeviatoricStresseffectiveEnum
@ DeviatoricStresseffectiveEnum
Definition: EnumDefinitions.h:523
VertexPIdEnum
@ VertexPIdEnum
Definition: EnumDefinitions.h:1324
SmbDlwrfEnum
@ SmbDlwrfEnum
Definition: EnumDefinitions.h:726
DamageStressThresholdEnum
@ DamageStressThresholdEnum
Definition: EnumDefinitions.h:120
Element::TMeltingPoint
IssmDouble TMeltingPoint(IssmDouble pressure)
Definition: Element.cpp:4583
TemperatureEnum
@ TemperatureEnum
Definition: EnumDefinitions.h:831
SmbMAddEnum
@ SmbMAddEnum
Definition: EnumDefinitions.h:746
Element::SetElementInput
virtual void SetElementInput(int enum_in, IssmDouble values)
Definition: Element.h:333
ArrayInput2Enum
@ ArrayInput2Enum
Definition: EnumDefinitions.h:1041
SealevelEnum
@ SealevelEnum
Definition: EnumDefinitions.h:675
Gauss::GaussVertex
virtual void GaussVertex(int iv)=0
CalvingLevermannEnum
@ CalvingLevermannEnum
Definition: EnumDefinitions.h:1003
ElementMatrix::nrows
int nrows
Definition: ElementMatrix.h:23
CalvingFluxLevelsetEnum
@ CalvingFluxLevelsetEnum
Definition: EnumDefinitions.h:512
Inputs2::GetTransientInput
TransientInput2 * GetTransientInput(int enum_type)
Definition: Inputs2.cpp:406
SmbRunoffEnum
@ SmbRunoffEnum
Definition: EnumDefinitions.h:772
SmbSizeiniEnum
@ SmbSizeiniEnum
Definition: EnumDefinitions.h:778
Inputs2::GetInputObjectEnum
int GetInputObjectEnum(int enum_type)
Definition: Inputs2.cpp:254
Element::CalvingMeltingFluxLevelset
virtual void CalvingMeltingFluxLevelset(void)
Definition: Element.h:225
ComputeDelta18oTemperaturePrecipitation
void ComputeDelta18oTemperaturePrecipitation(IssmDouble Delta18oSurfacePresent, IssmDouble Delta18oSurfaceLgm, IssmDouble Delta18oSurfaceTime, IssmDouble Delta18oPresent, IssmDouble Delta18oLgm, IssmDouble Delta18oTime, IssmDouble *PrecipitationsPresentday, IssmDouble *TemperaturesLgm, IssmDouble *TemperaturesPresentday, IssmDouble *monthlytemperaturesout, IssmDouble *monthlyprecout)
Definition: ComputeDelta18oTemperaturePrecipitation.cpp:10
Element::Element
Element()
Definition: Element.cpp:34
BasalforcingsPicoMaxboxcountEnum
@ BasalforcingsPicoMaxboxcountEnum
Definition: EnumDefinitions.h:84
BasalforcingsIsmip6BasinIdEnum
@ BasalforcingsIsmip6BasinIdEnum
Definition: EnumDefinitions.h:480
IssmComm::GetRank
static int GetRank(void)
Definition: IssmComm.cpp:34
StrainRatexxEnum
@ StrainRatexxEnum
Definition: EnumDefinitions.h:804
Element::IsIceInElement
bool IsIceInElement()
Definition: Element.cpp:2021
Element::MigrateGroundingLine
void MigrateGroundingLine(IssmDouble *sheet_ungrounding)
Definition: Element.cpp:2238
StrainRateyzEnum
@ StrainRateyzEnum
Definition: EnumDefinitions.h:808
PentaInput2Enum
@ PentaInput2Enum
Definition: EnumDefinitions.h:1125
Element::IsOceanInElement
bool IsOceanInElement()
Definition: Element.cpp:2036
StrainRatexzEnum
@ StrainRatexzEnum
Definition: EnumDefinitions.h:806
Node::Echo
void Echo()
Definition: Node.cpp:339
Inputs2::SetInput
void SetInput(int enum_in, int index, bool value)
Definition: Inputs2.cpp:572
R
const double R
Definition: Gembx.cpp:30
Node
Definition: Node.h:23
Node::Lid
int Lid(void)
Definition: Node.cpp:618
Element::StrainRateHO
void StrainRateHO(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:4084
Element::GetSolutionFromInputsOneDof
void GetSolutionFromInputsOneDof(Vector< IssmDouble > *solution, int solutionenum)
Definition: Element.cpp:1281
SmbNetSWEnum
@ SmbNetSWEnum
Definition: EnumDefinitions.h:759
Node::Sid
int Sid(void)
Definition: Node.cpp:622
StressIntensityFactorEnum
@ StressIntensityFactorEnum
Definition: EnumDefinitions.h:1284
Element::LinearFloatingiceMeltingRate
void LinearFloatingiceMeltingRate()
Definition: Element.cpp:2106
SmbDailypressureEnum
@ SmbDailypressureEnum
Definition: EnumDefinitions.h:720
SmbVmeanEnum
@ SmbVmeanEnum
Definition: EnumDefinitions.h:792
NoneEnum
@ NoneEnum
Definition: EnumDefinitions.h:1202
Parameters::Echo
void Echo()
Definition: Parameters.cpp:106
Element::GetVerticesCoordinatesBase
virtual void GetVerticesCoordinatesBase(IssmDouble **xyz_list)=0
Element::ResultInterpolation
void ResultInterpolation(int *pinterpolation, int *nodesperelement, int *parray_size, int output_enum)
Definition: Element.cpp:3162
BasalforcingsDeepwaterElevationEnum
@ BasalforcingsDeepwaterElevationEnum
Definition: EnumDefinitions.h:61
Element::AnyFSet
bool AnyFSet(void)
Definition: Element.cpp:51
_error_
#define _error_(StreamArgs)
Definition: exceptions.h:49
SmbFEnum
@ SmbFEnum
Definition: EnumDefinitions.h:359
SmbTdiffEnum
@ SmbTdiffEnum
Definition: EnumDefinitions.h:393
MaterialsRheologyBEnum
@ MaterialsRheologyBEnum
Definition: EnumDefinitions.h:643
Element::parameters
Parameters * parameters
Definition: Element.h:51
StrainRateyyEnum
@ StrainRateyyEnum
Definition: EnumDefinitions.h:807
Element::GetYcoord
IssmDouble GetYcoord(IssmDouble *xyz_list, Gauss *gauss)
Definition: Element.cpp:1478
Gauss::begin
virtual int begin(void)=0
SmbMeanLHFEnum
@ SmbMeanLHFEnum
Definition: EnumDefinitions.h:751
VxEnum
@ VxEnum
Definition: EnumDefinitions.h:846
MeshVertexonsurfaceEnum
@ MeshVertexonsurfaceEnum
Definition: EnumDefinitions.h:655
min
IssmDouble min(IssmDouble a, IssmDouble b)
Definition: extrema.cpp:14
Node::GetCoordinateSystem
void GetCoordinateSystem(IssmDouble *coord_system_out)
Definition: Node.cpp:367
BasalforcingsDtbgEnum
@ BasalforcingsDtbgEnum
Definition: EnumDefinitions.h:63
SmbIsInitializedEnum
@ SmbIsInitializedEnum
Definition: EnumDefinitions.h:745
Element::StrainRateperpendicular
virtual void StrainRateperpendicular(void)=0
PentaEnum
@ PentaEnum
Definition: EnumDefinitions.h:1231
SmbMonthlytemperaturesEnum
@ SmbMonthlytemperaturesEnum
Definition: EnumDefinitions.h:756
Input2::GetResultInterpolation
virtual int GetResultInterpolation(void)
Definition: Input2.h:51
Element::InputUpdateFromConstant
void InputUpdateFromConstant(IssmDouble constant, int name)
Definition: Element.cpp:1963
SmbDelta18oSurfaceEnum
@ SmbDelta18oSurfaceEnum
Definition: EnumDefinitions.h:355
CalvingCalvingrateEnum
@ CalvingCalvingrateEnum
Definition: EnumDefinitions.h:502
SmbDziniEnum
@ SmbDziniEnum
Definition: EnumDefinitions.h:732
StressMaxPrincipalEnum
@ StressMaxPrincipalEnum
Definition: EnumDefinitions.h:810
SmbDailywindspeedEnum
@ SmbDailywindspeedEnum
Definition: EnumDefinitions.h:724
PartitioningEnum
@ PartitioningEnum
Definition: EnumDefinitions.h:663
ElementInput2::GetInputInterpolationType
int GetInputInterpolationType()
Definition: ElementInput2.cpp:32
Element::JacobianDeterminant
virtual void JacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)=0
DistanceToGroundinglineEnum
@ DistanceToGroundinglineEnum
Definition: EnumDefinitions.h:533
Gauss::GaussPoint
virtual void GaussPoint(int ig)=0
Input2::GetInputMin
virtual IssmDouble GetInputMin(void)
Definition: Input2.h:36
NodeSIdEnum
@ NodeSIdEnum
Definition: EnumDefinitions.h:1200
StressTensorxzEnum
@ StressTensorxzEnum
Definition: EnumDefinitions.h:813
Element::GetInputValue
void GetInputValue(bool *pvalue, int enum_type)
Definition: Element.cpp:1177
BasalforcingsPicoFarOceansalinityEnum
@ BasalforcingsPicoFarOceansalinityEnum
Definition: EnumDefinitions.h:80
Inputs2::SetTransientInput
void SetTransientInput(int enum_in, IssmDouble *times, int numtimes)
Definition: Inputs2.cpp:676
SmbDailyairhumidityEnum
@ SmbDailyairhumidityEnum
Definition: EnumDefinitions.h:717
Element::PicoComputeBasalMelt
void PicoComputeBasalMelt()
Definition: Element.cpp:2684
BasalforcingsIsmip6MeltAnomalyEnum
@ BasalforcingsIsmip6MeltAnomalyEnum
Definition: EnumDefinitions.h:483
Element::EnthalpyDiffusionParameterVolume
IssmDouble EnthalpyDiffusionParameterVolume(int numvertices, IssmDouble *enthalpy, IssmDouble *pressure)
Definition: Element.cpp:4634
Element::CalvingFluxLevelset
virtual void CalvingFluxLevelset(void)
Definition: Element.h:224
Element::ControlInputCreate
void ControlInputCreate(IssmDouble *doublearray, IssmDouble *independents_min, IssmDouble *independents_max, Inputs2 *inputs2, IoModel *iomodel, int M, int N, IssmDouble scale, int input_enum, int id)
Definition: Element.cpp:1753
Element::VelocityInterpolation
virtual int VelocityInterpolation()=0
TemperatureSEMICEnum
@ TemperatureSEMICEnum
Definition: EnumDefinitions.h:834
BoolInput2Enum
@ BoolInput2Enum
Definition: EnumDefinitions.h:995
SmbCldFracEnum
@ SmbCldFracEnum
Definition: EnumDefinitions.h:353
Parameters::FindParam
void FindParam(bool *pinteger, int enum_type)
Definition: Parameters.cpp:262
ThicknessEnum
@ ThicknessEnum
Definition: EnumDefinitions.h:840
SmbInitDensityScalingEnum
@ SmbInitDensityScalingEnum
Definition: EnumDefinitions.h:360
ElementInput2::element_values
IssmDouble * element_values
Definition: ElementInput2.h:18
SmbPrecipitationsAnomalyEnum
@ SmbPrecipitationsAnomalyEnum
Definition: EnumDefinitions.h:765
Element::GetVerticesPidList
void GetVerticesPidList(int *pidlist)
Definition: Element.cpp:1433
Element::IsLandInElement
bool IsLandInElement()
Definition: Element.cpp:2031
SmbRunoffgradEnum
@ SmbRunoffgradEnum
Definition: EnumDefinitions.h:386
Element::CalvingCrevasseDepth
virtual void CalvingCrevasseDepth(void)
Definition: Element.h:222
SmbAIdxEnum
@ SmbAIdxEnum
Definition: EnumDefinitions.h:343
Element::TotalGroundedBmb
IssmDouble TotalGroundedBmb(IssmDouble *mask, bool scaled)
Definition: Element.cpp:4273
MatrixMultiply
int MatrixMultiply(IssmDouble *a, int nrowa, int ncola, int itrna, IssmDouble *b, int nrowb, int ncolb, int itrnb, IssmDouble *c, int iaddc)
Definition: MatrixUtils.cpp:88
Element::GetNodeIndex
int GetNodeIndex(Node *node)
Definition: Element.cpp:1212
SmbRunoffaltiEnum
@ SmbRunoffaltiEnum
Definition: EnumDefinitions.h:385
SmbTiniEnum
@ SmbTiniEnum
Definition: EnumDefinitions.h:788
BasalforcingsUppercrustthicknessEnum
@ BasalforcingsUppercrustthicknessEnum
Definition: EnumDefinitions.h:92
AnalysisTypeEnum
@ AnalysisTypeEnum
Definition: EnumDefinitions.h:36
SmbKEnum
@ SmbKEnum
Definition: EnumDefinitions.h:378
SmbIsthermalEnum
@ SmbIsthermalEnum
Definition: EnumDefinitions.h:376
accumulation
void accumulation(IssmDouble **pT, IssmDouble **pdz, IssmDouble **pd, IssmDouble **pW, IssmDouble **pa, IssmDouble **pre, IssmDouble **pgdn, IssmDouble **pgsp, int *pm, int aIdx, int dsnowIdx, IssmDouble Tmean, IssmDouble T_air, IssmDouble P, IssmDouble dzMin, IssmDouble aSnow, IssmDouble C, IssmDouble V, IssmDouble Vmean, IssmDouble dIce, int sid)
Definition: Gembx.cpp:1190
Inputs2::GetInputValue
void GetInputValue(bool *pvalue, int enum_in, int index)
Definition: Inputs2.cpp:502
SmbPrecipitationEnum
@ SmbPrecipitationEnum
Definition: EnumDefinitions.h:764
Object::Echo
virtual void Echo()=0
ElementVector
Definition: ElementVector.h:20
IoModel::elements
int * elements
Definition: IoModel.h:79
BasalforcingsIsmip6TfShelfEnum
@ BasalforcingsIsmip6TfShelfEnum
Definition: EnumDefinitions.h:482
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
Element::CalvingRateLevermann
virtual void CalvingRateLevermann(void)=0
MaticeEnum
@ MaticeEnum
Definition: EnumDefinitions.h:1169
Input2::GetInputValue
virtual void GetInputValue(IssmDouble *pvalue, Gauss *gauss)
Definition: Input2.h:38
SubelementMigrationEnum
@ SubelementMigrationEnum
Definition: EnumDefinitions.h:1297
StrainRatexyEnum
@ StrainRatexyEnum
Definition: EnumDefinitions.h:805
SmbTzEnum
@ SmbTzEnum
Definition: EnumDefinitions.h:790
BasalforcingsGeothermalfluxEnum
@ BasalforcingsGeothermalfluxEnum
Definition: EnumDefinitions.h:477
Gauss::weight
IssmDouble weight
Definition: Gauss.h:11
Element::ViscousHeating
virtual void ViscousHeating(IssmDouble *pphi, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input, Input2 *vz_input)
Definition: Element.h:365
Element::HasNodeOnBase
bool HasNodeOnBase()
Definition: Element.cpp:1561
Element::IsOnSurface
bool IsOnSurface()
Definition: Element.cpp:1981
IoModel
Definition: IoModel.h:48
P0ArrayEnum
@ P0ArrayEnum
Definition: EnumDefinitions.h:1213
Inputs2::SetTriaDatasetInput
void SetTriaDatasetInput(int enum_in, int id, int interpolation, int numindices, int *indices, IssmDouble *values)
Definition: Inputs2.cpp:743
SigmaNNEnum
@ SigmaNNEnum
Definition: EnumDefinitions.h:704
LambdaSEnum
@ LambdaSEnum
Definition: EnumDefinitions.h:1140
Element::DatasetInputAdd
void DatasetInputAdd(int enum_type, IssmDouble *vector, Inputs2 *inputs2, IoModel *iomodel, int M, int N, int vector_type, int vector_enum, int code, int input_enum)
Definition: Element.cpp:1831
SmbT0wetEnum
@ SmbT0wetEnum
Definition: EnumDefinitions.h:392
FsetEnum
@ FsetEnum
Definition: EnumDefinitions.h:1075
P1xP4Enum
@ P1xP4Enum
Definition: EnumDefinitions.h:1222
MaterialsTemperateiceconductivityEnum
@ MaterialsTemperateiceconductivityEnum
Definition: EnumDefinitions.h:266
Element::StrainRateHO2dvertical
void StrainRateHO2dvertical(IssmDouble *epsilon, IssmDouble *xyz_list, Gauss *gauss, Input2 *vx_input, Input2 *vy_input)
Definition: Element.cpp:4114
binary_search
int binary_search(int *poffset, int target, int *sorted_integers, int num_integers)
Definition: binary_search.cpp:14
max
IssmDouble max(IssmDouble a, IssmDouble b)
Definition: extrema.cpp:24
BasalforcingsIsmip6AverageTfEnum
@ BasalforcingsIsmip6AverageTfEnum
Definition: EnumDefinitions.h:65
ControlInputSizeNEnum
@ ControlInputSizeNEnum
Definition: EnumDefinitions.h:106
densification
void densification(IssmDouble **pd, IssmDouble **pdz, IssmDouble *T, IssmDouble *re, int denIdx, IssmDouble C, IssmDouble dt, IssmDouble Tmean, IssmDouble dIce, int m, int sid)
Definition: Gembx.cpp:1951
StrainRatezzEnum
@ StrainRatezzEnum
Definition: EnumDefinitions.h:809
Element::IceMass
IssmDouble IceMass(bool scaled)
Definition: Element.cpp:1569
SmbPfacEnum
@ SmbPfacEnum
Definition: EnumDefinitions.h:380
IntInput2Enum
@ IntInput2Enum
Definition: EnumDefinitions.h:996
BasalforcingsUpperdepthMeltEnum
@ BasalforcingsUpperdepthMeltEnum
Definition: EnumDefinitions.h:93
P1xP3Enum
@ P1xP3Enum
Definition: EnumDefinitions.h:1221
Element::GetNumberOfVertices
virtual int GetNumberOfVertices(void)=0
SmbASnowEnum
@ SmbASnowEnum
Definition: EnumDefinitions.h:344
SmbRlapslgmEnum
@ SmbRlapslgmEnum
Definition: EnumDefinitions.h:384
SmbMeltEnum
@ SmbMeltEnum
Definition: EnumDefinitions.h:754
Element::GetInputListOnVertices
void GetInputListOnVertices(IssmDouble *pvalue, int enumtype)
Definition: Element.cpp:1131
turbulentFlux
void turbulentFlux(IssmDouble *pshf, IssmDouble *plhf, IssmDouble *pEC, IssmDouble Ta, IssmDouble Ts, IssmDouble V, IssmDouble eAir, IssmDouble pAir, IssmDouble ds, IssmDouble Ws, IssmDouble Vz, IssmDouble Tz, IssmDouble dIce, int sid)
Definition: Gembx.cpp:2131
EsaStrainratexxEnum
@ EsaStrainratexxEnum
Definition: EnumDefinitions.h:563
SmbRlapsEnum
@ SmbRlapsEnum
Definition: EnumDefinitions.h:383
M_PI
#define M_PI
Definition: GridInsideHole.cpp:12
ElementMatrix
Definition: ElementMatrix.h:19
SmbTemperaturesReconstructedYearsEnum
@ SmbTemperaturesReconstructedYearsEnum
Definition: EnumDefinitions.h:395
SmbDailydlradiationEnum
@ SmbDailydlradiationEnum
Definition: EnumDefinitions.h:718
Element::GetInputListOnNodesVelocity
void GetInputListOnNodesVelocity(IssmDouble *pvalue, int enumtype)
Definition: Element.cpp:1114
Vector< IssmDouble >
Element::GradientIndexing
void GradientIndexing(int *indexing, int control_index)
Definition: Element.cpp:1510
SmbDesfacEnum
@ SmbDesfacEnum
Definition: EnumDefinitions.h:350
SmbRdlEnum
@ SmbRdlEnum
Definition: EnumDefinitions.h:381
Input2::GetInputAverage
virtual void GetInputAverage(IssmDouble *pvalue)
Definition: Input2.h:33
SmbThermoDeltaTScalingEnum
@ SmbThermoDeltaTScalingEnum
Definition: EnumDefinitions.h:394
Element::isonsurface
bool isonsurface
Definition: Element.h:52
Element::Delta18oParameterization
void Delta18oParameterization(void)
Definition: Element.cpp:432
Material::GetViscosity_B
virtual void GetViscosity_B(IssmDouble *pviscosity, IssmDouble epseff, Gauss *gauss)=0
Element::element_type
int element_type
Definition: Element.h:56
Node::GetNumberOfDofs
int GetNumberOfDofs(int approximation_enum, int setenum)
Definition: Node.cpp:741
Gauss
Definition: Gauss.h:8
Element::material
Material * material
Definition: Element.h:50
AggressiveMigrationEnum
@ AggressiveMigrationEnum
Definition: EnumDefinitions.h:973
TriaEnum
@ TriaEnum
Definition: EnumDefinitions.h:1318
SmbMInitnum
@ SmbMInitnum
Definition: EnumDefinitions.h:755
Element::GetDofListLocalVelocity
void GetDofListLocalVelocity(int **pdoflist, int setenum)
Definition: Element.cpp:1078
Element::GetDofListVelocity
void GetDofListVelocity(int **pdoflist, int setenum)
Definition: Element.cpp:1031
CalvingratexEnum
@ CalvingratexEnum
Definition: EnumDefinitions.h:509
BasalforcingsMeltrateFactorEnum
@ BasalforcingsMeltrateFactorEnum
Definition: EnumDefinitions.h:74
Element::GetVerticesLidList
void GetVerticesLidList(int *lidlist)
Definition: Element.cpp:1426
TransientInput2::AddTriaTimeInput
void AddTriaTimeInput(IssmDouble time, int numindices, int *indices, IssmDouble *values_in, int interp_in)
Definition: TransientInput2.cpp:138
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
BasalforcingsPicoAverageOverturningEnum
@ BasalforcingsPicoAverageOverturningEnum
Definition: EnumDefinitions.h:76
Vertex::Sid
int Sid(void)
Definition: Vertex.cpp:168
P1xP2Enum
@ P1xP2Enum
Definition: EnumDefinitions.h:1220
Element::GetInputLocalMinMaxOnNodes
void GetInputLocalMinMaxOnNodes(IssmDouble *min, IssmDouble *max, IssmDouble *ug)
Definition: Element.cpp:1152
Element::GetXcoord
IssmDouble GetXcoord(IssmDouble *xyz_list, Gauss *gauss)
Definition: Element.cpp:1462
SmbIsmeltEnum
@ SmbIsmeltEnum
Definition: EnumDefinitions.h:370
SmbIsshortwaveEnum
@ SmbIsshortwaveEnum
Definition: EnumDefinitions.h:374
SmbMeanSHFEnum
@ SmbMeanSHFEnum
Definition: EnumDefinitions.h:752
MaterialsMixedLayerCapacityEnum
@ MaterialsMixedLayerCapacityEnum
Definition: EnumDefinitions.h:260
Element::NumberofNodesVelocity
virtual int NumberofNodesVelocity(void)=0
DamageKappaEnum
@ DamageKappaEnum
Definition: EnumDefinitions.h:116
SmbZTopEnum
@ SmbZTopEnum
Definition: EnumDefinitions.h:799
StressTensoryzEnum
@ StressTensoryzEnum
Definition: EnumDefinitions.h:815
Inputs2::SetDatasetTransientInput
TransientInput2 * SetDatasetTransientInput(int enum_in, int id, IssmDouble *times, int numtimes)
Definition: Inputs2.cpp:649
BasalforcingsPicoIsplumeEnum
@ BasalforcingsPicoIsplumeEnum
Definition: EnumDefinitions.h:83
BasalforcingsBottomplumedepthEnum
@ BasalforcingsBottomplumedepthEnum
Definition: EnumDefinitions.h:59
Node::GetDof
int GetDof(int dofindex, int setenum)
Definition: Node.cpp:374
BasalforcingsPicoSubShelfOceanTempEnum
@ BasalforcingsPicoSubShelfOceanTempEnum
Definition: EnumDefinitions.h:491
ElementMatrix::values
IssmDouble * values
Definition: ElementMatrix.h:26
Element::GetNodesLidList
void GetNodesLidList(int *lidlist)
Definition: Element.cpp:1224
BasalforcingsPlumeradiusEnum
@ BasalforcingsPlumeradiusEnum
Definition: EnumDefinitions.h:86
Element::ComputeDeviatoricStressTensor
virtual void ComputeDeviatoricStressTensor(void)=0
Element::EnthalpyToThermal
void EnthalpyToThermal(IssmDouble *ptemperature, IssmDouble *pwaterfraction, IssmDouble enthalpy, IssmDouble pressure)
Definition: Element.cpp:4593
ComputeD18OTemperaturePrecipitationFromPD
void ComputeD18OTemperaturePrecipitationFromPD(IssmDouble d018, IssmDouble dpermil, bool isTemperatureScaled, bool isPrecipScaled, IssmDouble f, IssmDouble *PrecipitationPresentday, IssmDouble *TemperaturePresentday, IssmDouble *PrecipitationReconstructed, IssmDouble *TemperatureReconstructed, IssmDouble *monthlytemperaturesout, IssmDouble *monthlyprecout)
Definition: ComputeD18OTemperaturePrecipitationFromPD.cpp:10
Element::NewElementMatrix
ElementMatrix * NewElementMatrix(int approximation_enum=NoneApproximationEnum)
Definition: Element.cpp:2497
BasalforcingsMantleconductivityEnum
@ BasalforcingsMantleconductivityEnum
Definition: EnumDefinitions.h:73
Element::StressMaxPrincipalCreateInput
void StressMaxPrincipalCreateInput(void)
Definition: Element.cpp:4172
DefaultCalvingEnum
@ DefaultCalvingEnum
Definition: EnumDefinitions.h:1033