@@ -310,6 +310,156 @@ void Tria::AverageOntoPartition(Vector<IssmDouble>* partition_contribution
310310 }
311311}
312312/* }}}*/
313+ bool Tria::Buttressing (IssmDouble* ptheta, IssmDouble* plength){/* {{{*/
314+
315+ /* Make sure there is a grounding line here*/
316+ if (!IsIceInElement ()) return false ;
317+ if (!IsZeroLevelset (MaskOceanLevelsetEnum)) return true ;
318+
319+ int domaintype,index1,index2;
320+ const IssmPDouble epsilon = 1 .e -15 ;
321+ IssmDouble s1,s2,s_xx,s_yy,s_xy;
322+ IssmDouble gl[NUMVERTICES];
323+ IssmDouble xyz_front[2 ][3 ];
324+
325+ IssmDouble xyz_list[NUMVERTICES][3 ];
326+ ::GetVerticesCoordinates (&xyz_list[0 ][0 ],vertices,NUMVERTICES);
327+
328+ /* Recover parameters and values*/
329+ parameters->FindParam (&domaintype,DomainTypeEnum);
330+ Element::GetInputListOnVertices (&gl[0 ],MaskOceanLevelsetEnum);
331+
332+ /* Be sure that values are not zero*/
333+ if (gl[0 ]==0 .) gl[0 ]=gl[0 ]+epsilon;
334+ if (gl[1 ]==0 .) gl[1 ]=gl[1 ]+epsilon;
335+ if (gl[2 ]==0 .) gl[2 ]=gl[2 ]+epsilon;
336+
337+ if (domaintype==Domain2DverticalEnum){
338+ _error_ (" not implemented" );
339+ }
340+ else if (domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum || domaintype==Domain3DsurfaceEnum){
341+ int pt1 = 0 ;
342+ int pt2 = 1 ;
343+ if (gl[0 ]*gl[1 ]>0 ){ // Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
344+
345+ /* Portion of the segments*/
346+ s1=gl[2 ]/(gl[2 ]-gl[1 ]);
347+ s2=gl[2 ]/(gl[2 ]-gl[0 ]);
348+ if (gl[2 ]<0 .){
349+ pt1 = 1 ; pt2 = 0 ;
350+ }
351+ xyz_front[pt2][0 ]=xyz_list[2 ][0 ]+s1*(xyz_list[1 ][0 ]-xyz_list[2 ][0 ]);
352+ xyz_front[pt2][1 ]=xyz_list[2 ][1 ]+s1*(xyz_list[1 ][1 ]-xyz_list[2 ][1 ]);
353+ xyz_front[pt2][2 ]=xyz_list[2 ][2 ]+s1*(xyz_list[1 ][2 ]-xyz_list[2 ][2 ]);
354+ xyz_front[pt1][0 ]=xyz_list[2 ][0 ]+s2*(xyz_list[0 ][0 ]-xyz_list[2 ][0 ]);
355+ xyz_front[pt1][1 ]=xyz_list[2 ][1 ]+s2*(xyz_list[0 ][1 ]-xyz_list[2 ][1 ]);
356+ xyz_front[pt1][2 ]=xyz_list[2 ][2 ]+s2*(xyz_list[0 ][2 ]-xyz_list[2 ][2 ]);
357+ }
358+ else if (gl[1 ]*gl[2 ]>0 ){ // Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
359+
360+ /* Portion of the segments*/
361+ s1=gl[0 ]/(gl[0 ]-gl[1 ]);
362+ s2=gl[0 ]/(gl[0 ]-gl[2 ]);
363+ if (gl[0 ]<0 .){
364+ pt1 = 1 ; pt2 = 0 ;
365+ }
366+
367+ xyz_front[pt1][0 ]=xyz_list[0 ][0 ]+s1*(xyz_list[1 ][0 ]-xyz_list[0 ][0 ]);
368+ xyz_front[pt1][1 ]=xyz_list[0 ][1 ]+s1*(xyz_list[1 ][1 ]-xyz_list[0 ][1 ]);
369+ xyz_front[pt1][2 ]=xyz_list[0 ][2 ]+s1*(xyz_list[1 ][2 ]-xyz_list[0 ][2 ]);
370+ xyz_front[pt2][0 ]=xyz_list[0 ][0 ]+s2*(xyz_list[2 ][0 ]-xyz_list[0 ][0 ]);
371+ xyz_front[pt2][1 ]=xyz_list[0 ][1 ]+s2*(xyz_list[2 ][1 ]-xyz_list[0 ][1 ]);
372+ xyz_front[pt2][2 ]=xyz_list[0 ][2 ]+s2*(xyz_list[2 ][2 ]-xyz_list[0 ][2 ]);
373+ }
374+ else if (gl[0 ]*gl[2 ]>0 ){ // Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
375+
376+ /* Portion of the segments*/
377+ s1=gl[1 ]/(gl[1 ]-gl[0 ]);
378+ s2=gl[1 ]/(gl[1 ]-gl[2 ]);
379+ if (gl[1 ]<0 .){
380+ pt1 = 1 ; pt2 = 0 ;
381+ }
382+
383+ xyz_front[pt2][0 ]=xyz_list[1 ][0 ]+s1*(xyz_list[0 ][0 ]-xyz_list[1 ][0 ]);
384+ xyz_front[pt2][1 ]=xyz_list[1 ][1 ]+s1*(xyz_list[0 ][1 ]-xyz_list[1 ][1 ]);
385+ xyz_front[pt2][2 ]=xyz_list[1 ][2 ]+s1*(xyz_list[0 ][2 ]-xyz_list[1 ][2 ]);
386+ xyz_front[pt1][0 ]=xyz_list[1 ][0 ]+s2*(xyz_list[2 ][0 ]-xyz_list[1 ][0 ]);
387+ xyz_front[pt1][1 ]=xyz_list[1 ][1 ]+s2*(xyz_list[2 ][1 ]-xyz_list[1 ][1 ]);
388+ xyz_front[pt1][2 ]=xyz_list[1 ][2 ]+s2*(xyz_list[2 ][2 ]-xyz_list[1 ][2 ]);
389+ }
390+ else {
391+ _error_ (" case not possible" );
392+ }
393+
394+ }
395+ else _error_ (" mesh type " <<EnumToStringx (domaintype)<<" not supported yet " );
396+
397+ /* Some checks in debugging mode*/
398+ _assert_ (s1>=0 && s1<=1 .);
399+ _assert_ (s2>=0 && s2<=1 .);
400+
401+ /* Get normal vector*/
402+ IssmDouble normal[3 ];
403+ this ->NormalSection (&normal[0 ],&xyz_front[0 ][0 ]);
404+
405+ /* Get deviatoric stress tensor*/
406+ this ->ComputeDeviatoricStressTensor ();
407+
408+ /* Get inputs*/
409+ IssmDouble flux = 0 .;
410+ IssmDouble vx,vy,thickness,Jdet;
411+ IssmDouble rho_ice = this ->FindParam (MaterialsRhoIceEnum);
412+ IssmDouble rho_seawater = this ->FindParam (MaterialsRhoSeawaterEnum);
413+ IssmDouble constant_g = this ->FindParam (ConstantsGEnum);
414+ Input* vx_input=NULL ;
415+ Input* vy_input=NULL ;
416+ if (domaintype==Domain2DhorizontalEnum){
417+ vx_input=this ->GetInput (VxEnum); _assert_ (vx_input);
418+ vy_input=this ->GetInput (VyEnum); _assert_ (vy_input);
419+ }
420+ else {
421+ vx_input=this ->GetInput (VxAverageEnum); _assert_ (vx_input);
422+ vy_input=this ->GetInput (VyAverageEnum); _assert_ (vy_input);
423+ }
424+ Input *s_xx_input = this ->GetInput (DeviatoricStressxxEnum); _assert_ (s_xx_input);
425+ Input *s_xy_input = this ->GetInput (DeviatoricStressxyEnum); _assert_ (s_xy_input);
426+ Input *s_yy_input = this ->GetInput (DeviatoricStressyyEnum); _assert_ (s_yy_input);
427+ Input *thickness_input = this ->GetInput (ThicknessEnum); _assert_ (thickness_input);
428+
429+ IssmDouble theta = 0 .;
430+ IssmDouble length = 0 .;
431+ Gauss* gauss=this ->NewGauss (&xyz_list[0 ][0 ],&xyz_front[0 ][0 ],3 );
432+ while (gauss->next ()){
433+ thickness_input->GetInputValue (&thickness,gauss);
434+ vx_input->GetInputValue (&vx,gauss);
435+ vy_input->GetInputValue (&vy,gauss);
436+ s_xx_input->GetInputValue (&s_xx,gauss);
437+ s_xy_input->GetInputValue (&s_xy,gauss);
438+ s_yy_input->GetInputValue (&s_yy,gauss);
439+ this ->JacobianDeterminantSurface (&Jdet,&xyz_front[0 ][0 ],gauss);
440+
441+ IssmDouble R[2 ][2 ];
442+ R[0 ][0 ] = 2 *s_xx+s_yy;
443+ R[1 ][0 ] = s_xy;
444+ R[0 ][1 ] = s_xy;
445+ R[1 ][1 ] = 2 *s_yy+s_xx;
446+
447+ IssmDouble N = normal[0 ]*(R[0 ][0 ]*normal[0 ]+R[0 ][1 ]*normal[1 ]) + normal[1 ]*(R[1 ][0 ]*normal[0 ]+R[1 ][1 ]*normal[1 ]);
448+ IssmDouble N0 = 0.5 *constant_g*rho_ice*(1 -rho_ice/rho_seawater)*thickness;
449+
450+ theta += Jdet*gauss->weight *N/N0;
451+ length += Jdet*gauss->weight ;
452+ }
453+
454+ /* Cleanup and return*/
455+ delete gauss;
456+ _assert_ (theta>0 .);
457+ _assert_ (length>0 .);
458+ *ptheta = theta;
459+ *plength = length;
460+ return true ;
461+ }
462+ /* }}}*/
313463void Tria::CalvingRateVonmises (){/* {{{*/
314464
315465 /* First, compute Von Mises Stress*/
0 commit comments