Changeset 26626
- Timestamp:
- 11/15/21 14:39:11 (3 years ago)
- Location:
- issm/trunk-jpl/src/c/classes/Elements
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Penta.cpp ¶
r26531 r26626 1236 1236 /*return PentaRef field*/ 1237 1237 return this->element_type; 1238 } 1239 /*}}}*/ 1240 void Penta::GetFractionGeometry2D(IssmDouble* weights, IssmDouble* pphi, int* ppoint1,IssmDouble* pfraction1,IssmDouble* pfraction2, bool* ptrapezeisnegative, IssmDouble* gl){/*{{{*/ 1241 1242 /*Compute portion of element that is grounded based on levelset at the 3 lower vertices of the Penta element*/ 1243 bool trapezeisnegative=true; 1244 int point; 1245 const IssmPDouble epsilon= 1.e-15; 1246 IssmDouble f1,f2,phi; 1247 1248 /*Weights*/ 1249 Gauss* gauss = NULL; 1250 IssmDouble loadweights_g[NUMVERTICES2D]; 1251 IssmDouble total_weight = 0; 1252 1253 _assert_(!xIsNan<IssmDouble>(gl[0])); 1254 _assert_(!xIsNan<IssmDouble>(gl[1])); 1255 _assert_(!xIsNan<IssmDouble>(gl[2])); 1256 1257 /*Be sure that values are not zero*/ 1258 if(gl[0]==0.) gl[0] = gl[0]+epsilon; 1259 if(gl[1]==0.) gl[1] = gl[1]+epsilon; 1260 if(gl[2]==0.) gl[2] = gl[2]+epsilon; 1261 1262 /*Check that not all nodes are positive or negative: */ 1263 if(gl[0]>0 && gl[1]>0 && gl[2]>0){ 1264 point = 0; 1265 f1 = 1.; 1266 f2 = 1.; 1267 } 1268 else if(gl[0]<0 && gl[1]<0 && gl[2]<0){ 1269 point = 0; 1270 f1 = 0.; 1271 f2 = 0.; 1272 } 1273 else{ 1274 if(gl[0]*gl[1]*gl[2]<0) trapezeisnegative = false; 1275 1276 /*Find the similar nodes*/ 1277 if(gl[0]*gl[1]>0){ 1278 point = 2; 1279 f1 = gl[2]/(gl[2]-gl[0]); 1280 f2 = gl[2]/(gl[2]-gl[1]); 1281 } 1282 else if(gl[1]*gl[2]>0){ 1283 point = 0; 1284 f1 = gl[0]/(gl[0]-gl[1]); 1285 f2 = gl[0]/(gl[0]-gl[2]); 1286 } 1287 else if(gl[0]*gl[2]>0){ 1288 point = 1; 1289 f1 = gl[1]/(gl[1]-gl[2]); 1290 f2 = gl[1]/(gl[1]-gl[0]); 1291 } 1292 else _error_("case not possible"); 1293 } 1294 if(trapezeisnegative) phi = 1-f1*f2; 1295 else phi = f1*f2; 1296 1297 /*Compute weights*/ 1298 gauss = this->NewGauss(point,f1,f2,trapezeisnegative,2); 1299 1300 total_weight = 0.0; 1301 for(int i=0;i<NUMVERTICES2D;i++)weights[i] = 0; 1302 while(gauss->next()){ 1303 GetNodalFunctions(&loadweights_g[0],gauss,P1Enum); 1304 for(int i=0;i<NUMVERTICES2D;i++)weights[i] += loadweights_g[i]*gauss->weight; 1305 total_weight += gauss->weight; 1306 } 1307 1308 /*Normalize to phi*/ 1309 if(total_weight>0.){ 1310 for(int i=0;i<NUMVERTICES2D;i++) weights[i] = weights[i]*phi/total_weight; 1311 } 1312 else for(int i=0;i<NUMVERTICES2D;i++) weights[i] = 0.0; 1313 1314 /*Cleanup*/ 1315 delete gauss; 1316 1317 /*Assign output pointers*/ 1318 *pphi = phi; 1319 *ppoint1 = point; 1320 *pfraction1 = f1; 1321 *pfraction2 = f2; 1322 *ptrapezeisnegative = trapezeisnegative; 1238 1323 } 1239 1324 /*}}}*/ … … 2099 2184 IssmDouble base,height,scalefactor; 2100 2185 IssmDouble xyz_list[NUMVERTICES][3]; 2186 IssmDouble lsf[NUMVERTICES]; 2101 2187 2102 2188 if(!IsIceInElement())return 0; … … 2104 2190 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 2105 2191 2106 /*First calculate the area of the base (cross section triangle) 2107 * http://en.wikipedia.org/wiki/Pentangle 2108 * base = 1/2 abs((xA-xC)(yB-yA)-(xA-xB)(yC-yA))*/ 2109 base = 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1])); 2110 2111 if(scaled==true){ //scale for area projection correction 2112 Input* scalefactor_input = this->GetInput(MeshScaleFactorEnum); _assert_(scalefactor_input); 2113 scalefactor_input->GetInputAverage(&scalefactor); 2114 base=base*scalefactor; 2115 } 2116 2117 /*Now get the average height*/ 2118 height = 1./3.*((xyz_list[3][2]-xyz_list[0][2])+(xyz_list[4][2]-xyz_list[1][2])+(xyz_list[5][2]-xyz_list[2][2])); 2192 Element::GetInputListOnVertices(&lsf[0],MaskIceLevelsetEnum); 2193 /*Deal with partially ice-covered elements*/ 2194 if(false && (lsf[0]*lsf[1]<=0 || lsf[0]*lsf[2]<=0 || lsf[1]*lsf[2]<=0)){ 2195 bool istrapneg; 2196 int point; 2197 IssmDouble f1,f2,phi; 2198 IssmDouble* heights = xNew<IssmDouble>(NUMVERTICES2D); 2199 IssmDouble weights[NUMVERTICES2D]; 2200 IssmDouble lsf2d[NUMVERTICES2D]; 2201 for(int i=0;i<NUMVERTICES2D;i++){ 2202 heights[i] = xyz_list[i+NUMVERTICES2D][2]-xyz_list[i][2]; 2203 lsf2d[i] = lsf[i]; 2204 } 2205 GetFractionGeometry2D(weights,&phi,&point,&f1,&f2,&istrapneg,lsf2d); 2206 2207 IssmDouble basetot; 2208 height = 0.0; 2209 for(int i=0;i<NUMVERTICES2D;i++) height += weights[i]*heights[i]; 2210 basetot = 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1])); 2211 base = basetot*phi; 2212 2213 /*Account for scaling factor averaged over subelement 2D area*/ 2214 if(scaled==true){ 2215 IssmDouble* scalefactor_vertices = xNew<IssmDouble>(NUMVERTICES); 2216 Element::GetInputListOnVertices(&scalefactor_vertices[0],MeshScaleFactorEnum); 2217 /*Compute loop only over lower vertices: i<NUMVERTICES2D*/ 2218 scalefactor = 0.0; 2219 for(int i=0;i<NUMVERTICES2D;i++) scalefactor += weights[i]*scalefactor_vertices[i]; 2220 base = base*scalefactor; 2221 xDelete<IssmDouble>(scalefactor_vertices); 2222 } 2223 xDelete<IssmDouble>(heights); 2224 } 2225 2226 else{ 2227 /*First calculate the area of the base (cross section triangle) 2228 * http://en.wikipedia.org/wiki/Pentangle 2229 * base = 1/2 abs((xA-xC)(yB-yA)-(xA-xB)(yC-yA))*/ 2230 base = 1./2.*fabs((xyz_list[0][0]-xyz_list[2][0])*(xyz_list[1][1]-xyz_list[0][1]) - (xyz_list[0][0]-xyz_list[1][0])*(xyz_list[2][1]-xyz_list[0][1])); 2231 2232 if(scaled==true){ //scale for area projection correction 2233 Input* scalefactor_input = this->GetInput(MeshScaleFactorEnum); _assert_(scalefactor_input); 2234 scalefactor_input->GetInputAverage(&scalefactor); 2235 base=base*scalefactor; 2236 } 2237 2238 /*Now get the average height*/ 2239 height = 1./3.*((xyz_list[3][2]-xyz_list[0][2])+(xyz_list[4][2]-xyz_list[1][2])+(xyz_list[5][2]-xyz_list[2][2])); 2240 } 2119 2241 2120 2242 /*Return: */ -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Penta.h ¶
r26501 r26626 86 86 IssmDouble GetGroundedPortion(IssmDouble* xyz_list); 87 87 void GetFractionGeometry(IssmDouble* weights, IssmDouble* pphi, int* ppoint1,IssmDouble* pfraction1,IssmDouble* pfraction2, bool* ptrapezeisnegative, IssmDouble* gl){_error_("not implemented yet");}; 88 void GetFractionGeometry2D(IssmDouble* weights, IssmDouble* pphi, int* ppoint1,IssmDouble* pfraction1,IssmDouble* pfraction2, bool* ptrapezeisnegative, IssmDouble* gl); 88 89 void GetNodalWeightsAndAreaAndCentroidsFromLeveset(IssmDouble* loadweights, IssmDouble* ploadarea, IssmDouble* platbar, IssmDouble* plongbar, IssmDouble late, IssmDouble longe, IssmDouble area, int levelsetenum){_error_("not implemented yet");}; 89 90 void GetNodalWeightsAndAreaAndCentroidsFromLeveset(IssmDouble* loadweights, IssmDouble* ploadarea, IssmDouble* platbar, IssmDouble* plongbar, IssmDouble late, IssmDouble longe, IssmDouble area, int levelset1enum, int levelset2enum){_error_("not implemented yet");}; -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Tria.cpp ¶
r26531 r26626 3489 3489 parameters->FindParam(&domaintype,DomainTypeEnum); 3490 3490 3491 /*Relict code 3491 3492 if(false && IsIcefront()){ 3492 3493 //Assumption: linear ice thickness profile on element. … … 3543 3544 for(i=0;i<numthk;i++) Haverage+=H[i]; 3544 3545 Haverage/=IssmDouble(numthk); 3545 } 3546 }*/ 3547 3548 IssmDouble* lsf = xNew<IssmDouble>(NUMVERTICES); 3549 Element::GetInputListOnVertices(&lsf[0],MaskIceLevelsetEnum); 3550 /*Deal with partially ice-covered elements*/ 3551 if(false && (lsf[0]*lsf[1]<=0 || lsf[0]*lsf[2]<=0 || lsf[1]*lsf[2]<=0)){ 3552 bool istrapneg; 3553 int point; 3554 IssmDouble* weights = xNew<IssmDouble>(NUMVERTICES); 3555 IssmDouble* surfaces = xNew<IssmDouble>(NUMVERTICES); 3556 IssmDouble* bases = xNew<IssmDouble>(NUMVERTICES); 3557 IssmDouble* Hice = xNew<IssmDouble>(NUMVERTICES); 3558 IssmDouble area_basetot,f1,f2,phi; 3559 /*Average thickness over subelement*/ 3560 Element::GetInputListOnVertices(&surfaces[0],SurfaceEnum); 3561 Element::GetInputListOnVertices(&bases[0],BaseEnum); 3562 GetFractionGeometry(weights,&phi,&point,&f1,&f2,&istrapneg,lsf); 3563 for(int i=0;i<NUMVERTICES;i++) Hice[i] = surfaces[i]-bases[i]; 3564 Haverage = 0.0; 3565 for(int i=0;i<NUMVERTICES;i++) Haverage += weights[i]*Hice[i]; 3566 /*Get back area of ice-covered base*/ 3567 area_basetot = this->GetArea(); 3568 area_base = phi*area_basetot; 3569 3570 /*Account for scaling factor averaged over subelement*/ 3571 if(scaled==true){ 3572 IssmDouble* scalefactor_vertices = xNew<IssmDouble>(NUMVERTICES); 3573 Element::GetInputListOnVertices(&scalefactor_vertices[0],MeshScaleFactorEnum); 3574 scalefactor = 0.0; 3575 for(int i=0;i<NUMVERTICES;i++) scalefactor += weights[i]*scalefactor_vertices[i]; 3576 area_base = area_base*scalefactor; 3577 xDelete<IssmDouble>(scalefactor_vertices); 3578 } 3579 3580 /*Cleanup*/ 3581 xDelete<IssmDouble>(weights); 3582 xDelete<IssmDouble>(surfaces); 3583 xDelete<IssmDouble>(bases); 3584 xDelete<IssmDouble>(Hice); 3585 } 3546 3586 else{ 3547 3587 /*First get back the area of the base*/ … … 3561 3601 } 3562 3602 3603 3563 3604 /*Cleanup & return: */ 3564 3605 xDelete<int>(indices); 3565 3606 xDelete<IssmDouble>(H); 3566 3607 xDelete<IssmDouble>(SF); 3608 xDelete<IssmDouble>(lsf); 3567 3609 3568 3610 if(domaintype==Domain2DverticalEnum){
Note:
See TracChangeset
for help on using the changeset viewer.