source: issm/oecreview/Archive/23390-24306/ISSM-23800-23801.diff@ 24307

Last change on this file since 24307 was 24307, checked in by Mathieu Morlighem, 5 years ago

NEW: adding Archive/23390-24306

File size: 12.6 KB
  • ../trunk-jpl/src/c/classes/Elements/Penta.h

     
    7474                int            GetElementType(void);
    7575                void           GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
    7676                IssmDouble     GetGroundedPortion(IssmDouble* xyz_list);
     77                IssmDouble              GetIcefrontArea();
    7778                void           GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum);
    7879                void           GetInputValue(IssmDouble* pvalue,Node* node,int enumtype);
    7980                void           GetLevelCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum,IssmDouble level){_error_("not implemented yet");};
    8081                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);
    8183                Node*          GetNode(int node_number);
    8284                int            GetNodeIndex(Node* node);
    8385                int            GetNumberOfNodes(void);
     
    149151                void           ReduceMatrices(ElementMatrix* Ke,ElementVector* pe);
    150152                void           ResetFSBasalBoundaryCondition(void);
    151153                void           ResetHooks();
     154                void                            RignotMeltParameterization();
    152155                void           SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N,int M);
    153156                void           SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index);
    154157                void           SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters);
  • ../trunk-jpl/src/c/classes/FemModel.cpp

     
    14971497}/*}}}*/
    14981498void FemModel::IcefrontAreax(){/*{{{*/
    14991499
    1500         int numvertices      = this->GetElementsWidth();
    15011500        int numbasins;
    1502         IssmDouble* BasinId   = xNew<IssmDouble>(numvertices);
    15031501        this->parameters->FindParam(&numbasins,FrontalForcingsNumberofBasinsEnum);
    15041502        IssmDouble* basin_icefront_area           = xNewZeroInit<IssmDouble>(numbasins);
    15051503
     
    15091507
    15101508                for(int i=0;i<this->elements->Size();i++){
    15111509                        Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1510                        if(!element->IsOnBase()) continue;
     1511                        int  numvertices = element->GetNumberOfVertices();
     1512                        IssmDouble* BasinId   = xNew<IssmDouble>(numvertices);
    15121513                        element->GetInputListOnVertices(BasinId,FrontalForcingsBasinIdEnum);
    1513                         for(int j=0;j<numvertices;j++){
     1514                        for(int j=0;j<3;j++){
    15141515                                if(BasinId[j]==basin){
    15151516                                        local_icefront_area+=element->GetIcefrontArea();
    15161517                                        break;
    15171518                                }
    15181519                        }
     1520                        xDelete<IssmDouble>(BasinId);
    15191521                }
    15201522                ISSM_MPI_Reduce(&local_icefront_area,&total_icefront_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm());
    15211523                ISSM_MPI_Bcast(&total_icefront_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1522        
     1524               
    15231525                basin_icefront_area[basin-1]=total_icefront_area;
    15241526        }
    15251527       
    15261528        this->parameters->AddObject(new DoubleVecParam(FrontalForcingsBasinIcefrontAreaEnum,basin_icefront_area,numbasins));
     1529        xDelete<IssmDouble>(basin_icefront_area);
    15271530       
    1528         xDelete<IssmDouble>(basin_icefront_area);
    1529         xDelete<IssmDouble>(BasinId);
    15301531}/*}}}*/
    15311532void FemModel::IceMassx(IssmDouble* pM, bool scaled){/*{{{*/
    15321533
  • ../trunk-jpl/src/c/classes/Elements/Penta.cpp

     
    10691069        return phi;
    10701070}
    10711071/*}}}*/
     1072IssmDouble 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/*}}}*/
    10721173void       Penta::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    10731174
    10741175        /* Intermediaries */
     
    11321233        return lower_penta;
    11331234}
    11341235/*}}}*/
     1236void       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/*}}}*/
    11351312Node*      Penta::GetNode(int node_number){/*{{{*/
    11361313        _assert_(node_number>=0);
    11371314        _assert_(node_number<this->NumberofNodes(this->element_type));
     
    23112488
    23122489}
    23132490/*}}}*/
     2491void       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/*}}}*/
    23142550void       Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N, int M){/*{{{*/
    23152551
    23162552        IssmDouble  values[NUMVERTICES];
  • ../trunk-jpl/src/c/classes/Elements/Tria.cpp

     
    34193419        IssmDouble* basin_icefront_area=NULL;
    34203420
    34213421        /* Coefficients */
    3422         A    = 3e-4;        //
    3423         B    = 0.15;        //
     3422        A    = 3e-4;       
     3423        B    = 0.15;     
    34243424        alpha = 0.39;
    34253425        beta = 1.18;
    34263426       
     
    34573457
    34583458                if(xIsNan<IssmDouble>(meltrates[iv])) _error_("NaN found in vector");
    34593459                if(xIsInf<IssmDouble>(meltrates[iv])) _error_("Inf found in vector");
    3460                
    34613460        }
    34623461
    34633462        /*Add input*/
Note: See TracBrowser for help on using the repository browser.