source:
issm/oecreview/Archive/23390-24306/ISSM-23800-23801.diff@
24307
Last change on this file since 24307 was 24307, checked in by , 5 years ago | |
---|---|
File size: 12.6 KB |
-
../trunk-jpl/src/c/classes/Elements/Penta.h
74 74 int GetElementType(void); 75 75 void GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating); 76 76 IssmDouble GetGroundedPortion(IssmDouble* xyz_list); 77 IssmDouble GetIcefrontArea(); 77 78 void GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum); 78 79 void GetInputValue(IssmDouble* pvalue,Node* node,int enumtype); 79 80 void GetLevelCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum,IssmDouble level){_error_("not implemented yet");}; 80 81 void GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* levelsetvalues){_error_("not implemented yet");}; 82 void GetLevelsetIntersectionBase(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level); 81 83 Node* GetNode(int node_number); 82 84 int GetNodeIndex(Node* node); 83 85 int GetNumberOfNodes(void); … … 149 151 void ReduceMatrices(ElementMatrix* Ke,ElementVector* pe); 150 152 void ResetFSBasalBoundaryCondition(void); 151 153 void ResetHooks(); 154 void RignotMeltParameterization(); 152 155 void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N,int M); 153 156 void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index); 154 157 void SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters); -
../trunk-jpl/src/c/classes/FemModel.cpp
1497 1497 }/*}}}*/ 1498 1498 void FemModel::IcefrontAreax(){/*{{{*/ 1499 1499 1500 int numvertices = this->GetElementsWidth();1501 1500 int numbasins; 1502 IssmDouble* BasinId = xNew<IssmDouble>(numvertices);1503 1501 this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum); 1504 1502 IssmDouble* basin_icefront_area = xNewZeroInit<IssmDouble>(numbasins); 1505 1503 … … 1509 1507 1510 1508 for(int i=0;i<this->elements->Size();i++){ 1511 1509 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1510 if(!element->IsOnBase()) continue; 1511 int numvertices = element->GetNumberOfVertices(); 1512 IssmDouble* BasinId = xNew<IssmDouble>(numvertices); 1512 1513 element->GetInputListOnVertices(BasinId,FrontalForcingsBasinIdEnum); 1513 for(int j=0;j< numvertices;j++){1514 for(int j=0;j<3;j++){ 1514 1515 if(BasinId[j]==basin){ 1515 1516 local_icefront_area+=element->GetIcefrontArea(); 1516 1517 break; 1517 1518 } 1518 1519 } 1520 xDelete<IssmDouble>(BasinId); 1519 1521 } 1520 1522 ISSM_MPI_Reduce(&local_icefront_area,&total_icefront_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm()); 1521 1523 ISSM_MPI_Bcast(&total_icefront_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1522 1524 1523 1525 basin_icefront_area[basin-1]=total_icefront_area; 1524 1526 } 1525 1527 1526 1528 this->parameters->AddObject(new DoubleVecParam(FrontalForcingsBasinIcefrontAreaEnum,basin_icefront_area,numbasins)); 1529 xDelete<IssmDouble>(basin_icefront_area); 1527 1530 1528 xDelete<IssmDouble>(basin_icefront_area);1529 xDelete<IssmDouble>(BasinId);1530 1531 }/*}}}*/ 1531 1532 void FemModel::IceMassx(IssmDouble* pM, bool scaled){/*{{{*/ 1532 1533 -
../trunk-jpl/src/c/classes/Elements/Penta.cpp
1069 1069 return phi; 1070 1070 } 1071 1071 /*}}}*/ 1072 IssmDouble Penta::GetIcefrontArea(){/*{{{*/ 1073 1074 IssmDouble bed[NUMVERTICES]; //basinId[NUMVERTICES]; 1075 IssmDouble Haverage,frontarea; 1076 IssmDouble x1,y1,x2,y2,distance; 1077 IssmDouble lsf[NUMVERTICES], Haux[NUMVERTICES], surfaces[NUMVERTICES], bases[NUMVERTICES]; 1078 int* indices=NULL; 1079 IssmDouble* H=NULL;; 1080 int nrfrontbed,numiceverts; 1081 1082 /*Retrieve all inputs and parameters*/ 1083 GetInputListOnVertices(&bed[0],BedEnum); 1084 GetInputListOnVertices(&surfaces[0],SurfaceEnum); 1085 GetInputListOnVertices(&bases[0],BaseEnum); 1086 GetInputListOnVertices(&lsf[0],MaskIceLevelsetEnum); 1087 1088 if(!this->IsOnBase()) return 0; 1089 if(!IsZeroLevelset(MaskIceLevelsetEnum)) return 0; 1090 1091 nrfrontbed=0; 1092 for(int i=0;i<NUMVERTICES2D;i++){ 1093 /*Find if bed<0*/ 1094 if(bed[i]<0.) nrfrontbed++; 1095 } 1096 1097 if(nrfrontbed==3){ 1098 /*2. Find coordinates of where levelset crosses 0*/ 1099 int numiceverts; 1100 IssmDouble s[2],x[2],y[2]; 1101 this->GetLevelsetIntersectionBase(&indices, &numiceverts,&s[0],MaskIceLevelsetEnum,0.); 1102 _assert_(numiceverts); 1103 1104 /*3 Write coordinates*/ 1105 IssmDouble xyz_list[NUMVERTICES][3]; 1106 ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES); 1107 int counter = 0; 1108 if((numiceverts>0) && (numiceverts<NUMVERTICES2D)){ 1109 for(int i=0;i<numiceverts;i++){ 1110 for(int n=numiceverts;n<NUMVERTICES2D;n++){ // iterate over no-ice vertices 1111 x[counter] = xyz_list[indices[i]][0]+s[counter]*(xyz_list[indices[n]][0]-xyz_list[indices[i]][0]); 1112 y[counter] = xyz_list[indices[i]][1]+s[counter]*(xyz_list[indices[n]][1]-xyz_list[indices[i]][1]); 1113 counter++; 1114 } 1115 } 1116 } 1117 else if(numiceverts==NUMVERTICES2D){ //NUMVERTICES ice vertices: calving front lies on element edge 1118 1119 for(int i=0;i<NUMVERTICES2D;i++){ 1120 if(lsf[indices[i]]==0.){ 1121 x[counter]=xyz_list[indices[i]][0]; 1122 y[counter]=xyz_list[indices[i]][1]; 1123 counter++; 1124 } 1125 if(counter==2) break; 1126 } 1127 if(counter==1){ 1128 /*We actually have only 1 vertex on levelset, write a single point as a segment*/ 1129 x[counter]=x[0]; 1130 y[counter]=y[0]; 1131 counter++; 1132 } 1133 } 1134 else{ 1135 _error_("not sure what's going on here..."); 1136 } 1137 x1=x[0]; y1=y[0]; x2=x[1]; y2=y[1]; 1138 distance=sqrt(pow((x1-x2),2)+pow((y1-y2),2)); 1139 1140 int numthk=numiceverts+2; 1141 H=xNew<IssmDouble>(numthk); 1142 for(int iv=0;iv<NUMVERTICES2D;iv++) Haux[iv]=-bed[indices[iv]]; //sort bed in ice/noice 1143 1144 switch(numiceverts){ 1145 case 1: // average over triangle 1146 H[0]=Haux[0]; 1147 H[1]=Haux[0]+s[0]*(Haux[1]-Haux[0]); 1148 H[2]=Haux[0]+s[1]*(Haux[2]-Haux[0]); 1149 Haverage=(H[1]+H[2])/2; 1150 break; 1151 case 2: // average over quadrangle 1152 H[0]=Haux[0]; 1153 H[1]=Haux[1]; 1154 H[2]=Haux[0]+s[0]*(Haux[2]-Haux[0]); 1155 H[3]=Haux[1]+s[1]*(Haux[2]-Haux[1]); 1156 Haverage=(H[2]+H[3])/2; 1157 break; 1158 default: 1159 _error_("Number of ice covered vertices wrong in Tria::GetIceFrontArea(void)"); 1160 break; 1161 } 1162 frontarea=distance*Haverage; 1163 } 1164 else return 0; 1165 1166 xDelete<int>(indices); 1167 xDelete<IssmDouble>(H); 1168 1169 _assert_(frontarea>0); 1170 return frontarea; 1171 } 1172 /*}}}*/ 1072 1173 void Penta::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 1073 1174 1074 1175 /* Intermediaries */ … … 1132 1233 return lower_penta; 1133 1234 } 1134 1235 /*}}}*/ 1236 void Penta::GetLevelsetIntersectionBase(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/ 1237 1238 /* GetLevelsetIntersection computes: 1239 * 1. indices of element, sorted in [iceverts, noiceverts] in counterclockwise fashion, 1240 * 2. fraction of intersected triangle edges intersected by levelset, lying below level*/ 1241 1242 /*Intermediaries*/ 1243 int i, numiceverts, numnoiceverts; 1244 int ind0, ind1, lastindex; 1245 int indices_ice[NUMVERTICES2D],indices_noice[NUMVERTICES2D]; 1246 IssmDouble lsf[NUMVERTICES]; 1247 int* indices = xNew<int>(NUMVERTICES2D); 1248 1249 /*Retrieve all inputs and parameters*/ 1250 GetInputListOnVertices(&lsf[0],levelset_enum); 1251 1252 /* Determine distribution of ice over element. 1253 * Exploit: ice/no-ice parts are connected, so find starting vertex of segment*/ 1254 lastindex=0; 1255 for(i=0;i<NUMVERTICES2D;i++){ // go backwards along vertices, and check for sign change 1256 ind0=(NUMVERTICES2D-i)%NUMVERTICES2D; 1257 ind1=(ind0-1+NUMVERTICES2D)%NUMVERTICES2D; 1258 if((lsf[ind0]-level)*(lsf[ind1]-level)<=0.){ // levelset has been crossed, find last index belonging to segment 1259 if(lsf[ind1]==level) //if levelset intersects 2nd vertex, choose this vertex as last 1260 lastindex=ind1; 1261 else 1262 lastindex=ind0; 1263 break; 1264 } 1265 } 1266 1267 numiceverts=0; 1268 numnoiceverts=0; 1269 for(i=0;i<NUMVERTICES2D;i++){ 1270 ind0=(lastindex+i)%NUMVERTICES2D; 1271 if(lsf[i]<=level){ 1272 indices_ice[numiceverts]=i; 1273 numiceverts++; 1274 } 1275 else{ 1276 indices_noice[numnoiceverts]=i; 1277 numnoiceverts++; 1278 } 1279 } 1280 //merge indices 1281 for(i=0;i<numiceverts;i++){indices[i]=indices_ice[i];} 1282 for(i=0;i<numnoiceverts;i++){indices[numiceverts+i]=indices_noice[i];} 1283 1284 switch (numiceverts){ 1285 case 0: // no vertex has ice: element is ice free, no intersection 1286 for(i=0;i<2;i++) 1287 fraction[i]=0.; 1288 break; 1289 case 1: // one vertex has ice: 1290 for(i=0;i<2;i++){ 1291 fraction[i]=(level-lsf[indices[0]])/(lsf[indices[numiceverts+i]]-lsf[indices[0]]); 1292 } 1293 break; 1294 case 2: // two vertices have ice: fraction is computed from first ice vertex to last in CCW fashion 1295 for(i=0;i<2;i++){ 1296 fraction[i]=(level-lsf[indices[i]])/(lsf[indices[numiceverts]]-lsf[indices[i]]); 1297 } 1298 break; 1299 case NUMVERTICES2D: // all vertices have ice: return triangle area 1300 for(i=0;i<2;i++) 1301 fraction[i]=1.; 1302 break; 1303 default: 1304 _error_("Wrong number of ice vertices in Penta::GetLevelsetIntersectionBase!"); 1305 break; 1306 } 1307 1308 *pindices=indices; 1309 *pnumiceverts=numiceverts; 1310 } 1311 /*}}}*/ 1135 1312 Node* Penta::GetNode(int node_number){/*{{{*/ 1136 1313 _assert_(node_number>=0); 1137 1314 _assert_(node_number<this->NumberofNodes(this->element_type)); … … 2311 2488 2312 2489 } 2313 2490 /*}}}*/ 2491 void Penta::RignotMeltParameterization(){/*{{{*/ 2492 2493 IssmDouble A, B, alpha, beta; 2494 IssmDouble bed,qsg,qsg_basin,TF,yts; 2495 int numbasins; 2496 IssmDouble basinid[NUMVERTICES]; 2497 IssmDouble* basin_icefront_area=NULL; 2498 2499 /* Coefficients */ 2500 A = 3e-4; 2501 B = 0.15; 2502 alpha = 0.39; 2503 beta = 1.18; 2504 2505 /*Get inputs*/ 2506 Input* bed_input = this->GetInput(BedEnum); _assert_(bed_input); 2507 Input* qsg_input = this->GetInput(FrontalForcingsSubglacialDischargeEnum); _assert_(qsg_input); 2508 Input* TF_input = this->GetInput(FrontalForcingsThermalForcingEnum); _assert_(TF_input); 2509 GetInputListOnVertices(&basinid[0],FrontalForcingsBasinIdEnum); 2510 2511 this->FindParam(&yts, ConstantsYtsEnum); 2512 this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum); 2513 this->parameters->FindParam(&basin_icefront_area,&numbasins,FrontalForcingsBasinIcefrontAreaEnum); 2514 2515 IssmDouble meltrates[NUMVERTICES2D]; //frontal melt-rate 2516 2517 /* Start looping on the number of vertices: */ 2518 GaussPenta* gauss=new GaussPenta(); 2519 for(int iv=0;iv<NUMVERTICES2D;iv++){ 2520 gauss->GaussVertex(iv); 2521 2522 /* Get variables */ 2523 bed_input->GetInputValue(&bed,gauss); 2524 qsg_input->GetInputValue(&qsg,gauss); 2525 TF_input->GetInputValue(&TF,gauss); 2526 2527 if(basin_icefront_area[reCast<int>(basinid[iv])-1]==0.) meltrates[iv]=0.; 2528 else{ 2529 /* change the unit of qsg (m^3/d -> m/d) with ice front area */ 2530 qsg_basin=qsg/basin_icefront_area[reCast<int>(basinid[iv])-1]; 2531 2532 /* calculate melt rates */ 2533 meltrates[iv]=(A*max(-bed,0.)*pow(max(qsg_basin,0.),alpha)+B)*pow(max(TF,0.),beta)/86400; //[m/s] 2534 } 2535 2536 if(xIsNan<IssmDouble>(meltrates[iv])) _error_("NaN found in vector"); 2537 if(xIsInf<IssmDouble>(meltrates[iv])) _error_("Inf found in vector"); 2538 } 2539 2540 /*Add input*/ 2541 this->inputs->AddInput(new PentaInput(CalvingMeltingrateEnum,&meltrates[0],P1Enum)); 2542 2543 this->InputExtrude(CalvingMeltingrateEnum,-1); 2544 2545 /*Cleanup and return*/ 2546 xDelete<IssmDouble>(basin_icefront_area); 2547 delete gauss; 2548 } 2549 /*}}}*/ 2314 2550 void Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N, int M){/*{{{*/ 2315 2551 2316 2552 IssmDouble values[NUMVERTICES]; -
../trunk-jpl/src/c/classes/Elements/Tria.cpp
3419 3419 IssmDouble* basin_icefront_area=NULL; 3420 3420 3421 3421 /* Coefficients */ 3422 A = 3e-4; //3423 B = 0.15; //3422 A = 3e-4; 3423 B = 0.15; 3424 3424 alpha = 0.39; 3425 3425 beta = 1.18; 3426 3426 … … 3457 3457 3458 3458 if(xIsNan<IssmDouble>(meltrates[iv])) _error_("NaN found in vector"); 3459 3459 if(xIsInf<IssmDouble>(meltrates[iv])) _error_("Inf found in vector"); 3460 3461 3460 } 3462 3461 3463 3462 /*Add input*/
Note:
See TracBrowser
for help on using the repository browser.