Changeset 26626


Ignore:
Timestamp:
11/15/21 14:39:11 (3 years ago)
Author:
vverjans
Message:

CHG: IceVolume() in Tria.cpp and Penta.cpp can account for partial ice coverage of frontal elements (currently disabled using false condition)

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  
    12361236        /*return PentaRef field*/
    12371237        return this->element_type;
     1238}
     1239/*}}}*/
     1240void       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;
    12381323}
    12391324/*}}}*/
     
    20992184        IssmDouble base,height,scalefactor;
    21002185        IssmDouble xyz_list[NUMVERTICES][3];
     2186        IssmDouble lsf[NUMVERTICES];
    21012187
    21022188        if(!IsIceInElement())return 0;
     
    21042190        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    21052191
    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        }
    21192241
    21202242        /*Return: */
  • TabularUnified issm/trunk-jpl/src/c/classes/Elements/Penta.h

    r26501 r26626  
    8686                IssmDouble     GetGroundedPortion(IssmDouble* xyz_list);
    8787                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);
    8889                void       GetNodalWeightsAndAreaAndCentroidsFromLeveset(IssmDouble* loadweights, IssmDouble* ploadarea, IssmDouble* platbar, IssmDouble* plongbar, IssmDouble late, IssmDouble longe, IssmDouble area,  int levelsetenum){_error_("not implemented yet");};
    8990                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  
    34893489        parameters->FindParam(&domaintype,DomainTypeEnum);
    34903490
     3491        /*Relict code
    34913492        if(false && IsIcefront()){
    34923493                //Assumption: linear ice thickness profile on element.
     
    35433544                for(i=0;i<numthk;i++)   Haverage+=H[i];
    35443545                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   }
    35463586        else{
    35473587                /*First get back the area of the base*/
     
    35613601        }
    35623602
     3603       
    35633604        /*Cleanup & return: */
    35643605        xDelete<int>(indices);
    35653606        xDelete<IssmDouble>(H);
    35663607        xDelete<IssmDouble>(SF);
     3608        xDelete<IssmDouble>(lsf);
    35673609
    35683610        if(domaintype==Domain2DverticalEnum){
Note: See TracChangeset for help on using the changeset viewer.