Index: ../trunk-jpl/src/c/classes/Elements/Penta.h =================================================================== --- ../trunk-jpl/src/c/classes/Elements/Penta.h (revision 23800) +++ ../trunk-jpl/src/c/classes/Elements/Penta.h (revision 23801) @@ -74,10 +74,12 @@ int GetElementType(void); void GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating); IssmDouble GetGroundedPortion(IssmDouble* xyz_list); + IssmDouble GetIcefrontArea(); void GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum); void GetInputValue(IssmDouble* pvalue,Node* node,int enumtype); void GetLevelCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum,IssmDouble level){_error_("not implemented yet");}; void GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* levelsetvalues){_error_("not implemented yet");}; + void GetLevelsetIntersectionBase(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level); Node* GetNode(int node_number); int GetNodeIndex(Node* node); int GetNumberOfNodes(void); @@ -149,6 +151,7 @@ void ReduceMatrices(ElementMatrix* Ke,ElementVector* pe); void ResetFSBasalBoundaryCondition(void); void ResetHooks(); + void RignotMeltParameterization(); void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N,int M); void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index); void SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters); Index: ../trunk-jpl/src/c/classes/FemModel.cpp =================================================================== --- ../trunk-jpl/src/c/classes/FemModel.cpp (revision 23800) +++ ../trunk-jpl/src/c/classes/FemModel.cpp (revision 23801) @@ -1497,9 +1497,7 @@ }/*}}}*/ void FemModel::IcefrontAreax(){/*{{{*/ - int numvertices = this->GetElementsWidth(); int numbasins; - IssmDouble* BasinId = xNew(numvertices); this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum); IssmDouble* basin_icefront_area = xNewZeroInit(numbasins); @@ -1509,24 +1507,27 @@ for(int i=0;ielements->Size();i++){ Element* element=xDynamicCast(this->elements->GetObjectByOffset(i)); + if(!element->IsOnBase()) continue; + int numvertices = element->GetNumberOfVertices(); + IssmDouble* BasinId = xNew(numvertices); element->GetInputListOnVertices(BasinId,FrontalForcingsBasinIdEnum); - for(int j=0;jGetIcefrontArea(); break; } } + xDelete(BasinId); } ISSM_MPI_Reduce(&local_icefront_area,&total_icefront_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm()); ISSM_MPI_Bcast(&total_icefront_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); - + basin_icefront_area[basin-1]=total_icefront_area; } this->parameters->AddObject(new DoubleVecParam(FrontalForcingsBasinIcefrontAreaEnum,basin_icefront_area,numbasins)); + xDelete(basin_icefront_area); - xDelete(basin_icefront_area); - xDelete(BasinId); }/*}}}*/ void FemModel::IceMassx(IssmDouble* pM, bool scaled){/*{{{*/ Index: ../trunk-jpl/src/c/classes/Elements/Penta.cpp =================================================================== --- ../trunk-jpl/src/c/classes/Elements/Penta.cpp (revision 23800) +++ ../trunk-jpl/src/c/classes/Elements/Penta.cpp (revision 23801) @@ -1069,6 +1069,107 @@ return phi; } /*}}}*/ +IssmDouble Penta::GetIcefrontArea(){/*{{{*/ + + IssmDouble bed[NUMVERTICES]; //basinId[NUMVERTICES]; + IssmDouble Haverage,frontarea; + IssmDouble x1,y1,x2,y2,distance; + IssmDouble lsf[NUMVERTICES], Haux[NUMVERTICES], surfaces[NUMVERTICES], bases[NUMVERTICES]; + int* indices=NULL; + IssmDouble* H=NULL;; + int nrfrontbed,numiceverts; + + /*Retrieve all inputs and parameters*/ + GetInputListOnVertices(&bed[0],BedEnum); + GetInputListOnVertices(&surfaces[0],SurfaceEnum); + GetInputListOnVertices(&bases[0],BaseEnum); + GetInputListOnVertices(&lsf[0],MaskIceLevelsetEnum); + + if(!this->IsOnBase()) return 0; + if(!IsZeroLevelset(MaskIceLevelsetEnum)) return 0; + + nrfrontbed=0; + for(int i=0;iGetLevelsetIntersectionBase(&indices, &numiceverts,&s[0],MaskIceLevelsetEnum,0.); + _assert_(numiceverts); + + /*3 Write coordinates*/ + IssmDouble xyz_list[NUMVERTICES][3]; + ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES); + int counter = 0; + if((numiceverts>0) && (numiceverts(numthk); + for(int iv=0;iv(indices); + xDelete(H); + + _assert_(frontarea>0); + return frontarea; +} +/*}}}*/ void Penta::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ /* Intermediaries */ @@ -1132,6 +1233,82 @@ return lower_penta; } /*}}}*/ +void Penta::GetLevelsetIntersectionBase(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/ + + /* GetLevelsetIntersection computes: + * 1. indices of element, sorted in [iceverts, noiceverts] in counterclockwise fashion, + * 2. fraction of intersected triangle edges intersected by levelset, lying below level*/ + + /*Intermediaries*/ + int i, numiceverts, numnoiceverts; + int ind0, ind1, lastindex; + int indices_ice[NUMVERTICES2D],indices_noice[NUMVERTICES2D]; + IssmDouble lsf[NUMVERTICES]; + int* indices = xNew(NUMVERTICES2D); + + /*Retrieve all inputs and parameters*/ + GetInputListOnVertices(&lsf[0],levelset_enum); + + /* Determine distribution of ice over element. + * Exploit: ice/no-ice parts are connected, so find starting vertex of segment*/ + lastindex=0; + for(i=0;i=0); _assert_(node_numberNumberofNodes(this->element_type)); @@ -2311,6 +2488,65 @@ } /*}}}*/ +void Penta::RignotMeltParameterization(){/*{{{*/ + + IssmDouble A, B, alpha, beta; + IssmDouble bed,qsg,qsg_basin,TF,yts; + int numbasins; + IssmDouble basinid[NUMVERTICES]; + IssmDouble* basin_icefront_area=NULL; + + /* Coefficients */ + A = 3e-4; + B = 0.15; + alpha = 0.39; + beta = 1.18; + + /*Get inputs*/ + Input* bed_input = this->GetInput(BedEnum); _assert_(bed_input); + Input* qsg_input = this->GetInput(FrontalForcingsSubglacialDischargeEnum); _assert_(qsg_input); + Input* TF_input = this->GetInput(FrontalForcingsThermalForcingEnum); _assert_(TF_input); + GetInputListOnVertices(&basinid[0],FrontalForcingsBasinIdEnum); + + this->FindParam(&yts, ConstantsYtsEnum); + this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum); + this->parameters->FindParam(&basin_icefront_area,&numbasins,FrontalForcingsBasinIcefrontAreaEnum); + + IssmDouble meltrates[NUMVERTICES2D]; //frontal melt-rate + + /* Start looping on the number of vertices: */ + GaussPenta* gauss=new GaussPenta(); + for(int iv=0;ivGaussVertex(iv); + + /* Get variables */ + bed_input->GetInputValue(&bed,gauss); + qsg_input->GetInputValue(&qsg,gauss); + TF_input->GetInputValue(&TF,gauss); + + if(basin_icefront_area[reCast(basinid[iv])-1]==0.) meltrates[iv]=0.; + else{ + /* change the unit of qsg (m^3/d -> m/d) with ice front area */ + qsg_basin=qsg/basin_icefront_area[reCast(basinid[iv])-1]; + + /* calculate melt rates */ + meltrates[iv]=(A*max(-bed,0.)*pow(max(qsg_basin,0.),alpha)+B)*pow(max(TF,0.),beta)/86400; //[m/s] + } + + if(xIsNan(meltrates[iv])) _error_("NaN found in vector"); + if(xIsInf(meltrates[iv])) _error_("Inf found in vector"); + } + + /*Add input*/ + this->inputs->AddInput(new PentaInput(CalvingMeltingrateEnum,&meltrates[0],P1Enum)); + + this->InputExtrude(CalvingMeltingrateEnum,-1); + + /*Cleanup and return*/ + xDelete(basin_icefront_area); + delete gauss; +} +/*}}}*/ void Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N, int M){/*{{{*/ IssmDouble values[NUMVERTICES]; Index: ../trunk-jpl/src/c/classes/Elements/Tria.cpp =================================================================== --- ../trunk-jpl/src/c/classes/Elements/Tria.cpp (revision 23800) +++ ../trunk-jpl/src/c/classes/Elements/Tria.cpp (revision 23801) @@ -3419,8 +3419,8 @@ IssmDouble* basin_icefront_area=NULL; /* Coefficients */ - A = 3e-4; // - B = 0.15; // + A = 3e-4; + B = 0.15; alpha = 0.39; beta = 1.18; @@ -3457,7 +3457,6 @@ if(xIsNan(meltrates[iv])) _error_("NaN found in vector"); if(xIsInf(meltrates[iv])) _error_("Inf found in vector"); - } /*Add input*/