Changeset 26165
- Timestamp:
- 03/30/21 19:32:13 (4 years ago)
- Location:
- issm/trunk-jpl
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/SealevelchangeAnalysis.cpp
r26126 r26165 145 145 parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.settings.glfraction",SolidearthSettingsGlfractionEnum)); 146 146 parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.settings.cross_section_shape",SolidearthSettingsCrossSectionShapeEnum)); 147 parameters->AddObject(iomodel->CopyConstantObject("md.solidearth.settings.optim",SolidearthSettingsOptimEnum));148 147 parameters->AddObject(new DoubleParam(CumBslcEnum,0.0)); 149 148 parameters->AddObject(new DoubleParam(CumBslcIceEnum,0.0)); -
issm/trunk-jpl/src/c/classes/Elements/Element.h
r26164 r26165 383 383 virtual IssmDouble GetArea3D(void)=0; 384 384 virtual IssmDouble GetAreaSpherical(void)=0; 385 virtual IssmDouble OceanAverage(IssmDouble* Sg, SealevelMasks* masks)=0; 386 virtual void SealevelchangeMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old, SealevelMasks* masks)=0; 387 virtual void SealevelchangeMomentOfInertiaElement(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads)=0; 388 virtual IssmDouble SealevelchangeBarystaticIce(IssmDouble* Sgi, SealevelMasks* masks,Vector<IssmDouble>* barystatic_contribution,IssmDouble* partition,IssmDouble oceanarea)=0; 389 virtual IssmDouble SealevelchangeBarystaticHydro(IssmDouble* Sgi, SealevelMasks* masks,Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea)=0; 390 virtual void SealevelchangeBarystaticBottomPressure(IssmDouble* Sgi, SealevelMasks* masks)=0; 391 virtual void SealevelchangeGeometry(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, 392 IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze)=0; 393 virtual void SealevelchangeSal(IssmDouble* Sgo, IssmDouble* Sg_old,SealevelMasks* mask)=0; 394 virtual void DeformationFromSurfaceLoads(IssmDouble* Up, IssmDouble* North, IssmDouble* East, IssmDouble* Sg,SealevelMasks* masks)=0; 395 virtual void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y)=0; 396 397 virtual void SealevelchangeGeometryOptim(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae)=0; 398 virtual void SealevelchangeBarystaticLoads(Vector<IssmDouble>* loads, BarystaticContributions* barycontrib, SealevelMasks* masks)=0; 399 virtual void SealevelchangeConvolution(Vector<IssmDouble>* sealevelloads, Vector<IssmDouble>* oceanareas, IssmDouble* allsealevelloads, IssmDouble* allloads,IssmDouble* rotationaxismotionvector)=0; 400 virtual void SealevelchangeDeformationConvolution(IssmDouble* sealevelloads, IssmDouble* loads, IssmDouble* rotationvector)=0; 401 virtual void SealevelchangeShift(Vector<IssmDouble>* loads, IssmDouble offset, SealevelMasks* masks)=0; 385 virtual void SealevelchangeMomentOfInertia(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads)=0; 386 virtual void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y)=0; 387 388 virtual void SealevelchangeGeometry(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae)=0; 389 virtual void SealevelchangeBarystaticLoads(Vector<IssmDouble>* loads, BarystaticContributions* barycontrib, SealevelMasks* masks)=0; 390 virtual void SealevelchangeConvolution(Vector<IssmDouble>* sealevelloads, Vector<IssmDouble>* oceanareas, IssmDouble* allsealevelloads, IssmDouble* allloads,IssmDouble* rotationaxismotionvector)=0; 391 virtual void SealevelchangeDeformationConvolution(IssmDouble* sealevelloads, IssmDouble* loads, IssmDouble* rotationvector)=0; 392 virtual void SealevelchangeShift(Vector<IssmDouble>* loads, IssmDouble offset, SealevelMasks* masks)=0; 402 393 #endif 403 394 -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r26164 r26165 219 219 #endif 220 220 #ifdef _HAVE_SEALEVELCHANGE_ 221 IssmDouble OceanAverage(IssmDouble* Sg, SealevelMasks* masks){_error_("not implemented yet!");}; 222 void SetSealevelMasks(SealevelMasks* masks){_error_("not implemented yet!");}; 223 void SealevelchangeMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old, SealevelMasks* masks){_error_("not implemented yet!");}; 224 void SealevelchangeMomentOfInertiaElement(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){_error_("not implemented yet!");}; 225 void SealevelchangeGeometry(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, 226 IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze){_error_("not implemented yet!");}; 227 IssmDouble SealevelchangeBarystaticIce(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea){_error_("not implemented yet!");}; 228 IssmDouble SealevelchangeBarystaticHydro(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition,IssmDouble oceanarea){_error_("not implemented yet!");}; 229 void SealevelchangeBarystaticBottomPressure(IssmDouble* Sgi,SealevelMasks* masks){_error_("not implemented yet!");}; 230 void SealevelchangeSal(IssmDouble* Sgo, IssmDouble* Sg_old, SealevelMasks* masks){_error_("not implemented yet!");}; 231 void DeformationFromSurfaceLoads(IssmDouble* Up, IssmDouble* North, IssmDouble* East, IssmDouble* Sg, SealevelMasks* masks){_error_("not implemented yet!");}; 232 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");}; 233 234 void SealevelchangeGeometryOptim(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");}; 221 void SetSealevelMasks(SealevelMasks* masks){_error_("not implemented yet!");}; 222 void SealevelchangeMomentOfInertia(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){_error_("not implemented yet!");}; 223 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");}; 224 225 void SealevelchangeGeometry(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");}; 235 226 void SealevelchangeBarystaticLoads(Vector<IssmDouble>* loads, BarystaticContributions* barycontrib, SealevelMasks* masks){_error_("not implemented yet");}; 236 227 void SealevelchangeConvolution(Vector<IssmDouble>* sealevelloads, Vector<IssmDouble>* oceanareas, IssmDouble* allsealevelloads, IssmDouble* allloads,IssmDouble* rotationaxismotionvector){_error_("not implemented yet");}; -
issm/trunk-jpl/src/c/classes/Elements/Seg.h
r26164 r26165 174 174 #endif 175 175 #ifdef _HAVE_SEALEVELCHANGE_ 176 void SealevelchangeMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old, SealevelMasks* masks){_error_("not implemented yet!");}; 177 void SealevelchangeMomentOfInertiaElement(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){_error_("not implemented yet!");}; 178 void SetSealevelMasks(SealevelMasks* masks){_error_("not implemented yet!");}; 179 void SealevelchangeGeometry(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, 180 IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze){_error_("not implemented yet!");}; 181 IssmDouble SealevelchangeBarystaticIce(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea){_error_("not implemented yet!");}; 182 IssmDouble SealevelchangeBarystaticHydro(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition,IssmDouble oceanarea){_error_("not implemented yet!");}; 183 void SealevelchangeBarystaticBottomPressure(IssmDouble* Sgi,SealevelMasks* masks){_error_("not implemented yet!");}; 184 void SealevelchangeSal(IssmDouble* Sgo,IssmDouble* Sg_old, SealevelMasks* masks){_error_("not implemented yet!");}; 185 void DeformationFromSurfaceLoads(IssmDouble* Up, IssmDouble* North, IssmDouble* East, IssmDouble* Sg, SealevelMasks* masks){_error_("not implemented yet!");}; 186 IssmDouble OceanAverage(IssmDouble* Sg, SealevelMasks* masks){_error_("not implemented yet!");}; 187 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");}; 188 189 void SealevelchangeGeometryOptim(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");}; 176 void SealevelchangeMomentOfInertia(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){_error_("not implemented yet!");}; 177 void SetSealevelMasks(SealevelMasks* masks){_error_("not implemented yet!");}; 178 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");}; 179 void SealevelchangeGeometry(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");}; 190 180 void SealevelchangeBarystaticLoads(Vector<IssmDouble>* loads, BarystaticContributions* barycontrib, SealevelMasks* masks){_error_("not implemented yet");}; 191 181 void SealevelchangeConvolution(Vector<IssmDouble>* sealevelloads, Vector<IssmDouble>* oceanareas, IssmDouble* allsealevelloads, IssmDouble* allloads,IssmDouble* rotationaxismotionvector){_error_("not implemented yet");}; -
issm/trunk-jpl/src/c/classes/Elements/Tetra.h
r26164 r26165 181 181 #endif 182 182 #ifdef _HAVE_SEALEVELCHANGE_ 183 void SetSealevelMasks(SealevelMasks* masks){_error_("not implemented yet!");}; 184 void SealevelchangeMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old, SealevelMasks* masks){_error_("not implemented yet!");}; 185 void SealevelchangeMomentOfInertiaElement(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){_error_("not implemented yet!");}; 186 void SealevelchangeGeometry(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, 187 IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze){_error_("not implemented yet!");}; 188 IssmDouble SealevelchangeBarystaticIce(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea){_error_("not implemented yet!");}; 189 IssmDouble SealevelchangeBarystaticHydro(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition,IssmDouble oceanarea){_error_("not implemented yet!");}; 190 void SealevelchangeBarystaticBottomPressure(IssmDouble* Sgi,SealevelMasks* masks){_error_("not implemented yet!");}; 191 void SealevelchangeSal(IssmDouble* Sgo, IssmDouble* Sg_old, SealevelMasks* masks){_error_("not implemented yet!");}; 192 void DeformationFromSurfaceLoads(IssmDouble* Up ,IssmDouble* North, IssmDouble* East, IssmDouble* Sg, SealevelMasks* masks){_error_("not implemented yet!");}; 193 IssmDouble OceanAverage(IssmDouble* Sg, SealevelMasks* masks){_error_("not implemented yet!");}; 194 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");}; 195 void SealevelchangeGeometryOptim(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");}; 183 void SetSealevelMasks(SealevelMasks* masks){_error_("not implemented yet!");}; 184 void SealevelchangeMomentOfInertia(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){_error_("not implemented yet!");}; 185 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, Matlitho* litho, IssmDouble* x,IssmDouble* y){_error_("not implemented yet");}; 186 void SealevelchangeGeometry(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){_error_("not implemented yet");}; 196 187 void SealevelchangeBarystaticLoads(Vector<IssmDouble>* loads, BarystaticContributions* barycontrib, SealevelMasks* masks){_error_("not implemented yet");}; 197 188 void SealevelchangeConvolution(Vector<IssmDouble>* sealevelloads, Vector<IssmDouble>* oceanareas, IssmDouble* allsealevelloads, IssmDouble* allloads,IssmDouble* rotationaxismotionvector){_error_("not implemented yet");}; -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r26164 r26165 5556 5556 #ifdef _HAVE_SEALEVELCHANGE_ 5557 5557 //old code 5558 IssmDouble Tria::OceanAverage(IssmDouble* Sg, SealevelMasks* masks){ /*{{{*/5559 5560 if(masks->isoceanin[this->lid]){5561 5562 IssmDouble area;5563 5564 /*Get area of element:*/5565 this->Element::GetInputValue(&area,AreaEnum);5566 5567 /*Average Sg over vertices:*/5568 IssmDouble Sg_avg=0; for(int i=0;i<NUMVERTICES;i++) Sg_avg+=Sg[this->vertices[i]->Sid()]/NUMVERTICES;5569 5570 /*return: */5571 return area*Sg_avg;5572 }5573 else return 0;5574 5575 }5576 /*}}}*/5577 void Tria::SealevelchangeMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old, SealevelMasks* masks){/*{{{*/5578 /*early return if we are not on an ice cap OR ocean:*/5579 if(!masks->isiceonly[this->lid] && !masks->isoceanin[this->lid]){5580 dI_list[0] = 0.0; // this is important!!!5581 dI_list[1] = 0.0; // this is important!!!5582 dI_list[2] = 0.0; // this is important!!!5583 return;5584 }5585 5586 /*Compute area of element:*/5587 IssmDouble area,planetarea;5588 this->Element::GetInputValue(&area,AreaEnum);5589 5590 /*recover earth area: */5591 this->parameters->FindParam(&planetarea,SolidearthPlanetAreaEnum);5592 5593 /*Compute lat,long,radius of elemental centroid: */5594 bool spherical=true;5595 IssmDouble llr_list[NUMVERTICES][3];5596 IssmDouble late,longe,re;5597 /* Where is the centroid of this element?:{{{*/5598 ::GetVerticesCoordinates(&llr_list[0][0],this->vertices,NUMVERTICES,spherical);5599 5600 IssmDouble minlong=400;5601 IssmDouble maxlong=-20;5602 for (int i=0;i<NUMVERTICES;i++){5603 llr_list[i][0]=(90-llr_list[i][0]);5604 if(llr_list[i][1]<0)llr_list[i][1]=180+(180+llr_list[i][1]);5605 if(llr_list[i][1]>maxlong)maxlong=llr_list[i][1];5606 if(llr_list[i][1]<minlong)minlong=llr_list[i][1];5607 }5608 if(minlong==0 && maxlong>180){5609 if (llr_list[0][1]==0)llr_list[0][1]=360;5610 if (llr_list[1][1]==0)llr_list[1][1]=360;5611 if (llr_list[2][1]==0)llr_list[2][1]=360;5612 }5613 5614 // correction at the north pole5615 if(llr_list[0][0]==0)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0;5616 if(llr_list[1][0]==0)llr_list[1][1]=(llr_list[0][1]+llr_list[2][1])/2.0;5617 if(llr_list[2][0]==0)llr_list[2][1]=(llr_list[0][1]+llr_list[1][1])/2.0;5618 5619 //correction at the south pole5620 if(llr_list[0][0]==180)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0;5621 if(llr_list[1][0]==180)llr_list[1][1]=(llr_list[0][1]+llr_list[2][1])/2.0;5622 if(llr_list[2][0]==180)llr_list[2][1]=(llr_list[0][1]+llr_list[1][1])/2.0;5623 5624 late=(llr_list[0][0]+llr_list[1][0]+llr_list[2][0])/3.0;5625 longe=(llr_list[0][1]+llr_list[1][1]+llr_list[2][1])/3.0;5626 5627 late=90.-late;5628 if(longe>180.)longe=(longe-180.)-180.;5629 5630 late=late/180.*M_PI;5631 longe=longe/180.*M_PI;5632 /*}}}*/5633 re=(llr_list[0][2]+llr_list[1][2]+llr_list[2][2])/3.0;5634 5635 if(masks->isoceanin[this->lid]){5636 IssmDouble rho_water, S;5637 5638 /*recover material parameters: */5639 rho_water=FindParam(MaterialsRhoSeawaterEnum);5640 5641 /*From Sg_old, recover water sea level change:*/5642 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg_old[this->vertices[i]->Sid()]/NUMVERTICES;5643 5644 /* Perturbation terms for moment of inertia (moi_list):5645 * computed analytically (see Wu & Peltier, eqs 10 & 32)5646 * also consistent with my GMD formulation!5647 * ALL in geographic coordinates5648 * */5649 dI_list[0] = -4*M_PI*(rho_water*S*area)*pow(re,4)*(sin(late)*cos(late)*cos(longe))/planetarea;5650 dI_list[1] = -4*M_PI*(rho_water*S*area)*pow(re,4)*(sin(late)*cos(late)*sin(longe))/planetarea;5651 dI_list[2] = +4*M_PI*(rho_water*S*area)*pow(re,4)*(1-pow(sin(late),2))/planetarea;5652 }5653 if(masks->isiceonly[this->lid]){5654 5655 IssmDouble rho_ice,I;5656 bool computerigid= false;5657 5658 bool notfullygrounded=false;5659 5660 bool scaleoceanarea= false;5661 int glfraction=1;5662 IssmDouble phi=1.0;5663 /*{{{*/5664 if (masks->notfullygrounded[this->lid]) notfullygrounded=true; //used later on.5665 5666 /*recover some parameters:*/5667 rho_ice=FindParam(MaterialsRhoIceEnum);5668 this->parameters->FindParam(&computerigid,SolidearthSettingsRigidEnum);5669 this->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum);5670 this->parameters->FindParam(&glfraction,SolidearthSettingsGlfractionEnum);5671 5672 /*Get area of element: precomputed in the sealevelchange_geometry:*/5673 this->Element::GetInputValue(&area,AreaEnum);5674 5675 /*Compute fraction of the element that is grounded: */5676 if(notfullygrounded){5677 IssmDouble xyz_list[NUMVERTICES][3];5678 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5679 5680 phi=this->GetGroundedPortion(&xyz_list[0][0]); //watch out, this only works because of the Thales theorem! We are in 3D, but this routine is inherently for 2D trias5681 if(glfraction==0)phi=1;5682 #ifdef _ISSM_DEBUG_5683 this->AddInput(SealevelBarystaticMaskEnum,&phi,P0Enum);5684 #endif5685 }5686 else phi=1.0;5687 5688 /*Retrieve surface load for ice: */5689 Input* deltathickness_input=this->GetInput(DeltaIceThicknessEnum);5690 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level change!");5691 5692 /*/Average ice thickness over grounded area of the element only: {{{*/5693 if(!notfullygrounded)deltathickness_input->GetInputAverage(&I);5694 else{5695 IssmDouble total_weight=0;5696 bool mainlyfloating = true;5697 int point1;5698 IssmDouble fraction1,fraction2;5699 5700 /*Recover portion of element that is grounded*/5701 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);5702 Gauss* gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);5703 5704 /* Start looping on the number of gaussian points and average over these gaussian points: */5705 total_weight=0;5706 I=0;5707 while(gauss->next()){5708 IssmDouble Ig=0;5709 deltathickness_input->GetInputValue(&Ig,gauss);5710 I+=Ig*gauss->weight;5711 total_weight+=gauss->weight;5712 }5713 if(total_weight) I=I/total_weight;5714 delete gauss;5715 }5716 /*}}}*/5717 5718 /*}}}*/5719 /*convert to kg/m^2*/5720 I=I*phi;5721 5722 dI_list[0] = -4*M_PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*cos(longe))/planetarea;5723 dI_list[1] = -4*M_PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*sin(longe))/planetarea;5724 dI_list[2] = +4*M_PI*(rho_ice*I*area)*pow(re,4)*(1-pow(sin(late),2))/planetarea;5725 }5726 5727 return;5728 }/*}}}*/5729 5558 void Tria::SetSealevelMasks(SealevelMasks* masks){ /*{{{*/ 5730 5559 … … 5740 5569 if ((gr_input->GetInputMin())<0) masks->notfullygrounded[this->lid]=true; 5741 5570 else masks->notfullygrounded[this->lid]=false; 5742 }5743 /*}}}*/5744 void Tria::SealevelchangeGeometry(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze){ /*{{{*/5745 5746 /*diverse:*/5747 int gsize;5748 bool spherical=true;5749 IssmDouble llr_list[NUMVERTICES][3];5750 IssmDouble xyz_list[NUMVERTICES][3];5751 IssmDouble area,planetarea,planetradius;5752 IssmDouble I; //change in ice thickness or water level(Farrel and Clarke, Equ. 4)5753 IssmDouble rho_earth;5754 IssmDouble late,longe,re;5755 IssmDouble lati,longi,ri;5756 IssmDouble constant;5757 IssmDouble x_element,y_element,z_element,x,y,z,dx,dy,dz,N_azim,E_azim;5758 5759 #ifdef _HAVE_RESTRICT_5760 IssmDouble* __restrict__ G=NULL;5761 IssmDouble* __restrict__ GU=NULL;5762 IssmDouble* __restrict__ GN=NULL;5763 IssmDouble* __restrict__ GE=NULL;5764 IssmDouble* __restrict__ G_elastic_precomputed=NULL;5765 IssmDouble* __restrict__ G_rigid_precomputed=NULL;5766 IssmDouble* __restrict__ U_elastic_precomputed=NULL;5767 IssmDouble* __restrict__ H_elastic_precomputed=NULL;5768 IssmDouble* __restrict__ indices=NULL;5769 #else5770 IssmDouble* G=NULL;5771 IssmDouble* GU=NULL;5772 IssmDouble* GN=NULL;5773 IssmDouble* GE=NULL;5774 IssmDouble* G_elastic_precomputed=NULL;5775 IssmDouble* G_rigid_precomputed=NULL;5776 IssmDouble* U_elastic_precomputed=NULL;5777 IssmDouble* H_elastic_precomputed=NULL;5778 IssmDouble* indices=NULL;5779 #endif5780 5781 /*elastic green function:*/5782 int index;5783 int M,Mtest;5784 5785 /*Computational flags:*/5786 bool computerigid = false;5787 bool computeelastic = false;5788 int horiz;5789 5790 /*recover parameters: */5791 rho_earth=FindParam(MaterialsEarthDensityEnum);5792 this->parameters->FindParam(&computerigid,SolidearthSettingsRigidEnum);5793 this->parameters->FindParam(&computeelastic,SolidearthSettingsElasticEnum);5794 this->parameters->FindParam(&gsize,MeshNumberofverticesEnum);5795 this->parameters->FindParam(&planetarea,SolidearthPlanetAreaEnum);5796 this->parameters->FindParam(&planetradius,SolidearthPlanetRadiusEnum);5797 this->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);5798 5799 /*compute area and add to inputs:*/5800 area=GetAreaSpherical();5801 this->inputs->SetDoubleInput(AreaEnum,this->lid,area);5802 this->AddInput(SealevelAreaEnum,&area,P0Enum);5803 if(!computerigid)return;5804 5805 /*recover precomputed green function kernels:*/5806 DoubleVecParam* parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeGRigidEnum)); _assert_(parameter);5807 parameter->GetParameterValueByPointer((IssmDouble**)&G_rigid_precomputed,&M);5808 _assert_(M>0);5809 5810 /*allocate indices:*/5811 indices=xNew<IssmDouble>(gsize);5812 G=xNewZeroInit<IssmDouble>(gsize);5813 5814 if(computeelastic){5815 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeGElasticEnum)); _assert_(parameter);5816 parameter->GetParameterValueByPointer((IssmDouble**)&G_elastic_precomputed,&Mtest); _assert_(Mtest==M);5817 5818 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeHElasticEnum)); _assert_(parameter);5819 parameter->GetParameterValueByPointer((IssmDouble**)&H_elastic_precomputed,&Mtest); _assert_(Mtest==M);5820 5821 parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelchangeUElasticEnum)); _assert_(parameter);5822 parameter->GetParameterValueByPointer((IssmDouble**)&U_elastic_precomputed,&Mtest); _assert_(Mtest==M);5823 5824 GU=xNewZeroInit<IssmDouble>(gsize);5825 if(horiz){5826 GN=xNewZeroInit<IssmDouble>(gsize);5827 GE=xNewZeroInit<IssmDouble>(gsize);5828 }5829 }5830 5831 /* Where is the centroid of this element:*/5832 5833 /*retrieve coordinates: */5834 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5835 5836 /*figure out gravity center of our element (Cartesian): */5837 x_element=(xyz_list[0][0]+xyz_list[1][0]+xyz_list[2][0])/3.0;5838 y_element=(xyz_list[0][1]+xyz_list[1][1]+xyz_list[2][1])/3.0;5839 z_element=(xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2])/3.0;5840 5841 /*compute gravity center in lat,long: */5842 late= asin(z_element/planetradius);5843 longe = atan2(y_element,x_element);5844 5845 constant=3/rho_earth*area/planetarea;5846 5847 for(int i=0;i<gsize;i++){5848 IssmDouble alpha;5849 IssmDouble delPhi,delLambda;5850 5851 /*Compute alpha angle between centroid and current vertex and index into precomputed tables: */5852 lati=latitude[i]/180.*M_PI; longi=longitude[i]/180.*M_PI;5853 delPhi=fabs(lati-late); delLambda=fabs(longi-longe); if (delLambda>M_PI)delLambda=2*M_PI-delLambda;5854 alpha=2.*asin(sqrt(pow(sin(delPhi/2),2)+cos(lati)*cos(late)*pow(sin(delLambda/2),2)));5855 indices[i]=alpha/M_PI*reCast<IssmDouble,int>(M-1);5856 index=reCast<int,IssmDouble>(indices[i]);5857 _assert_(index>=0); _assert_(index<M);5858 5859 /*Rigid earth gravitational perturbation: */5860 G[i]+=G_rigid_precomputed[index];5861 5862 if(computeelastic){5863 G[i]+=G_elastic_precomputed[index];5864 }5865 G[i]=G[i]*constant;5866 5867 /*Elastic components:*/5868 if(computeelastic){5869 GU[i] = constant * U_elastic_precomputed[index];5870 if(horiz){5871 /*Compute azimuths, both north and east components: */5872 x = xx[i]; y = yy[i]; z = zz[i];5873 if(latitude[i]==90){5874 x=1e-12; y=1e-12;5875 }5876 if(latitude[i]==-90){5877 x=1e-12; y=1e-12;5878 }5879 dx = x_element-x; dy = y_element-y; dz = z_element-z;5880 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);5881 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);5882 5883 GN[i] = constant*H_elastic_precomputed[index]*N_azim;5884 GE[i] = constant*H_elastic_precomputed[index]*E_azim;5885 }5886 }5887 }5888 5889 /*Add in inputs:*/5890 this->inputs->SetArrayInput(SealevelchangeGEnum,this->lid,G,gsize);5891 if(computeelastic){5892 this->inputs->SetArrayInput(SealevelchangeGUEnum,this->lid,GU,gsize);5893 if(horiz){5894 this->inputs->SetArrayInput(SealevelchangeGNEnum,this->lid,GN,gsize);5895 this->inputs->SetArrayInput(SealevelchangeGEEnum,this->lid,GE,gsize);5896 }5897 }5898 this->inputs->SetDoubleInput(AreaEnum,this->lid,area);5899 this->AddInput(SealevelAreaEnum,&area,P0Enum);5900 5901 /*Free allocations:*/5902 #ifdef _HAVE_RESTRICT_5903 delete indices;5904 delete G;5905 if(computeelastic){5906 delete GU;5907 if(horiz){5908 delete GN;5909 delete GE;5910 }5911 }5912 #else5913 xDelete(indices);5914 xDelete(G);5915 if(computeelastic){5916 xDelete(GU);5917 if(horiz){5918 xDelete(GN);5919 xDelete(GE);5920 }5921 }5922 #endif5923 5924 return;5925 }5926 /*}}}*/5927 IssmDouble Tria::SealevelchangeBarystaticIce(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea){ /*{{{*/5928 5929 /*diverse:*/5930 int gsize;5931 IssmDouble area;5932 IssmDouble phi=1.0; //WARNING: do not touch this, default is entire elemnt contributes barystatic5933 IssmDouble I; //change in ice thickness or water level(Farrel and Clarke, Equ. 4)5934 bool notfullygrounded=false;5935 bool scaleoceanarea= false;5936 bool computerigid= false;5937 int glfraction=1;5938 5939 /*output: */5940 IssmDouble bslcice=0;5941 5942 /*elastic green function:*/5943 IssmDouble* G=NULL;5944 5945 /*ice properties: */5946 IssmDouble rho_ice,rho_water;5947 5948 /*constants:*/5949 IssmDouble constant=0;5950 5951 /*early return if we are not on an ice cap:*/5952 if(!masks->isiceonly[this->lid]){5953 #ifdef _ISSM_DEBUG_5954 constant=0; this->AddInput(SealevelBarystaticMaskEnum,&constant,P0Enum);5955 #endif5956 bslcice=0;5957 return bslcice;5958 }5959 5960 /*early return if we are fully floating:*/5961 if (masks->isfullyfloating[this->lid]){5962 constant=0;5963 #ifdef _ISSM_DEBUG_5964 this->AddInput(SealevelBarystaticMaskEnum,&constant,P0Enum);5965 #endif5966 bslcice=0;5967 return bslcice;5968 }5969 5970 /*If we are here, we are on ice that is fully grounded or half-way to floating:*/5971 if (masks->notfullygrounded[this->lid]) notfullygrounded=true; //used later on.5972 5973 /*Inform mask: */5974 constant=1;5975 #ifdef _ISSM_DEBUG_5976 this->AddInput(SealevelBarystaticMaskEnum,&constant,P0Enum);5977 #endif5978 5979 /*recover some parameters:*/5980 rho_ice=FindParam(MaterialsRhoIceEnum);5981 rho_water=FindParam(MaterialsRhoSeawaterEnum);5982 this->parameters->FindParam(&computerigid,SolidearthSettingsRigidEnum);5983 this->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum);5984 this->parameters->FindParam(&glfraction,SolidearthSettingsGlfractionEnum);5985 5986 /*retrieve precomputed G:*/5987 if(computerigid)this->inputs->GetArrayPtr(SealevelchangeGEnum,this->lid,&G,&gsize);5988 5989 /*Get area of element: precomputed in the sealevelchange_geometry:*/5990 this->Element::GetInputValue(&area,AreaEnum);5991 5992 /*Compute fraction of the element that is grounded: */5993 if(notfullygrounded){5994 IssmDouble xyz_list[NUMVERTICES][3];5995 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5996 5997 phi=this->GetGroundedPortion(&xyz_list[0][0]); //watch out, this only works because of the Thales theorem! We are in 3D, but this routine is inherently for 2D trias5998 if(glfraction==0)phi=1;5999 #ifdef _ISSM_DEBUG_6000 this->AddInput(SealevelBarystaticMaskEnum,&phi,P0Enum);6001 #endif6002 }6003 else phi=1.0;6004 6005 /*Retrieve surface load for ice: */6006 Input* deltathickness_input=this->GetInput(DeltaIceThicknessEnum);6007 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level change!");6008 6009 /*/Average ice thickness over grounded area of the element only: {{{*/6010 if(!notfullygrounded)deltathickness_input->GetInputAverage(&I);6011 else{6012 IssmDouble total_weight=0;6013 bool mainlyfloating = true;6014 int point1;6015 IssmDouble fraction1,fraction2;6016 6017 /*Recover portion of element that is grounded*/6018 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);6019 Gauss* gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);6020 6021 /* Start looping on the number of gaussian points and average over these gaussian points: */6022 total_weight=0;6023 I=0;6024 while(gauss->next()){6025 IssmDouble Ig=0;6026 deltathickness_input->GetInputValue(&Ig,gauss);6027 I+=Ig*gauss->weight;6028 total_weight+=gauss->weight;6029 }6030 I=I/total_weight;6031 delete gauss;6032 }6033 /*}}}*/6034 6035 /*Compute barystatic contribution:*/6036 _assert_(oceanarea>0.);6037 if(scaleoceanarea) oceanarea=3.619e+14; // use true ocean area, m^26038 bslcice = rho_ice*area*phi*I/(oceanarea*rho_water);6039 _assert_(!xIsNan<IssmDouble>(bslcice));6040 6041 if(computerigid){6042 /*convert from m to kg/m^2:*/6043 I=I*rho_ice*phi;6044 6045 /*convolve:*/6046 for(int i=0;i<gsize;i++) Sgi[i]+=G[i]*I;6047 }6048 6049 /*Plug bslcice into barystatic contribution vector:*/6050 if(barystatic_contribution){6051 id=reCast<int>(partition[this->Sid()])+1;6052 barystatic_contribution->SetValue(id,bslcice,ADD_VAL);6053 }6054 /*return :*/6055 return bslcice;6056 }6057 /*}}}*/6058 IssmDouble Tria::SealevelchangeBarystaticHydro(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea){ /*{{{*/6059 6060 /*diverse:*/6061 int gsize;6062 IssmDouble area;6063 IssmDouble phi=1.0; //WARNING: do not touch this, default is entire elemnt contributes barystatic6064 IssmDouble W; //change in water height thickness (Farrel and Clarke, Equ. 4)6065 bool notfullygrounded=false;6066 bool scaleoceanarea= false;6067 bool computeelastic= false;6068 6069 /*elastic green function:*/6070 IssmDouble* G=NULL;6071 6072 /*ice properties: */6073 IssmDouble rho_water;6074 IssmDouble rho_freshwater;6075 6076 /*output:*/6077 IssmDouble bslchydro = 0;6078 6079 /*early return if we are on an ice cap. Nop, we may have hydro6080 * and ice on the same masscon:*/6081 /*if(masks->isiceonly[this->lid]){6082 bslchydro=0;6083 return bslchydro;6084 }*/6085 6086 /*early return if we are fully floating:*/6087 if (masks->isfullyfloating[this->lid]){6088 bslchydro=0;6089 return bslchydro;6090 }6091 6092 /*If we are here, we are on earth, not on ice: */6093 6094 /*recover parameters: */6095 rho_water=FindParam(MaterialsRhoSeawaterEnum);6096 rho_freshwater=FindParam(MaterialsRhoFreshwaterEnum);6097 this->parameters->FindParam(&computeelastic,SolidearthSettingsElasticEnum);6098 this->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum);6099 6100 /*retrieve precomputed G:*/6101 if(computeelastic)this->inputs->GetArrayPtr(SealevelchangeGEnum,this->lid,&G,&gsize);6102 6103 /*Get area of element: precomputed in the sealevelchange_geometry:*/6104 this->Element::GetInputValue(&area,AreaEnum);6105 6106 /*Retrieve water height at vertices: */6107 Input* deltathickness_input=this->GetInput(DeltaTwsEnum);6108 if (!deltathickness_input)_error_("DeltaTwsEnum input needed to compute sea level change!");6109 deltathickness_input->GetInputAverage(&W);6110 6111 /*Compute barystatic component:*/6112 _assert_(oceanarea>0.);6113 if(scaleoceanarea) oceanarea=3.619e+14; // use true ocean area, m^26114 bslchydro = rho_freshwater*area*phi*W/(oceanarea*rho_water);6115 _assert_(!xIsNan<IssmDouble>(bslchydro));6116 6117 if(computeelastic){6118 /*convert from m to kg/m^2:*/6119 W=W*rho_freshwater*phi;6120 6121 /*convolve:*/6122 for(int i=0;i<gsize;i++) Sgi[i]+=G[i]*W;6123 }6124 6125 /*Plug bslcice into barystatic contribution vector:*/6126 if(barystatic_contribution){6127 id=reCast<int>(partition[this->Sid()])+1;6128 barystatic_contribution->SetValue(id,bslchydro,ADD_VAL);6129 }6130 /*output:*/6131 return bslchydro;6132 }6133 /*}}}*/6134 void Tria::SealevelchangeBarystaticBottomPressure(IssmDouble* Sgi,SealevelMasks* masks){ /*{{{*/6135 6136 /*diverse:*/6137 int gsize;6138 IssmDouble area;6139 IssmDouble BP; //change in bottom pressure (Farrel and Clarke, Equ. 4)6140 IssmDouble constant;6141 bool computeelastic= false;6142 6143 /*elastic green function:*/6144 IssmDouble* G=NULL;6145 6146 /*water properties: */6147 IssmDouble rho_water;6148 6149 /*exit now?:*/6150 this->parameters->FindParam(&computeelastic,SolidearthSettingsElasticEnum);6151 if(!computeelastic)return;6152 6153 /*we are here to compute fingerprints originating fromn bottom pressure changes:*/6154 if(!masks->isoceanin[this->lid])return;6155 6156 /*Inform mask: */6157 #ifdef _ISSM_DEBUG_6158 constant=1; this->AddInput(SealevelBarystaticMaskEnum,&constant,P0Enum);6159 #endif6160 6161 /*recover material parameters: */6162 rho_water=FindParam(MaterialsRhoSeawaterEnum);6163 6164 /*retrieve precomputed G:*/6165 this->inputs->GetArrayPtr(SealevelchangeGEnum,this->lid,&G,&gsize);6166 6167 /*Get area of element: precomputed in the sealevelchange_geometry:*/6168 this->Element::GetInputValue(&area,AreaEnum);6169 6170 /*Retrieve bottom pressure change and average over the element: */6171 Input* bottompressure_change_input=this->GetInput(DeltaBottomPressureEnum);6172 if (!bottompressure_change_input)_error_("DeltaBottomPressureEnum pressure input needed to compute sea level change fingerprint!");6173 bottompressure_change_input->GetInputAverage(&BP);6174 6175 /*convert from m to kg/m^2:*/6176 BP=BP*rho_water;6177 6178 /*convolve:*/6179 for(int i=0;i<gsize;i++) Sgi[i]+=G[i]*BP;6180 6181 return;6182 }6183 /*}}}*/6184 void Tria::SealevelchangeSal(IssmDouble* Sgo,IssmDouble* Sg_old, SealevelMasks* masks){ /*{{{*/6185 6186 /*diverse:*/6187 int gsize,dummy;6188 IssmDouble S; //change in water water level(Farrel and Clarke, Equ. 4)6189 IssmDouble constant=0;6190 IssmDouble rho_water;6191 IssmDouble* G=NULL;6192 6193 /*retrieve parameters:*/6194 rho_water=FindParam(MaterialsRhoSeawaterEnum);6195 6196 /*early return if we are not on the ocean:*/6197 if (!masks->isoceanin[this->lid]){6198 constant=0;6199 #ifdef _ISSM_DEBUG_6200 this->AddInput(SealevelBarystaticOceanMaskEnum,&constant,P0Enum);6201 #endif6202 return;6203 }6204 constant=1;6205 #ifdef _ISSM_DEBUG_6206 this->AddInput(SealevelBarystaticOceanMaskEnum,&constant,P0Enum);6207 #endif6208 6209 /*how many dofs are we working with here? */6210 this->parameters->FindParam(&gsize,MeshNumberofverticesEnum);6211 6212 /*retrieve precomputed G:*/6213 this->inputs->GetArrayPtr(SealevelchangeGEnum,this->lid,&G,&dummy); _assert_(dummy==gsize);6214 6215 /*From Sg_old, recover water sea level change:*/6216 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg_old[this->vertices[i]->Sid()]/NUMVERTICES;6217 6218 /*convert to kg/m^2: */6219 S=S*rho_water;6220 6221 for(int i=0;i<gsize;i++) Sgo[i]+=G[i]*S;6222 6223 return;6224 }6225 /*}}}*/6226 void Tria::DeformationFromSurfaceLoads(IssmDouble* Up, IssmDouble* North ,IssmDouble* East,IssmDouble* Sg, SealevelMasks* masks){ /*{{{*/6227 6228 /*diverse:*/6229 int gsize;6230 IssmDouble I=0;6231 IssmDouble S=0;6232 IssmDouble BP=0;6233 IssmDouble rho_ice,rho_water;6234 int horiz;6235 int bp_compute_fingerprints= 0;6236 6237 /*precomputed elastic green functions:*/6238 IssmDouble* GU=NULL;6239 IssmDouble* GN=NULL;6240 IssmDouble* GE=NULL;6241 6242 /*computational flags:*/6243 bool computeelastic= false;6244 bool computerigid= false;6245 bool notfullygrounded=false;6246 bool scaleoceanarea= false;6247 int glfraction=1;6248 IssmDouble area;6249 IssmDouble phi=1.0;6250 6251 /*early return if we are not on the ocean or on an ice cap:*/6252 if(!masks->isiceonly[this->lid] && !masks->isoceanin[this->lid]) return;6253 6254 /*recover parameters:*/6255 this->parameters->FindParam(&computeelastic,SolidearthSettingsElasticEnum);6256 this->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);6257 this->parameters->FindParam(&bp_compute_fingerprints,SolidearthSettingsComputeBpGrdEnum);6258 6259 /*early return if elastic not requested:*/6260 if(!computeelastic) return;6261 6262 /*recover material parameters: */6263 rho_ice=FindParam(MaterialsRhoIceEnum);6264 rho_water=FindParam(MaterialsRhoSeawaterEnum);6265 6266 /*recover elastic Green's functions for displacement:*/6267 this->inputs->GetArrayPtr(SealevelchangeGUEnum,this->lid,&GU,&gsize);6268 if(horiz){6269 this->inputs->GetArrayPtr(SealevelchangeGEEnum,this->lid,&GE,&gsize);6270 this->inputs->GetArrayPtr(SealevelchangeGNEnum,this->lid,&GN,&gsize);6271 }6272 6273 6274 if(masks->isoceanin[this->lid]){6275 /*From Sg, recover water sea level change:*/6276 S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg[this->vertices[i]->Sid()]/NUMVERTICES;6277 6278 /*convert to kg/m^2:*/6279 S=rho_water*S;6280 6281 /*If bottom pressures are available, retrieve them to load the bedrock:*/6282 if(bp_compute_fingerprints){6283 Input* bottompressure_change_input=this->GetInput(DeltaBottomPressureEnum);6284 if (!bottompressure_change_input)_error_("bottom pressure input needed to compute sea level change fingerprint!");6285 bottompressure_change_input->GetInputAverage(&BP);6286 6287 /*convert from m to kg/m^2:*/6288 BP=BP*rho_water;6289 6290 S+=BP;6291 }6292 6293 for(int i=0;i<gsize;i++){6294 Up[i]+=S*GU[i];6295 if(horiz){6296 North[i]+=S*GN[i];6297 East[i]+=S*GE[i];6298 }6299 }6300 }6301 if (masks->isiceonly[this->lid]){6302 6303 if (masks->isfullyfloating[this->lid]) return;6304 6305 6306 if (masks->notfullygrounded[this->lid]) notfullygrounded=true; //used later on.6307 6308 /*recover some parameters:*/6309 rho_ice=FindParam(MaterialsRhoIceEnum);6310 rho_water=FindParam(MaterialsRhoSeawaterEnum);6311 this->parameters->FindParam(&computerigid,SolidearthSettingsRigidEnum);6312 this->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum);6313 this->parameters->FindParam(&glfraction,SolidearthSettingsGlfractionEnum);6314 6315 /*Get area of element: precomputed in the sealevelchange_geometry:*/6316 this->Element::GetInputValue(&area,AreaEnum);6317 6318 /*Compute fraction of the element that is grounded: */6319 if(notfullygrounded){6320 IssmDouble xyz_list[NUMVERTICES][3];6321 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6322 6323 phi=this->GetGroundedPortion(&xyz_list[0][0]); //watch out, this only works because of the Thales theorem! We are in 3D, but this routine is inherently for 2D trias6324 if(glfraction==0)phi=1;6325 #ifdef _ISSM_DEBUG_6326 this->AddInput(SealevelBarystaticMaskEnum,&phi,P0Enum);6327 #endif6328 }6329 else phi=1.0;6330 6331 /*Retrieve surface load for ice: */6332 Input* deltathickness_input=this->GetInput(DeltaIceThicknessEnum);6333 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level change!");6334 6335 /*/Average ice thickness over grounded area of the element only: {{{*/6336 if(!notfullygrounded)deltathickness_input->GetInputAverage(&I);6337 else{6338 IssmDouble total_weight=0;6339 bool mainlyfloating = true;6340 int point1;6341 IssmDouble fraction1,fraction2;6342 6343 /*Recover portion of element that is grounded*/6344 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);6345 Gauss* gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);6346 6347 /* Start looping on the number of gaussian points and average over these gaussian points: */6348 total_weight=0;6349 I=0;6350 while(gauss->next()){6351 IssmDouble Ig=0;6352 deltathickness_input->GetInputValue(&Ig,gauss);6353 I+=Ig*gauss->weight;6354 total_weight+=gauss->weight;6355 }6356 I=I/total_weight;6357 delete gauss;6358 }6359 /*}}}*/6360 6361 /*convert to kg/m^2*/6362 I=I*rho_ice*phi;6363 6364 for(int i=0;i<gsize;i++){6365 Up[i]+=I*GU[i];6366 if(horiz){6367 North[i]+=I*GN[i];6368 East[i]+=I*GE[i];6369 }6370 }6371 }6372 6373 return;6374 5571 } 6375 5572 /*}}}*/ … … 6479 5676 } 6480 5677 /*}}}*/ 6481 6482 //new code 6483 void Tria::SealevelchangeGeometryOptim(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){ /*{{{*/ 5678 void Tria::SealevelchangeGeometry(IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae){ /*{{{*/ 6484 5679 6485 5680 /*diverse:*/ … … 7098 6293 } 7099 6294 /*}}}*/ 7100 void Tria::SealevelchangeMomentOfInertia Element(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){/*{{{*/6295 void Tria::SealevelchangeMomentOfInertia(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads){/*{{{*/ 7101 6296 7102 6297 IssmDouble S=0; -
issm/trunk-jpl/src/c/classes/Elements/Tria.h
r26164 r26165 165 165 #endif 166 166 #ifdef _HAVE_SEALEVELCHANGE_ 167 void SealevelchangeMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old,SealevelMasks* masks); 168 void SealevelchangeMomentOfInertiaElement(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads); 167 void SealevelchangeMomentOfInertia(IssmDouble* dI_list, IssmDouble* loads, IssmDouble* sealevelloads); 169 168 void SealevelchangeGeometry(IssmDouble* lat, IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze); 170 IssmDouble SealevelchangeBarystaticIce(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition, IssmDouble oceanarea);171 IssmDouble SealevelchangeBarystaticHydro(IssmDouble* Sgi, SealevelMasks* masks, Vector<IssmDouble>* barystatic_contribution, IssmDouble* partition,IssmDouble oceanarea);172 void SealevelchangeBarystaticBottomPressure(IssmDouble* Sgi,SealevelMasks* masks);173 void SealevelchangeSal(IssmDouble* Sgo,IssmDouble* Sg_old,SealevelMasks* masks);174 void DeformationFromSurfaceLoads(IssmDouble* Up, IssmDouble* North, IssmDouble* East, IssmDouble* Sg,SealevelMasks* masks);175 169 void GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,Matlitho* litho, IssmDouble* x,IssmDouble* y); 176 IssmDouble OceanAverage(IssmDouble* Sg, SealevelMasks* masks);177 170 void SetSealevelMasks(SealevelMasks* masks); 178 179 void SealevelchangeGeometryOptim(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae); 171 void SealevelchangeGeometry(IssmDouble* lat,IssmDouble* longi,IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz, IssmDouble* xxe, IssmDouble* yye, IssmDouble* zze, IssmDouble* areae); 180 172 void SealevelchangeBarystaticLoads(Vector<IssmDouble>* loads, BarystaticContributions* barycontrib, SealevelMasks* masks); 181 173 void SealevelchangeConvolution(Vector<IssmDouble>* sealevelloads, Vector<IssmDouble>* oceanareas, IssmDouble* allsealevelloads, IssmDouble* allloads,IssmDouble* rotationaxismotionvector); -
issm/trunk-jpl/src/c/classes/FemModel.cpp
r26114 r26165 4748 4748 /*}}}*/ 4749 4749 #endif 4750 #ifdef _HAVE_SEALEVELCHANGE_4751 void FemModel::SealevelchangeBarystatic(Vector<IssmDouble>* pRSLgi, IssmDouble* poceanarea, IssmDouble* pbslc,IssmDouble* pbslcice, IssmDouble* pbslchydro, IssmDouble** pbslcice_partition,IssmDouble** pbslchydro_partition,SealevelMasks* masks) { /*{{{*/4752 4753 /*serialized vectors:*/4754 IssmDouble bslcice = 0.;4755 IssmDouble bslcice_cpu = 0.;4756 IssmDouble bslchydro = 0.;4757 IssmDouble bslchydro_cpu = 0.;4758 IssmDouble area = 0.;4759 IssmDouble oceanarea = 0.;4760 IssmDouble oceanarea_cpu = 0.;4761 int bp_compute_fingerprints= 0;4762 bool isoceantransport=false;4763 4764 Vector<IssmDouble>* bslcice_partition=NULL;4765 IssmDouble* bslcice_partition_serial=NULL;4766 IssmDouble* partitionice=NULL;4767 int npartice,nel;4768 4769 Vector<IssmDouble>* bslchydro_partition=NULL;4770 IssmDouble* bslchydro_partition_serial=NULL;4771 IssmDouble* partitionhydro=NULL;4772 bool istws=0;4773 int nparthydro;4774 4775 int npartocean;4776 Vector<IssmDouble>* bslcocean_partition=NULL;4777 IssmDouble* bslcocean_partition_serial=NULL;4778 IssmDouble* partitionocean=NULL;4779 4780 /*Initialize temporary vector that will be used to sum barystatic components4781 * on all local elements, prior to assembly:*/4782 int gsize = this->nodes->NumberOfDofs(GsetEnum);4783 IssmDouble* RSLgi=xNewZeroInit<IssmDouble>(gsize);4784 int* indices=xNew<int>(gsize);4785 for(int i=0;i<gsize;i++) indices[i]=i;4786 4787 /*First, figure out the area of the ocean, which is needed to compute the barystatic component: */4788 int i = -1;4789 for(Object* & object : this->elements->objects){4790 i +=1;4791 Element* element = xDynamicCast<Element*>(object);4792 element->GetInputValue(&area,AreaEnum);4793 if (masks->isoceanin[i]) oceanarea_cpu += area;4794 }4795 ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );4796 ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());4797 _assert_(oceanarea>0.);4798 4799 /*Initialize partition vectors to retrieve barystatic contributions: */4800 this->parameters->FindParam(&npartice,SolidearthNpartIceEnum);4801 if(npartice){4802 this->parameters->FindParam(&partitionice,&nel,NULL,SolidearthPartitionIceEnum);4803 bslcice_partition= new Vector<IssmDouble>(npartice);4804 }4805 4806 this->parameters->FindParam(&nparthydro,SolidearthNpartHydroEnum);4807 if(nparthydro){4808 this->parameters->FindParam(&partitionhydro,&nel,NULL,SolidearthPartitionHydroEnum);4809 bslchydro_partition= new Vector<IssmDouble>(nparthydro);4810 }4811 4812 this->parameters->FindParam(&npartocean,SolidearthNpartOceanEnum);4813 if(npartocean){4814 this->parameters->FindParam(&partitionocean,&nel,NULL,SolidearthPartitionOceanEnum);4815 bslchydro_partition= new Vector<IssmDouble>(npartocean);4816 }4817 /*For later:4818 npartbarystatic=npartice;4819 if(nparthydro>npartbarystatic)npartbarystatic=nparthydro;4820 if(npartocean>npartbarystatic)npartbarystatic=npartocean;4821 bslc_partition=new Matrix(IssmDouble>(npartbarystatic,3);4822 4823 bslc_cpu[0]=0; bslc_cpu[1]=0; bslc_cpu[2]=0;4824 for(Object* & object : this->elements->objects){4825 Element* element = xDynamicCast<Element*>(object);4826 element->SealevelchangeBarystaticLoads(&bslc_cpu[0], localloads,masks, bslcice_partition,partitionice,oceanarea);4827 }4828 MPI Bcast localloads -> loads4829 4830 for(Object* & object : this->elements->objects){4831 Element* element = xDynamicCast<Element*>(object);4832 element->SealevelchangeConvolution(loads);4833 }4834 */4835 4836 4837 4838 4839 4840 /*Call the barystatic sea level change core for ice : */4841 bslcice_cpu=0;4842 for(Object* & object : this->elements->objects){4843 Element* element = xDynamicCast<Element*>(object);4844 bslcice_cpu+=element->SealevelchangeBarystaticIce(RSLgi,masks, bslcice_partition,partitionice,oceanarea);4845 }4846 4847 /*Call the barystatic sea level change core for hydro: */4848 bslchydro_cpu=0; //make sure to initialize this, so we have a total barystatic contribution computed at 0.4849 this->parameters->FindParam(&istws,TransientIshydrologyEnum);4850 if(istws){4851 for(int i=0;i<elements->Size();i++){4852 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));4853 bslchydro_cpu+=element->SealevelchangeBarystaticHydro(RSLgi,masks, bslchydro_partition,partitionhydro,oceanarea);4854 }4855 }4856 4857 /*Call the barystatic sea level change core for bottom pressures: */4858 this->parameters->FindParam(&bp_compute_fingerprints,SolidearthSettingsComputeBpGrdEnum);4859 this->parameters->FindParam(&isoceantransport,TransientIsoceantransportEnum);4860 if(bp_compute_fingerprints && isoceantransport){4861 for(int i=0;i<elements->Size();i++){4862 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));4863 element->SealevelchangeBarystaticBottomPressure(RSLgi,masks);4864 }4865 }4866 4867 /*Plug values once and assemble: */4868 pRSLgi->SetValues(gsize,indices,RSLgi,ADD_VAL);4869 pRSLgi->Assemble();4870 4871 /*Sum all barystatic components from all cpus:*/4872 ISSM_MPI_Reduce (&bslcice_cpu,&bslcice,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );4873 ISSM_MPI_Bcast(&bslcice,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());4874 _assert_(!xIsNan<IssmDouble>(bslcice));4875 4876 ISSM_MPI_Reduce (&bslchydro_cpu,&bslchydro,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );4877 ISSM_MPI_Bcast(&bslchydro,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());4878 _assert_(!xIsNan<IssmDouble>(bslchydro));4879 4880 /*Take care of partition vectors:*/4881 if(bslcice_partition){4882 bslcice_partition->Assemble();4883 bslcice_partition_serial=bslcice_partition->ToMPISerial();4884 }4885 if(bslchydro_partition){4886 bslchydro_partition->Assemble();4887 bslchydro_partition_serial=bslchydro_partition->ToMPISerial();4888 }4889 4890 4891 /*Free ressources:*/4892 xDelete<int>(indices);4893 xDelete<IssmDouble>(RSLgi);4894 if(bslchydro_partition)delete bslchydro_partition;4895 if(bslcice_partition)delete bslcice_partition;4896 if(partitionhydro)xDelete<IssmDouble>(partitionhydro);4897 if(partitionice)xDelete<IssmDouble>(partitionice);4898 4899 /*Assign output pointers:*/4900 *poceanarea = oceanarea;4901 *pbslcice = bslcice;4902 *pbslchydro = bslchydro;4903 *pbslc=bslchydro+bslcice;4904 *pbslcice_partition=bslcice_partition_serial;4905 *pbslchydro_partition=bslchydro_partition_serial;4906 4907 }4908 /*}}}*/4909 void FemModel::SealevelchangeSal(Vector<IssmDouble>* pRSLgo, Vector<IssmDouble>* pRSLg_old, SealevelMasks* masks, bool verboseconvolution){/*{{{*/4910 4911 /*serialized vectors:*/4912 IssmDouble* RSLg_old=NULL;4913 4914 IssmDouble* RSLgo = NULL;4915 int* indices = NULL;4916 int gsize;4917 4918 bool computerigid = true;4919 bool computeelastic= true;4920 4921 /*recover computational flags: */4922 this->parameters->FindParam(&computerigid,SolidearthSettingsRigidEnum);4923 4924 /*Initialize temporary vector that will be used to sum barystatic components on all local elements, prior4925 * to assembly:*/4926 gsize = this->nodes->NumberOfDofs(GsetEnum);4927 RSLgo=xNewZeroInit<IssmDouble>(gsize);4928 indices=xNew<int>(gsize); for (int i=0;i<gsize;i++)indices[i]=i;4929 4930 /*Serialize vectors from previous iteration:*/4931 RSLg_old=pRSLg_old->ToMPISerial();4932 4933 /*Call the sal sea level change core only if required: */4934 if(computerigid){4935 for(Object* & object : this->elements->objects){4936 Element* element = xDynamicCast<Element*>(object);4937 element->SealevelchangeSal(RSLgo,RSLg_old,masks);4938 }4939 }4940 pRSLgo->SetValues(gsize,indices,RSLgo,ADD_VAL);4941 pRSLgo->Assemble();4942 4943 /*Free ressources:*/4944 xDelete<int>(indices);4945 xDelete<IssmDouble>(RSLgo);4946 xDelete<IssmDouble>(RSLg_old);4947 4948 }4949 /*}}}*/4950 void FemModel::SealevelchangeRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, SealevelMasks* masks){/*{{{*/4951 4952 /*serialized vectors:*/4953 bool spherical=true;4954 IssmDouble* RSLg_old=NULL;4955 IssmDouble* tide_love_h = NULL;4956 IssmDouble* tide_love_k = NULL;4957 IssmDouble* load_love_k = NULL;4958 IssmDouble tide_love_k2secular;4959 IssmDouble moi_e, moi_p, omega, g;4960 IssmDouble m1, m2, m3;4961 IssmDouble lati, longi, radi, value;4962 IssmDouble *latitude = NULL;4963 IssmDouble *longitude = NULL;4964 IssmDouble *radius = NULL;4965 4966 /*Serialize vectors from previous iteration:*/4967 RSLg_old=pRSLg_old->ToMPISerial();4968 4969 IssmDouble moi_list[3]={0,0,0};4970 IssmDouble moi_list_cpu[3]={0,0,0};4971 for(Object* & object : this->elements->objects){4972 Element* element = xDynamicCast<Element*>(object);4973 element->SealevelchangeMomentOfInertia(&moi_list[0],RSLg_old,masks );4974 moi_list_cpu[0] += moi_list[0];4975 moi_list_cpu[1] += moi_list[1];4976 moi_list_cpu[2] += moi_list[2];4977 }4978 ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );4979 ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());4980 //4981 ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );4982 ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());4983 //4984 ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );4985 ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());4986 4987 /*pull out some useful parameters: */4988 parameters->FindParam(&load_love_k,NULL,NULL,LoadLoveKEnum);4989 parameters->FindParam(&tide_love_h,NULL,NULL,TidalLoveHEnum);4990 parameters->FindParam(&tide_love_k,NULL,NULL,TidalLoveKEnum);4991 parameters->FindParam(&tide_love_k2secular,TidalLoveK2SecularEnum);4992 parameters->FindParam(&moi_e,RotationalEquatorialMoiEnum);4993 parameters->FindParam(&moi_p,RotationalPolarMoiEnum);4994 parameters->FindParam(&omega,RotationalAngularVelocityEnum);4995 4996 /*compute perturbation terms for angular velocity vector: */4997 m1 = 1/(1-tide_love_k[2]/tide_love_k2secular) * (1+load_love_k[2])/(moi_p-moi_e) * moi_list[0];4998 m2 = 1/(1-tide_love_k[2]/tide_love_k2secular) * (1+load_love_k[2])/(moi_p-moi_e) * moi_list[1];4999 m3 = -(1+load_love_k[2])/moi_p * moi_list[2]; // term associated with fluid number (3-order-of-magnitude smaller) is negelected5000 5001 /*recover lat,long and radius vectors from vertices: */5002 VertexCoordinatesx(&latitude,&longitude,&radius,this->vertices,spherical);5003 5004 /* Green's function (1+k_2-h_2/g): checked against Glenn Milne's thesis Chapter 3 (eqs: 3.3-4, 3.10-11)5005 * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3)5006 * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered)5007 * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180]5008 */5009 for(Object* & object : vertices->objects){5010 Vertex* vertex=xDynamicCast<Vertex*>(object);5011 int sid=vertex->Sid();5012 5013 lati=latitude[sid]/180*PI;5014 longi=longitude[sid]/180*PI;5015 radi=radius[sid];5016 5017 /*only first order terms are considered now: */5018 value=((1.0+tide_love_k[2]-tide_love_h[2])/9.81)*pow(omega*radi,2.0)*5019 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi)));5020 5021 pRSLgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times5022 }5023 5024 /*Assemble mesh velocity*/5025 pRSLgo_rot->Assemble();5026 5027 /*Assign output pointers:*/5028 if(pIxz)*pIxz=moi_list[0];5029 if(pIyz)*pIyz=moi_list[1];5030 if(pIzz)*pIzz=moi_list[2];5031 xDelete<IssmDouble>(latitude);5032 xDelete<IssmDouble>(longitude);5033 xDelete<IssmDouble>(tide_love_h);5034 xDelete<IssmDouble>(tide_love_k);5035 xDelete<IssmDouble>(load_love_k);5036 5037 xDelete<IssmDouble>(radius);5038 5039 /*Free ressources:*/5040 xDelete<IssmDouble>(RSLg_old);5041 5042 }5043 /*}}}*/5044 void FemModel::SealevelchangeDeformation(Vector<IssmDouble>* pgeoid, Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pRSLg, SealevelMasks* masks){/*{{{*/5045 5046 /*serialized vectors:*/5047 IssmDouble* RSLg=NULL;5048 5049 IssmDouble* Up = NULL;5050 IssmDouble* North = NULL;5051 IssmDouble* East = NULL;5052 int* indices = NULL;5053 int gsize;5054 int horiz;5055 5056 /*retrieve parameters:*/5057 this->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);5058 5059 /*Serialize vectors from previous iteration:*/5060 RSLg=pRSLg->ToMPISerial();5061 5062 /*Initialize temporary vector that will be used to sum barystatic components on all local elements, prior5063 * to assembly:*/5064 gsize = this->nodes->NumberOfDofs(GsetEnum);5065 Up=xNewZeroInit<IssmDouble>(gsize);5066 if(horiz){5067 North=xNewZeroInit<IssmDouble>(gsize);5068 East=xNewZeroInit<IssmDouble>(gsize);5069 }5070 indices=xNew<int>(gsize); for (int i=0;i<gsize;i++)indices[i]=i;5071 5072 /*Call the deformation from loading routines:*/5073 for(Object* & object : this->elements->objects){5074 Element* element = xDynamicCast<Element*>(object);5075 element->DeformationFromSurfaceLoads(Up,North,East,RSLg,masks);5076 }5077 5078 pUp->SetValues(gsize,indices,Up,ADD_VAL);5079 pUp->Assemble();5080 5081 5082 /*Add RSL to Up to find the geoid: */5083 pUp->Copy(pgeoid); pgeoid->AXPY(pRSLg,1);5084 5085 if (horiz){5086 pNorth->SetValues(gsize,indices,North,ADD_VAL);5087 pNorth->Assemble();5088 pEast->SetValues(gsize,indices,East,ADD_VAL);5089 pEast->Assemble();5090 }5091 5092 /*Free ressources:*/5093 xDelete<IssmDouble>(Up);5094 if(horiz){5095 xDelete<IssmDouble>(North);5096 xDelete<IssmDouble>(East);5097 }5098 xDelete<int>(indices);5099 xDelete<IssmDouble>(RSLg);5100 }5101 /*}}}*/5102 IssmDouble FemModel::SealevelchangeOceanAverage(Vector<IssmDouble>* RSLg,SealevelMasks* masks, IssmDouble oceanarea) { /*{{{*/5103 5104 IssmDouble* RSLg_serial=NULL;5105 IssmDouble oceanvalue,oceanvalue_cpu;5106 5107 /*Serialize vectors from previous iteration:*/5108 RSLg_serial=RSLg->ToMPISerial();5109 5110 /*Initialize:*/5111 oceanvalue_cpu=0;5112 5113 /*Go through elements, and add contribution from each element and divide by overall ocean area:*/5114 for(Object* & object : this->elements->objects){5115 Element* element = xDynamicCast<Element*>(object);5116 oceanvalue_cpu += element->OceanAverage(RSLg_serial,masks);5117 }5118 5119 ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );5120 ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());5121 5122 /*Free ressources:*/5123 xDelete<IssmDouble>(RSLg_serial);5124 5125 return oceanvalue/oceanarea;5126 }5127 /*}}}*/5128 void FemModel::IvinsDeformation(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y){ /*{{{*/5129 5130 /*Find the litho material to be used by all the elements:*/5131 Matlitho* matlitho=NULL;5132 for (Object* & object: this->materials->objects){5133 Material* material=xDynamicCast<Material*>(object);5134 if(material->ObjectEnum()==MatlithoEnum){5135 matlitho=xDynamicCast<Matlitho*>(material);5136 break;5137 }5138 }5139 _assert_(matlitho);5140 5141 5142 /*Go through elements, and add contribution from each element to the deflection vector wg:*/5143 for(Object* & object : this->elements->objects){5144 Element* element = xDynamicCast<Element*>(object);5145 element->GiaDeflection(wg,dwgdt, matlitho, x,y);5146 }5147 5148 /*Assemble parallel vector:*/5149 dwgdt->Assemble();5150 wg->Assemble();5151 }5152 /*}}}*/5153 #endif5154 4750 void FemModel::HydrologyEPLupdateDomainx(IssmDouble* pEplcount){ /*{{{*/ 5155 4751 -
issm/trunk-jpl/src/c/classes/FemModel.h
r26114 r26165 163 163 void EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz); 164 164 #endif 165 #ifdef _HAVE_SEALEVELCHANGE_166 void SealevelchangeBarystatic(Vector<IssmDouble>* pRSLgi, IssmDouble* poceanarea, IssmDouble* pbslc,IssmDouble* pbslcice, IssmDouble* pbslchydro, IssmDouble** pbslcice_partition,IssmDouble** pbslchydro_partition, SealevelMasks* masks);167 void SealevelchangeSal(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, SealevelMasks* masks,bool verboseconvolution);168 void SealevelchangeRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, SealevelMasks* masks);169 void SealevelchangeDeformation(Vector<IssmDouble>* pgeoid,Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, SealevelMasks* masks);170 IssmDouble SealevelchangeOceanAverage(Vector<IssmDouble>* Sg,SealevelMasks* masks, IssmDouble oceanarea);171 void IvinsDeformation(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y);172 #endif173 165 void HydrologyEPLupdateDomainx(IssmDouble* pEplcount); 174 166 void HydrologyIDSupdateDomainx(IssmDouble* pIDScount); -
issm/trunk-jpl/src/c/cores/cores.h
r26119 r26165 63 63 #endif 64 64 void grd_core(FemModel* femmodel); 65 void grd_core_optim(FemModel* femmodel);66 65 void solidearthexternal_core(FemModel* femmodel); 67 66 void dynstr_core(FemModel* femmodel); 68 Vector<IssmDouble>* sealevelchange_core_barystatic(FemModel* femmodel,SealevelMasks* mask, IssmDouble* poceanarea);69 Vector<IssmDouble>* sealevelchange_core_sal(FemModel* femmodel,SealevelMasks* masks, Vector<IssmDouble>* RSLg_barystatic,IssmDouble oceanarea);70 void sealevelchange_core_deformation(Vector<IssmDouble>** pN_radial, Vector<IssmDouble>** pU_radial, Vector<IssmDouble>** pU_north,Vector<IssmDouble>** pU_east,FemModel* femmodel,Vector<IssmDouble>* RSLg, SealevelMasks* masks);71 67 void couplerinput_core(FemModel* femmodel); 72 68 void coupleroutput_core(FemModel* femmodel); -
issm/trunk-jpl/src/c/cores/sealevelchange_core.cpp
r26164 r26165 21 21 void RotationAxisMotion(IssmDouble* m, FemModel* femmodel,IssmDouble* loads, IssmDouble* sealeveloads); 22 22 void ConserveOceanMass(FemModel* femmodel,Vector<IssmDouble>* sealevelloads, IssmDouble offset, SealevelMasks* masks); 23 void ivins_deformation_core(FemModel* femmodel); 23 24 /*}}}*/ 24 25 … … 31 32 /*Parameters, variables:*/ 32 33 bool save_results; 33 int optim=0;34 34 35 35 /*Retrieve parameters:*/ 36 36 femmodel->parameters->FindParam(&save_results,SaveResultsEnum); 37 femmodel->parameters->FindParam(&optim,SolidearthSettingsOptimEnum);38 37 39 38 /*Verbose: */ … … 53 52 54 53 /*Run geodetic:*/ 55 if(!optim) grd_core(femmodel); 56 else grd_core_optim(femmodel); 54 grd_core(femmodel); 57 55 58 56 /*Run steric core for sure:*/ … … 208 206 209 207 }; /*}}}*/ 210 void grd_core(FemModel* femmodel){ /*{{{*/ 211 212 /*Gravity rotation deformation core GRD: */ 213 214 /*variables:*/ 215 Vector<IssmDouble> *RSLg = NULL; 216 Vector<IssmDouble> *RSLg_barystatic = NULL; 217 Vector<IssmDouble> *U_grd = NULL; 218 Vector<IssmDouble> *N_grd = NULL; 219 Vector<IssmDouble> *U_north_grd = NULL; 220 Vector<IssmDouble> *U_east_grd = NULL; 221 Vector<IssmDouble> *bedrock = NULL; 222 Vector<IssmDouble> *bedrockeast = NULL; 223 Vector<IssmDouble> *bedrocknorth = NULL; 224 Vector<IssmDouble> *geoid= NULL; 208 void grd_core(FemModel* femmodel) { /*{{{*/ 209 210 /*variables:{{{*/ 211 int nel; 212 BarystaticContributions* barycontrib=NULL; 225 213 SealevelMasks* masks=NULL; 226 227 /*parameters:*/ 214 GenericParam<BarystaticContributions*>* barycontribparam=NULL; 215 IssmDouble rotationaxismotionvector[3]={0}; 216 217 Vector<IssmDouble>* loads=NULL; 218 IssmDouble* allloads=NULL; 219 Vector<IssmDouble>* sealevelloads=NULL; 220 Vector<IssmDouble>* oldsealevelloads=NULL; 221 IssmDouble* allsealevelloads=NULL; 222 Vector<IssmDouble>* oceanareas=NULL; 223 IssmDouble oceanarea; 224 IssmDouble oceanaverage; 225 bool scaleoceanarea=false; 226 IssmDouble rho_water; 227 228 IssmDouble eps_rel; 229 IssmDouble eps_abs; 230 int max_nonlinear_iterations; 231 int iterations=0; 232 int step; 233 IssmDouble time; 234 bool converged=false; 235 228 236 int modelid,earthid; 229 237 int horiz; 230 IssmDouble oceanarea;231 238 int count,frequency,iscoupling; 232 239 int grd=0; 240 int grdmodel; 241 int computesealevel=0; 242 243 /*}}}*/ 233 244 234 245 /*Verbose: */ 235 246 if(VerboseSolution()) _printf0_(" computing GRD patterns\n"); 236 237 /*retrieve parameters: */247 248 /*retrieve parameters:{{{*/ 238 249 femmodel->parameters->FindParam(&grd,SolidearthSettingsGRDEnum); 239 250 femmodel->parameters->FindParam(&frequency,SolidearthSettingsRunFrequencyEnum); 240 251 femmodel->parameters->FindParam(&count,SealevelchangeRunCountEnum); 252 femmodel->parameters->FindParam(&computesealevel,SolidearthSettingsComputesealevelchangeEnum); 253 femmodel->parameters->FindParam(&max_nonlinear_iterations,SolidearthSettingsMaxiterEnum); 254 femmodel->parameters->FindParam(&grdmodel,GrdModelEnum); 255 /*}}}*/ 241 256 242 257 /*only run if grd was requested, if we are the earth, and we have reached … … 251 266 } 252 267 268 /*branch directly to Ivins deformation core if requested:*/ 269 if(grdmodel==IvinsEnum){ 270 ivins_deformation_core(femmodel); 271 return; 272 } 273 274 /*retrieve parameters: {{{*/ 275 femmodel->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum); 276 barycontribparam = xDynamicCast<GenericParam<BarystaticContributions*>*>(femmodel->parameters->FindParamObject(BarystaticContributionsEnum)); 277 barycontrib=barycontribparam->GetParameterValue(); 278 femmodel->parameters->FindParam(&rho_water,MaterialsRhoSeawaterEnum); 279 femmodel->parameters->FindParam(&eps_rel,SolidearthSettingsReltolEnum); 280 femmodel->parameters->FindParam(&eps_abs,SolidearthSettingsAbstolEnum); 281 femmodel->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum); 282 /*}}}*/ 283 284 /*initialize matrices and vectors:*/ 285 femmodel->parameters->FindParam(&nel,MeshNumberofelementsEnum); 286 loads=new Vector<IssmDouble>(nel); 287 oceanareas=new Vector<IssmDouble>(nel); 288 sealevelloads=new Vector<IssmDouble>(nel); 289 sealevelloads->Set(0);sealevelloads->Assemble(); 290 253 291 /*call masks core: */ 254 292 masks=sealevel_masks(femmodel); 255 256 /*call barystatic core (generalized eustatic - Farrel and Clark, Eq 4, 1st, 3rd and 4rd terms on the RHS) */ 257 RSLg_barystatic=sealevelchange_core_barystatic(femmodel,masks,&oceanarea); 258 259 /*call self attraction and loading module (ocean loading tems - 2nd and 5th terms on the RHS of Farrel and Clark) */ 260 RSLg=sealevelchange_core_sal(femmodel,masks,RSLg_barystatic,oceanarea); 261 262 /*compute bedrock motion and derive geoid: */ 263 sealevelchange_core_deformation(&N_grd,&U_grd,&U_north_grd,&U_east_grd,femmodel,RSLg,masks); 293 if(VerboseSolution()) _printf0_(" starting GRD convolutions\n"); 294 295 /*buildup loads: */ 296 for(Object* & object : femmodel->elements->objects){ 297 Element* element = xDynamicCast<Element*>(object); 298 element->SealevelchangeBarystaticLoads(loads, barycontrib,masks); 299 } 300 loads->Assemble(); 301 302 //broadcast loads 303 allloads=loads->ToMPISerial(); 304 305 //compute rotation axis motion: 306 RotationAxisMotion(&rotationaxismotionvector[0],femmodel,allloads,NULL); 307 308 /*skip computation of sea level if requested, which means sea level loads should be zeroed */ 309 if(!computesealevel){ 310 allsealevelloads=xNewZeroInit<IssmDouble>(nel); 311 goto deformation; 312 } 313 314 if(VerboseSolution()) _printf0_(" converging GRD convolutions\n"); 315 for(;;){ 316 317 oldsealevelloads=sealevelloads->Duplicate(); sealevelloads->Copy(oldsealevelloads); 318 319 /*convolve load and sealevel loads on oceans:*/ 320 for(Object* & object : femmodel->elements->objects){ 321 Element* element = xDynamicCast<Element*>(object); 322 element->SealevelchangeConvolution(sealevelloads, oceanareas, allsealevelloads, allloads,rotationaxismotionvector); 323 } 324 sealevelloads->Assemble(); 325 326 /*compute ocean areas:*/ 327 if(!allsealevelloads){ //first time in the loop 328 oceanareas->Assemble(); oceanareas->Sum(&oceanarea); _assert_(oceanarea>0.); 329 if(scaleoceanarea) oceanarea=3.619e+14; // use true ocean area, m^2 330 } 331 332 //Conserve ocean mass: 333 oceanaverage=SealevelloadsOceanAverage(sealevelloads,oceanareas,oceanarea); 334 ConserveOceanMass(femmodel,sealevelloads,barycontrib->Total()/oceanarea - oceanaverage,masks); 335 336 //broadcast sea level loads 337 allsealevelloads=sealevelloads->ToMPISerial(); 338 339 //compute rotation axis motion: 340 RotationAxisMotion(&rotationaxismotionvector[0],femmodel,allloads,allsealevelloads); 341 342 //convergence? 343 slcconvergence(&converged,sealevelloads,oldsealevelloads,eps_rel,eps_abs); 344 if (converged)break; 345 346 //early return? 347 if(iterations>=max_nonlinear_iterations)break; 348 else iterations++; 349 } 350 351 deformation: 352 353 if(VerboseSolution()) _printf0_(" deformation GRD convolutions\n"); 354 355 /*convolve loads and sea level loads to get the deformation:*/ 356 for(Object* & object : femmodel->elements->objects){ 357 Element* element = xDynamicCast<Element*>(object); 358 element->SealevelchangeDeformationConvolution(allsealevelloads, allloads, rotationaxismotionvector); 359 } 360 361 if(VerboseSolution()) _printf0_(" updating GRD fields\n"); 264 362 265 363 /*Update bedrock motion and geoid:*/ 266 GetVectorFromInputsx(&geoid,femmodel,SealevelEnum,VertexSIdEnum); 267 GetVectorFromInputsx(&bedrock,femmodel,BedEnum,VertexSIdEnum); 364 if(computesealevel){ 365 femmodel->inputs->Shift(SealevelGRDEnum,barycontrib->Total()/rho_water/oceanarea- oceanaverage/rho_water); 366 367 /*cumulate barystatic contributions and save to results: */ 368 barycontrib->Cumulate(femmodel->parameters); 369 barycontrib->Save(femmodel->results,femmodel->parameters,oceanarea); 370 } 371 372 femmodel->inputs->AXPY(1,SealevelGRDEnum,SealevelEnum); 373 femmodel->inputs->AXPY(1,BedGRDEnum,BedEnum); 268 374 if(horiz){ 269 GetVectorFromInputsx(&bedrockeast,femmodel,BedEastEnum,VertexSIdEnum); 270 GetVectorFromInputsx(&bedrocknorth,femmodel,BedNorthEnum,VertexSIdEnum); 271 } 272 273 geoid->AXPY(N_grd,1); 274 bedrock->AXPY(U_grd,1); 275 if(horiz){ 276 bedrockeast->AXPY(U_east_grd,1); 277 bedrocknorth->AXPY(U_north_grd,1); 278 } 279 280 /*get some of the updates into elements:*/ 281 InputUpdateFromVectorx(femmodel,U_grd,SealevelUGrdEnum,VertexSIdEnum); 282 InputUpdateFromVectorx(femmodel,N_grd,SealevelEnum,VertexSIdEnum); 283 InputUpdateFromVectorx(femmodel,N_grd,SealevelNGrdEnum,VertexSIdEnum); 284 InputUpdateFromVectorx(femmodel,bedrock,BedEnum,VertexSIdEnum); 285 if(RSLg)InputUpdateFromVectorx(femmodel,RSLg,SealevelRSLEnum,VertexSIdEnum); 286 if(RSLg_barystatic)InputUpdateFromVectorx(femmodel,RSLg_barystatic,SealevelRSLBarystaticEnum,VertexSIdEnum); 287 if (horiz){ 288 InputUpdateFromVectorx(femmodel,U_north_grd,SealevelUNorthEsaEnum,VertexSIdEnum); 289 InputUpdateFromVectorx(femmodel,U_east_grd,SealevelUEastEsaEnum,VertexSIdEnum); 290 } 291 292 /*reset counter to 1:*/ 293 femmodel->parameters->SetParam(1,SealevelchangeRunCountEnum); //reset counter. 294 295 /*free ressources:{{{*/ 296 delete RSLg; 297 delete RSLg_barystatic; 298 delete U_grd; 299 delete N_grd; 300 delete bedrock; 301 delete geoid; 302 if(horiz){ 303 delete U_north_grd; 304 delete U_east_grd; 305 delete bedrockeast; 306 delete bedrocknorth; 307 } 308 delete masks; 309 /*}}}*/ 310 311 } 375 femmodel->inputs->AXPY(1,BedEastGRDEnum,BedEastEnum); 376 femmodel->inputs->AXPY(1,BedNorthGRDEnum, BedNorthEnum); 377 } 378 379 } 312 380 /*}}}*/ 313 381 void dynstr_core(FemModel* femmodel){ /*{{{*/ … … 397 465 } 398 466 }; /*}}}*/ 399 400 void grd_core_optim(FemModel* femmodel) { /*{{{*/ 401 402 /*variables:{{{*/ 403 int nel; 404 BarystaticContributions* barycontrib=NULL; 405 SealevelMasks* masks=NULL; 406 GenericParam<BarystaticContributions*>* barycontribparam=NULL; 407 IssmDouble rotationaxismotionvector[3]={0}; 408 409 Vector<IssmDouble>* loads=NULL; 410 IssmDouble* allloads=NULL; 411 Vector<IssmDouble>* sealevelloads=NULL; 412 Vector<IssmDouble>* oldsealevelloads=NULL; 413 IssmDouble* allsealevelloads=NULL; 414 Vector<IssmDouble>* oceanareas=NULL; 415 IssmDouble oceanarea; 416 IssmDouble oceanaverage; 417 bool scaleoceanarea=false; 418 IssmDouble rho_water; 419 420 IssmDouble eps_rel; 421 IssmDouble eps_abs; 422 int max_nonlinear_iterations; 423 int iterations=0; 424 int step; 425 IssmDouble time; 426 bool converged=false; 427 428 int modelid,earthid; 429 int horiz; 430 int count,frequency,iscoupling; 431 int grd=0; 432 int computesealevel=0; 433 434 /*}}}*/ 435 436 /*Verbose: */ 437 if(VerboseSolution()) _printf0_(" computing GRD patterns\n"); 438 439 /*retrieve parameters:{{{*/ 440 femmodel->parameters->FindParam(&grd,SolidearthSettingsGRDEnum); 441 femmodel->parameters->FindParam(&frequency,SolidearthSettingsRunFrequencyEnum); 442 femmodel->parameters->FindParam(&count,SealevelchangeRunCountEnum); 443 femmodel->parameters->FindParam(&computesealevel,SolidearthSettingsComputesealevelchangeEnum); 444 femmodel->parameters->FindParam(&max_nonlinear_iterations,SolidearthSettingsMaxiterEnum); 445 /*}}}*/ 446 447 /*only run if grd was requested, if we are the earth, and we have reached 448 * the necessary number of time steps dictated by :*/ 449 if(!grd) return; 450 if(count!=frequency)return; 451 femmodel->parameters->FindParam(&iscoupling,IsSlcCouplingEnum); 452 if(iscoupling){ 453 femmodel->parameters->FindParam(&modelid,ModelIdEnum); 454 femmodel->parameters->FindParam(&earthid,EarthIdEnum); 455 if(modelid!=earthid)return; 456 } 457 /*retrieve parameters: {{{*/ 458 femmodel->parameters->FindParam(&scaleoceanarea,SolidearthSettingsOceanAreaScalingEnum); 459 barycontribparam = xDynamicCast<GenericParam<BarystaticContributions*>*>(femmodel->parameters->FindParamObject(BarystaticContributionsEnum)); 460 barycontrib=barycontribparam->GetParameterValue(); 461 femmodel->parameters->FindParam(&rho_water,MaterialsRhoSeawaterEnum); 462 femmodel->parameters->FindParam(&eps_rel,SolidearthSettingsReltolEnum); 463 femmodel->parameters->FindParam(&eps_abs,SolidearthSettingsAbstolEnum); 464 femmodel->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum); 465 /*}}}*/ 466 467 /*initialize matrices and vectors:*/ 468 femmodel->parameters->FindParam(&nel,MeshNumberofelementsEnum); 469 loads=new Vector<IssmDouble>(nel); 470 oceanareas=new Vector<IssmDouble>(nel); 471 sealevelloads=new Vector<IssmDouble>(nel); 472 sealevelloads->Set(0);sealevelloads->Assemble(); 473 474 /*call masks core: */ 475 masks=sealevel_masks(femmodel); 476 if(VerboseSolution()) _printf0_(" starting GRD convolutions\n"); 477 478 /*buildup loads: */ 467 void ivins_deformation_core(FemModel* femmodel){ /*{{{*/ 468 469 int gsize; 470 Vector<IssmDouble> *bedup = NULL; 471 Vector<IssmDouble> *beduprate= NULL; 472 IssmDouble *xx = NULL; 473 IssmDouble *yy = NULL; 474 475 if(VerboseSolution()) _printf0_(" computing vertical deformation using Ivins model. \n"); 476 477 /*find size of vectors:*/ 478 gsize = femmodel->nodes->NumberOfDofs(GsetEnum); 479 480 /*Find the litho material to be used by all the elements:*/ 481 Matlitho* matlitho=NULL; 482 for (Object* & object: femmodel->materials->objects){ 483 Material* material=xDynamicCast<Material*>(object); 484 if(material->ObjectEnum()==MatlithoEnum){ 485 matlitho=xDynamicCast<Matlitho*>(material); 486 break; 487 } 488 } 489 490 /*initialize vectors:*/ 491 bedup = new Vector<IssmDouble>(gsize); 492 beduprate = new Vector<IssmDouble>(gsize); 493 494 /*retrieve geometric information: */ 495 VertexCoordinatesx(&xx,&yy,NULL,femmodel->vertices); 496 497 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 479 498 for(Object* & object : femmodel->elements->objects){ 480 499 Element* element = xDynamicCast<Element*>(object); 481 element->SealevelchangeBarystaticLoads(loads, barycontrib,masks); 482 } 483 loads->Assemble(); 484 485 //broadcast loads 486 allloads=loads->ToMPISerial(); 487 488 //compute rotation axis motion: 489 RotationAxisMotion(&rotationaxismotionvector[0],femmodel,allloads,NULL); 490 491 /*skip computation of sea level if requested, which means sea level loads should be zeroed */ 492 if(!computesealevel){ 493 allsealevelloads=xNewZeroInit<IssmDouble>(nel); 494 goto deformation; 495 } 496 497 if(VerboseSolution()) _printf0_(" converging GRD convolutions\n"); 498 for(;;){ 499 500 oldsealevelloads=sealevelloads->Duplicate(); sealevelloads->Copy(oldsealevelloads); 501 502 /*convolve load and sealevel loads on oceans:*/ 503 for(Object* & object : femmodel->elements->objects){ 504 Element* element = xDynamicCast<Element*>(object); 505 element->SealevelchangeConvolution(sealevelloads, oceanareas, allsealevelloads, allloads,rotationaxismotionvector); 506 } 507 sealevelloads->Assemble(); 508 509 /*compute ocean areas:*/ 510 if(!allsealevelloads){ //first time in the loop 511 oceanareas->Assemble(); oceanareas->Sum(&oceanarea); _assert_(oceanarea>0.); 512 if(scaleoceanarea) oceanarea=3.619e+14; // use true ocean area, m^2 513 } 514 515 //Conserve ocean mass: 516 oceanaverage=SealevelloadsOceanAverage(sealevelloads,oceanareas,oceanarea); 517 ConserveOceanMass(femmodel,sealevelloads,barycontrib->Total()/oceanarea - oceanaverage,masks); 518 519 //broadcast sea level loads 520 allsealevelloads=sealevelloads->ToMPISerial(); 521 522 //compute rotation axis motion: 523 RotationAxisMotion(&rotationaxismotionvector[0],femmodel,allloads,allsealevelloads); 524 525 //convergence? 526 slcconvergence(&converged,sealevelloads,oldsealevelloads,eps_rel,eps_abs); 527 if (converged)break; 528 529 //early return? 530 if(iterations>=max_nonlinear_iterations)break; 531 else iterations++; 532 } 533 534 deformation: 535 536 if(VerboseSolution()) _printf0_(" deformation GRD convolutions\n"); 537 538 /*convolve loads and sea level loads to get the deformation:*/ 539 for(Object* & object : femmodel->elements->objects){ 540 Element* element = xDynamicCast<Element*>(object); 541 element->SealevelchangeDeformationConvolution(allsealevelloads, allloads, rotationaxismotionvector); 542 } 543 544 if(VerboseSolution()) _printf0_(" updating GRD fields\n"); 545 546 /*Update bedrock motion and geoid:*/ 547 if(computesealevel){ 548 femmodel->inputs->Shift(SealevelGRDEnum,barycontrib->Total()/rho_water/oceanarea- oceanaverage/rho_water); 549 550 /*cumulate barystatic contributions and save to results: */ 551 barycontrib->Cumulate(femmodel->parameters); 552 barycontrib->Save(femmodel->results,femmodel->parameters,oceanarea); 553 } 554 555 femmodel->inputs->AXPY(1,SealevelGRDEnum,SealevelEnum); 500 element->GiaDeflection(bedup,beduprate, matlitho, xx,yy); 501 } 502 503 /*Assemble parallel vector:*/ 504 beduprate->Assemble(); 505 bedup->Assemble(); 506 507 /*Save results:*/ 508 InputUpdateFromVectorx(femmodel,bedup,BedGRDEnum,VertexSIdEnum); 556 509 femmodel->inputs->AXPY(1,BedGRDEnum,BedEnum); 557 if(horiz){ 558 femmodel->inputs->AXPY(1,BedEastGRDEnum,BedEastEnum); 559 femmodel->inputs->AXPY(1,BedNorthGRDEnum, BedNorthEnum); 560 } 561 510 511 /*Free ressources: */ 512 xDelete<IssmDouble>(xx); 513 xDelete<IssmDouble>(yy); 514 delete beduprate; 515 delete bedup; 562 516 } 563 517 /*}}}*/ … … 612 566 femmodel->parameters->FindParam(&geometrydone,SealevelchangeGeometryDoneEnum); 613 567 femmodel->parameters->FindParam(&grdmodel,GrdModelEnum); 614 femmodel->parameters->FindParam(&optim,SolidearthSettingsOptimEnum);615 568 616 569 /*early return?:*/ … … 635 588 for(Object* & object : femmodel->elements->objects){ 636 589 Element* element=xDynamicCast<Element*>(object); 637 if(optim) element->SealevelchangeGeometryOptim(latitude,longitude,radius,xx,yy,zz,xxe,yye,zze,areae); 638 else element->SealevelchangeGeometry(latitude,longitude,radius,xx,yy,zz,xxe,yye,zze); 590 element->SealevelchangeGeometry(latitude,longitude,radius,xx,yy,zz,xxe,yye,zze,areae); 639 591 } 640 592 … … 658 610 659 611 }/*}}}*/ 660 661 //GRD:662 Vector<IssmDouble>* sealevelchange_core_barystatic(FemModel* femmodel,SealevelMasks* masks, IssmDouble* poceanarea){ /*{{{*/663 664 /*Barystatic core of the SLR solution (terms that are constant with respect to sea-level)*/665 666 Vector<IssmDouble> *RSLgi = NULL;667 IssmDouble RSLgi_oceanaverage = 0;668 669 /*parameters: */670 int gsize;671 IssmDouble oceanarea;672 int step;673 IssmDouble time;674 675 /*barystatic contribution:*/676 IssmDouble bslc;677 IssmDouble bslcice;678 IssmDouble* bslcice_partition=NULL;679 IssmDouble bslchydro;680 IssmDouble* bslchydro_partition=NULL;681 IssmDouble cumbslc;682 IssmDouble cumbslcice;683 IssmDouble cumbslchydro;684 IssmDouble* cumbslcice_partition=NULL;685 int npartice;686 IssmDouble* cumbslchydro_partition=NULL;687 int nparthydro;688 int computesealevel=0;689 690 /*early return if we are not computing sea level, but rather deformation: */691 femmodel->parameters->FindParam(&computesealevel,SolidearthSettingsComputesealevelchangeEnum);692 if (!computesealevel)return NULL;693 694 if(VerboseSolution()) _printf0_(" computing bslc components on ice\n");695 696 /*Figure out size of g-set deflection vector and allocate solution vector: */697 gsize = femmodel->nodes->NumberOfDofs(GsetEnum);698 699 /*some parameters:*/700 femmodel->parameters->FindParam(&step,StepEnum);701 femmodel->parameters->FindParam(&time,TimeEnum);702 femmodel->parameters->FindParam(&cumbslc,CumBslcEnum);703 femmodel->parameters->FindParam(&cumbslcice,CumBslcIceEnum);704 femmodel->parameters->FindParam(&cumbslchydro,CumBslcHydroEnum);705 femmodel->parameters->FindParam(&npartice,SolidearthNpartIceEnum);706 femmodel->parameters->FindParam(&nparthydro,SolidearthNpartHydroEnum);707 if(npartice) femmodel->parameters->FindParam(&cumbslcice_partition,&npartice,NULL,CumBslcIcePartitionEnum);708 if(nparthydro) femmodel->parameters->FindParam(&cumbslchydro_partition,&nparthydro,NULL,CumBslcHydroPartitionEnum);709 710 /*Initialize:*/711 RSLgi = new Vector<IssmDouble>(gsize);712 713 /*call the bslc main module: */714 femmodel->SealevelchangeBarystatic(RSLgi,&oceanarea,&bslc, &bslcice, &bslchydro, &bslcice_partition, &bslchydro_partition,masks); //this computes715 716 /*we need to average RSLgi over the ocean: RHS term 4 in Eq.4 of Farrel and clarke. Only the elements can do that: */717 RSLgi_oceanaverage=femmodel->SealevelchangeOceanAverage(RSLgi,masks, oceanarea);718 719 /*RSLg is the sum of the pure bslc component (term 3) and the contribution from the perturbation to the graviation potential due to the720 * presence of ice (terms 1 and 4 in Eq.4 of Farrel and Clarke):*/721 RSLgi->Shift(-bslc-RSLgi_oceanaverage);722 723 /*save bslc and cumulated bslc value for results:{{{ */724 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,BslcEnum,-bslc,step,time));725 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,BslcIceEnum,-bslcice,step,time));726 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,BslcHydroEnum,-bslchydro,step,time));727 728 //cumulative barystatic contribution:729 cumbslc=cumbslc-bslc;730 cumbslcice=cumbslcice-bslcice;731 cumbslchydro=cumbslchydro-bslchydro;732 733 femmodel->parameters->SetParam(cumbslc,CumBslcEnum);734 femmodel->parameters->SetParam(cumbslcice,CumBslcIceEnum);735 femmodel->parameters->SetParam(cumbslchydro,CumBslcHydroEnum);736 737 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,CumBslcEnum,cumbslc,step,time));738 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,CumBslcIceEnum,cumbslcice,step,time));739 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,CumBslcHydroEnum,cumbslchydro,step,time));740 741 //cumulative barystatic contributions by partition:742 if(npartice){743 for(int i=0;i<npartice;i++) cumbslcice_partition[i] -= bslcice_partition[i];744 femmodel->parameters->SetParam(cumbslcice_partition,npartice,1,CumBslcIcePartitionEnum);745 femmodel->results->AddResult(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,CumBslcIcePartitionEnum,cumbslcice_partition,npartice,1,step,time));746 }747 748 if(nparthydro){749 for(int i=0;i<nparthydro;i++) cumbslchydro_partition[i] -= bslchydro_partition[i];750 femmodel->parameters->SetParam(cumbslchydro_partition,nparthydro,1,CumBslcHydroPartitionEnum);751 femmodel->results->AddResult(new GenericExternalResult<IssmDouble*>(femmodel->results->Size()+1,CumBslcHydroPartitionEnum,cumbslchydro_partition,nparthydro,1,step,time));752 }753 /*}}}*/754 755 /*Assign output pointers and return: */756 *poceanarea=oceanarea;757 return RSLgi;758 }/*}}}*/759 Vector<IssmDouble>* sealevelchange_core_sal(FemModel* femmodel, SealevelMasks* masks, Vector<IssmDouble>* RSLg_barystatic,IssmDouble oceanarea){ /*{{{*/760 761 /*this core computes the contributions from Eq.4 of Farrel and Clarke, rhs terms 2 and 5.762 sal core of the SLR solution */763 764 Vector<IssmDouble> *RSLg = NULL;765 Vector<IssmDouble> *RSLg_old = NULL;766 767 Vector<IssmDouble> *RSLgo = NULL; //ocean convolution of the perturbation to gravity potential.768 Vector<IssmDouble> *RSLgo_rot= NULL; // rotational feedback769 IssmDouble RSLgo_oceanaverage = 0; //average of RSLgo over the ocean.770 771 /*parameters: */772 int count;773 bool save_results;774 int gsize;775 bool converged=true;776 bool rotation=true;777 bool verboseconvolution=true;778 int max_nonlinear_iterations;779 IssmDouble eps_rel;780 IssmDouble eps_abs;781 IssmDouble Ixz, Iyz, Izz;782 int computesealevel=0;783 784 /*early return if we are not computing sea level, but rather deformation: */785 femmodel->parameters->FindParam(&computesealevel,SolidearthSettingsComputesealevelchangeEnum);786 if (!computesealevel)return NULL;787 788 if(VerboseSolution()) _printf0_(" converging on ocean components\n");789 790 /*Recover some parameters: */791 femmodel->parameters->FindParam(&max_nonlinear_iterations,SolidearthSettingsMaxiterEnum);792 femmodel->parameters->FindParam(&eps_rel,SolidearthSettingsReltolEnum);793 femmodel->parameters->FindParam(&eps_abs,SolidearthSettingsAbstolEnum);794 795 /*computational flag: */796 femmodel->parameters->FindParam(&rotation,SolidearthSettingsRotationEnum);797 798 /*Figure out size of g-set deflection vector and allocate solution vector: */799 gsize = femmodel->nodes->NumberOfDofs(GsetEnum);800 801 /*Initialize:*/802 RSLg = new Vector<IssmDouble>(gsize);803 RSLg->Assemble();804 RSLg_barystatic->Copy(RSLg); //first initialize RSLg with the barystatic component computed in sealevelchange_core_barystatic.805 806 RSLg_old = new Vector<IssmDouble>(gsize);807 RSLg_old->Assemble();808 809 count=1;810 converged=false;811 812 /*Start loop: */813 for(;;){814 815 //save pointer to old sea level816 delete RSLg_old; RSLg_old=RSLg;817 818 /*Initialize solution vector: */819 RSLg = new Vector<IssmDouble>(gsize); RSLg->Assemble();820 RSLgo = new Vector<IssmDouble>(gsize); RSLgo->Assemble();821 822 /*call the sal module: */823 femmodel->SealevelchangeSal(RSLgo, RSLg_old, masks, verboseconvolution);824 825 /*assemble solution vector: */826 RSLgo->Assemble();827 828 if(rotation){829 830 /*call rotational feedback module: */831 RSLgo_rot = new Vector<IssmDouble>(gsize); RSLgo_rot->Assemble();832 femmodel->SealevelchangeRotationalFeedback(RSLgo_rot,RSLg_old,&Ixz,&Iyz,&Izz, masks);833 RSLgo_rot->Assemble();834 835 /*save changes in inertia tensor as results: */836 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,SealevelInertiaTensorXZEnum,Ixz));837 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,SealevelInertiaTensorYZEnum,Iyz));838 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,SealevelInertiaTensorZZEnum,Izz));839 840 RSLgo->AXPY(RSLgo_rot,1);841 }842 843 /*we need to average RSLgo over the ocean: RHS term 5 in Eq.4 of Farrel and clarke. Only the elements can do that: */844 RSLgo_oceanaverage=femmodel->SealevelchangeOceanAverage(RSLgo,masks, oceanarea);845 846 /*RSLg is the sum of the barystatic term, and the ocean terms: */847 RSLg_barystatic->Copy(RSLg); RSLg->AXPY(RSLgo,1);848 RSLg->Shift(-RSLgo_oceanaverage);849 850 /*convergence criterion:*/851 slcconvergence(&converged,RSLg,RSLg_old,eps_rel,eps_abs);852 853 854 /*free ressources: */855 delete RSLgo;856 delete RSLgo_rot;857 858 /*Increase count: */859 count++;860 if(converged==true){861 break;862 }863 if(count>=max_nonlinear_iterations){864 _printf0_(" maximum number of nonlinear iterations (" << max_nonlinear_iterations << ") exceeded\n");865 converged=true;866 break;867 }868 869 /*some minor verbosing adjustment:*/870 if(count>1)verboseconvolution=false;871 872 }873 if(VerboseConvergence()) _printf0_("\n total number of iterations: " << count-1 << "\n");874 875 876 delete RSLg_old;877 878 return RSLg;879 } /*}}}*/880 void sealevelchange_core_deformation(Vector<IssmDouble>** pN_grd, Vector<IssmDouble>** pU_grd, Vector<IssmDouble>** pU_north_grd,Vector<IssmDouble>** pU_east_grd,FemModel* femmodel,Vector<IssmDouble>* RSLg, SealevelMasks* masks){ /*{{{*/881 882 Vector<IssmDouble> *U_grd = NULL;883 Vector<IssmDouble> *dUdt_grd = NULL;884 Vector<IssmDouble> *N_grd = NULL;885 Vector<IssmDouble> *U_north_grd = NULL;886 Vector<IssmDouble> *U_east_grd = NULL;887 888 /*parameters: */889 int gsize;890 bool spherical=true;891 892 IssmDouble *latitude = NULL;893 IssmDouble *longitude = NULL;894 IssmDouble *radius = NULL;895 IssmDouble *xx = NULL;896 IssmDouble *yy = NULL;897 IssmDouble *zz = NULL;898 int horiz;899 int grdmodel;900 901 if(VerboseSolution()) _printf0_(" computing vertical and horizontal geodetic signatures\n");902 903 /*retrieve some parameters:*/904 femmodel->parameters->FindParam(&horiz,SolidearthSettingsHorizEnum);905 femmodel->parameters->FindParam(&grdmodel,GrdModelEnum);906 907 /*find size of vectors:*/908 gsize = femmodel->nodes->NumberOfDofs(GsetEnum);909 910 /*intialize vectors:*/911 U_grd = new Vector<IssmDouble>(gsize);912 if(grdmodel==IvinsEnum) dUdt_grd = new Vector<IssmDouble>(gsize);913 N_grd = new Vector<IssmDouble>(gsize);914 if (horiz){915 U_north_grd = new Vector<IssmDouble>(gsize);916 U_east_grd = new Vector<IssmDouble>(gsize);917 }918 919 /*retrieve geometric information: */920 VertexCoordinatesx(&latitude,&longitude,&radius,femmodel->vertices,spherical);921 VertexCoordinatesx(&xx,&yy,&zz,femmodel->vertices);922 923 /*call the deformation module: */924 switch(grdmodel){925 case NoneEnum:926 //do nothing:927 break;928 case IvinsEnum:929 femmodel->IvinsDeformation(U_grd,dUdt_grd,xx,yy);930 break;931 case ElasticEnum:932 femmodel->SealevelchangeDeformation(N_grd, U_grd,U_north_grd,U_east_grd,RSLg, masks);933 break;934 default:935 _error_("Grd model " << EnumToStringx(grdmodel) << " not supported yet");936 }937 938 /*Assign output pointers:*/939 *pU_grd=U_grd;940 *pN_grd=N_grd;941 if(horiz){942 *pU_east_grd=U_east_grd;943 *pU_north_grd=U_north_grd;944 }945 946 /*Free ressources: */947 xDelete<IssmDouble>(longitude);948 xDelete<IssmDouble>(latitude);949 xDelete<IssmDouble>(xx);950 xDelete<IssmDouble>(yy);951 xDelete<IssmDouble>(zz);952 xDelete<IssmDouble>(radius);953 if(grdmodel==IvinsEnum)delete dUdt_grd;954 }955 /*}}}*/956 612 957 613 /*Support routines:*/ … … 1284 940 for(Object* & object : femmodel->elements->objects){ 1285 941 Element* element = xDynamicCast<Element*>(object); 1286 element->SealevelchangeMomentOfInertia Element(&moi_list[0],loads,sealevelloads);942 element->SealevelchangeMomentOfInertia(&moi_list[0],loads,sealevelloads); 1287 943 moi_list_cpu[0] += moi_list[0]; 1288 944 moi_list_cpu[1] += moi_list[1]; -
issm/trunk-jpl/src/c/shared/Enum/Enum.vim
r26155 r26165 350 350 syn keyword cConstant SolidearthSettingsAbstolEnum 351 351 syn keyword cConstant SolidearthSettingsCrossSectionShapeEnum 352 syn keyword cConstant SolidearthSettingsOptimEnum353 352 syn keyword cConstant RotationalAngularVelocityEnum 354 353 syn keyword cConstant SolidearthSettingsElasticEnum … … 1452 1451 syn keyword cType Cfsurfacesquare 1453 1452 syn keyword cType Channel 1454 syn keyword cType classes1455 1453 syn keyword cType Constraint 1456 1454 syn keyword cType Constraints … … 1459 1457 syn keyword cType ControlInput 1460 1458 syn keyword cType Covertree 1459 syn keyword cType DataSetParam 1461 1460 syn keyword cType DatasetInput 1462 syn keyword cType DataSetParam1463 1461 syn keyword cType Definition 1464 1462 syn keyword cType DependentObject … … 1473 1471 syn keyword cType ElementInput 1474 1472 syn keyword cType ElementMatrix 1473 syn keyword cType ElementVector 1475 1474 syn keyword cType Elements 1476 syn keyword cType ElementVector1477 1475 syn keyword cType ExponentialVariogram 1478 1476 syn keyword cType ExternalResult … … 1481 1479 syn keyword cType Friction 1482 1480 syn keyword cType Gauss 1483 syn keyword cType GaussianVariogram1484 syn keyword cType gaussobjects1485 1481 syn keyword cType GaussPenta 1486 1482 syn keyword cType GaussSeg 1487 1483 syn keyword cType GaussTetra 1488 1484 syn keyword cType GaussTria 1485 syn keyword cType GaussianVariogram 1489 1486 syn keyword cType GenericExternalResult 1490 1487 syn keyword cType GenericOption … … 1501 1498 syn keyword cType IssmDirectApplicInterface 1502 1499 syn keyword cType IssmParallelDirectApplicInterface 1503 syn keyword cType krigingobjects1504 1500 syn keyword cType Load 1505 1501 syn keyword cType Loads … … 1512 1508 syn keyword cType Matice 1513 1509 syn keyword cType Matlitho 1514 syn keyword cType matrixobjects1515 1510 syn keyword cType MatrixParam 1516 1511 syn keyword cType Misfit … … 1525 1520 syn keyword cType Observations 1526 1521 syn keyword cType Option 1522 syn keyword cType OptionUtilities 1527 1523 syn keyword cType Options 1528 syn keyword cType OptionUtilities1529 1524 syn keyword cType Param 1530 1525 syn keyword cType Parameters … … 1540 1535 syn keyword cType Regionaloutput 1541 1536 syn keyword cType Results 1537 syn keyword cType RiftStruct 1542 1538 syn keyword cType Riftfront 1543 syn keyword cType RiftStruct1544 1539 syn keyword cType SealevelMasks 1545 1540 syn keyword cType Seg 1546 1541 syn keyword cType SegInput 1542 syn keyword cType SegRef 1547 1543 syn keyword cType Segment 1548 syn keyword cType SegRef1549 1544 syn keyword cType SpcDynamic 1550 1545 syn keyword cType SpcStatic … … 1565 1560 syn keyword cType Vertex 1566 1561 syn keyword cType Vertices 1562 syn keyword cType classes 1563 syn keyword cType gaussobjects 1564 syn keyword cType krigingobjects 1565 syn keyword cType matrixobjects 1567 1566 syn keyword cType AdjointBalancethickness2Analysis 1568 1567 syn keyword cType AdjointBalancethicknessAnalysis -
issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
r26155 r26165 344 344 SolidearthSettingsAbstolEnum, 345 345 SolidearthSettingsCrossSectionShapeEnum, 346 SolidearthSettingsOptimEnum,347 346 RotationalAngularVelocityEnum, 348 347 SolidearthSettingsElasticEnum, -
issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
r26155 r26165 352 352 case SolidearthSettingsAbstolEnum : return "SolidearthSettingsAbstol"; 353 353 case SolidearthSettingsCrossSectionShapeEnum : return "SolidearthSettingsCrossSectionShape"; 354 case SolidearthSettingsOptimEnum : return "SolidearthSettingsOptim";355 354 case RotationalAngularVelocityEnum : return "RotationalAngularVelocity"; 356 355 case SolidearthSettingsElasticEnum : return "SolidearthSettingsElastic"; -
issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
r26155 r26165 358 358 else if (strcmp(name,"SolidearthSettingsAbstol")==0) return SolidearthSettingsAbstolEnum; 359 359 else if (strcmp(name,"SolidearthSettingsCrossSectionShape")==0) return SolidearthSettingsCrossSectionShapeEnum; 360 else if (strcmp(name,"SolidearthSettingsOptim")==0) return SolidearthSettingsOptimEnum;361 360 else if (strcmp(name,"RotationalAngularVelocity")==0) return RotationalAngularVelocityEnum; 362 361 else if (strcmp(name,"SolidearthSettingsElastic")==0) return SolidearthSettingsElasticEnum; … … 383 382 else if (strcmp(name,"SolidearthSettingsReltol")==0) return SolidearthSettingsReltolEnum; 384 383 else if (strcmp(name,"SealevelchangeRequestedOutputs")==0) return SealevelchangeRequestedOutputsEnum; 384 else if (strcmp(name,"SolidearthSettingsRigid")==0) return SolidearthSettingsRigidEnum; 385 385 else stage=4; 386 386 } 387 387 if(stage==4){ 388 if (strcmp(name,"SolidearthSettingsRigid")==0) return SolidearthSettingsRigidEnum; 389 else if (strcmp(name,"SolidearthSettingsRotation")==0) return SolidearthSettingsRotationEnum; 388 if (strcmp(name,"SolidearthSettingsRotation")==0) return SolidearthSettingsRotationEnum; 390 389 else if (strcmp(name,"SealevelchangeRunCount")==0) return SealevelchangeRunCountEnum; 391 390 else if (strcmp(name,"SealevelchangeTransitions")==0) return SealevelchangeTransitionsEnum; … … 506 505 else if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum; 507 506 else if (strcmp(name,"TransientIshydrology")==0) return TransientIshydrologyEnum; 507 else if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum; 508 508 else stage=5; 509 509 } 510 510 if(stage==5){ 511 if (strcmp(name,"TransientIsmasstransport")==0) return TransientIsmasstransportEnum; 512 else if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum; 511 if (strcmp(name,"TransientIsoceantransport")==0) return TransientIsoceantransportEnum; 513 512 else if (strcmp(name,"TransientIsmovingfront")==0) return TransientIsmovingfrontEnum; 514 513 else if (strcmp(name,"TransientIsoceancoupling")==0) return TransientIsoceancouplingEnum; … … 629 628 else if (strcmp(name,"EplHead")==0) return EplHeadEnum; 630 629 else if (strcmp(name,"EplHeadOld")==0) return EplHeadOldEnum; 630 else if (strcmp(name,"EplHeadSlopeX")==0) return EplHeadSlopeXEnum; 631 631 else stage=6; 632 632 } 633 633 if(stage==6){ 634 if (strcmp(name,"EplHeadSlopeX")==0) return EplHeadSlopeXEnum; 635 else if (strcmp(name,"EplHeadSlopeY")==0) return EplHeadSlopeYEnum; 634 if (strcmp(name,"EplHeadSlopeY")==0) return EplHeadSlopeYEnum; 636 635 else if (strcmp(name,"EplHeadSubstep")==0) return EplHeadSubstepEnum; 637 636 else if (strcmp(name,"EplHeadTransient")==0) return EplHeadTransientEnum; … … 752 751 else if (strcmp(name,"RadarIcePeriod")==0) return RadarIcePeriodEnum; 753 752 else if (strcmp(name,"RadarPowerMacGregor")==0) return RadarPowerMacGregorEnum; 753 else if (strcmp(name,"RadarPowerWolff")==0) return RadarPowerWolffEnum; 754 754 else stage=7; 755 755 } 756 756 if(stage==7){ 757 if (strcmp(name,"RadarPowerWolff")==0) return RadarPowerWolffEnum; 758 else if (strcmp(name,"RheologyBAbsGradient")==0) return RheologyBAbsGradientEnum; 757 if (strcmp(name,"RheologyBAbsGradient")==0) return RheologyBAbsGradientEnum; 759 758 else if (strcmp(name,"RheologyBInitialguess")==0) return RheologyBInitialguessEnum; 760 759 else if (strcmp(name,"RheologyBInitialguessMisfit")==0) return RheologyBInitialguessMisfitEnum; … … 875 874 else if (strcmp(name,"SmbReini")==0) return SmbReiniEnum; 876 875 else if (strcmp(name,"SmbRunoff")==0) return SmbRunoffEnum; 876 else if (strcmp(name,"SmbRunoffSubstep")==0) return SmbRunoffSubstepEnum; 877 877 else stage=8; 878 878 } 879 879 if(stage==8){ 880 if (strcmp(name,"SmbRunoffSubstep")==0) return SmbRunoffSubstepEnum; 881 else if (strcmp(name,"SmbRunoffTransient")==0) return SmbRunoffTransientEnum; 880 if (strcmp(name,"SmbRunoffTransient")==0) return SmbRunoffTransientEnum; 882 881 else if (strcmp(name,"SmbS0gcm")==0) return SmbS0gcmEnum; 883 882 else if (strcmp(name,"SmbS0p")==0) return SmbS0pEnum; … … 998 997 else if (strcmp(name,"Outputdefinition22")==0) return Outputdefinition22Enum; 999 998 else if (strcmp(name,"Outputdefinition23")==0) return Outputdefinition23Enum; 999 else if (strcmp(name,"Outputdefinition24")==0) return Outputdefinition24Enum; 1000 1000 else stage=9; 1001 1001 } 1002 1002 if(stage==9){ 1003 if (strcmp(name,"Outputdefinition24")==0) return Outputdefinition24Enum; 1004 else if (strcmp(name,"Outputdefinition25")==0) return Outputdefinition25Enum; 1003 if (strcmp(name,"Outputdefinition25")==0) return Outputdefinition25Enum; 1005 1004 else if (strcmp(name,"Outputdefinition26")==0) return Outputdefinition26Enum; 1006 1005 else if (strcmp(name,"Outputdefinition27")==0) return Outputdefinition27Enum; … … 1121 1120 else if (strcmp(name,"CalvingHab")==0) return CalvingHabEnum; 1122 1121 else if (strcmp(name,"CalvingLevermann")==0) return CalvingLevermannEnum; 1122 else if (strcmp(name,"CalvingVonmises")==0) return CalvingVonmisesEnum; 1123 1123 else stage=10; 1124 1124 } 1125 1125 if(stage==10){ 1126 if (strcmp(name,"CalvingVonmises")==0) return CalvingVonmisesEnum; 1127 else if (strcmp(name,"Cfdragcoeffabsgrad")==0) return CfdragcoeffabsgradEnum; 1126 if (strcmp(name,"Cfdragcoeffabsgrad")==0) return CfdragcoeffabsgradEnum; 1128 1127 else if (strcmp(name,"Cfsurfacelogvel")==0) return CfsurfacelogvelEnum; 1129 1128 else if (strcmp(name,"Cfsurfacesquare")==0) return CfsurfacesquareEnum; … … 1244 1243 else if (strcmp(name,"IntParam")==0) return IntParamEnum; 1245 1244 else if (strcmp(name,"IntVecParam")==0) return IntVecParamEnum; 1245 else if (strcmp(name,"Inputs")==0) return InputsEnum; 1246 1246 else stage=11; 1247 1247 } 1248 1248 if(stage==11){ 1249 if (strcmp(name,"Inputs")==0) return InputsEnum; 1250 else if (strcmp(name,"Internal")==0) return InternalEnum; 1249 if (strcmp(name,"Internal")==0) return InternalEnum; 1251 1250 else if (strcmp(name,"Intersect")==0) return IntersectEnum; 1252 1251 else if (strcmp(name,"InversionVzObs")==0) return InversionVzObsEnum; … … 1367 1366 else if (strcmp(name,"SMBd18opdd")==0) return SMBd18opddEnum; 1368 1367 else if (strcmp(name,"SMBforcing")==0) return SMBforcingEnum; 1368 else if (strcmp(name,"SMBgcm")==0) return SMBgcmEnum; 1369 1369 else stage=12; 1370 1370 } 1371 1371 if(stage==12){ 1372 if (strcmp(name,"SMBgcm")==0) return SMBgcmEnum; 1373 else if (strcmp(name,"SMBgemb")==0) return SMBgembEnum; 1372 if (strcmp(name,"SMBgemb")==0) return SMBgembEnum; 1374 1373 else if (strcmp(name,"SMBgradients")==0) return SMBgradientsEnum; 1375 1374 else if (strcmp(name,"SMBgradientscomponents")==0) return SMBgradientscomponentsEnum; -
issm/trunk-jpl/src/m/classes/solidearthsettings.m
r26126 r26165 22 22 grdmodel = 0; %grd model (0 by default, 1 for elastic, 2 for Ivins) 23 23 cross_section_shape = 0; %cross section only used when grd model is Ivins 24 optim = 0; %new optimized version of the GRD code.25 24 end 26 25 methods … … 66 65 self.cross_section_shape=1; %square as default (see iedge in GiaDeflectionCorex) 67 66 68 %optim?69 self.optim=0;70 71 67 %no grd model by default: 72 68 self.grdmodel=0; … … 87 83 md = checkfield(md,'fieldname','solidearth.settings.grdmodel','values',[1 2]); 88 84 md = checkfield(md,'fieldname','solidearth.settings.cross_section_shape','numel',[1],'values',[1,2]); 89 md = checkfield(md,'fieldname','solidearth.settings.optim','values',[0,1]);90 85 91 86 %checks on computational flags … … 131 126 fielddisplay(self,'grdmodel','type of deformation model, 1 for elastic, 2 for visco-elastic from Ivins'); 132 127 fielddisplay(self,'cross_section_shape','1: square-edged (default). 2: elliptical. See iedge in GiaDeflectionCore'); 133 fielddisplay(self,'optim','use optimized version of the GRD code? (default 0)');134 128 end % }}} 135 129 function marshall(self,prefix,md,fid) % {{{ … … 150 144 WriteData(fid,prefix,'object',self,'fieldname','grdmodel','name','md.solidearth.settings.grdmodel','format','Integer'); 151 145 WriteData(fid,prefix,'object',self,'fieldname','cross_section_shape','name','md.solidearth.settings.cross_section_shape','format','Integer'); 152 WriteData(fid,prefix,'object',self,'fieldname','optim','name','md.solidearth.settings.optim','format','Integer');153 146 end % }}} 154 147 function savemodeljs(self,fid,modelname) % {{{ … … 165 158 writejsdouble(fid,[modelname '.solidearth.settings.glfraction'],self.glfraction); 166 159 writejsdouble(fid,[modelname '.solidearth.settings.cross_section_shape'],self.cross_section_shape); 167 writejsdouble(fid,[modelname '.solidearth.settings.optim'],self.optim);168 160 end % }}} 169 161 function self = extrude(self,md) % {{{ -
issm/trunk-jpl/test/NightlyRun/test2001.m
r26087 r26165 18 18 md.solidearth.settings.cross_section_shape=1; % for square-edged x-section 19 19 md.solidearth.settings.computesealevelchange=0; %do not compute sea level, only deformation 20 md.solidearth.requested_outputs={'Sealevel',' SealevelUGrd'};20 md.solidearth.requested_outputs={'Sealevel','BedGRD'}; 21 21 22 22 %Loading history … … 50 50 field_names ={'UGrd'}; 51 51 field_tolerances={1e-13}; 52 field_values={md.results.TransientSolution(2). SealevelUGrd};52 field_values={md.results.TransientSolution(2).BedGRD}; -
issm/trunk-jpl/test/NightlyRun/test2002.m
r26099 r26165 3 3 %mesh earth: 4 4 md=model; 5 md.mesh=gmshplanet('radius',6.371012*10^3,'resolution', 700.); %700 km resolution mesh5 md.mesh=gmshplanet('radius',6.371012*10^3,'resolution',500.); %700 km resolution mesh 6 6 7 7 %Geometry for the bed, arbitrary thickness of 1000: … … 24 24 pos=find(late < -80); 25 25 md.masstransport.spcthickness(md.mesh.elements(pos,:))= md.masstransport.spcthickness(md.mesh.elements(pos,:))-100; 26 posant=pos; 26 27 %greenland 27 28 pos=find(late>70 & late<80 & longe>-60 & longe<-30); 28 29 md.masstransport.spcthickness(md.mesh.elements(pos,:))= md.masstransport.spcthickness(md.mesh.elements(pos,:))-100; 30 posgre=pos; 29 31 30 32 %elastic loading from love numbers: … … 34 36 %mask: {{{ 35 37 mask=gmtmask(md.mesh.lat,md.mesh.long); 38 oceanmask=-ones(md.mesh.numberofvertices,1); 39 pos=find(mask==0); oceanmask(pos)=1; 40 36 41 icemask=ones(md.mesh.numberofvertices,1); 37 pos=find(mask==0); 38 icemask(pos)=-1; 39 pos=find(sum(mask(md.mesh.elements),2)<3); 40 icemask(md.mesh.elements(pos,:))=-1; 42 icemask(md.mesh.elements(posant))=-1; 43 icemask(md.mesh.elements(posgre))=-1; 44 41 45 md.mask.ice_levelset=icemask; 42 md.mask.ocean_levelset=-icemask; 43 44 45 %make sure wherever there is an ice load, that the mask is set to ice: 46 pos=find(md.masstransport.spcthickness(1:end-1)); 47 md.mask.ice_levelset(md.mesh.elements(pos,:))=-1; 46 md.mask.ocean_levelset=oceanmask; 48 47 % }}} 49 48 … … 66 65 md.materials=materials('hydro'); 67 66 68 69 67 %Miscellaneous 70 68 md.miscellaneous.name='test2002'; 71 69 72 70 %Solution parameters 71 md.cluster.np=3; 73 72 md.solidearth.settings.reltol=NaN; 74 73 md.solidearth.settings.abstol=1e-3; … … 83 82 md.transient.isthermal=0; 84 83 md.transient.ismasstransport=1; 85 md.transient.isoceantransport=1;86 84 md.transient.isslc=1; 87 85 md.solidearth.requested_outputs={'Sealevel'};
Note:
See TracChangeset
for help on using the changeset viewer.