Changeset 22955
- Timestamp:
- 07/16/18 15:39:26 (7 years ago)
- Location:
- issm/trunk-jpl/src
- Files:
-
- 2 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/Makefile.am
r22911 r22955 509 509 if SEALEVELRISE 510 510 issm_sources += ./cores/sealevelrise_core.cpp\ 511 ./cores/sealevelrise_core_eustatic.cpp\512 ./cores/sealevelrise_core_noneustatic.cpp\513 511 ./analyses/SealevelriseAnalysis.cpp 514 512 endif -
issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp
r22787 r22955 124 124 bool isoceancoupling; 125 125 bool issmb; 126 int basalforcingsmodel; 126 127 127 128 /*Fetch data needed: */ … … 132 133 iomodel->FindConstant(&isoceancoupling,"md.transient.isoceancoupling"); 133 134 iomodel->FindConstant(&issmb,"md.transient.issmb"); 135 iomodel->FindConstant(&basalforcingsmodel,"md.basalforcings.model"); 134 136 135 137 /*Finite element type*/ … … 156 158 iomodel->FetchDataToInput(elements,"md.mask.groundedice_levelset",MaskGroundediceLevelsetEnum); 157 159 iomodel->FetchDataToInput(elements,"md.basalforcings.groundedice_melting_rate",BasalforcingsGroundediceMeltingRateEnum); 160 if (basalforcingsmodel==SpatialLinearFloatingMeltRateEnum){ 161 iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_melting_rate",BasalforcingsDeepwaterMeltingRateEnum); 162 iomodel->FetchDataToInput(elements,"md.basalforcings.deepwater_elevation",BasalforcingsDeepwaterElevationEnum); 163 iomodel->FetchDataToInput(elements,"md.basalforcings.upperwater_elevation",BasalforcingsUpperwaterElevationEnum); 164 } 158 165 iomodel->FetchDataToInput(elements,"md.initialization.vx",VxEnum); 159 166 iomodel->FetchDataToInput(elements,"md.initialization.vy",VyEnum); 167 168 /*Initialize cumdeltalthickness input: unfortunately, we don't have femmodel, so we need to iterate on 169 *elements, otherwise we would have used InputUpdateFromConstantx: */ 170 counter=0; 171 for(int i=0;i<iomodel->numberofelements;i++){ 172 if(iomodel->my_elements[i]){ 173 Element* element=(Element*)elements->GetObjectByOffset(counter); 174 element->InputUpdateFromConstant(0.0,SealevelriseCumDeltathicknessEnum); 175 counter++; 176 } 177 } 160 178 161 179 /*Get what we need for ocean-induced basal melting*/ … … 706 724 basalelement->GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 707 725 IssmDouble* newthickness = xNew<IssmDouble>(numnodes); 708 IssmDouble* deltathickness = xNew<IssmDouble>(numnodes); 726 IssmDouble* cumdeltathickness = xNew<IssmDouble>(numnodes); 727 IssmDouble* deltathickness = xNew<IssmDouble>(numnodes); 709 728 IssmDouble* newbase = xNew<IssmDouble>(numnodes); 729 IssmDouble* bed = xNew<IssmDouble>(numnodes); 710 730 IssmDouble* newsurface = xNew<IssmDouble>(numnodes); 711 731 IssmDouble* oldthickness = xNew<IssmDouble>(numnodes); … … 725 745 } 726 746 727 /*Get previous base, thickness, surfac and current sealevel :*/747 /*Get previous base, thickness, surfac and current sealevel and bed:*/ 728 748 basalelement->GetInputListOnNodes(&oldbase[0],BaseEnum); 729 749 basalelement->GetInputListOnNodes(&oldsurface[0],SurfaceEnum); … … 731 751 basalelement->GetInputListOnNodes(&phi[0],MaskGroundediceLevelsetEnum); 732 752 basalelement->GetInputListOnNodes(&sealevel[0],SealevelEnum); 733 734 /*What is the delta thickness forcing the sea-level rise core: */ 735 for(i=0;i<numnodes;i++) deltathickness[i]=newthickness[i]-oldthickness[i]; 753 basalelement->GetInputListOnNodes(&bed[0],BedEnum); 754 basalelement->GetInputListOnNodes(&cumdeltathickness[0],SealevelriseCumDeltathicknessEnum); 755 756 /*What is the delta thickness forcing the sea-level rise core: cumulated over time, hence the +=:*/ 757 for(i=0;i<numnodes;i++){ 758 cumdeltathickness[i]+=newthickness[i]-oldthickness[i]; 759 deltathickness[i]=newthickness[i]-oldthickness[i]; 760 } 736 761 737 762 /*Find MasstransportHydrostaticAdjustment to figure out how to update the geometry:*/ … … 742 767 for(i=0;i<numnodes;i++) { 743 768 if (phi[i]>0.){ //this is an ice sheet: just add thickness to base. 744 newsurface[i] = oldbase[i]+newthickness[i]; //surface = oldbase + newthickness 745 newbase[i] = oldbase[i]; //same base: do nothing 769 /*Update! actually, the bed has moved too!:*/ 770 newsurface[i] = bed[i]+newthickness[i]; //surface = bed + newthickness 771 newbase[i] = bed[i]; //new base at new bed 746 772 } 747 773 else{ //this is an ice shelf: hydrostatic equilibrium*/ … … 760 786 /*Add input to the element: */ 761 787 element->AddBasalInput(ThicknessEnum,newthickness,P1Enum); 762 element->AddBasalInput(SealevelriseDeltathicknessEnum,deltathickness,P1Enum);763 788 element->AddBasalInput(SurfaceEnum,newsurface,P1Enum); 764 789 element->AddBasalInput(BaseEnum,newbase,P1Enum); 790 element->AddBasalInput(SealevelriseCumDeltathicknessEnum,cumdeltathickness,P1Enum); 791 element->AddBasalInput(SealevelriseDeltathicknessEnum,deltathickness,P1Enum); 765 792 766 793 /*Free ressources:*/ 767 794 xDelete<IssmDouble>(newthickness); 795 xDelete<IssmDouble>(cumdeltathickness); 768 796 xDelete<IssmDouble>(newbase); 769 797 xDelete<IssmDouble>(newsurface); … … 774 802 xDelete<IssmDouble>(phi); 775 803 xDelete<IssmDouble>(sealevel); 804 xDelete<IssmDouble>(bed); 805 776 806 xDelete<int>(doflist); 777 807 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; -
issm/trunk-jpl/src/c/analyses/SealevelriseAnalysis.cpp
r22609 r22955 19 19 }/*}}}*/ 20 20 void SealevelriseAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/ 21 22 int geodetic=0; 21 23 22 24 /*Update elements: */ … … 31 33 32 34 /*Create inputs: */ 35 iomodel->FetchDataToInput(elements,"md.mask.groundedice_levelset",MaskGroundediceLevelsetEnum); 33 36 iomodel->FetchDataToInput(elements,"md.mask.ice_levelset",MaskIceLevelsetEnum); 34 iomodel->FetchDataToInput(elements,"md.mask.ocean_levelset",MaskOceanLevelsetEnum); 35 iomodel->FetchDataToInput(elements,"md.mask.land_levelset",MaskLandLevelsetEnum); 37 //those only if we have requested geodetic computations: 38 iomodel->FetchData(&geodetic,"md.slr.geodetic"); 39 if (geodetic){ 40 char* masktype=NULL; 41 iomodel->FetchData(&masktype,"md.mask.type"); 42 if (strcmp(masktype,"maskpsl")==0){ 43 iomodel->FetchDataToInput(elements,"md.mask.ocean_levelset",MaskOceanLevelsetEnum); 44 iomodel->FetchDataToInput(elements,"md.mask.land_levelset",MaskLandLevelsetEnum); 45 } 46 xDelete<char>(masktype); 47 } 36 48 iomodel->FetchDataToInput(elements,"md.slr.deltathickness",SealevelriseDeltathicknessEnum); 49 iomodel->FetchDataToInput(elements,"md.slr.spcthickness",SealevelriseSpcthicknessEnum); 37 50 iomodel->FetchDataToInput(elements,"md.slr.sealevel",SealevelEnum,0); 51 iomodel->FetchDataToInput(elements,"md.geometry.bed",BedEnum); 52 iomodel->FetchDataToInput(elements,"md.slr.Ngia",SealevelNGiaRateEnum); 53 iomodel->FetchDataToInput(elements,"md.slr.Ugia",SealevelUGiaRateEnum); 54 55 /*Initialize cumdeltalthickness and sealevel rise rate input: unfortunately, we don't have femmodel, so we 56 * need to iterate on elements, otherwise we would have used InputUpdateFromConstantx: */ 57 counter=0; 58 for(int i=0;i<iomodel->numberofelements;i++){ 59 if(iomodel->my_elements[i]){ 60 Element* element=(Element*)elements->GetObjectByOffset(counter); 61 element->InputUpdateFromConstant(0.0,SealevelriseCumDeltathicknessEnum); 62 element->InputUpdateFromConstant(0.0,SealevelNEsaRateEnum); 63 element->InputUpdateFromConstant(0.0,SealevelUEsaRateEnum); 64 element->InputUpdateFromConstant(0.0,SealevelRSLRateEnum); 65 element->InputUpdateFromConstant(0.0,SealevelEustaticMaskEnum); 66 element->InputUpdateFromConstant(0.0,SealevelEustaticOceanMaskEnum); 67 counter++; 68 } 69 } 70 38 71 iomodel->FetchDataToInput(elements,"md.slr.steric_rate",SealevelriseStericRateEnum); 39 72 … … 69 102 parameters->AddObject(iomodel->CopyConstantObject("md.slr.abstol",SealevelriseAbstolEnum)); 70 103 parameters->AddObject(iomodel->CopyConstantObject("md.slr.maxiter",SealevelriseMaxiterEnum)); 104 parameters->AddObject(iomodel->CopyConstantObject("md.slr.loop_increment",SealevelriseLoopIncrementEnum)); 71 105 parameters->AddObject(iomodel->CopyConstantObject("md.slr.rigid",SealevelriseRigidEnum)); 106 parameters->AddObject(iomodel->CopyConstantObject("md.slr.horiz",SealevelriseHorizEnum)); 72 107 parameters->AddObject(iomodel->CopyConstantObject("md.slr.elastic",SealevelriseElasticEnum)); 73 108 parameters->AddObject(iomodel->CopyConstantObject("md.slr.rotation",SealevelriseRotationEnum)); … … 79 114 parameters->AddObject(iomodel->CopyConstantObject("md.slr.angular_velocity",SealevelriseAngularVelocityEnum)); 80 115 parameters->AddObject(iomodel->CopyConstantObject("md.slr.ocean_area_scaling",SealevelriseOceanAreaScalingEnum)); 116 parameters->AddObject(iomodel->CopyConstantObject("md.slr.geodetic",SealevelriseGeodeticEnum)); 81 117 82 118 iomodel->FetchData(&elastic,"md.slr.elastic"); … … 249 285 }/*}}}*/ 250 286 void SealevelriseAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/ 251 252 IssmDouble *deltaS = NULL; 253 IssmDouble *S = NULL; 254 int* sidlist = NULL; 255 int numvertices; 256 257 numvertices= element->GetNumberOfVertices(); 258 sidlist=xNew<int>(numvertices); 259 260 element->GetVerticesSidList(sidlist); 261 262 deltaS = xNew<IssmDouble>(numvertices); 263 for(int i=0;i<numvertices;i++){ 264 deltaS[i]=solution[sidlist[i]]; 265 } 266 267 S = xNew<IssmDouble>(numvertices); 268 element->GetInputListOnVertices(S,SealevelEnum,0); 269 270 /*Add deltaS to S:*/ 271 for (int i=0;i<numvertices;i++)S[i]+=deltaS[i]; 272 273 /*Add S back into inputs: */ 274 element->AddInput(SealevelEnum,S,P1Enum); 275 276 /*Free ressources:*/ 277 xDelete<int>(sidlist); 278 xDelete<IssmDouble>(deltaS); 279 xDelete<IssmDouble>(S); 287 _error_("not implemeneted yet!"); 280 288 281 289 }/*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Element.cpp
r22898 r22955 100 100 dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]); 101 101 } 102 103 102 /*Build strain rate tensor*/ 104 103 eps[0][0] = dvx[0]; eps[0][1] = .5*(dvx[1]+dvy[0]); eps[0][2] = .5*(dvx[2]+dvz[0]); … … 1050 1049 gauss->GaussVertex(iv); 1051 1050 input->GetInputValue(&pvalue[iv],gauss); 1051 } 1052 1053 /*clean-up*/ 1054 delete gauss; 1055 } 1056 /*}}}*/ 1057 void Element::GetInputListOnVerticesAtTime(IssmDouble* pvalue, int enumtype, IssmDouble time){/*{{{*/ 1058 1059 /*Recover input*/ 1060 Input* input=this->GetInput(enumtype); 1061 if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element"); 1062 1063 /*Fetch number vertices for this element*/ 1064 int numvertices = this->GetNumberOfVertices(); 1065 1066 /*Checks in debugging mode*/ 1067 _assert_(pvalue); 1068 1069 /* Start looping on the number of vertices: */ 1070 Gauss*gauss=this->NewGauss(); 1071 for(int iv=0;iv<numvertices;iv++){ 1072 gauss->GaussVertex(iv); 1073 input->GetInputValue(&pvalue[iv],gauss,time); 1052 1074 } 1053 1075 … … 1333 1355 } 1334 1356 1357 /*Clean up*/ 1358 xDelete<int>(doflist); 1359 xDelete<IssmDouble>(values); 1360 1361 } 1362 /*}}}*/ 1363 void Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum,int type, IssmDouble time){/*{{{*/ 1364 1365 /*Fetch number vertices for this element and allocate arrays*/ 1366 int numvertices = this->GetNumberOfVertices(); 1367 int numnodes = this->GetNumberOfNodes(); 1368 int* doflist = NULL; 1369 IssmDouble* values = NULL; 1370 1371 switch(type){ 1372 case VertexPIdEnum: 1373 doflist = xNew<int>(numvertices); 1374 values = xNew<IssmDouble>(numvertices); 1375 /*Fill in values*/ 1376 this->GetVertexPidList(doflist); 1377 this->GetInputListOnVerticesAtTime(values,input_enum,time); 1378 vector->SetValues(numvertices,doflist,values,INS_VAL); 1379 break; 1380 case VertexSIdEnum: 1381 doflist = xNew<int>(numvertices); 1382 values = xNew<IssmDouble>(numvertices); 1383 /*Fill in values*/ 1384 this->GetVerticesSidList(doflist); 1385 this->GetInputListOnVerticesAtTime(values,input_enum,time); 1386 vector->SetValues(numvertices,doflist,values,INS_VAL); 1387 break; 1388 default: 1389 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet"); 1390 } 1391 1335 1392 /*Clean up*/ 1336 1393 xDelete<int>(doflist); … … 2039 2096 name==MaterialsRheologyEsEnum || 2040 2097 name==MaterialsRheologyEsbarEnum || 2041 name==SealevelEnum || 2042 name==SealevelUmotionEnum || 2043 name==SealevelNmotionEnum || 2044 name==SealevelEmotionEnum || 2045 name==SealevelAbsoluteEnum || 2046 name==SealevelEustaticEnum || 2047 name==SealevelriseDeltathicknessEnum || 2048 name==EsaUmotionEnum || 2049 name==EsaNmotionEnum || 2050 name==EsaEmotionEnum || 2051 name==EsaXmotionEnum || 2052 name==EsaYmotionEnum || 2098 name==SealevelEnum || 2099 name==SealevelUEsaEnum || 2100 name==SealevelUEsaRateEnum || 2101 name==SealevelNEsaEnum || 2102 name==SealevelNEsaRateEnum || 2103 name==SealevelUNorthEsaEnum || 2104 name==SealevelUEastEsaEnum || 2105 name==SealevelRSLEustaticEnum || 2106 name==SealevelRSLEustaticRateEnum || 2107 name==SealevelRSLEnum || 2108 name==SealevelRSLRateEnum || 2109 name==SealevelEustaticMaskEnum || 2110 name==SealevelEustaticOceanMaskEnum || 2111 name==SealevelUGiaEnum || 2112 name==SealevelUGiaRateEnum || 2113 name==SealevelNGiaEnum || 2114 name==SealevelNGiaRateEnum || 2115 name==SealevelriseDeltathicknessEnum || 2116 name==SealevelriseCumDeltathicknessEnum || 2117 name==EsaUmotionEnum || 2118 name==EsaNmotionEnum || 2119 name==EsaEmotionEnum || 2053 2120 name==EsaStrainratexxEnum || 2054 2121 name==EsaStrainratexyEnum || … … 2125 2192 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum); 2126 2193 xDelete<IssmDouble>(base); 2194 xDelete<IssmDouble>(values); 2195 2196 }/*}}}*/ 2197 void Element::SpatialLinearFloatingiceMeltingRate(){/*{{{*/ 2198 2199 int numvertices = this->GetNumberOfVertices(); 2200 IssmDouble* deepwatermelt = xNew<IssmDouble>(numvertices); 2201 IssmDouble* deepwaterel = xNew<IssmDouble>(numvertices); 2202 IssmDouble* upperwaterel = xNew<IssmDouble>(numvertices); 2203 IssmDouble* base = xNew<IssmDouble>(numvertices); 2204 IssmDouble* values = xNew<IssmDouble>(numvertices); 2205 2206 this->GetInputListOnVertices(base,BaseEnum); 2207 this->GetInputListOnVertices(deepwatermelt,BasalforcingsDeepwaterMeltingRateEnum); 2208 this->GetInputListOnVertices(deepwaterel,BasalforcingsDeepwaterElevationEnum); 2209 this->GetInputListOnVertices(upperwaterel,BasalforcingsUpperwaterElevationEnum); 2210 2211 for(int i=0;i<numvertices;i++){ 2212 if(base[i]>upperwaterel[i]) values[i]=0; 2213 else if (base[i]<deepwaterel[i]) values[i]=deepwatermelt[i]; 2214 else values[i]=deepwatermelt[i]*(base[i]-upperwaterel[i])/(deepwaterel[i]-upperwaterel[i]); 2215 } 2216 2217 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum); 2218 xDelete<IssmDouble>(base); 2219 xDelete<IssmDouble>(deepwaterel); 2220 xDelete<IssmDouble>(deepwatermelt); 2221 xDelete<IssmDouble>(upperwaterel); 2127 2222 xDelete<IssmDouble>(values); 2128 2223 -
issm/trunk-jpl/src/c/classes/Elements/Element.h
r22918 r22955 90 90 void GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype); 91 91 void GetInputListOnVertices(IssmDouble* pvalue,int enumtype); 92 void GetInputListOnVerticesAtTime(IssmDouble* pvalue,int enumtype,IssmDouble time); 92 93 void GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue); 93 94 void GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug); … … 104 105 void GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int solutionenum); 105 106 void GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum, int type); 107 void GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum, int type,IssmDouble time); 106 108 void GetVertexPidList(int* pidlist); 107 109 void GetVerticesConnectivityList(int* connectivitylist); … … 134 136 bool IsWaterInElement(); 135 137 void LinearFloatingiceMeltingRate(); 138 void SpatialLinearFloatingiceMeltingRate(); 136 139 void MantlePlumeGeothermalFlux(); 137 140 void MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses); … … 336 339 virtual void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0; 337 340 virtual void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea)=0; 338 virtual void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea )=0;341 virtual void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz)=0; 339 342 #endif 340 343 -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r22918 r22955 201 201 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 202 202 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");}; 203 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){_error_("not implemented yet!");};203 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");}; 204 204 #endif 205 205 -
issm/trunk-jpl/src/c/classes/Elements/Seg.h
r22918 r22955 182 182 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 183 183 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");}; 184 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){_error_("not implemented yet!");};184 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");}; 185 185 IssmDouble OceanArea(void){_error_("not implemented yet!");}; 186 186 IssmDouble OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");}; -
issm/trunk-jpl/src/c/classes/Elements/Tetra.h
r22918 r22955 189 189 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 190 190 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");}; 191 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){_error_("not implemented yet!");};191 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");}; 192 192 IssmDouble OceanArea(void){_error_("not implemented yet!");}; 193 193 IssmDouble OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");}; -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r22918 r22955 1354 1354 1355 1355 } 1356 else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum ){1356 else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum || domaintype==Domain3DsurfaceEnum){ 1357 1357 /*Check that not all nodes are grounded or floating*/ 1358 1358 if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded … … 1905 1905 1906 1906 if(!IsIceInElement())return 0.; 1907 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0)) return 0; 1907 1908 1908 1909 int domaintype; … … 4676 4677 /*}}}*/ 4677 4678 void Tria::SealevelriseMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old,IssmDouble eartharea){/*{{{*/ 4678 4679 4679 /*early return if we are not on an ice cap OR ocean:*/ 4680 4680 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0) && !IsWaterInElement()){ … … 4778 4778 IssmDouble late,longe,re; 4779 4779 IssmDouble lati,longi,ri; 4780 bool notfullygrounded=false; 4780 4781 4781 4782 /*elastic green function:*/ … … 4785 4786 /*ice properties: */ 4786 4787 IssmDouble rho_ice,rho_water,rho_earth; 4788 4789 /*constants:*/ 4790 IssmDouble constant=0; 4787 4791 4788 4792 /*Initialize eustatic component: do not skip this step :):*/ … … 4795 4799 4796 4800 /*early return if we are not on an ice cap:*/ 4797 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0)){ 4801 if(!(this->inputs->Max(MaskIceLevelsetEnum)<=0)){ 4802 constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); 4798 4803 *peustatic=0; //do not forget to assign this pointer, otherwise, global eustatic will be garbage! 4799 4804 return; 4800 4805 } 4806 4807 /*early return if we are fully floating: */ 4808 if (this->inputs->Max(MaskGroundediceLevelsetEnum)<=0){ 4809 constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); 4810 *peustatic=0; //do not forget to assign this pointer, otherwise, global eustatic will be garbage! 4811 return; 4812 } 4813 4814 /*If we are here, we are on ice that is fully grounded or half-way to floating: */ 4815 if ((this->inputs->Min(MaskGroundediceLevelsetEnum))<0){ 4816 notfullygrounded=true; //used later on. 4817 } 4818 4819 /*Inform mask: */ 4820 constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum)); 4801 4821 4802 4822 /*recover material parameters: */ … … 4859 4879 /*}}}*/ 4860 4880 4861 /*Compute area of element :*/4881 /*Compute area of element. Scale it by grounded fraction if not fully grounded: */ 4862 4882 area=GetAreaSpherical(); 4863 4883 if(notfullygrounded){ 4884 IssmDouble phi=0; 4885 IssmDouble xyz_list[NUMVERTICES][3]; 4886 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 4887 4888 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 trias 4889 area*=phi; 4890 } 4891 4864 4892 /*Compute ice thickness change: */ 4865 4893 Input* deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum); 4866 4894 if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!"); 4867 deltathickness_input->GetInputAverage(&I); 4895 4896 /*If we are fully grounded, take the average over the element: */ 4897 if(!notfullygrounded)deltathickness_input->GetInputAverage(&I); 4898 else{ 4899 IssmDouble total_weight=0; 4900 bool mainlyfloating = true; 4901 int point1; 4902 IssmDouble fraction1,fraction2; 4903 4904 /*Recover portion of element that is grounded*/ 4905 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating); 4906 Gauss* gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,2); 4907 4908 /* Start looping on the number of gaussian points and average over these gaussian points: */ 4909 total_weight=0; 4910 I=0; 4911 for(int ig=gauss->begin();ig<gauss->end();ig++){ 4912 IssmDouble Ig=0; 4913 gauss->GaussPoint(ig); 4914 deltathickness_input->GetInputValue(&Ig,gauss); 4915 I+=Ig*gauss->weight; 4916 total_weight+=gauss->weight; 4917 } 4918 I=I/total_weight; 4919 delete gauss; 4920 } 4868 4921 4869 4922 /*Compute eustatic compoent:*/ … … 4927 4980 IssmDouble minlong=400; 4928 4981 IssmDouble maxlong=-20; 4982 IssmDouble constant=0; 4929 4983 4930 4984 /*precomputed elastic green functions:*/ … … 4947 5001 4948 5002 /*early return if we are not on the ocean:*/ 4949 if (!IsWaterInElement())return; 5003 if (!IsWaterInElement()){ 5004 constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticOceanMaskEnum,&constant,P0Enum)); 5005 return; 5006 } 5007 constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticOceanMaskEnum,&constant,P0Enum)); 4950 5008 4951 5009 /*recover computational flags: */ … … 5058 5116 } 5059 5117 /*}}}*/ 5060 void Tria::SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea ){ /*{{{*/5118 void Tria::SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){ /*{{{*/ 5061 5119 5062 5120 /*diverse:*/ … … 5082 5140 IssmDouble* N_elastic= NULL; 5083 5141 IssmDouble* E_elastic= NULL; 5142 DoubleVecParam* U_parameter = NULL; 5143 DoubleVecParam* H_parameter = NULL; 5144 IssmDouble* U_values=NULL; 5145 IssmDouble* N_values=NULL; 5146 IssmDouble* E_values=NULL; 5084 5147 5085 5148 /*optimization:*/ … … 5092 5155 /*early return if we are not on the ocean or on an ice cap:*/ 5093 5156 if(!(this->inputs->Max(MaskIceLevelsetEnum)<0) && !IsWaterInElement()) return; 5157 5158 /*early return if we are fully floating: */ 5159 if (this->inputs->Max(MaskGroundediceLevelsetEnum)<=0)return; 5094 5160 5095 5161 /*recover computational flags: */ … … 5156 5222 5157 5223 /*recover elastic Green's functions for displacement:*/ 5158 DoubleVecParam* U_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(U_parameter); 5159 DoubleVecParam* H_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(H_parameter); 5224 U_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(U_parameter); 5160 5225 U_parameter->GetParameterValueByPointer(&U_elastic_precomputed,&M); 5161 H_parameter->GetParameterValueByPointer(&H_elastic_precomputed,&M); 5226 if(horiz){ 5227 H_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(H_parameter); 5228 H_parameter->GetParameterValueByPointer(&H_elastic_precomputed,&M); 5229 } 5162 5230 5163 5231 /*From Sg, recover water sea level rise:*/ … … 5171 5239 /*initialize: */ 5172 5240 U_elastic=xNewZeroInit<IssmDouble>(gsize); 5173 N_elastic=xNewZeroInit<IssmDouble>(gsize); 5174 E_elastic=xNewZeroInit<IssmDouble>(gsize); 5241 if(horiz){ 5242 N_elastic=xNewZeroInit<IssmDouble>(gsize); 5243 E_elastic=xNewZeroInit<IssmDouble>(gsize); 5244 } 5175 5245 5176 5246 int* indices=xNew<int>(gsize); 5177 IssmDouble* U_values=xNewZeroInit<IssmDouble>(gsize); 5178 IssmDouble* N_values=xNewZeroInit<IssmDouble>(gsize); 5179 IssmDouble* E_values=xNewZeroInit<IssmDouble>(gsize); 5247 U_values=xNewZeroInit<IssmDouble>(gsize); 5248 if(horiz){ 5249 N_values=xNewZeroInit<IssmDouble>(gsize); 5250 E_values=xNewZeroInit<IssmDouble>(gsize); 5251 } 5180 5252 IssmDouble alpha; 5181 5253 IssmDouble delPhi,delLambda; … … 5202 5274 } 5203 5275 dx = x_element-x; dy = y_element-y; dz = z_element-z; 5204 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); 5205 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5276 if(horiz){ 5277 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); 5278 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5); 5279 } 5206 5280 5207 5281 /*Elastic component (from Eq 17 in Adhikari et al, GMD 2015): */ 5208 5282 int index=reCast<int,IssmDouble>(alpha/PI*(M-1)); 5209 5283 U_elastic[i] += U_elastic_precomputed[index]; 5210 N_elastic[i] += H_elastic_precomputed[index]*N_azim; 5211 E_elastic[i] += H_elastic_precomputed[index]*E_azim; 5284 if(horiz){ 5285 N_elastic[i] += H_elastic_precomputed[index]*N_azim; 5286 E_elastic[i] += H_elastic_precomputed[index]*E_azim; 5287 } 5212 5288 5213 5289 /*Add all components to the pUp solution vectors:*/ 5214 5290 if(this->inputs->Max(MaskIceLevelsetEnum)<0){ 5215 5291 U_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*U_elastic[i]; 5216 N_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*N_elastic[i]; 5217 E_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*E_elastic[i]; 5292 if(horiz){ 5293 N_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*N_elastic[i]; 5294 E_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*E_elastic[i]; 5295 } 5218 5296 } 5219 5297 else if(IsWaterInElement()) { 5220 5298 U_values[i]+=3*rho_water/rho_earth*area/eartharea*S*U_elastic[i]; 5221 N_values[i]+=3*rho_water/rho_earth*area/eartharea*S*N_elastic[i]; 5222 E_values[i]+=3*rho_water/rho_earth*area/eartharea*S*E_elastic[i]; 5299 if(horiz){ 5300 N_values[i]+=3*rho_water/rho_earth*area/eartharea*S*N_elastic[i]; 5301 E_values[i]+=3*rho_water/rho_earth*area/eartharea*S*E_elastic[i]; 5302 } 5223 5303 } 5224 5304 } 5225 5305 pUp->SetValues(gsize,indices,U_values,ADD_VAL); 5226 pNorth->SetValues(gsize,indices,N_values,ADD_VAL); 5227 pEast->SetValues(gsize,indices,E_values,ADD_VAL); 5306 if(horiz){ 5307 pNorth->SetValues(gsize,indices,N_values,ADD_VAL); 5308 pEast->SetValues(gsize,indices,E_values,ADD_VAL); 5309 } 5228 5310 5229 5311 /*free ressources:*/ 5230 5312 xDelete<int>(indices); 5231 xDelete<IssmDouble>(U_values); xDelete<IssmDouble>(N_values); xDelete<IssmDouble>(E_values); 5232 xDelete<IssmDouble>(U_elastic); xDelete<IssmDouble>(N_elastic); xDelete<IssmDouble>(E_elastic); 5313 xDelete<IssmDouble>(U_values); 5314 xDelete<IssmDouble>(U_elastic); 5315 if(horiz){ 5316 xDelete<IssmDouble>(N_values); xDelete<IssmDouble>(E_values); 5317 xDelete<IssmDouble>(N_elastic); xDelete<IssmDouble>(E_elastic); 5318 } 5233 5319 5234 5320 return; -
issm/trunk-jpl/src/c/classes/Elements/Tria.h
r22918 r22955 162 162 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea); 163 163 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea); 164 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea );164 void SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz); 165 165 #endif 166 166 /*}}}*/ -
issm/trunk-jpl/src/c/classes/FemModel.cpp
r22902 r22955 1454 1454 /*Figure out maximum across the cluster: */ 1455 1455 ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1456 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1456 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1457 1457 maxvy=node_maxvy; 1458 1458 … … 1478 1478 /*Figure out maximum across the cluster: */ 1479 1479 ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1480 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1480 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1481 1481 maxvz=node_maxvz; 1482 1482 … … 1502 1502 /*Figure out minimum across the cluster: */ 1503 1503 ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1504 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1504 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1505 1505 minvel=node_minvel; 1506 1506 … … 1526 1526 /*Figure out minimum across the cluster: */ 1527 1527 ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1528 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1528 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1529 1529 minvx=node_minvx; 1530 1530 … … 1550 1550 /*Figure out minimum across the cluster: */ 1551 1551 ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1552 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1552 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1553 1553 minvy=node_minvy; 1554 1554 … … 1574 1574 /*Figure out minimum across the cluster: */ 1575 1575 ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1576 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1576 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1577 1577 minvz=node_minvz; 1578 1578 … … 1619 1619 omega_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 1620 1620 1621 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1621 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 1622 1622 //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 1623 1623 J+=weight*1/2*pow(dp[0]*dp[0]+dp[1]*dp[1],2)*Jdet*gauss->weight; … … 1955 1955 IssmDouble* values = xNewZeroInit<IssmDouble>(nlines*ncols); 1956 1956 IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols); 1957 1957 1958 1958 /*Fill-in matrix*/ 1959 1959 for(int j=0;j<elements->Size();j++){ … … 1964 1964 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1965 1965 xDelete<IssmDouble>(values); 1966 1966 1967 1967 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time)); 1968 1968 xDelete<IssmDouble>(allvalues); … … 2012 2012 int domaintype; 2013 2013 this->parameters->FindParam(&domaintype,DomainTypeEnum); 2014 2014 2015 2015 /*1: go throug all elements of this partition and figure out how many 2016 2016 * segments we have (corresopnding to levelset = 0)*/ … … 2132 2132 case VelEnum: this->ElementResponsex(responses,VelEnum); break; 2133 2133 case FrictionCoefficientEnum: NodalValuex(responses, FrictionCoefficientEnum,elements,nodes, vertices, loads, materials, parameters); break; 2134 default: 2134 default: 2135 2135 if(response_descriptor_enum>=Outputdefinition1Enum && response_descriptor_enum <=Outputdefinition100Enum){ 2136 2136 IssmDouble double_result = OutputDefinitionsResponsex(this,response_descriptor_enum); 2137 2137 *responses=double_result; 2138 2138 } 2139 else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 2140 break; 2139 else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 2140 break; 2141 2141 } 2142 2142 … … 2269 2269 thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss); 2270 2270 2271 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 2271 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 2272 2272 J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight; 2273 2273 } … … 2460 2460 analysis->UpdateConstraints(this); 2461 2461 delete analysis; 2462 2462 2463 2463 /*Second, constraints might be time dependent: */ 2464 SpcNodesx(nodes,constraints,parameters,analysis_type); 2464 SpcNodesx(nodes,constraints,parameters,analysis_type); 2465 2465 2466 2466 /*Now, update degrees of freedoms: */ … … 2473 2473 IssmDouble *surface = NULL; 2474 2474 IssmDouble *bed = NULL; 2475 2475 2476 2476 if(VerboseSolution()) _printf0_(" updating vertices positions\n"); 2477 2477 … … 2512 2512 2513 2513 /*AMR*/ 2514 #if !defined(_HAVE_ADOLC_) 2514 #if !defined(_HAVE_ADOLC_) 2515 2515 void FemModel::ReMesh(void){/*{{{*/ 2516 2516 … … 2522 2522 int newnumberofvertices = -1; 2523 2523 int newnumberofelements = -1; 2524 bool* my_elements = NULL; 2524 bool* my_elements = NULL; 2525 2525 int* my_vertices = NULL; 2526 2526 int elementswidth = this->GetElementsWidth();//just tria elements in this version … … 2528 2528 bool isgroundingline; 2529 2529 2530 /*Branch to specific amr depending on requested method*/ 2530 /*Branch to specific amr depending on requested method*/ 2531 2531 this->parameters->FindParam(&amrtype,AmrTypeEnum); 2532 2532 switch(amrtype){ … … 2541 2541 default: _error_("not implemented yet"); 2542 2542 } 2543 2543 2544 2544 /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/ 2545 2545 this->ElementsAndVerticesPartitioning(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,&my_elements,&my_vertices); … … 2572 2572 2573 2573 /*As the domain is 2D, it is not necessary to create nodes for this analysis*/ 2574 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue; 2574 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue; 2575 2575 2576 2576 this->CreateNodes(newnumberofvertices,my_vertices,nodecounter,analysis_enum,new_nodes); … … 2602 2602 //SetCurrentConfiguration(analysis_type); 2603 2603 2604 this->analysis_counter=i; 2604 this->analysis_counter=i; 2605 2605 /*Now, plug analysis_counter and analysis_type inside the parameters: */ 2606 2606 this->parameters->SetParam(this->analysis_counter,AnalysisCounterEnum); … … 2619 2619 2620 2620 ConfigureObjectsx(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters); 2621 if(i==0){ 2621 if(i==0){ 2622 2622 VerticesDofx(new_vertices,this->parameters); //only call once, we only have one set of vertices 2623 2623 } … … 2663 2663 /*Insert bedrock from mismip+ setup*/ 2664 2664 /*This was used to Misomip project/simulations*/ 2665 2665 2666 2666 if(VerboseSolution())_printf0_(" call Mismip bedrock adjust module\n"); 2667 2667 … … 2680 2680 by = 500./(1.+exp((-2./4000.)*(y-80000./2.-24000.)))+500./(1.+exp((2./4000.)*(y-80000./2.+24000.))); 2681 2681 r[i] = max(bx+by,-720.); 2682 } 2682 } 2683 2683 /*insert new bedrock*/ 2684 2684 element->AddInput(BedEnum,&r[0],P1Enum); … … 2693 2693 2694 2694 if(VerboseSolution())_printf0_(" call adjust base and thickness module\n"); 2695 2695 2696 2696 int numvertices = this->GetElementsWidth(); 2697 2697 IssmDouble rho_water,rho_ice,density,base_float; … … 2705 2705 for(int el=0;el<this->elements->Size();el++){ 2706 2706 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(el)); 2707 2707 2708 2708 element->GetInputListOnVertices(&s[0],SurfaceEnum); 2709 2709 element->GetInputListOnVertices(&r[0],BedEnum); … … 2717 2717 base_float = rho_ice*s[i]/(rho_ice-rho_water); 2718 2718 if(r[i]>base_float){ 2719 b[i] = r[i]; 2720 } 2719 b[i] = r[i]; 2720 } 2721 2721 else { 2722 b[i] = base_float; 2723 } 2722 b[i] = base_float; 2723 } 2724 2724 2725 2725 if(fabs(sl[i])>0) _error_("Sea level value "<<sl[i]<<" not supported!"); 2726 2726 /*update thickness and mask grounded ice level set*/ 2727 2727 h[i] = s[i]-b[i]; 2728 phi[i] = h[i]+r[i]/density; 2728 phi[i] = h[i]+r[i]/density; 2729 2729 } 2730 2730 … … 2734 2734 element->AddInput(BaseEnum,&b[0],P1Enum); 2735 2735 } 2736 2736 2737 2737 /*Delete*/ 2738 2738 xDelete<IssmDouble>(phi); … … 2762 2762 Vector<IssmDouble>* input_interpolations = NULL; 2763 2763 IssmDouble* input_interpolations_serial = NULL; 2764 int* pos = NULL; 2764 int* pos = NULL; 2765 2765 IssmDouble value = 0; 2766 2766 … … 2782 2782 P0input_interp = xNew<int>(numP0inputs); 2783 2783 P1input_enums = xNew<int>(numP1inputs); 2784 P1input_interp = xNew<int>(numP1inputs); 2784 P1input_interp = xNew<int>(numP1inputs); 2785 2785 } 2786 2786 numP0inputs = 0; … … 2814 2814 } 2815 2815 } 2816 2817 /*Get P0 and P1 inputs over the elements*/ 2816 2817 /*Get P0 and P1 inputs over the elements*/ 2818 2818 pos = xNew<int>(elementswidth); 2819 2819 vP0inputs= new Vector<IssmDouble>(numberofelements*numP0inputs); … … 2821 2821 for(int i=0;i<this->elements->Size();i++){ 2822 2822 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 2823 2823 2824 2824 /*Get P0 inputs*/ 2825 2825 for(int j=0;j<numP0inputs;j++){ 2826 TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j])); 2826 TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j])); 2827 2827 input->GetInputAverage(&value); 2828 2828 pos[0]=element->Sid()*numP0inputs+j; 2829 /*Insert input in the vector*/ 2829 /*Insert input in the vector*/ 2830 2830 vP0inputs->SetValues(1,pos,&value,INS_VAL); 2831 2831 } 2832 2832 2833 2833 /*Get P1 inputs*/ 2834 2834 for(int j=0;j<numP1inputs;j++){ … … 2837 2837 pos[1]=element->vertices[1]->Sid()*numP1inputs+j; 2838 2838 pos[2]=element->vertices[2]->Sid()*numP1inputs+j; 2839 /*Insert input in the vector*/ 2840 vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 2839 /*Insert input in the vector*/ 2840 vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 2841 2841 } 2842 2842 } … … 2847 2847 P0inputs=vP0inputs->ToMPISerial(); 2848 2848 P1inputs=vP1inputs->ToMPISerial(); 2849 2849 2850 2850 /*Assign pointers*/ 2851 *pnumP0inputs = numP0inputs; 2852 *pP0inputs = P0inputs; 2851 *pnumP0inputs = numP0inputs; 2852 *pP0inputs = P0inputs; 2853 2853 *pP0input_enums = P0input_enums; 2854 2854 *pP0input_interp = P0input_interp; 2855 *pnumP1inputs = numP1inputs; 2856 *pP1inputs = P1inputs; 2855 *pnumP1inputs = numP1inputs; 2856 *pP1inputs = P1inputs; 2857 2857 *pP1input_enums = P1input_enums; 2858 *pP1input_interp = P1input_interp; 2858 *pP1input_interp = P1input_interp; 2859 2859 2860 2860 /*Cleanup*/ … … 2867 2867 /*}}}*/ 2868 2868 void FemModel::InterpolateInputs(Vertices* newfemmodel_vertices,Elements* newfemmodel_elements){/*{{{*/ 2869 2869 2870 2870 int numberofelements = this->elements->NumberOfElements(); //global, entire old mesh 2871 2871 int newnumberofelements = newfemmodel_elements->Size(); //just on the new partition … … 2883 2883 int* P1input_enums = NULL; 2884 2884 int* P1input_interp = NULL; 2885 IssmDouble* values = NULL; 2885 IssmDouble* values = NULL; 2886 2886 IssmDouble* vector = NULL; 2887 2887 IssmDouble* x = NULL;//global, entire old mesh … … 2895 2895 IssmDouble* newyc = NULL;//just on the new partition 2896 2896 int* newelementslist = NULL;//just on the new partition 2897 int* sidtoindex = NULL;//global vertices sid to partition index 2897 int* sidtoindex = NULL;//global vertices sid to partition index 2898 2898 2899 2899 /*Get old P0 and P1 inputs (entire mesh)*/ … … 2928 2928 2929 2929 /*Insert P0 and P1 inputs into the new elements (just on the new partition)*/ 2930 values=xNew<IssmDouble>(elementswidth); 2930 values=xNew<IssmDouble>(elementswidth); 2931 2931 for(int i=0;i<newfemmodel_elements->Size();i++){//just on the new partition 2932 2932 Element* element=xDynamicCast<Element*>(newfemmodel_elements->GetObjectByOffset(i)); 2933 2933 /*newP0inputs is just on the new partition*/ 2934 2934 for(int j=0;j<numP0inputs;j++){ 2935 switch(P0input_interp[j]){ 2935 switch(P0input_interp[j]){ 2936 2936 case P0Enum: 2937 2937 case DoubleInputEnum: 2938 2938 element->AddInput(new DoubleInput(P0input_enums[j],newP0inputs[i*numP0inputs+j])); 2939 2939 break; 2940 case IntInputEnum: 2940 case IntInputEnum: 2941 2941 element->AddInput(new IntInput(P0input_enums[j],reCast<int>(newP0inputs[i*numP0inputs+j]))); 2942 2942 break; … … 2956 2956 } 2957 2957 } 2958 2958 2959 2959 /*Cleanup*/ 2960 2960 xDelete<IssmDouble>(P0inputs); … … 2995 2995 2996 2996 if(!this->elements || !this->vertices || !this->results || !this->parameters) return; 2997 2997 2998 2998 parameters->FindParam(&step,StepEnum); 2999 2999 parameters->FindParam(&time,TimeEnum); … … 3013 3013 this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshYEnum, 3014 3014 y,numberofvertices,1,step,time)); 3015 3015 3016 3016 /*Cleanup*/ 3017 3017 xDelete<IssmDouble>(x); … … 3074 3074 /*Assemble*/ 3075 3075 vmasklevelset->Assemble(); 3076 3076 3077 3077 /*Serialize and set output*/ 3078 3078 (*pmasklevelset)=vmasklevelset->ToMPISerial(); … … 3088 3088 3089 3089 /*newelementslist is in Matlab indexing*/ 3090 3090 3091 3091 /*Creating connectivity table*/ 3092 3092 int* connectivity=NULL; … … 3099 3099 connectivity[vertexid-1]+=1;//Matlab to C indexing 3100 3100 } 3101 } 3101 } 3102 3102 3103 3103 /*Create vertex and insert in vertices*/ 3104 3104 for(int i=0;i<newnumberofvertices;i++){ 3105 3105 if(my_vertices[i]){ 3106 Vertex *newvertex=new Vertex(); 3106 Vertex *newvertex=new Vertex(); 3107 3107 newvertex->id=i+1; 3108 3108 newvertex->sid=i; … … 3115 3115 newvertex->connectivity=connectivity[i]; 3116 3116 newvertex->clone=false;//itapopo check this 3117 vertices->AddObject(newvertex); 3118 } 3117 vertices->AddObject(newvertex); 3118 } 3119 3119 } 3120 3120 … … 3143 3143 } 3144 3144 else newtria->element_type_list=NULL; 3145 3145 3146 3146 /*Element hook*/ 3147 3147 int matpar_id=newnumberofelements+1; //retrieve material parameter id (last pointer in femodel->materials) … … 3149 3149 /*retrieve vertices ids*/ 3150 3150 int* vertex_ids=xNew<int>(elementswidth); 3151 for(int j=0;j<elementswidth;j++) vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing 3151 for(int j=0;j<elementswidth;j++) vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing 3152 3152 /*Setting the hooks*/ 3153 3153 newtria->numanalyses =this->nummodels; … … 3161 3161 /*Clean up*/ 3162 3162 xDelete<int>(vertex_ids); 3163 elements->AddObject(newtria); 3164 } 3163 elements->AddObject(newtria); 3164 } 3165 3165 } 3166 3166 … … 3172 3172 for(int i=0;i<newnumberofelements;i++){ 3173 3173 if(my_elements[i]){ 3174 materials->AddObject(new Matice(i+1,i,MaticeEnum)); 3175 } 3176 } 3177 3174 materials->AddObject(new Matice(i+1,i,MaticeEnum)); 3175 } 3176 } 3177 3178 3178 /*Add new constant material property to materials, at the end: */ 3179 3179 Matpar *newmatpar=static_cast<Matpar*>(this->materials->GetObjectByOffset(this->materials->Size()-1)->copy()); 3180 3180 newmatpar->SetMid(newnumberofelements+1); 3181 materials->AddObject(newmatpar);//put it at the end of the materials 3181 materials->AddObject(newmatpar);//put it at the end of the materials 3182 3182 } 3183 3183 /*}}}*/ … … 3186 3186 int lid=0; 3187 3187 for(int j=0;j<newnumberofvertices;j++){ 3188 if(my_vertices[j]){ 3189 3190 Node* newnode=new Node(); 3191 3188 if(my_vertices[j]){ 3189 3190 Node* newnode=new Node(); 3191 3192 3192 /*id: */ 3193 3193 newnode->id=nodecounter+j+1; … … 3195 3195 newnode->lid=lid++; 3196 3196 newnode->analysis_enum=analysis_enum; 3197 3197 3198 3198 /*Initialize coord_system: Identity matrix by default*/ 3199 3199 for(int k=0;k<3;k++) for(int l=0;l<3;l++) newnode->coord_system[k][l]=0.0; 3200 3200 for(int k=0;k<3;k++) newnode->coord_system[k][k]=1.0; 3201 3201 3202 3202 /*indexing:*/ 3203 3203 newnode->indexingupdate=true; 3204 3204 3205 3205 Analysis* analysis=EnumToAnalysis(analysis_enum); 3206 3206 int *doftypes=NULL; … … 3216 3216 /*Stressbalance Horiz*/ 3217 3217 if(analysis_enum==StressbalanceAnalysisEnum){ 3218 // itapopo this code is rarely used. 3218 // itapopo this code is rarely used. 3219 3219 /*Coordinate system provided, convert to coord_system matrix*/ 3220 3220 //XZvectorsToCoordinateSystem(&this->coord_system[0][0],&iomodel->Data(StressbalanceReferentialEnum)[j*6]); … … 3231 3231 if(!femmodel_vertices) _error_("GetMesh: vertices are NULL."); 3232 3232 if(!femmodel_elements) _error_("GetMesh: elements are NULL."); 3233 3233 3234 3234 int numberofvertices = femmodel_vertices->NumberOfVertices(); 3235 3235 int numberofelements = femmodel_elements->NumberOfElements(); … … 3237 3237 IssmDouble* x = NULL; 3238 3238 IssmDouble* y = NULL; 3239 IssmDouble* z = NULL; 3239 IssmDouble* z = NULL; 3240 3240 int* elementslist = NULL; 3241 3241 int* elem_vertices = NULL; … … 3246 3246 /*Get vertices coordinates*/ 3247 3247 VertexCoordinatesx(&x,&y,&z,femmodel_vertices,false) ; 3248 3248 3249 3249 /*Get element vertices*/ 3250 3250 elem_vertices = xNew<int>(elementswidth); … … 3261 3261 vid3->SetValue(element->sid,elem_vertices[2],INS_VAL); 3262 3262 } 3263 3263 3264 3264 /*Assemble*/ 3265 3265 vid1->Assemble(); … … 3271 3271 id2 = vid2->ToMPISerial(); 3272 3272 id3 = vid3->ToMPISerial(); 3273 3273 3274 3274 /*Construct elements list*/ 3275 3275 elementslist=xNew<int>(numberofelements*elementswidth); … … 3280 3280 elementslist[elementswidth*i+2] = reCast<int>(id3[i])+1; //InterpMesh wants Matlab indexing 3281 3281 } 3282 3282 3283 3283 /*Assign pointers*/ 3284 3284 *px = x; … … 3301 3301 if(!femmodel_vertices) _error_("GetMesh: vertices are NULL."); 3302 3302 if(!femmodel_elements) _error_("GetMesh: elements are NULL."); 3303 3303 3304 3304 int numberofvertices = femmodel_vertices->Size(); //number of vertices of this partition 3305 3305 int numbertotalofvertices = femmodel_vertices->NumberOfVertices(); //number total of vertices (entire mesh) … … 3308 3308 IssmDouble* x = NULL; 3309 3309 IssmDouble* y = NULL; 3310 IssmDouble* z = NULL; 3310 IssmDouble* z = NULL; 3311 3311 int* elementslist = NULL; 3312 3312 int* sidtoindex = NULL; 3313 3313 int* elem_vertices = NULL; 3314 3314 3315 3315 /*Get vertices coordinates of this partition*/ 3316 3316 sidtoindex = xNewZeroInit<int>(numbertotalofvertices);//entire mesh, all vertices … … 3318 3318 y = xNew<IssmDouble>(numberofvertices);//just this partitio; 3319 3319 z = xNew<IssmDouble>(numberofvertices);//just this partitio; 3320 3320 3321 3321 /*Go through in this partition (vertices)*/ 3322 3322 for(int i=0;i<numberofvertices;i++){//just this partition 3323 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i); 3323 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i); 3324 3324 /*Attention: no spherical coordinates*/ 3325 3325 x[i]=vertex->GetX(); … … 3334 3334 elementslist = xNew<int>(numberofelements*elementswidth); 3335 3335 if(numberofelements*elementswidth<0) _error_("numberofelements negative."); 3336 3336 3337 3337 for(int i=0;i<numberofelements;i++){//just this partition 3338 3338 Element* element=xDynamicCast<Element*>(femmodel_elements->GetObjectByOffset(i)); … … 3341 3341 elementslist[elementswidth*i+1] = sidtoindex[elem_vertices[1]]+1; //InterpMesh wants Matlab indexing 3342 3342 elementslist[elementswidth*i+2] = sidtoindex[elem_vertices[2]]+1; //InterpMesh wants Matlab indexing 3343 } 3344 3343 } 3344 3345 3345 /*Assign pointers*/ 3346 3346 *px = x; … … 3348 3348 *pz = z; 3349 3349 *pelementslist = elementslist; //Matlab indexing. InterMesh uses this type. 3350 *psidtoindex = sidtoindex; //it is ncessary to insert inputs 3350 *psidtoindex = sidtoindex; //it is ncessary to insert inputs 3351 3351 3352 3352 /*Cleanup*/ … … 3359 3359 /*OTHERS CONSTRAINTS MUST BE IMPLEMENTED*/ 3360 3360 if(analysis_enum!=StressbalanceAnalysisEnum) return; 3361 3361 3362 3362 int numberofnodes_analysistype= this->nodes->NumberOfNodes(analysis_enum); 3363 int dofpernode = 2; //vx and vy 3363 int dofpernode = 2; //vx and vy 3364 3364 int numberofcols = dofpernode*2; //to keep dofs and flags in the vspc vector 3365 3365 int numberofvertices = this->vertices->NumberOfVertices(); //global, entire old mesh … … 3385 3385 newy=xNew<IssmDouble>(newnumberofvertices);//just the new partition 3386 3386 for(int i=0;i<newnumberofvertices;i++){//just the new partition 3387 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i); 3387 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i); 3388 3388 /*Attention: no spherical coordinates*/ 3389 3389 newx[i]=vertex->GetX(); … … 3393 3393 /*Get spcvx and spcvy of old mesh*/ 3394 3394 for(int i=0;i<this->constraints->Size();i++){ 3395 3395 3396 3396 Constraint* constraint=(Constraint*)constraints->GetObjectByOffset(i); 3397 3397 if(!constraint->InAnalysis(analysis_enum)) _error_("AMR create constraints for "<<EnumToStringx(analysis_enum)<<" not supported yet!\n"); … … 3400 3400 int dof = spcstatic->GetDof(); 3401 3401 int node = spcstatic->GetNodeId(); 3402 IssmDouble spcvalue = spcstatic->GetValue(); 3402 IssmDouble spcvalue = spcstatic->GetValue(); 3403 3403 int nodeindex = node-1; 3404 3404 3405 3405 /*vx and vx flag insertion*/ 3406 3406 if(dof==0) {//vx 3407 3407 vspc->SetValue(nodeindex*numberofcols,spcvalue,INS_VAL); //vx 3408 3408 vspc->SetValue(nodeindex*numberofcols+dofpernode,1,INS_VAL);//vxflag 3409 } 3409 } 3410 3410 /*vy and vy flag insertion*/ 3411 3411 if(dof==1){//vy … … 3423 3423 spc,numberofvertices,numberofcols, 3424 3424 newx,newy,newnumberofvertices,NULL); 3425 3425 3426 3426 /*Now, insert the interpolated constraints in the data set (constraints)*/ 3427 3427 count=0; … … 3440 3440 /*spcvy*/ 3441 3441 if(!xIsNan<IssmDouble>(newspc[i*numberofcols+1]) && newspc[i*numberofcols+dofpernode+1]>(1-eps) ){ 3442 newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum)); 3442 newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum)); 3443 3443 //add count'th spc, on node i+1, setting dof 1 to vx. 3444 3444 count++; … … 3497 3497 bool *my_elements = NULL; 3498 3498 int *my_vertices = NULL; 3499 3500 _assert_(newnumberofvertices>0); 3501 _assert_(newnumberofelements>0); 3499 3500 _assert_(newnumberofvertices>0); 3501 _assert_(newnumberofelements>0); 3502 3502 epart=xNew<int>(newnumberofelements); 3503 3503 npart=xNew<int>(newnumberofvertices); 3504 3504 index=xNew<int>(elementswidth*newnumberofelements); 3505 3505 3506 3506 for (int i=0;i<newnumberofelements;i++){ 3507 3507 for (int j=0;j<elementswidth;j++){ … … 3523 3523 for (int i=0;i<newnumberofvertices;i++) npart[i]=0; 3524 3524 } 3525 else _error_("At least one processor is required"); 3525 else _error_("At least one processor is required"); 3526 3526 3527 3527 my_vertices=xNew<int>(newnumberofvertices); … … 3533 3533 for(int i=0;i<newnumberofelements;i++){ 3534 3534 /*!All elements have been partitioned above, only deal with elements for this cpu: */ 3535 if(my_rank==epart[i]){ 3535 if(my_rank==epart[i]){ 3536 3536 my_elements[i]=true; 3537 /*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use 3538 *the element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing) 3539 into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices 3537 /*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use 3538 *the element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing) 3539 into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices 3540 3540 will hold which vertices belong to this partition*/ 3541 3541 for(int j=0;j<elementswidth;j++){ 3542 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 3542 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 3543 3543 my_vertices[newelementslist[elementswidth*i+j]-1]=1;//newelementslist is in Matlab indexing 3544 3544 } … … 3552 3552 /*Free ressources:*/ 3553 3553 xDelete<int>(epart); 3554 xDelete<int>(npart); 3554 xDelete<int>(npart); 3555 3555 xDelete<int>(index); 3556 3556 } 3557 3557 /*}}}*/ 3558 3558 void FemModel::SmoothedDeviatoricStressTensor(IssmDouble** ptauxx,IssmDouble** ptauyy,IssmDouble** ptauxy){/*{{{*/ 3559 3559 3560 3560 int elementswidth = this->GetElementsWidth();//just 2D mesh, tria elements 3561 3561 int numberofvertices = this->vertices->NumberOfVertices(); 3562 3562 IssmDouble weight = 0.; 3563 IssmDouble* tauxx = NULL; 3564 IssmDouble* tauyy = NULL; 3565 IssmDouble* tauxy = NULL; 3563 IssmDouble* tauxx = NULL; 3564 IssmDouble* tauyy = NULL; 3565 IssmDouble* tauxy = NULL; 3566 3566 IssmDouble* totalweight = NULL; 3567 3567 IssmDouble* deviatoricstressxx = xNew<IssmDouble>(elementswidth); … … 3573 3573 Vector<IssmDouble>* vectauxy = new Vector<IssmDouble>(numberofvertices); 3574 3574 Vector<IssmDouble>* vectotalweight = new Vector<IssmDouble>(numberofvertices); 3575 3575 3576 3576 /*Update the Deviatoric Stress tensor over the elements*/ 3577 3577 this->DeviatoricStressx(); 3578 3578 3579 3579 /*Calculate the Smoothed Deviatoric Stress tensor*/ 3580 3580 for(int i=0;i<this->elements->Size();i++){ … … 3621 3621 /*Divide for the total weight*/ 3622 3622 for(int i=0;i<numberofvertices;i++){ 3623 _assert_(totalweight[i]>0); 3623 _assert_(totalweight[i]>0); 3624 3624 tauxx[i] = tauxx[i]/totalweight[i]; 3625 3625 tauyy[i] = tauyy[i]/totalweight[i]; … … 3646 3646 void FemModel::ZZErrorEstimator(IssmDouble** pelementerror){/*{{{*/ 3647 3647 3648 /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 3648 /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 3649 3649 * Ref.: Zienkiewicz and Zhu, A Simple Error Estimator and Adaptive Procedure for Practical Engineering Analysis, Int. J. Numer. Meth. Eng, 1987*/ 3650 3650 … … 3666 3666 /*Get smoothed deviatoric stress tensor*/ 3667 3667 this->SmoothedDeviatoricStressTensor(&smoothedtauxx,&smoothedtauyy,&smoothedtauxy); 3668 3668 3669 3669 /*Integrate the error over elements*/ 3670 3670 for(int i=0;i<this->elements->Size();i++){ … … 3674 3674 element->GetInputListOnVertices(tauxy,DeviatoricStressxyEnum); 3675 3675 element->GetVerticesSidList(elem_vertices); 3676 3676 3677 3677 /*Integrate*/ 3678 3678 element->GetVerticesCoordinates(&xyz_list); … … 3689 3689 ftxy+=(tauxy[n]-smoothedtauxy[elem_vertices[n]])*basis[n]; 3690 3690 } 3691 error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2 3692 } 3693 /*Set the error in the global vector*/ 3691 error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2 3692 } 3693 /*Set the error in the global vector*/ 3694 3694 sid=element->Sid(); 3695 3695 error = sqrt(error);//sqrt(e^2) … … 3705 3705 /*Serialize and set output*/ 3706 3706 (*pelementerror)=velementerror->ToMPISerial(); 3707 3707 3708 3708 /*Cleanup*/ 3709 3709 xDelete<IssmDouble>(smoothedtauxx); … … 3749 3749 Tria* triaelement = xDynamicCast<Tria*>(element); 3750 3750 weight = triaelement->GetArea();//the tria area is a choice for the weight 3751 3751 3752 3752 /*dH/dx*/ 3753 3753 vecdHdx->SetValue(elem_vertices[0],weight*GradH[0],ADD_VAL); … … 3817 3817 /*Get smoothed deviatoric stress tensor*/ 3818 3818 this->SmoothedGradThickness(&smoothed_dHdx,&smoothed_dHdy); 3819 3819 3820 3820 /*Integrate the error over elements*/ 3821 3821 for(int i=0;i<this->elements->Size();i++){ … … 3903 3903 IssmDouble* x = NULL; 3904 3904 IssmDouble* y = NULL; 3905 IssmDouble* z = NULL; 3905 IssmDouble* z = NULL; 3906 3906 IssmDouble* xyz_list = NULL; 3907 3907 IssmDouble x1,y1,x2,y2,x3,y3; … … 3912 3912 //element->GetVerticesSidList(elem_vertices); 3913 3913 int sid = element->Sid(); 3914 element->GetVerticesCoordinates(&xyz_list); 3914 element->GetVerticesCoordinates(&xyz_list); 3915 3915 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 3916 3916 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 3945 3945 _error_("level set type not implemented yet!"); 3946 3946 } 3947 3947 3948 3948 /*Outputs*/ 3949 3949 IssmDouble* zerolevelset_points = NULL; 3950 3950 int npoints = 0; 3951 3951 3952 3952 /*Intermediaries*/ 3953 3953 int elementswidth = this->GetElementsWidth(); … … 3962 3962 int count,sid; 3963 3963 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 3964 3964 3965 3965 /*Use the element center coordinate if level set is zero (grounding line or ice front), otherwise set NAN*/ 3966 3966 for(int i=0;i<this->elements->Size();i++){ … … 3969 3969 element->GetVerticesSidList(elem_vertices); 3970 3970 sid= element->Sid(); 3971 element->GetVerticesCoordinates(&xyz_list); 3971 element->GetVerticesCoordinates(&xyz_list); 3972 3972 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 3973 3973 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; 3974 3974 x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1]; 3975 3975 xc = NAN; 3976 yc = NAN; 3976 yc = NAN; 3977 3977 Tria* tria = xDynamicCast<Tria*>(element); 3978 3978 if(tria->IsIceInElement()){/*verify if there is ice in the element*/ 3979 if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 3979 if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 3980 3980 abs(levelset[0]*levelset[1])<DBL_EPSILON || abs(levelset[0]*levelset[2])<DBL_EPSILON) { 3981 3981 xc=(x1+x2+x3)/3.; … … 4007 4007 } 4008 4008 } 4009 4009 4010 4010 /*Assign outputs*/ 4011 4011 numberofpoints = npoints; … … 4047 4047 responses_pointer=d_responses; 4048 4048 4049 //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 4049 //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 4050 4050 //because we don't know the d_responses descriptors (the scaled ones) we can't key off them, so we will key off the responses_descriptors: */ 4051 4051 … … 4140 4140 4141 4141 int ns,nsmax; 4142 4142 4143 4143 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4144 4144 ns = elements->Size(); 4145 4145 4146 4146 /*Figure out max of ns: */ 4147 4147 ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); … … 4162 4162 } 4163 4163 } 4164 4164 4165 4165 /*One last time: */ 4166 4166 pUp->Assemble(); … … 4181 4181 4182 4182 int ns,nsmax; 4183 4183 4184 4184 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4185 4185 ns = elements->Size(); 4186 4187 /*First, figure out the surface area of Earth: */ 4186 4187 /*First, figure out the surface area of Earth: */ 4188 4188 for(int i=0;i<ns;i++){ 4189 4189 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4209 4209 } 4210 4210 } 4211 4211 4212 4212 /*One last time: */ 4213 4213 pUp->Assemble(); … … 4226 4226 #endif 4227 4227 #ifdef _HAVE_SEALEVELRISE_ 4228 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* p Sgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius) { /*{{{*/4228 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pRSLgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop) { /*{{{*/ 4229 4229 4230 4230 /*serialized vectors:*/ … … 4262 4262 if(i<ns){ 4263 4263 4264 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% ");4264 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4265 4265 4266 4266 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4267 element->SealevelriseEustatic(p Sgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);4267 element->SealevelriseEustatic(pRSLgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea); 4268 4268 eustatic_cpu+=eustatic_cpu_e; 4269 4269 } 4270 if(i% 100==0)pSgi->Assemble();4270 if(i%loop==0)pRSLgi->Assemble(); 4271 4271 } 4272 4272 if(VerboseConvergence())_printf0_("\n"); 4273 4273 4274 4274 /*One last time: */ 4275 p Sgi->Assemble();4275 pRSLgi->Assemble(); 4276 4276 4277 4277 /*Sum all eustatic components from all cpus:*/ … … 4285 4285 } 4286 4286 /*}}}*/ 4287 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* p Sgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution){/*{{{*/4287 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pRSLgo, Vector<IssmDouble>* pRSLg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution,int loop){/*{{{*/ 4288 4288 4289 4289 /*serialized vectors:*/ 4290 IssmDouble* Sg_old=NULL;4291 4290 IssmDouble* RSLg_old=NULL; 4291 4292 4292 IssmDouble eartharea=0; 4293 4293 IssmDouble eartharea_cpu=0; 4294 4294 4295 4295 int ns,nsmax; 4296 4296 4297 4297 /*Serialize vectors from previous iteration:*/ 4298 Sg_old=pSg_old->ToMPISerial();4298 RSLg_old=pRSLg_old->ToMPISerial(); 4299 4299 4300 4300 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ … … 4306 4306 eartharea_cpu += element->GetAreaSpherical(); 4307 4307 } 4308 4308 4309 4309 ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4310 4310 ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); … … 4317 4317 for(int i=0;i<nsmax;i++){ 4318 4318 if(i<ns){ 4319 if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf _("\r" << "convolution progress: " << (double)i/(double)ns*100 << "% ");4319 if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4320 4320 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4321 element->SealevelriseNonEustatic(p Sgo,Sg_old,latitude,longitude,radius,eartharea);4322 } 4323 if(i% 100==0)pSgo->Assemble();4324 } 4325 if(verboseconvolution)if(VerboseConvergence())_printf _("\n");4326 4321 element->SealevelriseNonEustatic(pRSLgo,RSLg_old,latitude,longitude,radius,eartharea); 4322 } 4323 if(i%loop==0)pRSLgo->Assemble(); 4324 } 4325 if(verboseconvolution)if(VerboseConvergence())_printf0_("\n"); 4326 4327 4327 /*Free ressources:*/ 4328 xDelete<IssmDouble>( Sg_old);4329 } 4330 /*}}}*/ 4331 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* p Sgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/4328 xDelete<IssmDouble>(RSLg_old); 4329 } 4330 /*}}}*/ 4331 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/ 4332 4332 4333 4333 /*serialized vectors:*/ 4334 IssmDouble* Sg_old=NULL;4334 IssmDouble* RSLg_old=NULL; 4335 4335 IssmDouble eartharea=0; 4336 4336 IssmDouble eartharea_cpu=0; … … 4341 4341 4342 4342 /*Serialize vectors from previous iteration:*/ 4343 Sg_old=pSg_old->ToMPISerial();4343 RSLg_old=pRSLg_old->ToMPISerial(); 4344 4344 4345 4345 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ … … 4355 4355 for(int i=0;i<elements->Size();i++){ 4356 4356 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4357 element->SealevelriseMomentOfInertia(&moi_list[0], Sg_old,eartharea);4357 element->SealevelriseMomentOfInertia(&moi_list[0],RSLg_old,eartharea); 4358 4358 moi_list_cpu[0] += moi_list[0]; 4359 4359 moi_list_cpu[1] += moi_list[1]; … … 4399 4399 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi))); 4400 4400 4401 p Sgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times4401 pRSLgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times 4402 4402 } 4403 4403 4404 4404 /*Assemble mesh velocity*/ 4405 p Sgo_rot->Assemble();4405 pRSLgo_rot->Assemble(); 4406 4406 4407 4407 /*Assign output pointers:*/ 4408 *pIxz=moi_list[0];4409 *pIyz=moi_list[1];4410 *pIzz=moi_list[2];4408 if(pIxz)*pIxz=moi_list[0]; 4409 if(pIyz)*pIyz=moi_list[1]; 4410 if(pIzz)*pIzz=moi_list[2]; 4411 4411 4412 4412 /*Free ressources:*/ 4413 xDelete<IssmDouble>(Sg_old); 4414 4415 } 4416 /*}}}*/ 4417 void FemModel::SealevelriseGeodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/ 4413 xDelete<IssmDouble>(RSLg_old); 4414 4415 4416 } 4417 /*}}}*/ 4418 void FemModel::SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pRSLg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz,int loop,int horiz){/*{{{*/ 4418 4419 4419 4420 /*serialized vectors:*/ 4420 IssmDouble* Sg=NULL;4421 4421 IssmDouble* RSLg=NULL; 4422 4422 4423 IssmDouble eartharea=0; 4423 4424 IssmDouble eartharea_cpu=0; 4424 4425 4425 4426 int ns,nsmax; 4426 4427 4427 4428 /*Serialize vectors from previous iteration:*/ 4428 Sg=pSg->ToMPISerial();4429 RSLg=pRSLg->ToMPISerial(); 4429 4430 4430 4431 /*Go through elements, and add contribution from each element to the deflection vector wg:*/ 4431 4432 ns = elements->Size(); 4432 4433 4433 4434 /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */ 4434 4435 for(int i=0;i<ns;i++){ … … 4446 4447 for(int i=0;i<nsmax;i++){ 4447 4448 if(i<ns){ 4449 if(VerboseConvergence())if(i%100==0)_printf0_("\r" << " convolution progress: " << (double)i/(double)ns*100 << "% "); 4448 4450 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4449 element->SealevelriseGeodetic(pUp,pNorth,pEast, Sg,latitude,longitude,radius,xx,yy,zz,eartharea);4450 } 4451 if(i% 100==0){4451 element->SealevelriseGeodetic(pUp,pNorth,pEast,RSLg,latitude,longitude,radius,xx,yy,zz,eartharea,horiz); 4452 } 4453 if(i%loop==0){ 4452 4454 pUp->Assemble(); 4453 pNorth->Assemble(); 4454 pEast->Assemble(); 4455 } 4456 } 4457 4455 if (horiz){ 4456 pNorth->Assemble(); 4457 pEast->Assemble(); 4458 } 4459 } 4460 } 4461 4458 4462 /*One last time: */ 4459 4463 pUp->Assemble(); 4460 pNorth->Assemble(); 4461 pEast->Assemble(); 4464 if(horiz){ 4465 pNorth->Assemble(); 4466 pEast->Assemble(); 4467 } 4468 if(VerboseConvergence())_printf0_("\n"); 4462 4469 4463 4470 /*Free ressources:*/ 4464 xDelete<IssmDouble>(Sg); 4465 xDelete<IssmDouble>(latitude); 4466 xDelete<IssmDouble>(longitude); 4467 xDelete<IssmDouble>(radius); 4468 xDelete<IssmDouble>(xx); 4469 xDelete<IssmDouble>(yy); 4470 xDelete<IssmDouble>(zz); 4471 } 4472 /*}}}*/ 4473 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* Sg) { /*{{{*/ 4474 4475 IssmDouble* Sg_serial=NULL; 4471 xDelete<IssmDouble>(RSLg); 4472 } 4473 /*}}}*/ 4474 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* RSLg) { /*{{{*/ 4475 4476 IssmDouble* RSLg_serial=NULL; 4476 4477 IssmDouble oceanvalue,oceanvalue_cpu; 4477 4478 IssmDouble oceanarea,oceanarea_cpu; 4478 4479 4479 4480 /*Serialize vectors from previous iteration:*/ 4480 Sg_serial=Sg->ToMPISerial();4481 RSLg_serial=RSLg->ToMPISerial(); 4481 4482 4482 4483 /*Initialize:*/ … … 4488 4489 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 4489 4490 oceanarea_cpu += element->OceanArea(); 4490 oceanvalue_cpu += element->OceanAverage( Sg_serial);4491 oceanvalue_cpu += element->OceanAverage(RSLg_serial); 4491 4492 } 4492 4493 ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4493 4494 ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4494 4495 4495 4496 ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4496 4497 ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4497 4498 4498 4499 /*Free ressources:*/ 4499 xDelete<IssmDouble>( Sg_serial);4500 4500 xDelete<IssmDouble>(RSLg_serial); 4501 4501 4502 return oceanvalue/oceanarea; 4502 4503 } … … 4514 4515 int* eplzigzag_counter = NULL; 4515 4516 int eplflip_lock; 4516 4517 4517 4518 HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis(); 4518 4519 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis(); … … 4521 4522 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4522 4523 recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum)); 4523 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4524 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4524 this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 4525 this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 4525 4526 GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum); 4526 4527 4527 4528 for (int i=0;i<elements->Size();i++){ 4528 4529 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); … … 4542 4543 /*Assemble and serialize*/ 4543 4544 mask->Assemble(); 4544 serial_mask=mask->ToMPISerial(); 4545 4545 serial_mask=mask->ToMPISerial(); 4546 4546 4547 xDelete<int>(eplzigzag_counter); 4547 4548 xDelete<IssmDouble>(serial_rec); … … 4585 4586 int sum_counter; 4586 4587 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4587 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4588 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4588 4589 counter=sum_counter; 4589 4590 *pEplcount = counter; 4590 4591 if(VerboseSolution()) _printf0_(" Number of active nodes in EPL layer: "<< counter <<"\n"); 4591 4592 /*Update dof indexings*/4593 this->UpdateConstraintsx();4594 4595 }4596 /*}}}*/4597 void FemModel::HydrologyIDSupdateDomainx(IssmDouble* pIDScount){ /*{{{*/4598 4599 bool isthermal;4600 Vector<IssmDouble>* mask = NULL;4601 Vector<IssmDouble>* active = NULL;4602 IssmDouble* serial_mask = NULL;4603 IssmDouble* serial_active = NULL;4604 4605 HydrologyDCInefficientAnalysis* inefanalysis = new HydrologyDCInefficientAnalysis();4606 parameters->FindParam(&isthermal,TransientIsthermalEnum);4607 4608 /*When solving a thermal model we update the thawed nodes*/4609 if(isthermal){4610 /*Step 1: update mask, the mask correspond to thawed nodes (that have a meltingrate)*/4611 mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum));4612 4613 for (int i=0;i<elements->Size();i++){4614 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));4615 inefanalysis->HydrologyIDSGetMask(mask,element);4616 }4617 /*Assemble and serialize*/4618 mask->Assemble();4619 serial_mask=mask->ToMPISerial();4620 delete mask;4621 }4622 /*for other cases we just grab the mask from the initialisation value*/4623 else{4624 GetVectorFromInputsx(&serial_mask,this,HydrologydcMaskThawedNodeEnum,NodeSIdEnum);4625 }4626 /*Update Mask and elementize*/4627 InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskThawedNodeEnum,NodeSIdEnum);4628 xDelete<IssmDouble>(serial_mask);4629 inefanalysis->ElementizeIdsMask(this);4630 4631 /*get node mask coherent with element mask*/4632 active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum));4633 for (int i=0;i<elements->Size();i++){4634 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));4635 inefanalysis->HydrologyIdsGetActive(active,element);4636 }4637 4638 /*Assemble and serialize*/4639 active->Assemble();4640 serial_active=active->ToMPISerial();4641 delete active;4642 4643 /*Update node activation accordingly*/4644 int counter =0;4645 for (int i=0;i<nodes->Size();i++){4646 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));4647 if(node->InAnalysis(HydrologyDCInefficientAnalysisEnum)){4648 if(serial_active[node->Sid()]==1.){4649 node->Activate();4650 if(!node->IsClone()) counter++;4651 }4652 else{4653 node->Deactivate();4654 }4655 }4656 }4657 4658 xDelete<IssmDouble>(serial_active);4659 delete inefanalysis;4660 int sum_counter;4661 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );4662 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());4663 counter=sum_counter;4664 *pIDScount = counter;4665 if(VerboseSolution()) _printf0_(" Number of active nodes in IDS layer: "<< counter <<"\n");4666 4592 4667 4593 /*Update dof indexings*/ … … 4706 4632 int sum_counter; 4707 4633 ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 4708 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4634 ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 4709 4635 counter=sum_counter; 4710 4636 *pL2count = counter; … … 4791 4717 } 4792 4718 /*}}}*/ 4793 #ifdef _HAVE_JAVASCRIPT_ 4719 #ifdef _HAVE_JAVASCRIPT_ 4794 4720 FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/ 4795 4721 /*configuration: */ … … 4806 4732 /*From command line arguments, retrieve different filenames needed to create the FemModel: */ 4807 4733 solution_type=StringToEnumx(solution); 4808 4734 4809 4735 /*Create femmodel from input files: */ 4810 4736 profiler->Start(MPROCESSOR); 4811 4737 this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL); 4812 4738 profiler->Stop(MPROCESSOR); 4813 4739 4814 4740 /*Save communicator in the parameters dataset: */ 4815 4741 this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum)); … … 4826 4752 size_t* poutputbuffersize; 4827 4753 4828 4754 4829 4755 /*Before we delete the profiler, report statistics for this run: */ 4830 4756 profiler->Stop(TOTAL); //final tagging … … 4839 4765 ); 4840 4766 _printf0_("\n"); 4841 4767 4842 4768 /*Before we close the output file, recover the buffer and size:*/ 4843 4769 outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum)); … … 4879 4805 4880 4806 /*Open output file once for all and add output file descriptor to parameters*/ 4881 output_fid=open_memstream(&outputbuffer,&outputsize); 4807 output_fid=open_memstream(&outputbuffer,&outputsize); 4882 4808 if(output_fid==NULL)_error_("could not initialize output stream"); 4883 4809 this->parameters->SetParam(output_fid,OutputFilePointerEnum); … … 4887 4813 }/*}}}*/ 4888 4814 #endif 4815 4889 4816 4890 4817 #if defined(_HAVE_BAMG_) && !defined(_HAVE_ADOLC_) … … 4920 4847 /*Initialize hmaxvertices with NAN*/ 4921 4848 hmaxvertices_serial=xNew<IssmDouble>(numberofvertices); 4922 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4849 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 4923 4850 /*Fill hmaxvertices*/ 4924 4851 if(this->amrbamg->groundingline_distance>0) this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskGroundediceLevelsetEnum); … … 4927 4854 if(this->amrbamg->deviatoricerror_threshold>0) this->GethmaxVerticesFromEstimators(hmaxvertices_serial,DeviatoricStressErrorEstimatorEnum); 4928 4855 } 4929 4856 4930 4857 if(my_rank==0){ 4931 4858 this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); … … 4947 4874 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 4948 4875 } 4949 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4950 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4951 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4952 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4876 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4877 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4878 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 4879 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 4953 4880 4954 4881 /*Assign output pointers*/ … … 4983 4910 /*Create bamg data structures for bamg*/ 4984 4911 this->amrbamg = new AmrBamg(); 4985 4912 4986 4913 /*Get amr parameters*/ 4987 4914 this->parameters->FindParam(&hmin,AmrHminEnum); … … 5007 4934 5008 4935 /*Re-create original mesh and put it in bamg structure (only cpu 0)*/ 5009 if(my_rank==0){ 4936 if(my_rank==0){ 5010 4937 this->amrbamg->Initialize(elements,x,y,numberofvertices,numberofelements); 5011 4938 } … … 5021 4948 5022 4949 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 5023 4950 5024 4951 /*Intermediaries*/ 5025 4952 int numberofvertices = this->vertices->NumberOfVertices(); … … 5028 4955 5029 4956 switch(levelset_type){ 5030 case MaskGroundediceLevelsetEnum: 4957 case MaskGroundediceLevelsetEnum: 5031 4958 threshold = this->amrbamg->groundingline_distance; 5032 4959 resolution = this->amrbamg->groundingline_resolution; … … 5042 4969 this->GetVerticeDistanceToZeroLevelSet(&verticedistance,levelset_type); 5043 4970 if(!verticedistance) _error_("verticedistance is NULL!\n"); 5044 4971 5045 4972 /*Fill hmaxVertices*/ 5046 4973 for(int i=0;i<numberofvertices;i++){ … … 5056 4983 /*}}}*/ 5057 4984 void FemModel::GethmaxVerticesFromEstimators(IssmDouble* hmaxvertices,int errorestimator_type){/*{{{*/ 5058 4985 5059 4986 if(!hmaxvertices) _error_("hmaxvertices is NULL!\n"); 5060 4987 … … 5064 4991 int numberofvertices = this->vertices->NumberOfVertices(); 5065 4992 IssmDouble* maxlength = xNew<IssmDouble>(numberofelements); 5066 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 4993 IssmDouble* error_vertices = xNewZeroInit<IssmDouble>(numberofvertices); 5067 4994 IssmDouble* error_elements = NULL; 5068 4995 IssmDouble* x = NULL; … … 5077 5004 /*Fill variables*/ 5078 5005 switch(errorestimator_type){ 5079 case ThicknessErrorEstimatorEnum: 5006 case ThicknessErrorEstimatorEnum: 5080 5007 threshold = this->amrbamg->thicknesserror_threshold; 5081 5008 groupthreshold = this->amrbamg->thicknesserror_groupthreshold; … … 5102 5029 case ThicknessErrorEstimatorEnum: this->amrbamg->thicknesserror_maximum = maxerror;break; 5103 5030 case DeviatoricStressErrorEstimatorEnum: this->amrbamg->deviatoricerror_maximum = maxerror;break; 5104 } 5031 } 5105 5032 } 5106 5033 5107 5034 /*Get mesh*/ 5108 5035 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&index); 5109 5036 5110 5037 /*Fill error_vertices (this is the sum of all elements connected to the vertex)*/ 5111 5038 for(int i=0;i<numberofelements;i++){ … … 5121 5048 error_vertices[v2]+=error_elements[i]; 5122 5049 error_vertices[v3]+=error_elements[i]; 5123 } 5050 } 5124 5051 5125 5052 /*Fill hmaxvertices with the criteria*/ … … 5135 5062 } 5136 5063 } 5137 /*Now, fill the hmaxvertices if requested*/ 5064 /*Now, fill the hmaxvertices if requested*/ 5138 5065 if(refine){ 5139 5066 for(int j=0;j<elementswidth;j++){ … … 5165 5092 /*Output*/ 5166 5093 IssmDouble* verticedistance; 5167 5094 5168 5095 /*Intermediaries*/ 5169 5096 int numberofvertices = this->vertices->NumberOfVertices(); … … 5177 5104 /*Get vertices coordinates*/ 5178 5105 VertexCoordinatesx(&x,&y,&z,this->vertices,false) ; 5179 5180 /*Get points which level set is zero (center of elements with zero level set)*/ 5106 5107 /*Get points which level set is zero (center of elements with zero level set)*/ 5181 5108 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5182 5109 … … 5187 5114 for(int j=0;j<numberofpoints;j++){ 5188 5115 distance=sqrt((x[i]-levelset_points[2*j])*(x[i]-levelset_points[2*j])+(y[i]-levelset_points[2*j+1])*(y[i]-levelset_points[2*j+1])); 5189 verticedistance[i]=min(distance,verticedistance[i]); 5190 } 5191 } 5116 verticedistance[i]=min(distance,verticedistance[i]); 5117 } 5118 } 5192 5119 5193 5120 /*Assign the pointer*/ … … 5223 5150 if(this->amr->groundingline_distance>0) this->GetElementDistanceToZeroLevelSet(&gl_distance,MaskGroundediceLevelsetEnum); 5224 5151 if(this->amr->icefront_distance>0) this->GetElementDistanceToZeroLevelSet(&if_distance,MaskIceLevelsetEnum); 5225 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5226 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5227 5152 if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror); 5153 if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror); 5154 5228 5155 if(my_rank==0){ 5229 5156 this->amr->ExecuteRefinement(gl_distance,if_distance,deviatoricerror,thicknesserror, 5230 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5157 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist); 5231 5158 newz=xNewZeroInit<IssmDouble>(newnumberofvertices); 5232 5159 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the ReMeshNeopz."); … … 5242 5169 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth()); 5243 5170 } 5244 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5245 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5246 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5247 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5248 5249 /*Assign the pointers*/ 5171 ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5172 ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5173 ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 5174 ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm()); 5175 5176 /*Assign the pointers*/ 5250 5177 (*pnewelementslist) = newelementslist; //Matlab indexing 5251 5178 (*pnewx) = newx; … … 5263 5190 /*}}}*/ 5264 5191 void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/ 5265 5192 5266 5193 /*Define variables*/ 5267 5194 int my_rank = IssmComm::GetRank(); … … 5272 5199 IssmDouble* z = NULL; 5273 5200 int* elements = NULL; 5274 5201 5275 5202 /*Initialize field as NULL for now*/ 5276 5203 this->amr = NULL; … … 5280 5207 this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements); 5281 5208 5282 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5209 /*Create initial mesh (coarse mesh) in neopz data structure*/ 5283 5210 /*Just CPU #0 should keep AMR object*/ 5284 5211 /*Initialize refinement pattern*/ 5285 5212 this->SetRefPatterns(); 5286 5213 this->amr = new AdaptiveMeshRefinement(); 5287 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5214 this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 5288 5215 /*Get amr parameters*/ 5289 5216 this->parameters->FindParam(&this->amr->level_max,AmrLevelMaxEnum); … … 5298 5225 this->parameters->FindParam(&this->amr->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum); 5299 5226 this->parameters->FindParam(&this->amr->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum); 5300 if(my_rank==0){ 5227 if(my_rank==0){ 5301 5228 this->amr->CreateInitialMesh(numberofvertices,numberofelements,x,y,elements); 5302 5229 } … … 5319 5246 /*Output*/ 5320 5247 IssmDouble* elementdistance; 5321 5248 5322 5249 /*Intermediaries*/ 5323 5250 int numberofelements = this->elements->NumberOfElements(); … … 5328 5255 IssmDouble xc,yc,x1,y1,x2,y2,x3,y3; 5329 5256 int numberofpoints; 5330 5331 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5257 5258 /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/ 5332 5259 this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type); 5333 5260 … … 5335 5262 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 5336 5263 int sid = element->Sid(); 5337 element->GetVerticesCoordinates(&xyz_list); 5264 element->GetVerticesCoordinates(&xyz_list); 5338 5265 x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1]; 5339 5266 x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1]; … … 5345 5272 for(int j=0;j<numberofpoints;j++){ 5346 5273 distance =sqrt((xc-levelset_points[2*j])*(xc-levelset_points[2*j])+(yc-levelset_points[2*j+1])*(yc-levelset_points[2*j+1])); 5347 mindistance=min(distance,mindistance); 5274 mindistance=min(distance,mindistance); 5348 5275 } 5349 5276 velementdistance->SetValue(sid,mindistance,INS_VAL); 5350 5277 xDelete<IssmDouble>(xyz_list); 5351 } 5278 } 5352 5279 5353 5280 /*Assemble*/ -
issm/trunk-jpl/src/c/classes/FemModel.h
r22898 r22955 135 135 #endif 136 136 #ifdef _HAVE_ESA_ 137 void EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pX, Vector<IssmDouble>* pY, IssmDouble* xx, IssmDouble* yy); 138 void EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz); 137 void EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pX, Vector<IssmDouble>* pY, IssmDouble* xx, IssmDouble* yy); 138 void EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz); 139 139 #endif 140 140 #ifdef _HAVE_SEALEVELRISE_ 141 void SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius );142 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution );143 void SealevelriseRotationalFeedback(Vector<IssmDouble>* p Sgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius);144 void Sealevelrise Geodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz);141 void SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop); 142 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution,int loop); 143 void SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius); 144 void SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz,int loop,int horiz); 145 145 IssmDouble SealevelriseOceanAverage(Vector<IssmDouble>* Sg); 146 146 #endif -
issm/trunk-jpl/src/c/classes/Materials/Matpar.h
r22105 r22955 118 118 void ViscosityBHO(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,IssmDouble eps_eff){_error_("not supported");}; 119 119 void ViscosityBSSA(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,IssmDouble eps_eff){_error_("not supported");}; 120 void ViscosityBFS(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not supported");}; 121 void ViscosityBHO(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){_error_("not supported");}; 122 void ViscosityBSSA(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){_error_("not supported");}; 120 123 /*}}}*/ 121 124 /*Numerics: {{{*/ -
issm/trunk-jpl/src/c/cores/cores.h
r22908 r22955 54 54 void damage_core(FemModel* femmodel); 55 55 void sealevelrise_core(FemModel* femmodel); 56 void geodetic_core(FemModel* femmodel); 57 void steric_core(FemModel* femmodel); 56 58 Vector<IssmDouble>* sealevelrise_core_eustatic(FemModel* femmodel); 57 Vector<IssmDouble>* sealevelrise_core_noneustatic(FemModel* femmodel,Vector<IssmDouble>* Sg_eustatic); 59 Vector<IssmDouble>* sealevelrise_core_noneustatic(FemModel* femmodel,Vector<IssmDouble>* RSLg_eustatic); 60 void sealevelrise_core_elastic(Vector<IssmDouble>** pU_radial, Vector<IssmDouble>** pU_north,Vector<IssmDouble>** pU_east,FemModel* femmodel,Vector<IssmDouble>* RSLg); 61 void sealevelrise_core_viscous(Vector<IssmDouble>** pU_gia,Vector<IssmDouble>** pN_gia,FemModel* femmodel,Vector<IssmDouble>* RSLg); 62 void sealevelrise_diagnostics(FemModel* femmodel,Vector<IssmDouble>* RSLg); 58 63 IssmDouble objectivefunction(IssmDouble search_scalar,FemModel* femmodel); 59 64 … … 68 73 void TransferForcing(FemModel* femmodel,int forcingenum); 69 74 void TransferSealevel(FemModel* femmodel,int forcingenum); 75 void EarthMassTransport(FemModel* femmodel); 76 void slrconvergence(bool* pconverged, Vector<IssmDouble>* RSLg,Vector<IssmDouble>* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs); 70 77 71 78 //solution configuration -
issm/trunk-jpl/src/c/cores/sealevelrise_core.cpp
r22817 r22955 10 10 #include "../solutionsequences/solutionsequences.h" 11 11 12 /*cores:*/ 12 13 void sealevelrise_core(FemModel* femmodel){ /*{{{*/ 13 14 14 Vector<IssmDouble> *Sg = NULL; 15 Vector<IssmDouble> *Sg_absolute = NULL; 16 Vector<IssmDouble> *Sg_eustatic = NULL; 17 Vector<IssmDouble> *slr_initial = NULL; 15 16 /*Parameters, variables:*/ 17 bool save_results; 18 bool isslr=0; 19 int solution_type; 20 21 /*Retrieve parameters:*/ 22 femmodel->parameters->FindParam(&isslr,TransientIsslrEnum); 23 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 24 femmodel->parameters->FindParam(&save_results,SaveResultsEnum); 25 26 /*in case we are running SealevelriseSolutionEnum, then bypass transient settings:*/ 27 if(solution_type==SealevelriseSolutionEnum)isslr=1; 28 29 /*Should we be here?:*/ 30 if(!isslr)return; 31 32 /*Verbose: */ 33 if(VerboseSolution()) _printf0_(" computing sea level rise\n"); 34 35 /*set SLR configuration: */ 36 femmodel->SetCurrentConfiguration(SealevelriseAnalysisEnum); 37 38 /*Run geodetic:*/ 39 geodetic_core(femmodel); 40 41 /*Run steric core for sure:*/ 42 steric_core(femmodel); 43 44 /*Save results: */ 45 if(save_results){ 46 int numoutputs = 0; 47 char **requested_outputs = NULL; 48 49 if(VerboseSolution()) _printf0_(" saving results\n"); 50 femmodel->parameters->FindParam(&requested_outputs,&numoutputs,SealevelriseRequestedOutputsEnum); 51 femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs); 52 if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);} 53 } 54 55 /*requested dependents: */ 56 if(solution_type==SealevelriseSolutionEnum)femmodel->RequestedDependentsx(); 57 } 58 /*}}}*/ 59 void geodetic_core(FemModel* femmodel){ /*{{{*/ 60 61 62 /*variables:*/ 63 Vector<IssmDouble> *RSLg = NULL; 64 Vector<IssmDouble> *RSLg_rate = NULL; 65 Vector<IssmDouble> *RSLg_eustatic = NULL; 66 Vector<IssmDouble> *U_esa = NULL; 67 Vector<IssmDouble> *U_esa_rate = NULL; 68 Vector<IssmDouble> *N_esa = NULL; 69 Vector<IssmDouble> *N_esa_rate = NULL; 70 Vector<IssmDouble> *U_north_esa = NULL; 71 Vector<IssmDouble> *U_east_esa = NULL; 72 Vector<IssmDouble> *N_gia= NULL; 73 Vector<IssmDouble> *U_gia= NULL; 74 Vector<IssmDouble> *N_gia_rate= NULL; 75 Vector<IssmDouble> *U_gia_rate= NULL; 76 77 /*parameters:*/ 78 bool iscoupler; 79 int solution_type; 80 int configuration_type; 81 int modelid,earthid; 82 bool istransientmasstransport; 83 int frequency,count; 84 int horiz; 85 int geodetic=0; 86 IssmDouble dt; 87 88 /*Should we even be here?:*/ 89 femmodel->parameters->FindParam(&geodetic,SealevelriseGeodeticEnum); if(!geodetic)return; 90 91 /*Verbose: */ 92 if(VerboseSolution()) _printf0_(" computing geodetic sea level rise\n"); 93 94 /*retrieve more parameters:*/ 95 femmodel->parameters->FindParam(&iscoupler,TransientIscouplerEnum); 96 femmodel->parameters->FindParam(&frequency,SealevelriseGeodeticRunFrequencyEnum); 97 femmodel->parameters->FindParam(&count,SealevelriseRunCountEnum); 98 femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 99 femmodel->parameters->FindParam(&horiz,SealevelriseHorizEnum); 100 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum); 101 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 102 103 if(iscoupler){ 104 femmodel->parameters->FindParam(&modelid,ModelIdEnum); 105 femmodel->parameters->FindParam(&earthid,EarthIdEnum); 106 femmodel->parameters->FindParam(&istransientmasstransport,TransientIsmasstransportEnum); 107 } 108 else{ 109 /* we are here, we are not running in a coupler, so we will indeed compute SLR, 110 * so make sure we are identified as being the Earth.:*/ 111 modelid=1; earthid=1; 112 /* in addition, if we are running solution_type SealevelriseSolutionEnum, make sure we 113 * run, irresepective of the time settings:*/ 114 count=frequency; 115 } 116 117 /*If we are running in coupled mode, the Earth model needs to run its own mass transport (if 118 * not already done by the mass trasnport module. For ice caps, they rely on the transient mass 119 * transport module exclusively:*/ 120 if(iscoupler) if(modelid==earthid) if(!istransientmasstransport) EarthMassTransport(femmodel); 121 122 /*increment counter, or call solution core if count==frequency:*/ 123 if (count<frequency){ 124 count++; femmodel->parameters->SetParam(count,SealevelriseRunCountEnum); 125 return; 126 } 127 128 /*call sea-level rise sub cores:*/ 129 if(iscoupler){ 130 /*transfer cumulated deltathickness forcing from ice caps to earth model: */ 131 TransferForcing(femmodel,SealevelriseCumDeltathicknessEnum); 132 133 /*we have accumulated thicknesses, dump them in deltathcikness: */ 134 if(modelid==earthid)InputDuplicatex(femmodel,SealevelriseCumDeltathicknessEnum,SealevelriseDeltathicknessEnum); 135 } 136 137 /*run cores:*/ 138 if(modelid==earthid){ 139 140 /*call eustatic core (generalized eustatic - Farrel and Clark, Eq 4, 1st, 3rd and 4rd terms on the RHS) */ 141 RSLg_eustatic=sealevelrise_core_eustatic(femmodel); 142 143 /*call non-eustatic core (ocean loading tems - 2nd and 5th terms on the RHS of Farrel and Clark) */ 144 RSLg=sealevelrise_core_noneustatic(femmodel,RSLg_eustatic); 145 146 /*compute other elastic geodetic signatures, such as components of 3-D crustal motion: */ 147 sealevelrise_core_elastic(&U_esa,&U_north_esa,&U_east_esa,femmodel,RSLg); 148 149 /*compute viscosus (GIA) geodetic signatures:*/ 150 sealevelrise_core_viscous(&U_gia,&N_gia,femmodel,RSLg); 151 152 /*compute sea-level rise (low-order spherical harmonics coefficients) diagnostics:*/ 153 sealevelrise_diagnostics(femmodel,RSLg); 154 155 /*recover N_esa = U_esa + RSLg:*/ 156 N_esa=U_esa->Duplicate(); U_esa->Copy(N_esa); N_esa->AXPY(RSLg,1); 157 158 /*transform these values into rates (as we only run this once each frequency turn:*/ 159 N_esa_rate=N_esa->Duplicate(); N_esa->Copy(N_esa_rate); N_esa_rate->Scale(1/(dt*frequency)); 160 U_esa_rate=U_esa->Duplicate(); U_esa->Copy(U_esa_rate); U_esa_rate->Scale(1/(dt*frequency)); 161 N_gia_rate=N_gia->Duplicate(); N_gia->Copy(N_gia_rate); N_gia_rate->Scale(1/(dt*frequency)); 162 U_gia_rate=U_gia->Duplicate(); U_gia->Copy(U_gia_rate); U_gia_rate->Scale(1/(dt*frequency)); 163 RSLg_rate=RSLg->Duplicate(); RSLg->Copy(RSLg_rate); RSLg_rate->Scale(1/(dt*frequency)); 164 165 /*get some results into elements:{{{*/ 166 InputUpdateFromVectorx(femmodel,U_esa_rate,SealevelUEsaRateEnum,VertexSIdEnum); 167 InputUpdateFromVectorx(femmodel,N_esa_rate,SealevelNEsaRateEnum,VertexSIdEnum); 168 InputUpdateFromVectorx(femmodel,U_gia_rate,SealevelUGiaRateEnum,VertexSIdEnum); 169 InputUpdateFromVectorx(femmodel,N_gia_rate,SealevelNGiaRateEnum,VertexSIdEnum); 170 InputUpdateFromVectorx(femmodel,RSLg_rate,SealevelRSLRateEnum,VertexSIdEnum); 171 InputUpdateFromVectorx(femmodel,U_esa,SealevelUEsaEnum,VertexSIdEnum); 172 InputUpdateFromVectorx(femmodel,N_esa,SealevelNEsaEnum,VertexSIdEnum); 173 InputUpdateFromVectorx(femmodel,U_gia,SealevelUGiaEnum,VertexSIdEnum); 174 InputUpdateFromVectorx(femmodel,N_gia,SealevelNGiaEnum,VertexSIdEnum); 175 InputUpdateFromVectorx(femmodel,RSLg,SealevelRSLEnum,VertexSIdEnum); 176 InputUpdateFromVectorx(femmodel,RSLg_eustatic,SealevelRSLEustaticEnum,VertexSIdEnum); 177 178 if (horiz){ 179 InputUpdateFromVectorx(femmodel,U_north_esa,SealevelUNorthEsaEnum,VertexSIdEnum); // north motion 180 InputUpdateFromVectorx(femmodel,U_east_esa,SealevelUEastEsaEnum,VertexSIdEnum); // east motion 181 } /*}}}*/ 182 } 183 184 185 if(iscoupler){ 186 /*transfer sea level back to ice caps:*/ 187 TransferSealevel(femmodel,SealevelNEsaRateEnum); 188 TransferSealevel(femmodel,SealevelNGiaRateEnum); 189 TransferSealevel(femmodel,SealevelUEsaRateEnum); 190 TransferSealevel(femmodel,SealevelUGiaRateEnum); 191 192 //reset cumdeltathickness to 0: 193 InputUpdateFromConstantx(femmodel,0.0,SealevelriseCumDeltathicknessEnum); 194 } 195 196 /*reset counter to 1:*/ 197 femmodel->parameters->SetParam(1,SealevelriseRunCountEnum); //reset counter. 198 199 /*free ressources:{{{*/ 200 delete RSLg; 201 delete RSLg_rate; 202 delete RSLg_eustatic; 203 delete U_esa; 204 delete U_esa_rate; 205 delete N_esa; 206 delete N_esa_rate; 207 208 if(horiz){ 209 delete U_north_esa; 210 delete U_east_esa; 211 } 212 delete N_gia; 213 delete U_gia; 214 delete N_gia_rate; 215 delete U_gia_rate; 216 /*}}}*/ 217 218 } 219 /*}}}*/ 220 void steric_core(FemModel* femmodel){ /*{{{*/ 221 222 /*variables:*/ 223 Vector<IssmDouble> *bedrock = NULL; 224 Vector<IssmDouble> *SL = NULL; 18 225 Vector<IssmDouble> *steric_rate_g = NULL; 19 Vector<IssmDouble> *U_radial = NULL; 20 Vector<IssmDouble> *U_north = NULL; 21 Vector<IssmDouble> *U_east = NULL; 22 bool save_results,isslr,iscoupler; 23 int configuration_type; 24 int solution_type; 25 int numoutputs = 0; 26 char **requested_outputs = NULL; 27 28 /*additional parameters: */ 226 Vector<IssmDouble> *U_esa_rate= NULL; 227 Vector<IssmDouble> *N_esa_rate= NULL; 228 Vector<IssmDouble> *U_gia_rate= NULL; 229 Vector<IssmDouble> *N_gia_rate= NULL; 230 231 /*parameters: */ 232 bool isslr=0; 233 int solution_type; 234 IssmDouble dt; 235 int geodetic=0; 236 237 /*Retrieve parameters:*/ 238 femmodel->parameters->FindParam(&isslr,TransientIsslrEnum); 239 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum); 240 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 241 femmodel->parameters->FindParam(&geodetic,SealevelriseGeodeticEnum); 242 243 /*in case we are running SealevelriseSolutionEnum, then bypass transient settings:*/ 244 if(solution_type==SealevelriseSolutionEnum)isslr=1; 245 246 /*Should we be here?:*/ 247 if(!isslr)return; 248 249 /*Verbose: */ 250 if(VerboseSolution()) _printf0_(" computing steric sea level rise\n"); 251 252 /*Retrieve geoid viscous and elastic rates, bedrock uplift viscous and elastic rates + steric rate, as vectors:*/ 253 GetVectorFromInputsx(&bedrock,femmodel,BedEnum,VertexSIdEnum); 254 GetVectorFromInputsx(&SL,femmodel,SealevelEnum,VertexSIdEnum); 255 GetVectorFromInputsx(&steric_rate_g,femmodel,SealevelriseStericRateEnum,VertexSIdEnum); 256 if(geodetic){ 257 GetVectorFromInputsx(&U_esa_rate,femmodel,SealevelUEsaRateEnum,VertexSIdEnum); 258 GetVectorFromInputsx(&U_gia_rate,femmodel,SealevelUGiaRateEnum,VertexSIdEnum); 259 GetVectorFromInputsx(&N_esa_rate,femmodel,SealevelNEsaRateEnum,VertexSIdEnum); 260 GetVectorFromInputsx(&N_gia_rate,femmodel,SealevelNGiaRateEnum,VertexSIdEnum); 261 } 262 263 /*compute: sea level change = initial sea level + (N_gia_rate+N_esa_rate) * dt + steric_rate * dt*/ 264 if(geodetic){ 265 SL->AXPY(N_gia_rate,dt); 266 SL->AXPY(N_esa_rate,dt); 267 } 268 SL->AXPY(steric_rate_g,dt); 269 270 /*compute new bedrock position: */ 271 if(geodetic){ 272 bedrock->AXPY(U_esa_rate,dt); 273 bedrock->AXPY(U_gia_rate,dt); 274 } 275 276 /*update element inputs:*/ 277 InputUpdateFromVectorx(femmodel,bedrock,BedEnum,VertexSIdEnum); 278 InputUpdateFromVectorx(femmodel,SL,SealevelEnum,VertexSIdEnum); 279 280 /*Free ressources:*/ 281 delete bedrock; 282 delete SL; 283 delete steric_rate_g; 284 if(geodetic){ 285 delete U_esa_rate; 286 delete U_gia_rate; 287 delete N_esa_rate; 288 delete N_gia_rate; 289 } 290 } 291 /*}}}*/ 292 Vector<IssmDouble>* sealevelrise_core_eustatic(FemModel* femmodel){ /*{{{*/ 293 294 /*Eustatic core of the SLR solution (terms that are constant with respect to sea-level)*/ 295 296 Vector<IssmDouble> *RSLgi = NULL; 297 IssmDouble RSLgi_oceanaverage = 0; 298 299 /*parameters: */ 300 int configuration_type; 29 301 int gsize; 30 302 bool spherical=true; 303 IssmDouble *latitude = NULL; 304 IssmDouble *longitude = NULL; 305 IssmDouble *radius = NULL; 306 int loop; 307 308 /*outputs:*/ 309 IssmDouble eustatic; 310 311 /*recover parameters:*/ 312 femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 313 femmodel->parameters->FindParam(&loop,SealevelriseLoopIncrementEnum); 314 315 /*first, recover lat,long and radius vectors from vertices: */ 316 VertexCoordinatesx(&latitude,&longitude,&radius,femmodel->vertices,spherical); 317 318 /*Figure out size of g-set deflection vector and allocate solution vector: */ 319 gsize = femmodel->nodes->NumberOfDofs(configuration_type,GsetEnum); 320 321 /*Initialize:*/ 322 RSLgi = new Vector<IssmDouble>(gsize); 323 324 /*call the eustatic main module: */ 325 femmodel->SealevelriseEustatic(RSLgi,&eustatic, latitude, longitude, radius,loop); //this computes 326 327 /*we need to average RSLgi over the ocean: RHS term 4 in Eq.4 of Farrel and clarke. Only the elements can do that: */ 328 RSLgi_oceanaverage=femmodel->SealevelriseOceanAverage(RSLgi); 329 330 /*RSLg is the sum of the pure eustatic component (term 3) and the contribution from the perturbation to the graviation potential due to the 331 * presence of ice (terms 1 and 4 in Eq.4 of Farrel and Clarke):*/ 332 RSLgi->Shift(-eustatic-RSLgi_oceanaverage); 333 334 /*save eustatic value for results: */ 335 femmodel->results->AddResult(new GenericExternalResult<IssmDouble>(femmodel->results->Size()+1,SealevelRSLEustaticEnum,-eustatic)); 336 337 338 /*clean up and return:*/ 339 xDelete<IssmDouble>(latitude); 340 xDelete<IssmDouble>(longitude); 341 xDelete<IssmDouble>(radius); 342 return RSLgi; 343 }/*}}}*/ 344 Vector<IssmDouble>* sealevelrise_core_noneustatic(FemModel* femmodel,Vector<IssmDouble>* RSLg_eustatic){ /*{{{*/ 345 346 /*sealevelrise_core_noneustatic.cpp //this computes the contributions from Eq.4 of Farrel and Clarke, rhs terms 2 and 5. 347 non eustatic core of the SLR solution */ 348 349 350 Vector<IssmDouble> *RSLg = NULL; 351 Vector<IssmDouble> *RSLg_old = NULL; 352 353 Vector<IssmDouble> *RSLgo = NULL; //ocean convolution of the perturbation to gravity potential. 354 Vector<IssmDouble> *RSLgo_rot= NULL; // rotational feedback 355 IssmDouble RSLgo_oceanaverage = 0; //average of RSLgo over the ocean. 356 357 /*parameters: */ 358 int count; 359 bool save_results; 360 int gsize; 361 int configuration_type; 362 bool spherical=true; 363 bool converged=true; 364 bool rotation=true; 365 bool verboseconvolution=true; 366 int max_nonlinear_iterations; 367 IssmDouble eps_rel; 368 IssmDouble eps_abs; 369 IssmDouble *latitude = NULL; 370 IssmDouble *longitude = NULL; 371 IssmDouble *radius = NULL; 372 IssmDouble eustatic; 373 int loop; 374 375 /*Recover some parameters: */ 376 femmodel->parameters->FindParam(&max_nonlinear_iterations,SealevelriseMaxiterEnum); 377 femmodel->parameters->FindParam(&eps_rel,SealevelriseReltolEnum); 378 femmodel->parameters->FindParam(&eps_abs,SealevelriseAbstolEnum); 379 femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 380 femmodel->parameters->FindParam(&loop,SealevelriseLoopIncrementEnum); 381 382 /*computational flag: */ 383 femmodel->parameters->FindParam(&rotation,SealevelriseRotationEnum); 384 385 /*first, recover lat,long and radius vectors from vertices: */ 386 VertexCoordinatesx(&latitude,&longitude,&radius,femmodel->vertices,spherical); 387 388 /*Figure out size of g-set deflection vector and allocate solution vector: */ 389 gsize = femmodel->nodes->NumberOfDofs(configuration_type,GsetEnum); 390 391 /*Initialize:*/ 392 RSLg = new Vector<IssmDouble>(gsize); 393 RSLg->Assemble(); 394 RSLg_eustatic->Copy(RSLg); //first initialize RSLg with the eustatic component computed in sealevelrise_core_eustatic. 395 396 RSLg_old = new Vector<IssmDouble>(gsize); 397 RSLg_old->Assemble(); 398 399 count=1; 400 converged=false; 401 402 /*Start loop: */ 403 for(;;){ 404 405 //save pointer to old sea level rise 406 delete RSLg_old; RSLg_old=RSLg; 407 408 /*Initialize solution vector: */ 409 RSLg = new Vector<IssmDouble>(gsize); RSLg->Assemble(); 410 RSLgo = new Vector<IssmDouble>(gsize); RSLgo->Assemble(); 411 412 /*call the non eustatic module: */ 413 femmodel->SealevelriseNonEustatic(RSLgo, RSLg_old, latitude, longitude, radius,verboseconvolution,loop); 414 415 /*assemble solution vector: */ 416 RSLgo->Assemble(); 417 418 if(rotation){ 419 /*call rotational feedback module: */ 420 RSLgo_rot = new Vector<IssmDouble>(gsize); RSLgo_rot->Assemble(); 421 femmodel->SealevelriseRotationalFeedback(RSLgo_rot,RSLg_old,NULL,NULL,NULL,latitude,longitude,radius); 422 RSLgo_rot->Assemble(); 423 424 RSLgo->AXPY(RSLgo_rot,1); 425 } 426 427 /*we need to average RSLgo over the ocean: RHS term 5 in Eq.4 of Farrel and clarke. Only the elements can do that: */ 428 RSLgo_oceanaverage=femmodel->SealevelriseOceanAverage(RSLgo); 429 430 /*RSLg is the sum of the eustatic term, and the ocean terms: */ 431 RSLg_eustatic->Copy(RSLg); RSLg->AXPY(RSLgo,1); 432 RSLg->Shift(-RSLgo_oceanaverage); 433 434 /*convergence criterion:*/ 435 slrconvergence(&converged,RSLg,RSLg_old,eps_rel,eps_abs); 436 437 /*free ressources: */ 438 delete RSLgo; 439 440 /*Increase count: */ 441 count++; 442 if(converged==true){ 443 break; 444 } 445 if(count>=max_nonlinear_iterations){ 446 _printf0_(" maximum number of nonlinear iterations (" << max_nonlinear_iterations << ") exceeded\n"); 447 converged=true; 448 break; 449 } 450 451 /*some minor verbosing adjustment:*/ 452 if(count>1)verboseconvolution=false; 453 454 } 455 if(VerboseConvergence()) _printf0_("\n total number of iterations: " << count-1 << "\n"); 456 457 xDelete<IssmDouble>(latitude); 458 xDelete<IssmDouble>(longitude); 459 xDelete<IssmDouble>(radius); 460 delete RSLg_old; 461 462 return RSLg; 463 } /*}}}*/ 464 void sealevelrise_core_elastic(Vector<IssmDouble>** pU_esa, Vector<IssmDouble>** pU_north_esa,Vector<IssmDouble>** pU_east_esa,FemModel* femmodel,Vector<IssmDouble>* RSLg){ /*{{{*/ 465 466 Vector<IssmDouble> *U_esa = NULL; 467 Vector<IssmDouble> *U_north_esa = NULL; 468 Vector<IssmDouble> *U_east_esa = NULL; 469 470 /*parameters: */ 471 int configuration_type; 472 int gsize; 473 bool spherical=true; 474 31 475 IssmDouble *latitude = NULL; 32 476 IssmDouble *longitude = NULL; … … 35 479 IssmDouble *yy = NULL; 36 480 IssmDouble *zz = NULL; 481 int loop; 482 int horiz; 483 484 /*retrieve some parameters:*/ 485 femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 486 femmodel->parameters->FindParam(&loop,SealevelriseLoopIncrementEnum); 487 femmodel->parameters->FindParam(&horiz,SealevelriseHorizEnum); 488 489 /*find size of vectors:*/ 490 gsize = femmodel->nodes->NumberOfDofs(configuration_type,GsetEnum); 491 492 /*intialize vectors:*/ 493 U_esa = new Vector<IssmDouble>(gsize); 494 if (horiz){ 495 U_north_esa = new Vector<IssmDouble>(gsize); 496 U_east_esa = new Vector<IssmDouble>(gsize); 497 } 498 499 /*retrieve geometric information: */ 500 VertexCoordinatesx(&latitude,&longitude,&radius,femmodel->vertices,spherical); 501 VertexCoordinatesx(&xx,&yy,&zz,femmodel->vertices); 502 503 /*call the elastic main modlule:*/ 504 femmodel->SealevelriseElastic(U_esa,U_north_esa,U_east_esa,RSLg,latitude,longitude,radius,xx,yy,zz,loop,horiz); 505 506 /*Assign output pointers:*/ 507 *pU_esa=U_esa; 508 if(horiz){ 509 *pU_east_esa=U_east_esa; 510 *pU_north_esa=U_north_esa; 511 } 512 513 /*Free ressources: */ 514 delete longitude; 515 delete latitude; 516 delete radius; 517 delete xx; 518 delete yy; 519 delete zz; 520 } 521 /*}}}*/ 522 void sealevelrise_core_viscous(Vector<IssmDouble>** pU_gia, Vector<IssmDouble>** pN_gia,FemModel* femmodel,Vector<IssmDouble>* RSLg){ /*{{{*/ 523 524 /*variables:*/ 525 Vector<IssmDouble> *U_gia = NULL; 526 Vector<IssmDouble> *N_gia = NULL; 527 528 /*parameters:*/ 529 int frequency; 37 530 IssmDouble dt; 38 531 39 /*Recover some parameters: */ 40 femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 41 femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum); 42 femmodel->parameters->FindParam(&save_results,SaveResultsEnum); 43 femmodel->parameters->FindParam(&isslr,TransientIsslrEnum); 44 femmodel->parameters->FindParam(&iscoupler,TransientIscouplerEnum); 45 46 /*first, recover lat,long and radius vectors from vertices: */ 47 VertexCoordinatesx(&latitude,&longitude,&radius,femmodel->vertices,spherical); 48 49 /*recover x,y,z vectors from vertices: */ 50 VertexCoordinatesx(&xx,&yy,&zz,femmodel->vertices); 51 52 /*Figure out size of g-set deflection vector and allocate solution vector: */ 53 gsize = femmodel->nodes->NumberOfDofs(configuration_type,GsetEnum); 54 55 /*several cases here, depending on value of iscoupler and isslr: 56 solution_type == SealevelriseSolutionEnum) we are running sea level rise core (no coupler) 57 ( !iscoupler & !isslr) we are not interested in being here :) 58 ( !iscoupler & isslr) we are running in uncoupled mode 59 ( iscoupler & isslr) we are running in coupled mode, and better be earth 60 ( iscoupler & !isslr) we are running in coupled mode, and better be an ice cap 61 */ 62 63 if(solution_type==SealevelriseSolutionEnum){ 64 isslr=1; 65 iscoupler=0; 66 } 67 68 /*early return: */ 69 if( !iscoupler & !isslr) return; //we are not interested in being here :) 70 71 /*In what follows we assume we are all running slr, either in coupled, or uncoupled mode:*/ 72 if(VerboseSolution()) _printf0_(" computing sea level rise\n"); 73 74 /*set configuration: */ 75 if(isslr)femmodel->SetCurrentConfiguration(SealevelriseAnalysisEnum); 76 77 /*transfer deltathickness forcing from ice caps to earth model: */ 78 if(iscoupler) TransferForcing(femmodel,SealevelriseDeltathicknessEnum); 79 80 /*call sea-level rise sub cores:*/ 81 if(isslr){ 82 Sg_eustatic=sealevelrise_core_eustatic(femmodel); //generalized eustatic (Farrel and Clark, Eq 4, 1st, 3rd and 4rd terms on the RHS. 83 84 /* The following is for reproducing Farrell&Clark1976 Fig. 1, and aimed for the workshop! 85 * md.slr.sealevel is considered as the "initial sea-level" where 1 m slr is distributed uniformly over the ocean 86 * similar strategy may work for computin SAL due to "internal mass distribution" associated with ocean dynamics 87 * if it breaks the code, it will be reverted. And, we will strategize how we want to accomodate */ 88 GetVectorFromInputsx(&slr_initial,femmodel,SealevelEnum,VertexSIdEnum); 89 Sg_eustatic->AXPY(slr_initial,1); 90 91 Sg=sealevelrise_core_noneustatic(femmodel,Sg_eustatic); //ocean loading tems (2nd and 5th terms on the RHS of Farrel and Clark) 92 93 /*compute other geodetic signatures, such as absolute sea level chagne, components of 3-D crustal motion: */ 94 /*Initialize:*/ 95 U_radial = new Vector<IssmDouble>(gsize); 96 U_north = new Vector<IssmDouble>(gsize); 97 U_east = new Vector<IssmDouble>(gsize); 98 Sg_absolute = new Vector<IssmDouble>(gsize); 99 100 /*call the geodetic main modlule:*/ 101 femmodel->SealevelriseGeodetic(U_radial,U_north,U_east,Sg,latitude,longitude,radius,xx,yy,zz); 102 103 /*Now deal with steric ocean expansion by just shifting Sg by a spatial rate pattern : */ 104 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum); 105 GetVectorFromInputsx(&steric_rate_g,femmodel,SealevelriseStericRateEnum,VertexSIdEnum); 106 Sg->AXPY(steric_rate_g,dt); 107 108 /*compute: absolute sea level change = relative sea level change + vertical motion*/ 109 Sg->Copy(Sg_absolute); Sg_absolute->AXPY(U_radial,1); 110 111 /*get results into elements:*/ 112 InputUpdateFromVectorx(femmodel,U_radial,SealevelUmotionEnum,VertexSIdEnum); // radial displacement 113 InputUpdateFromVectorx(femmodel,U_north,SealevelNmotionEnum,VertexSIdEnum); // north motion 114 InputUpdateFromVectorx(femmodel,U_east,SealevelEmotionEnum,VertexSIdEnum); // east motion 115 InputUpdateFromVectorx(femmodel,Sg_absolute,SealevelAbsoluteEnum,VertexSIdEnum); //absolute sea level 116 InputUpdateFromVectorx(femmodel,Sg,SealevelEnum,VertexSIdEnum); //relative sea level 117 118 if(save_results){ 119 if(VerboseSolution()) _printf0_(" saving results\n"); 120 femmodel->parameters->FindParam(&requested_outputs,&numoutputs,SealevelriseRequestedOutputsEnum); 121 femmodel->RequestedOutputsx(&femmodel->results,requested_outputs,numoutputs); 122 } 123 124 if(solution_type==SealevelriseSolutionEnum)femmodel->RequestedDependentsx(); 125 126 /*Free ressources:*/ 127 delete Sg; 128 delete Sg_eustatic; 129 delete U_radial; 130 delete U_north; 131 delete U_east; 132 delete Sg_absolute; 133 delete steric_rate_g; 134 if(numoutputs){for(int i=0;i<numoutputs;i++){xDelete<char>(requested_outputs[i]);} xDelete<char*>(requested_outputs);} 135 } 136 137 /*transfer sea-level back to ice caps: */ 138 if(iscoupler)TransferSealevel(femmodel,SealevelEnum); 139 } 532 /*retrieve some parameters:*/ 533 femmodel->parameters->FindParam(&frequency,SealevelriseGeodeticRunFrequencyEnum); 534 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum); 535 536 /*recover GIA rates:*/ 537 GetVectorFromInputsx(&U_gia,femmodel,SealevelUGiaRateEnum,VertexSIdEnum); 538 GetVectorFromInputsx(&N_gia,femmodel,SealevelNGiaRateEnum,VertexSIdEnum); 539 540 /*we just loaded rates, that's not what's being asked, scale by time:*/ 541 U_gia->Scale(frequency*dt); 542 N_gia->Scale(frequency*dt); 543 544 /*Assign output pointers:*/ 545 *pU_gia=U_gia; 546 *pN_gia=N_gia; 547 548 } 140 549 /*}}}*/ 550 void sealevelrise_diagnostics(FemModel* femmodel,Vector<IssmDouble>* RSLg){ /*{{{*/ 551 552 /*compute spherical harmonics deg 1 and deg 2 coefficeints:*/ 553 554 } 555 /*}}}*/ 556 557 /*support routines:*/ 141 558 void TransferForcing(FemModel* femmodel,int forcingenum){ /*{{{*/ 142 559 … … 211 628 *First, build the global delta thickness vector in the earth model: */ 212 629 nv=femmodel->vertices->NumberOfVertices(); 213 forcingglobal= new Vector<IssmDouble>(nv);630 GetVectorFromInputsx(&forcingglobal,femmodel,forcingenum,VertexSIdEnum); 214 631 215 632 /*Retrieve transition vectors, used to plug from each ice cap into the global forcing:*/ … … 232 649 /*We are going to plug this vector into the earth model, at the right vertices corresponding to this particular 233 650 * ice cap: */ 234 forcingglobal->SetValues(M,index,forcingfromcap, INS_VAL);651 forcingglobal->SetValues(M,index,forcingfromcap,ADD_VAL); 235 652 xDelete<int>(index); 236 653 } … … 372 789 373 790 } /*}}}*/ 791 void EarthMassTransport(FemModel* femmodel){ /*{{{*/ 792 793 IssmDouble time,dt; 794 Vector<IssmDouble> *oldthickness = NULL; 795 Vector<IssmDouble> *newthickness = NULL; 796 Vector<IssmDouble> *deltathickness = NULL; 797 Vector<IssmDouble> *cumdeltathickness = NULL; 798 int nv; 799 800 if(VerboseSolution()) _printf0_(" computing earth mass transport\n"); 801 802 /*This mass transport module for the Earth is because we might have thickness variations as spcs 803 * specified in the md.slr class, outside of what we will get from the icecaps. That's why we get t 804 * the thickness variations from SealevelriseSpcthicknessEnum.*/ 805 806 /*No mass transport module was called, so we are just going to retrieve the geometry thickness 807 * at this time step, at prior time step, and plug the difference as deltathickness: */ 808 femmodel->parameters->FindParam(&time,TimeEnum); 809 femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum); 810 nv=femmodel->vertices->NumberOfVertices(); 811 812 GetVectorFromInputsx(&newthickness,femmodel,SealevelriseSpcthicknessEnum,VertexSIdEnum); 813 GetVectorFromInputsx(&oldthickness,femmodel,SealevelriseSpcthicknessEnum,VertexSIdEnum,time-dt); 814 815 /*compute deltathickness: */ 816 deltathickness = new Vector<IssmDouble>(nv); 817 newthickness->Copy(deltathickness); deltathickness->AXPY(oldthickness,-1); 818 819 /*plug into elements:*/ 820 InputUpdateFromVectorx(femmodel,deltathickness,SealevelriseDeltathicknessEnum,VertexSIdEnum); 821 822 /*add to cumulated delta thickness: */ 823 GetVectorFromInputsx(&cumdeltathickness,femmodel,SealevelriseCumDeltathicknessEnum,VertexSIdEnum); 824 cumdeltathickness->AXPY(deltathickness,1); 825 InputUpdateFromVectorx(femmodel,cumdeltathickness,SealevelriseCumDeltathicknessEnum,VertexSIdEnum); 826 827 /*free ressources:*/ 828 delete oldthickness; 829 delete newthickness; 830 delete deltathickness; 831 delete cumdeltathickness; 832 833 } /*}}}*/ 834 void slrconvergence(bool* pconverged, Vector<IssmDouble>* RSLg,Vector<IssmDouble>* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs){ /*{{{*/ 835 836 bool converged=true; 837 IssmDouble ndS,nS; 838 Vector<IssmDouble> *dRSLg = NULL; 839 840 //compute norm(du) and norm(u) if requested 841 dRSLg=RSLg_old->Duplicate(); RSLg_old->Copy(dRSLg); dRSLg->AYPX(RSLg,-1.0); 842 ndS=dRSLg->Norm(NORM_TWO); 843 844 if (xIsNan<IssmDouble>(ndS)) _error_("convergence criterion is NaN!"); 845 846 if(!xIsNan<IssmDouble>(eps_rel)){ 847 nS=RSLg_old->Norm(NORM_TWO); 848 if (xIsNan<IssmDouble>(nS)) _error_("convergence criterion is NaN!"); 849 } 850 851 852 //clean up 853 delete dRSLg; 854 855 //print 856 if(!xIsNan<IssmDouble>(eps_rel)){ 857 if((ndS/nS)<eps_rel){ 858 if(VerboseConvergence()) _printf0_(setw(50) << left << " convergence criterion: norm(dS)/norm(S)" << ndS/nS*100 << " < " << eps_rel*100 << " %\n"); 859 } 860 else{ 861 if(VerboseConvergence()) _printf0_(setw(50) << left << " convergence criterion: norm(dS)/norm(S)" << ndS/nS*100 << " > " << eps_rel*100 << " %\n"); 862 converged=false; 863 } 864 } 865 if(!xIsNan<IssmDouble>(eps_abs)){ 866 if(ndS<eps_abs){ 867 if(VerboseConvergence()) _printf0_(setw(50) << left << " convergence criterion: norm(dS)" << ndS << " < " << eps_abs << " \n"); 868 } 869 else{ 870 if(VerboseConvergence()) _printf0_(setw(50) << left << " convergence criterion: norm(dS)" << ndS << " > " << eps_abs << " \n"); 871 converged=false; 872 } 873 } 874 875 /*assign output*/ 876 *pconverged=converged; 877 878 } /*}}}*/ -
issm/trunk-jpl/src/c/cores/transient_core.cpp
r22908 r22955 358 358 359 359 /*Sea level rise: */ 360 if(isslr || iscoupler) sealevelrise_core(femmodel);360 if(isslr) sealevelrise_core(femmodel); 361 361 362 362 /*unload results*/ -
issm/trunk-jpl/src/m/classes/maskpsl.m
r22004 r22955 10 10 ocean_levelset = NaN; 11 11 land_levelset = NaN; 12 glacier_levelset = NaN; 12 13 end 13 14 methods (Static) … … 68 69 fielddisplay(self,'ocean_levelset','is the vertex on the ocean ? yes if = 1, no if = 0'); 69 70 fielddisplay(self,'land_levelset','is the vertex on the land ? yes if = 1, no if = 0'); 71 fielddisplay(self,'glacier_levelset','is the vertex on a glacier ? yes if = 1, no if = 0'); 70 72 end % }}} 71 73 function marshall(self,prefix,md,fid) % {{{ 74 WriteData(fid,prefix,'name','md.mask.type','data',class(md.mask),'format','String'); 72 75 WriteData(fid,prefix,'object',self,'class','mask','fieldname','groundedice_levelset','format','DoubleMat','mattype',1); 73 76 WriteData(fid,prefix,'object',self,'class','mask','fieldname','ice_levelset','format','DoubleMat','mattype',1); -
issm/trunk-jpl/src/m/classes/mesh3dsurface.m
r22879 r22955 103 103 end % }}} 104 104 function disp(obj) % {{{ 105 disp(sprintf(' 2D tria Mesh (horizontal):'));105 disp(sprintf(' 3D tria Mesh (surface):')); 106 106 107 107 disp(sprintf('\n Elements and vertices:')); -
issm/trunk-jpl/src/m/classes/model.js
r22719 r22955 83 83 this.levelset = new levelset(); 84 84 this.calving = new calving(); 85 this.gia = new gia(); 85 86 this.love = new fourierlove(); 86 this.gia = new giaivins();87 88 87 this.esa = new esa(); 89 88 this.autodiff = new autodiff(); 90 89 this.inversion = new inversion(); 91 90 this.qmu = new qmu(); 92 this.amr 93 91 this.amr = new amr(); 92 this.radaroverlay = new radaroverlay(); 94 93 this.results = {}; 95 94 this.outputdefinition = new outputdefinition(); … … 764 763 this.inversion = 0; 765 764 this.qmu = 0; 766 this.amr 765 this.amr = 0; 767 766 768 767 this.results = 0; -
issm/trunk-jpl/src/m/classes/model.m
r22324 r22955 38 38 steadystate = 0; 39 39 transient = 0; 40 levelse t= 0;40 levelse = 0; 41 41 calving = 0; 42 love = 0; 43 gia = 0; 42 gia = 0; 44 43 esa = 0; 45 44 love = 0; 46 45 autodiff = 0; 47 46 inversion = 0; 48 47 qmu = 0; 49 amr = 0; 50 48 amr = 0; 51 49 results = 0; 52 50 outputdefinition = 0; … … 128 126 %2016 October 11 129 127 if isa(md.esa,'double'); md.esa=esa(); end 130 %2017 Dec 21st (needs to be here)131 if isempty(md.settings)132 disp('Warning: md.settings had to be reset, make sure to adjust md.settings.output_frequency and other fields');133 md.settings = issmsettings();134 end135 128 %2017 February 10th 136 129 if md.settings.solver_residue_threshold==0, … … 147 140 disp('Warning: calvingdev is now calvingvonmises'); 148 141 md.calving=calvingvonmises(md.calving); 142 end 143 %2017 Dec 21st (needs to be here) 144 if isempty(md.settings) 145 disp('Warning: md.settings had to be reset, make sure to adjust md.settings.output_frequency and other fields'); 146 md.settings = issmsettings(); 149 147 end 150 148 … … 328 326 end 329 327 328 %lat long 329 if numel(md.mesh.lat) ==md.mesh.numberofvertices, md.mesh.lat=project2d(md,md.mesh.lat,1); end 330 if numel(md.mesh.long)==md.mesh.numberofvertices, md.mesh.long=project2d(md,md.mesh.long,1); end 331 330 332 %outputdefinitions 331 333 for i=1:length(md.outputdefinition.definitions) … … 361 363 362 364 end % }}} 363 function md2 = extract(md,area ) % {{{365 function md2 = extract(md,area,varargin) % {{{ 364 366 %extract - extract a model according to an Argus contour or flag list 365 367 % … … 383 385 md1=md; 384 386 387 %recover optoins: 388 options=pairoptions(varargin{:}); 389 385 390 %some checks 386 if ((nargin ~=2) | (nargout~=1)),391 if ((nargin<2) | (nargout~=1)), 387 392 help extract 388 393 error('extract error message: bad usage'); … … 396 401 397 402 %kick out all elements with 3 dirichlets 398 spc_elem=find(~flag_elem); 399 spc_node=sort(unique(md1.mesh.elements(spc_elem,:))); 400 flag=ones(md1.mesh.numberofvertices,1); 401 flag(spc_node)=0; 402 pos=find(sum(flag(md1.mesh.elements),2)==0); 403 flag_elem(pos)=0; 403 if getfieldvalue(options,'spccheck',1) 404 spc_elem=find(~flag_elem); 405 spc_node=sort(unique(md1.mesh.elements(spc_elem,:))); 406 flag=ones(md1.mesh.numberofvertices,1); 407 flag(spc_node)=0; 408 pos=find(sum(flag(md1.mesh.elements),2)==0); 409 flag_elem(pos)=0; 410 end 404 411 405 412 %extracted elements and nodes lists … … 827 834 md.calving=extrude(md.calving,md); 828 835 md.hydrology = extrude(md.hydrology,md); 836 md.slr = extrude(md.slr,md); 829 837 830 838 %connectivity … … 1167 1175 md.levelset = levelset(); 1168 1176 md.calving = calving(); 1169 md.gia = giaivins(); 1177 md.gia = giaivins(); 1178 md.esa = esa(); 1170 1179 md.love = fourierlove(); 1171 1180 md.esa = esa(); … … 1173 1182 md.inversion = inversion(); 1174 1183 md.qmu = qmu(); 1175 md.amr 1184 md.amr = amr(); 1176 1185 md.radaroverlay = radaroverlay(); 1177 1186 md.results = struct(); … … 1341 1350 disp(sprintf('%19s: %-22s -- %s','levelset' ,['[1x1 ' class(self.levelset) ']'],'parameters for moving boundaries (level-set method)')); 1342 1351 disp(sprintf('%19s: %-22s -- %s','calving' ,['[1x1 ' class(self.calving) ']'],'parameters for calving')); 1343 disp(sprintf('%19s: %-22s -- %s','gia' ,['[1x1 ' class(self.gia) ']'],'parameters for gia solution')); 1344 disp(sprintf('%19s: %-22s -- %s','love' ,['[1x1 ' class(self.love) ']'],'parameters for love solution')); 1352 disp(sprintf('%19s: %-22s -- %s','gia' ,['[1x1 ' class(self.gia) ']'],'parameters for gia solution')); 1345 1353 disp(sprintf('%19s: %-22s -- %s','esa' ,['[1x1 ' class(self.esa) ']'],'parameters for elastic adjustment solution')); 1354 disp(sprintf('%19s: %-22s -- %s','love' ,['[1x1 ' class(self.love) ']'],'parameters for love solution')); 1346 1355 disp(sprintf('%19s: %-22s -- %s','autodiff' ,['[1x1 ' class(self.autodiff) ']'],'automatic differentiation parameters')); 1347 1356 disp(sprintf('%19s: %-22s -- %s','inversion' ,['[1x1 ' class(self.inversion) ']'],'parameters for inverse methods')); … … 1443 1452 1444 1453 end % }}} 1445 function savemodeljs(md,modelname,websiteroot ) % {{{1446 1454 function savemodeljs(md,modelname,websiteroot,varargin) % {{{ 1455 1447 1456 %the goal of this routine is to save the model as a javascript array that can be included in any html 1448 1457 %file: 1449 1458 1459 options=pairoptions(varargin{:}); 1460 optimization=getfieldvalue(options,'optimize',0); 1461 1462 1450 1463 %disp: 1451 1464 disp(['saving model ''' modelname ''' in file ' websiteroot '/js/' modelname '.js']); … … 1466 1479 end 1467 1480 1481 %some optimization: 1482 if optimization==1, 1483 %optimize for plotting only: 1484 if ~ismember(field,{'geometry','mesh','mask'}), 1485 continue; 1486 end 1487 end 1488 1468 1489 %Check that current field is an object 1469 1490 if ~isobject(md.(field)) -
issm/trunk-jpl/src/m/classes/model.py
r22324 r22955 111 111 self.levelset = levelset() 112 112 self.calving = calving() 113 self.gia = giaivins() 113 114 self.love = fourierlove() 114 self.gia = giaivins()115 115 self.esa = esa() 116 117 116 self.autodiff = autodiff() 118 117 self.inversion = inversion() … … 128 127 def properties(self): # {{{ 129 128 # ordered list of properties since vars(self) is random 130 129 return ['mesh', 131 130 'mask', 132 131 'geometry', -
issm/trunk-jpl/src/m/classes/sealevelmodel.m
r20264 r22955 18 18 settings = 0; 19 19 private = 0; 20 range = 0; 21 mergedcaps = 0; 20 22 %}}} 21 23 end … … 43 45 for i=1:length(slm.icecaps), 44 46 if slm.icecaps{i}.transient.iscoupler==0, 45 error(sprintf('sealevelmodel checkconsistenty error: icecap model %s should have the transient coupler option turned on!',slm.icecaps{i}.miscellaneous.name));47 warning(sprintf('sealevelmodel checkconsistenty error: icecap model %s should have the transient coupler option turned on!',slm.icecaps{i}.miscellaneous.name)); 46 48 end 47 49 end 48 50 49 51 if slm.earth.transient.iscoupler==0, 50 error('sealevelmodel checkconsistenty error: earth model should have the transient coupler option turned on!');52 warning('sealevelmodel checkconsistenty error: earth model should have the transient coupler option turned on!'); 51 53 end 52 54 … … 54 56 for i=1:length(slm.icecaps), 55 57 if slm.icecaps{i}.mesh.numberofvertices ~= length(slm.earth.slr.transitions{i}), 56 error('sealevelmodel checkconsistenty issue with size of transition vectors!'); 58 error(['sealevelmodel checkconsistenty issue with size of transition vector for ice cap: ' num2str(i) ' name: ' slm.icecaps{i}.miscellaneous.name]); 59 end 60 end 61 62 %check that run_frequency is the same everywhere: 63 for i=1:length(slm.icecaps), 64 if slm.icecaps{i}.slr.geodetic_run_frequency~=slm.earth.slr.geodetic_run_frequency, 65 error(sprintf('sealevelmodel checkconsistenty error: icecap model %s should have the same run frequency as earth!',slm.icecaps{i}.miscellaneous.name)); 57 66 end 58 67 end 59 68 69 %make sure steric_rate is the same everywhere: 70 for i=1:length(slm.icecaps), 71 md= slm.icecaps{i}; 72 if ~isempty(find(md.slr.steric_rate - slm.earth.slr.steric_rate(slm.earth.slr.transitions{i}))), 73 error(sprintf('steric rate on ice cap %s is not the same as for the earth\n',md.miscellaneous.name)); 74 end 75 end 60 76 61 77 end … … 70 86 slm.private = private(); 71 87 slm.cluster = generic(); 88 slm.range = {}; 72 89 end 73 90 %}}} … … 78 95 disp(sprintf('%19s: %-22s -- %s','cluster' ,['[1x1 ' class(self.cluster) ']'],'cluster parameters (number of cpus...)')); 79 96 disp(sprintf('%19s: %-22s -- %s','miscellaneous' ,['[1x1 ' class(self.miscellaneous) ']'],'miscellaneous fields')); 97 disp(sprintf('%19s: %-22s -- %s','range' ,['[1x1 ' class(self.range) ']'],'ranges')); 98 end % }}} 99 function self=mergeresults(self) % {{{ 100 champs=fields(self.icecaps{1}.results.TransientSolution); 101 for i=1:length(self.mergedcaps)/2, 102 md=self.mergedcaps{2*(i-1)+1}; trans=self.mergedcaps{2*(i-1)+2}; 103 icecaps=self.icecaps(self.range{2*(i-1)+2}); 104 for j=1:length(self.icecaps{1}.results.TransientSolution), 105 for k=1:length(champs), 106 if strcmpi(class(icecaps{1}.results.TransientSolution(j).(champs{k})),'double'), 107 %vertex or element? 108 if length(icecaps{1}.results.TransientSolution(j).(champs{k}))==icecaps{1}.mesh.numberofvertices, 109 md.results.TransientSolution(j).(champs{k})=zeros(md.mesh.numberofvertices,1); 110 for l=1:length(trans), 111 resultcap=icecaps{l}.results.TransientSolution(j).(champs{k}); 112 md.results.TransientSolution(j).(champs{k})(trans{l})=resultcap; 113 end 114 else 115 if strcmpi(champs{k},'IceVolume') | strcmpi(champs{k},'IceVolumeAboveFloatation') , 116 md.results.TransientSolution(j).(champs{k})=0; 117 for l=1:length(trans), 118 resultcap=icecaps{l}.results.TransientSolution(j).(champs{k}); 119 md.results.TransientSolution(j).(champs{k})= md.results.TransientSolution(j).(champs{k})+resultcap; 120 end 121 elseif strcmpi(champs{k},'time'), 122 md.results.TransientSolution(j).(champs{k})= icecaps{1}.results.TransientSolution(j).(champs{k}); 123 else 124 continue; 125 end 126 end 127 else 128 continue; 129 end 130 end 131 end 132 self.mergedcaps{2*(i-1)+1}=md; 133 end 134 end % }}} 135 function listcaps(self) % {{{ 136 for i=1:length(self.icecaps), 137 disp(sprintf('%i: %s',i,self.icecaps{i}.miscellaneous.name)); 138 end 139 end % }}} 140 function viscousiterations(self) % {{{ 141 for i=1:length(self.icecaps), 142 ic=self.icecaps{i}; 143 mvi=ic.results.TransientSolution(1).StressbalanceConvergenceNumSteps; 144 for j=2:length(ic.results.TransientSolution)-1, 145 mvi=max(mvi,ic.results.TransientSolution(j).StressbalanceConvergenceNumSteps); 146 end 147 disp(sprintf('%i, %s: %i',i,self.icecaps{i}.miscellaneous.name,mvi)); 148 end 149 end % }}} 150 function maxtimestep(self) % {{{ 151 for i=1:length(self.icecaps), 152 ic=self.icecaps{i}; 153 mvi=length(ic.results.TransientSolution); 154 timei=ic.results.TransientSolution(end).time; 155 disp(sprintf('%i, %s: %i/%g',i,self.icecaps{i}.miscellaneous.name,mvi,timei)); 156 end 157 mvi=length(self.earth.results.TransientSolution); 158 timei=self.earth.results.TransientSolution(end).time; 159 disp(sprintf('Earth: %i/%g',mvi,timei)); 160 end % }}} 161 function self=homogeneize(self,noearth) % {{{ 162 if nargin==1, 163 noearth=0; 164 end 165 mintimestep=Inf; 166 for i=1:length(self.icecaps), 167 ic=self.icecaps{i}; 168 mintimestep=min(mintimestep, length(ic.results.TransientSolution)); 169 end 170 if ~noearth, 171 mintimestep=min(mintimestep, length(self.earth.results.TransientSolution)); 172 end 173 174 for i=1:length(self.icecaps), 175 ic=self.icecaps{i}; 176 ic.results.TransientSolution=ic.results.TransientSolution(1:mintimestep); 177 self.icecaps{i}=ic; 178 end 179 ic=self.earth; 180 if ~noearth, 181 ic.results.TransientSolution=ic.results.TransientSolution(1:mintimestep); 182 end 183 self.earth=ic; 80 184 end % }}} 81 185 end -
issm/trunk-jpl/src/m/classes/slr.js
r22808 r22955 88 88 console.log(sprintf(' Sealevelrise solution parameters:')); 89 89 90 fielddisplay(this,'deltathickness','thickness change: ice height equivalent[m]');91 92 fielddisplay(this,'reltol','sea level rise relative convergence criterion, (NaN: not applied)');93 fielddisplay(this,'abstol','sea level rise absolute convergence criterion, (default, NaN: not applied)');94 95 96 97 98 99 100 101 102 103 104 105 106 107 fielddisplay(this,'ocean_area_scaling','correction for model representation of ocean area (default: No correction)');108 fielddisplay(this,'steric_rate','rate of steric ocean expansion [mm/yr]');109 fielddisplay(this,'degacc',"accuracy (default .01 deg) for numerical discretization of the Green's functions");110 fielddisplay(this,'transitions','indices into parts of the mesh that will be icecaps');111 fielddisplay(this,'requested_outputs','additional outputs requested');90 fielddisplay(this,'deltathickness','thickness change (main loading of the slr solution core [m]'); 91 fielddisplay(this,'sealevel','current sea level (prior to computation) [m]'); 92 fielddisplay(this,'reltol','sea level rise relative convergence criterion, (default, NaN: not applied)'); 93 fielddisplay(this,'abstol','sea level rise absolute convergence criterion, NaN: not applied'); 94 fielddisplay(this,'maxiter','maximum number of nonlinear iterations'); 95 fielddisplay(this,'love_h','load Love number for radial displacement'); 96 fielddisplay(this,'love_k','load Love number for gravitational potential perturbation'); 97 fielddisplay(this,'love_l','load Love number for horizontal displacements'); 98 fielddisplay(this,'tide_love_h','tidal love number (degree 2)'); 99 fielddisplay(this,'tide_love_k','tidal love number (degree 2)'); 100 fielddisplay(this,'fluid_love','secular fluid Love number'); 101 fielddisplay(this,'equatorial_moi','mean equatorial moment of inertia [kg m^2]'); 102 fielddisplay(this,'polar_moi','polar moment of inertia [kg m^2]'); 103 fielddisplay(this,'angular_velocity','mean rotational velocity of earth [per second]'); 104 fielddisplay(this,'rigid','rigid earth graviational potential perturbation'); 105 fielddisplay(this,'elastic','elastic earth graviational potential perturbation'); 106 fielddisplay(this,'rotation','rotational earth potential perturbation'); 107 fielddisplay(this,'ocean_area_scaling','correction for model representation of ocean area [default: No correction]'); 108 fielddisplay(this,'degacc',"accuracy (default .01 deg) for numerical discretization of the Green's functions"); 109 fielddisplay(this,'transitions','indices into parts of the mesh that will be icecaps'); 110 fielddisplay(this,'requested_outputs','additional outputs requested'); 111 fielddisplay(this,'steric_rate','rate of steric ocean expansion [mm/yr]'); 112 112 } //}}} 113 113 this.marshall=function(md,prefix,fid) { //{{{ -
issm/trunk-jpl/src/m/classes/slr.m
r22808 r22955 8 8 deltathickness = NaN; 9 9 sealevel = NaN; 10 spcthickness = NaN; 10 11 maxiter = 0; 11 12 reltol = 0; … … 25 26 ocean_area_scaling = 0; 26 27 steric_rate = 0; %rate of ocean expansion from steric effects. 28 geodetic_run_frequency = 1; %how many time steps we skip before we run the geodetic part of the solver during transient 29 geodetic = 0; %compute geodetic SLR? (in addition to steric?) 27 30 degacc = 0; 31 loop_increment = 0; 32 horiz = 0; 33 Ngia = 0; 34 Ugia = 0; 28 35 requested_outputs = {}; 29 36 transitions = {}; … … 46 53 %maximum of non-linear iterations. 47 54 self.maxiter=5; 55 self.loop_increment=200; 48 56 49 57 %computational flags: 58 self.geodetic=0; 50 59 self.rigid=1; 51 60 self.elastic=1; 52 self.rotation=0;53 61 self.ocean_area_scaling=0; 62 self.rotation=1; 54 63 55 64 %tidal love numbers: … … 73 82 self.steric_rate=0; 74 83 84 %how many time steps we skip before we run SLR solver during transient 85 self.geodetic_run_frequency=1; 75 86 76 87 %output default: … … 79 90 %transitions should be a cell array of vectors: 80 91 self.transitions={}; 92 93 %horizontal displacement? (not by default) 94 self.horiz=0; 81 95 82 96 end % }}} … … 86 100 md = checkfield(md,'fieldname','slr.deltathickness','NaN',1,'Inf',1,'size',[md.mesh.numberofelements 1]); 87 101 md = checkfield(md,'fieldname','slr.sealevel','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]); 102 md = checkfield(md,'fieldname','slr.spcthickness','Inf',1,'timeseries',1); 88 103 md = checkfield(md,'fieldname','slr.love_h','NaN',1,'Inf',1); 89 104 md = checkfield(md,'fieldname','slr.love_k','NaN',1,'Inf',1); … … 98 113 md = checkfield(md,'fieldname','slr.abstol','size',[1 1]); 99 114 md = checkfield(md,'fieldname','slr.maxiter','size',[1 1],'>=',1); 115 md = checkfield(md,'fieldname','slr.geodetic_run_frequency','size',[1 1],'>=',1); 100 116 md = checkfield(md,'fieldname','slr.steric_rate','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]); 101 117 md = checkfield(md,'fieldname','slr.degacc','size',[1 1],'>=',1e-10); 102 118 md = checkfield(md,'fieldname','slr.requested_outputs','stringrow',1); 119 md = checkfield(md,'fieldname','slr.loop_increment','NaN',1,'Inf',1,'>=',1); 120 md = checkfield(md,'fieldname','slr.horiz','NaN',1,'Inf',1,'values',[0 1]); 121 md = checkfield(md,'fieldname','slr.Ngia','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]); 122 md = checkfield(md,'fieldname','slr.Ugia','NaN',1,'Inf',1,'size',[md.mesh.numberofvertices 1]); 103 123 104 124 %check that love numbers are provided at the same level of accuracy: … … 112 132 [els,vertices]=find(maskpos>0); 113 133 if length(els), 114 error('slr checkconsistency fail: there are elements with ice loads where some vertices are not on the ice!'); 115 end 134 warning('slr checkconsistency fail: there are elements with ice loads where some vertices are not on the ice!'); 135 end 136 137 %check that if geodetic is requested, we are a mesh3dsurface model (planet), or if we are not, 138 %a coupler to a planet model is provided. 139 if self.geodetic, 140 if md.transient.iscoupler, 141 %we are good; 142 else 143 if strcmpi(class(md.mesh),'mesh3dsurface'), 144 %we are good 145 else 146 error('model is requesting geodetic computations without being a mesh3dsurface, or being coupled to one!'); 147 end 148 end 149 end 150 116 151 117 152 end % }}} … … 124 159 fielddisplay(self,'deltathickness','thickness change: ice height equivalent [m]'); 125 160 fielddisplay(self,'sealevel','current sea level (prior to computation) [m]'); 126 fielddisplay(self,'reltol','sea level rise relative convergence criterion, (NaN: not applied)'); 127 fielddisplay(self,'abstol','sea level rise absolute convergence criterion, (default, NaN: not applied)'); 161 fielddisplay(self,'spcthickness','thickness constraints (NaN means no constraint) [m]'); 162 fielddisplay(self,'reltol','sea level rise relative convergence criterion, (default, NaN: not applied)'); 163 fielddisplay(self,'abstol','sea level rise absolute convergence criterion, NaN: not applied'); 128 164 fielddisplay(self,'maxiter','maximum number of nonlinear iterations'); 129 165 fielddisplay(self,'love_h','load Love number for radial displacement'); … … 136 172 fielddisplay(self,'polar_moi','polar moment of inertia [kg m^2]'); 137 173 fielddisplay(self,'angular_velocity','mean rotational velocity of earth [per second]'); 174 fielddisplay(self,'ocean_area_scaling','correction for model representation of ocean area [default: No correction]'); 175 fielddisplay(self,'steric_rate','rate of steric ocean expansion (in mm/yr)'); 176 fielddisplay(self,'Ngia','rate of viscous (GIA) geoid expansion (in mm/yr)'); 177 fielddisplay(self,'Ugia','rate of viscous (GIA) bedrock uplift (in mm/yr)'); 178 fielddisplay(self,'loop_increment','vector assembly (in the convolution) framentation'); 179 fielddisplay(self,'geodetic','compute geodetic SLR? ( in addition to steric?) default 0'); 180 fielddisplay(self,'geodetic_run_frequency','how many time steps we skip before we run SLR solver during transient (default: 1)'); 138 181 fielddisplay(self,'rigid','rigid earth graviational potential perturbation'); 139 182 fielddisplay(self,'elastic','elastic earth graviational potential perturbation'); 140 183 fielddisplay(self,'rotation','earth rotational potential perturbation'); 141 fielddisplay(self,'ocean_area_scaling','correction for model representation of ocean area (default: No correction)');142 fielddisplay(self,'steric_rate','rate of steric ocean expansion [mm/yr]');143 184 fielddisplay(self,'degacc','accuracy (default .01 deg) for numerical discretization of the Green''s functions'); 144 185 fielddisplay(self,'transitions','indices into parts of the mesh that will be icecaps'); … … 149 190 %WriteData(fid,prefix,'object',self,'fieldname','deltathickness','format','DoubleMat','mattype',2); 150 191 WriteData(fid,prefix,'object',self,'fieldname','deltathickness','format','DoubleMat','mattype',2,'timeserieslength',md.mesh.numberofelements+1,'yts',md.constants.yts); 192 %WriteData(fid,prefix,'object',self,'fieldname','deltathickness','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofelements+1); 151 193 WriteData(fid,prefix,'object',self,'fieldname','sealevel','mattype',1,'format','DoubleMat','timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts); 194 WriteData(fid,prefix,'object',self,'fieldname','spcthickness','format','DoubleMat','mattype',1,'timeserieslength',md.mesh.numberofvertices+1,'yts',md.constants.yts); 152 195 WriteData(fid,prefix,'object',self,'fieldname','reltol','format','Double'); 153 196 WriteData(fid,prefix,'object',self,'fieldname','abstol','format','Double'); … … 166 209 WriteData(fid,prefix,'object',self,'fieldname','rotation','format','Boolean'); 167 210 WriteData(fid,prefix,'object',self,'fieldname','ocean_area_scaling','format','Boolean'); 211 WriteData(fid,prefix,'object',self,'fieldname','geodetic_run_frequency','format','Integer'); 168 212 WriteData(fid,prefix,'object',self,'fieldname','steric_rate','format','DoubleMat','mattype',1,'scale',1e-3/md.constants.yts); 213 WriteData(fid,prefix,'object',self,'fieldname','Ngia','format','DoubleMat','mattype',1,'scale',1e-3/md.constants.yts); 214 WriteData(fid,prefix,'object',self,'fieldname','Ugia','format','DoubleMat','mattype',1,'scale',1e-3/md.constants.yts); 169 215 WriteData(fid,prefix,'object',self,'fieldname','degacc','format','Double'); 170 216 WriteData(fid,prefix,'object',self,'fieldname','transitions','format','MatArray'); 217 WriteData(fid,prefix,'object',self,'fieldname','loop_increment','format','Integer'); 218 WriteData(fid,prefix,'object',self,'fieldname','horiz','format','Integer'); 219 WriteData(fid,prefix,'object',self,'fieldname','geodetic','format','Integer'); 171 220 172 221 %process requested outputs … … 184 233 writejs1Darray(fid,[modelname '.slr.deltathickness'],self.deltathickness); 185 234 writejs1Darray(fid,[modelname '.slr.sealevel'],self.sealevel); 235 writejs1Darray(fid,[modelname '.slr.spcthickness'],self.spcthickness); 186 236 writejsdouble(fid,[modelname '.slr.maxiter'],self.maxiter); 187 237 writejsdouble(fid,[modelname '.slr.reltol'],self.reltol); … … 200 250 writejsdouble(fid,[modelname '.slr.rotation'],self.rotation); 201 251 writejsdouble(fid,[modelname '.slr.ocean_area_scaling'],self.ocean_area_scaling); 252 writejsdouble(fid,[modelname '.slr.geodetic_run_frequency'],self.geodetic_run_frequency); 202 253 writejs1Darray(fid,[modelname '.slr.steric_rate'],self.steric_rate); 203 254 writejsdouble(fid,[modelname '.slr.degacc'],self.degacc); … … 205 256 writejscellarray(fid,[modelname '.slr.transitions'],self.transitions); 206 257 end % }}} 258 function self = extrude(self,md) % {{{ 259 self.sealevel=project3d(md,'vector',self.sealevel,'type','node'); 260 end % }}} 207 261 end 208 262 end -
issm/trunk-jpl/src/m/classes/slr.py
r22808 r22955 60 60 string="%s\n%s"%(string,fielddisplay(self,'elastic','elastic earth graviational potential perturbation')) 61 61 string="%s\n%s"%(string,fielddisplay(self,'rotation','earth rotational potential perturbation')) 62 string="%s\n%s"%(string,fielddisplay(self,'ocean_area_scaling','correction for model representation of ocean area (default: No correction)'))62 string="%s\n%s"%(string,fielddisplay(self,'ocean_area_scaling','correction for model representation of ocean area [default: No correction]')) 63 63 string="%s\n%s"%(string,fielddisplay(self,'steric_rate','rate of steric ocean expansion [mm/yr]')) 64 64 string="%s\n%s"%(string,fielddisplay(self,'degacc','accuracy (default .01 deg) for numerical discretization of the Green''s functions')) … … 71 71 72 72 #Convergence criterion: absolute, relative and residual 73 self.reltol= 0.01 # 1 per cent74 self.abstol= float('NaN') #default73 self.reltol=float('NaN') #default 74 self.abstol=0.001 #1 mm of sea level rise 75 75 76 76 #maximum of non-linear iterations. … … 87 87 self.tide_love_k=0.3055; #degree 2 88 88 89 #secular fluid love number:89 #secular fluid love number: 90 90 self.fluid_love=0.942; 91 91 … … 93 93 self.equatorial_moi=8.0077*10**37; # [kg m^2] 94 94 self.polar_moi =8.0345*10**37; # [kg m^2] 95 95 96 96 #mean rotational velocity of earth 97 97 self.angular_velocity=7.2921*10**-5; # [s^-1]
Note:
See TracChangeset
for help on using the changeset viewer.