Changeset 21802


Ignore:
Timestamp:
07/17/17 21:18:32 (8 years ago)
Author:
Mathieu Morlighem
Message:

CHG: working on bamg amr

Location:
issm/trunk-jpl/src
Files:
3 added
18 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/Makefile.am

    r21623 r21802  
    4747                                         ./bamg/Mesh.cpp\
    4848                                         ./shared/Bamg/BigPrimeNumber.cpp\
     49                                         ./classes/AmrBamg.cpp\
    4950                                         ./modules/Bamgx/Bamgx.cpp\
    5051                                         ./modules/BamgConvertMeshx/BamgConvertMeshx.cpp\
  • issm/trunk-jpl/src/c/bamg/BamgOpts.cpp

    r18064 r21802  
    55BamgOpts::BamgOpts(){/*{{{*/
    66
    7         this->anisomax=0;
    8         this->cutoff=0;
    9         this->coeff=0;
    10         this->errg=0;
    11         this->gradation=0;
    12         this->Hessiantype=0;
    13         this->MaxCornerAngle=0;
    14         this->maxnbv=0;
    15         this->maxsubdiv=0;
    16         this->Metrictype=0;
    17         this->nbjacobi=0;
    18         this->nbsmooth=0;
    19         this->omega=0;
    20         this->power=0;
    21         this->random=0;
    22         this->verbose=0;
     7        this->anisomax          = 0;
     8        this->cutoff            = 0;
     9        this->coeff             = 0;
     10        this->errg              = 0;
     11        this->gradation         = 0;
     12        this->Hessiantype       = 0;
     13        this->MaxCornerAngle    = 0;
     14        this->maxnbv            = 0;
     15        this->maxsubdiv         = 0;
     16        this->Metrictype        = 0;
     17        this->nbjacobi          = 0;
     18        this->nbsmooth          = 0;
     19        this->omega             = 0;
     20        this->power             = 0;
     21        this->random            = 0;
     22        this->verbose           = 0;
    2323
    24         this->Crack=0;
    25         this->geometricalmetric=0;
    26         this->KeepVertices=0;
    27         this->splitcorners=0;
     24        this->Crack             = 0;
     25        this->geometricalmetric = 0;
     26        this->KeepVertices      = 0;
     27        this->splitcorners      = 0;
    2828
    29         this->hmin=0;
    30         this->hmax=0;
     29        this->hmin              = 0;
     30        this->hmax              = 0;
    3131        this->hminVertices=NULL; this->hminVerticesSize[0]=this->hminVerticesSize[1]=0;
    3232        this->hmaxVertices=NULL; this->hmaxVerticesSize[0]=this->hmaxVerticesSize[1]=0;
  • issm/trunk-jpl/src/c/bamg/Mesh.cpp

    r21791 r21802  
    698698                        for (i=0;i<nbsubdomains;i++){
    699699                                bamgmesh->SubDomains[i*4+0]=3;
    700                                 bamgmesh->SubDomains[i*4+1]=reft[GetId(subdomains[i].head)];
     700                                bamgmesh->SubDomains[i*4+1]=reft[GetId(subdomains[i].head)]+1;//MATLAB indexing
    701701                                bamgmesh->SubDomains[i*4+2]=1;
    702702                                bamgmesh->SubDomains[i*4+3]=subdomains[i].ReferenceNumber;
     
    30763076                                IssmDouble area_3 =((bv.r.x -(*tcvj)(1)->r.x)*((*tcvj)(0)->r.y-(*tcvj)(1)->r.y)
    30773077                                                - (bv.r.y -(*tcvj)(1)->r.y)*((*tcvj)(0)->r.x-(*tcvj)(1)->r.x));
    3078                                 if(area_1<0 || area_2<0 || area_3<0){
    3079                                         pointsoutside = true;
    3080                                         continue;
    3081                                 }
     3078                        //      if(area_1<0 || area_2<0 || area_3<0){
     3079                        //              pointsoutside = true;
     3080                        //              continue;
     3081                        //      }
    30823082                                if(!bv.GeomEdgeHook){
    30833083                                        vertices[nbv].r              = bv.r;
     
    30863086                                }
    30873087                        }
    3088                         if(pointsoutside) _printf_("WARNING: One or more points of the initial mesh fall outside of the geometric boundary\n");
     3088                        //if(pointsoutside) _printf_("WARNING: One or more points of the initial mesh fall outside of the geometric boundary\n");
    30893089                        Bh.CreateSingleVertexToTriangleConnectivity();     
    30903090                        InsertNewPoints(nbvold,NbTSwap,bamgopts->random);
  • issm/trunk-jpl/src/c/classes/FemModel.cpp

    r21799 r21802  
    4545
    4646        /*configuration: */
    47         int  solution_type;
     47        int  solution_type,amrtype,amr_frequency;
    4848        int  ierr;
    4949
     
    8080        this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum));
    8181
    82         #ifdef _HAVE_NEOPZ_
    83         this->InitializeAdaptiveRefinement();
    84         #endif
     82   /*AMR stuff*/
     83        this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
     84        if(amr_frequency){
     85                this->parameters->FindParam(&amrtype,AmrTypeEnum);
     86                switch(amrtype){
     87
     88                        #ifdef _HAVE_NEOPZ_
     89                        case AmrNeopzEnum: this->InitializeAdaptiveRefinementNeopz(); break;
     90                        #endif
     91
     92                        #ifdef _HAVE_BAMG_
     93                        case AmrBamgEnum: this->InitializeAdaptiveRefinementBamg(); break;
     94                        #endif
     95
     96                        default: _error_("not implemented yet");
     97                }
     98        }
    8599
    86100        /*Free resources */
     
    140154        #ifdef _HAVE_NEOPZ_
    141155        if(amr)delete amr;
     156        #endif
     157
     158        #ifdef _HAVE_BAMG_
     159        if(amrbamg)delete amrbamg;
    142160        #endif
    143161
     
    15021520}
    15031521/*}}}*/
     1522void FemModel::ReMesh(void){/*{{{*/
     1523
     1524        /*Intermediaries*/
     1525        IssmDouble *newx                        = NULL;
     1526        IssmDouble *newy                        = NULL;
     1527        IssmDouble *newz                        = NULL;
     1528        int *newelementslist            = NULL;
     1529        int newnumberofvertices = -1;
     1530        int newnumberofelements = -1;
     1531        bool* my_elements                       = NULL;
     1532        int* my_vertices                        = NULL;
     1533        int elementswidth       = this->GetElementsWidth();//just tria elements in this version
     1534        int amrtype;
     1535
     1536        /*Branch to specific amr depending on requested method*/       
     1537        parameters->FindParam(&amrtype,AmrTypeEnum);
     1538        switch(amrtype){
     1539                #ifdef _HAVE_NEOPZ_
     1540                case AmrNeopzEnum: this->ReMeshNeopz(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); break;
     1541                #endif
     1542
     1543                #ifdef _HAVE_BAMG_
     1544                case AmrBamgEnum: this->ReMeshBamg(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); break;
     1545                #endif
     1546
     1547                default: _error_("not implemented yet");
     1548        }
     1549
     1550        /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/
     1551        this->ElementsAndVerticesPartitioning(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,&my_elements,&my_vertices);
     1552
     1553        if(this->loads->Size()!=0) _error_("not supported yet");
     1554
     1555        /*Create vertices*/
     1556        Vertices* new_vertices=new Vertices();
     1557        this->CreateVertices(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,my_vertices,newx,newy,newz,new_vertices);
     1558
     1559        /*Creating elements*/
     1560        /*Just Tria in this version*/
     1561        Elements* new_elements=new Elements();
     1562        this->CreateElements(newnumberofelements,elementswidth,newelementslist,my_elements,new_elements);
     1563
     1564        /*Creating materials*/
     1565        Materials* new_materials=new Materials();
     1566        this->CreateMaterials(newnumberofelements,my_elements,new_materials);
     1567
     1568        /*Creating nodes and constraints*/
     1569        /*Just SSA (2D) and P1 in this version*/
     1570        Nodes* new_nodes=new Nodes();
     1571        Constraints* new_constraints=new Constraints();
     1572
     1573        int nodecounter=0;
     1574        int constraintcounter=0;
     1575        for(int i=0;i<this->nummodels;i++){//create nodes for each analysis in analysis_type_list
     1576
     1577                int analysis_enum = this->analysis_type_list[i];
     1578
     1579                /*As the domain is 2D, it is not necessary to create nodes for this analysis*/
     1580                /*itapopo must verify if domain is not 3D. Only 2D in this version!*/
     1581                if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue;     
     1582
     1583                this->CreateNodes(newnumberofvertices,my_vertices,nodecounter,analysis_enum,new_nodes);
     1584                if(analysis_enum==StressbalanceAnalysisEnum) this->CreateConstraints(newnumberofvertices,newnumberofelements,nodecounter,constraintcounter,newx,newy,my_vertices,new_constraints);
     1585                this->UpdateElements(newnumberofelements,newelementslist,my_elements,nodecounter,i,new_elements);
     1586
     1587                if(new_nodes->Size()) nodecounter=new_nodes->MaximumId();
     1588                constraintcounter = new_constraints->NumberOfConstraints();
     1589                /*Make sure nodecounter is at least 0 (if no node exists, maxid will be -1*/
     1590                _assert_(nodecounter>=0);
     1591        }
     1592
     1593        new_elements->Presort();
     1594        new_nodes->Presort();
     1595        new_vertices->Presort();
     1596        this->loads->Presort();
     1597        new_materials->Presort();
     1598        new_constraints->Presort();
     1599
     1600        /*reset hooks for elements, loads and nodes: */
     1601        new_elements->ResetHooks();
     1602        this->loads->ResetHooks();
     1603        new_materials->ResetHooks();
     1604
     1605        /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
     1606        int analysis_type;
     1607        for(int i=0;i<this->nummodels;i++){
     1608                analysis_type=this->analysis_type_list[i];
     1609                //SetCurrentConfiguration(analysis_type);
     1610
     1611                this->analysis_counter=i;       
     1612                /*Now, plug analysis_counter and analysis_type inside the parameters: */
     1613                this->parameters->SetParam(this->analysis_counter,AnalysisCounterEnum);
     1614                this->parameters->SetParam(analysis_type,AnalysisTypeEnum);
     1615                this->parameters->SetParam(analysis_type,ConfigurationTypeEnum);
     1616
     1617                /*configure elements, loads and nodes, for this new analysis: */
     1618                new_elements->SetCurrentConfiguration(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
     1619                this->loads->SetCurrentConfiguration(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
     1620
     1621                /*take care of toolkits options, that depend on this analysis type (present only after model processor)*/
     1622                if(this->parameters->Exist(ToolkitsOptionsStringsEnum)){
     1623                        ToolkitsOptionsFromAnalysis(this->parameters,analysis_type);
     1624                        if(VerboseSolver()) _printf0_("      toolkits Options set for analysis type: " << EnumToStringx(analysis_type) << "\n");
     1625                }
     1626
     1627                ConfigureObjectsx(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
     1628                if(i==0){
     1629                        VerticesDofx(new_vertices,this->parameters); //only call once, we only have one set of vertices
     1630                }
     1631                SpcNodesx(new_nodes,new_constraints,this->parameters,analysis_type);
     1632                NodesDofx(new_nodes,this->parameters,analysis_type);
     1633        }
     1634
     1635        /*Finally: interpolate all inputs and insert them into the new elements.*/
     1636        this->InterpolateInputs(new_vertices,new_elements);
     1637
     1638        /*Delete old structure and set new pointers*/
     1639        delete this->vertices;          this->vertices          = new_vertices;
     1640        delete this->elements;          this->elements          = new_elements;
     1641        delete this->nodes;                     this->nodes                     = new_nodes;
     1642        delete this->constraints;       this->constraints       = new_constraints;
     1643        delete this->materials;         this->materials = new_materials;
     1644
     1645        GetMaskOfIceVerticesLSMx(this);
     1646
     1647        /*Insert MISMIP+ bed topography*/
     1648        if(false) this->BedrockFromMismipPlus();
     1649
     1650        /*Adjust base, thickness and mask grounded ice leve set*/
     1651        if(true) this->AdjustBaseThicknessAndMask();
     1652
     1653        /*Reset current configuration: */
     1654        analysis_type=this->analysis_type_list[this->analysis_counter];
     1655        SetCurrentConfiguration(analysis_type);
     1656
     1657        /*Cleanup*/
     1658        xDelete<IssmDouble>(newx);
     1659        xDelete<IssmDouble>(newy);
     1660        xDelete<IssmDouble>(newz);
     1661        xDelete<int>(newelementslist);
     1662        xDelete<int>(my_vertices);
     1663        xDelete<bool>(my_elements);
     1664}
     1665/*}}}*/
    15041666void FemModel::RequestedDependentsx(void){/*{{{*/
    15051667
     
    22342396}
    22352397/*}}}*/
    2236 #ifdef  _HAVE_DAKOTA_
    2237 void FemModel::DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses){/*{{{*/
    2238 
    2239         int        i,j;
    2240         int        my_rank;
    2241 
    2242         /*intermediary: */
    2243         char   root[50];
    2244         int    index;
    2245         int    npart;
    2246         double femmodel_response;
    2247         int    flag;
    2248         double *vertex_response   = NULL;
    2249         double *qmu_response      = NULL;
    2250         double *responses_pointer = NULL;
    2251 
    2252         /*retrieve npart: */
    2253         parameters->FindParam(&npart,QmuNumberofpartitionsEnum);
    2254         my_rank=IssmComm::GetRank();
    2255 
    2256         /*save the d_responses pointer: */
    2257         responses_pointer=d_responses;
    2258 
    2259         //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled.
    2260         //because we don't know the d_responses descriptors (the scaled ones) we can't key off them, so we will key off the responses_descriptors: */
    2261 
    2262         for(i=0;i<numresponsedescriptors;i++){
    2263 
    2264                 flag=DescriptorIndex(root,&index,responses_descriptors[i]);
    2265 
    2266                 if(flag==ScaledEnum){
    2267 
    2268                         /*this response was scaled. pick up the response from the inputs: */
    2269                         GetVectorFromInputsx(&vertex_response,this, StringToEnumx(root),VertexPIdEnum);
    2270 
    2271                         /*Now, average it onto the partition nodes: */
    2272                         AverageOntoPartitionx(&qmu_response,elements,nodes,vertices,loads,materials,parameters,vertex_response);
    2273 
    2274                         /*Copy onto our dakota responses: */
    2275                         if(my_rank==0){
    2276                                 /*plug response: */
    2277                                 for(j=0;j<npart;j++)responses_pointer[j]=qmu_response[j];
    2278 
    2279                                 /*increment response_pointer :*/
    2280                                 responses_pointer+=npart;
    2281                         }
    2282 
    2283                         /*Free ressources:*/
    2284                         xDelete<double>(vertex_response);
    2285                         xDelete<double>(qmu_response);
    2286 
    2287                 }
    2288                 else if (flag==IndexedEnum){
    2289 
    2290                         /*indexed response: plug index into parameters and call response module: */
    2291                         parameters->SetParam(index,IndexEnum);
    2292 
    2293                         this->Responsex(&femmodel_response,root);
    2294 
    2295                         if(my_rank==0){
    2296                                 /*plug response: */
    2297                                 responses_pointer[0]=femmodel_response;
    2298 
    2299                                 /*increment response_pointer :*/
    2300                                 responses_pointer++;
    2301                         }
    2302                 }
    2303                 else if (flag==NodalEnum){
    2304                         _error_("nodal response functions not supported yet!");
    2305 
    2306                         /*increment response_pointer :*/
    2307                         responses_pointer++;
    2308                 }
    2309                 else if (flag==RegularEnum){
    2310 
    2311                         /*perfectly normal response function: */
    2312                         this->Responsex(&femmodel_response,root);
    2313 
    2314                         if(my_rank==0){
    2315                                 /*plug response: */
    2316                                 responses_pointer[0]=femmodel_response;
    2317 
    2318                                 /*increment response_pointer :*/
    2319                                 responses_pointer++;
    2320                         }
    2321                 }
    2322                 else _error_("flag type " << flag << " not supported yet for response analysis");
    2323         }
    2324 
    2325         /*Synthesize echo: {{{*/
    2326         if(my_rank==0){
    2327                 _printf_("   responses: " << d_numresponses << ": ");
    2328                 for(i=0;i<d_numresponses-1;i++)_printf_(d_responses[i] << "|");
    2329                 _printf_(d_responses[d_numresponses-1]);
    2330                 _printf_("\n");
    2331         }
    2332         /*}}}*/
    2333 
    2334 }
    2335 /*}}}*/
    2336 #endif
    2337 #ifdef _HAVE_GIAIVINS_
    2338 void FemModel::Deflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y){ /*{{{*/
    2339 
    2340         /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    2341         for(int i=0;i<elements->Size();i++){
    2342                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2343                 element->GiaDeflection(wg,dwgdt, x,y);
    2344         }
    2345 }
    2346 /*}}}*/
    2347 #endif
    2348 #ifdef _HAVE_ESA_
    2349 void FemModel::EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* xx, IssmDouble* yy){/*{{{*/
    2350 
    2351         int         ns,nsmax;
    2352        
    2353         /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    2354         ns = elements->Size();
    2355        
    2356         /*Figure out max of ns: */
    2357         ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    2358         ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2359 
    2360         /*Call the esa geodetic core: */
    2361         for(int i=0;i<nsmax;i++){
    2362                 if(i<ns){
    2363                         Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2364                         element->EsaGeodetic2D(pUp,pNorth,pEast,xx,yy);
    2365                 }
    2366                 if(i%100==0){
    2367                         pUp->Assemble();
    2368                         pNorth->Assemble();
    2369                         pEast->Assemble();
    2370                 }
    2371         }
    2372        
    2373         /*One last time: */
    2374         pUp->Assemble();
    2375         pNorth->Assemble();
    2376         pEast->Assemble();
    2377 
    2378         /*Free ressources:*/
    2379         xDelete<IssmDouble>(xx);
    2380         xDelete<IssmDouble>(yy);
    2381 }
    2382 /*}}}*/
    2383 void FemModel::EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/
    2384 
    2385         IssmDouble  eartharea=0;
    2386         IssmDouble  eartharea_cpu=0;
    2387 
    2388         int         ns,nsmax;
    2389        
    2390         /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    2391         ns = elements->Size();
    2392        
    2393         /*First, figure out the surface area of Earth: */
    2394         for(int i=0;i<ns;i++){
    2395                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2396                 eartharea_cpu += element->GetAreaSpherical();
    2397         }
    2398         ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2399         ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2400 
    2401         /*Figure out max of ns: */
    2402         ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    2403         ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2404 
    2405         /*Call the esa geodetic core: */
    2406         for(int i=0;i<nsmax;i++){
    2407                 if(i<ns){
    2408                         Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2409                         element->EsaGeodetic3D(pUp,pNorth,pEast,latitude,longitude,radius,xx,yy,zz,eartharea);
    2410                 }
    2411                 if(i%100==0){
    2412                         pUp->Assemble();
    2413                         pNorth->Assemble();
    2414                         pEast->Assemble();
    2415                 }
    2416         }
    2417        
    2418         /*One last time: */
    2419         pUp->Assemble();
    2420         pNorth->Assemble();
    2421         pEast->Assemble();
    2422 
    2423         /*Free ressources:*/
    2424         xDelete<IssmDouble>(latitude);
    2425         xDelete<IssmDouble>(longitude);
    2426         xDelete<IssmDouble>(radius);
    2427         xDelete<IssmDouble>(xx);
    2428         xDelete<IssmDouble>(yy);
    2429         xDelete<IssmDouble>(zz);
    2430 }
    2431 /*}}}*/
    2432 #endif
    2433 #ifdef _HAVE_SEALEVELRISE_
    2434 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius) { /*{{{*/
    2435 
    2436         /*serialized vectors:*/
    2437         IssmDouble  eustatic       = 0.;
    2438         IssmDouble  eustatic_cpu   = 0.;
    2439         IssmDouble  eustatic_cpu_e = 0.;
    2440         IssmDouble  oceanarea      = 0.;
    2441         IssmDouble  oceanarea_cpu  = 0.;
    2442         IssmDouble  eartharea      = 0.;
    2443         IssmDouble  eartharea_cpu  = 0.;
    2444         int         ns,nsmax;
    2445        
    2446         /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    2447         ns = elements->Size();
    2448 
    2449         /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
    2450         for(int i=0;i<ns;i++){
    2451                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2452                 oceanarea_cpu += element->OceanArea();
    2453                 eartharea_cpu += element->GetAreaSpherical();
    2454         }
    2455         ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2456         ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2457         _assert_(oceanarea>0.);
    2458 
    2459         ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2460         ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2461 
    2462         /*Figure out max of ns: */
    2463         ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    2464         ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2465 
    2466         /*Call the sea level rise core: */
    2467         for(int i=0;i<nsmax;i++){
    2468                 if(i<ns){
    2469                
    2470                         if(VerboseConvergence())if(i%100==0)_printf0_("\r" << "      convolution progress: " << (double)i/(double)ns*100 << "%  ");
    2471                
    2472                         Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2473                         element->SealevelriseEustatic(pSgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);
    2474                         eustatic_cpu+=eustatic_cpu_e;
    2475                 }
    2476                 if(i%100==0)pSgi->Assemble();
    2477         }
    2478         if(VerboseConvergence())_printf0_("\n");
    2479                
    2480         /*One last time: */
    2481         pSgi->Assemble();
    2482 
    2483         /*Sum all eustatic components from all cpus:*/
    2484         ISSM_MPI_Reduce (&eustatic_cpu,&eustatic,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2485         ISSM_MPI_Bcast(&eustatic,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2486         _assert_(!xIsNan<IssmDouble>(eustatic));
    2487 
    2488         /*Assign output pointers:*/
    2489         *peustatic=eustatic;
    2490 
    2491 }
    2492 /*}}}*/
    2493 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution){/*{{{*/
    2494 
    2495         /*serialized vectors:*/
    2496         IssmDouble* Sg_old=NULL;
    2497        
    2498         IssmDouble  eartharea=0;
    2499         IssmDouble  eartharea_cpu=0;
    2500 
    2501         int         ns,nsmax;
    2502        
    2503         /*Serialize vectors from previous iteration:*/
    2504         Sg_old=pSg_old->ToMPISerial();
    2505 
    2506         /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    2507         ns = elements->Size();
    2508 
    2509         /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
    2510         for(int i=0;i<ns;i++){
    2511                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2512                 eartharea_cpu += element->GetAreaSpherical();
    2513         }
    2514        
    2515         ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2516         ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2517 
    2518         /*Figure out max of ns: */
    2519         ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    2520         ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2521 
    2522         /*Call the sea level rise core: */
    2523         for(int i=0;i<nsmax;i++){
    2524                 if(i<ns){
    2525                         if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf_("\r" << "      convolution progress: " << (double)i/(double)ns*100 << "%   ");
    2526                         Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2527                         element->SealevelriseNonEustatic(pSgo,Sg_old,latitude,longitude,radius,eartharea);
    2528                 }
    2529                 if(i%100==0)pSgo->Assemble();
    2530         }
    2531         if(verboseconvolution)if(VerboseConvergence())_printf_("\n");
    2532        
    2533         /*Free ressources:*/
    2534         xDelete<IssmDouble>(Sg_old);
    2535 }
    2536 /*}}}*/
    2537 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pSgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/
    2538 
    2539         /*serialized vectors:*/
    2540         IssmDouble* Sg_old=NULL;
    2541         IssmDouble  eartharea=0;
    2542         IssmDouble  eartharea_cpu=0;
    2543         IssmDouble      tide_love_h, tide_love_k, fluid_love, moi_e, moi_p, omega, g;
    2544         IssmDouble      load_love_k2 = -0.30922675; //degree 2 load Love number
    2545         IssmDouble      m1, m2, m3;
    2546         IssmDouble      lati, longi, radi, value;
    2547 
    2548         /*Serialize vectors from previous iteration:*/
    2549         Sg_old=pSg_old->ToMPISerial();
    2550 
    2551         /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
    2552         for(int i=0;i<elements->Size();i++){
    2553                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2554                 eartharea_cpu += element->GetAreaSpherical();
    2555         }
    2556         ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2557         ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2558 
    2559         IssmDouble moi_list[3]={0,0,0};
    2560         IssmDouble moi_list_cpu[3]={0,0,0};
    2561         for(int i=0;i<elements->Size();i++){
    2562                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2563                 element->SealevelriseMomentOfInertia(&moi_list[0],Sg_old,eartharea);
    2564                 moi_list_cpu[0] += moi_list[0];
    2565                 moi_list_cpu[1] += moi_list[1];
    2566                 moi_list_cpu[2] += moi_list[2];
    2567         }
    2568         ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2569         ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2570         //     
    2571         ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2572         ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2573         //     
    2574         ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2575         ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2576        
    2577         /*pull out some useful parameters: */
    2578         parameters->FindParam(&tide_love_h,SealevelriseTidalLoveHEnum);
    2579         parameters->FindParam(&tide_love_k,SealevelriseTidalLoveKEnum);
    2580         parameters->FindParam(&fluid_love,SealevelriseFluidLoveEnum);
    2581         parameters->FindParam(&moi_e,SealevelriseEquatorialMoiEnum);
    2582         parameters->FindParam(&moi_p,SealevelrisePolarMoiEnum);
    2583         parameters->FindParam(&omega,SealevelriseAngularVelocityEnum);
    2584 
    2585         /*compute perturbation terms for angular velocity vector: */
    2586         m1 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[0];
    2587         m2 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[1];
    2588         m3 = -(1+load_love_k2)/moi_p * moi_list[2];     // term associated with fluid number (3-order-of-magnitude smaller) is negelected 
    2589 
    2590         /* Green's function (1+k_2-h_2/g): checked against Glenn Milne's thesis Chapter 3 (eqs: 3.3-4, 3.10-11)
    2591          * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3)
    2592          * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered)
    2593          * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180]
    2594          */
    2595         for(int i=0;i<vertices->Size();i++){
    2596                 int sid;
    2597                 //Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i);
    2598                 Vertex* vertex=xDynamicCast<Vertex*>(vertices->GetObjectByOffset(i));
    2599                 sid=vertex->Sid();
    2600 
    2601                 lati=latitude[sid]/180*PI;      longi=longitude[sid]/180*PI; radi=radius[sid];
    2602 
    2603                 /*only first order terms are considered now: */
    2604                 value=((1.0+tide_love_k-tide_love_h)/9.81)*pow(omega*radi,2.0)*
    2605                                                 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi)));
    2606        
    2607                 pSgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times
    2608         }
    2609 
    2610         /*Assemble mesh velocity*/
    2611         pSgo_rot->Assemble();
    2612        
    2613         /*Free ressources:*/
    2614         xDelete<IssmDouble>(Sg_old);
    2615        
    2616 }
    2617 /*}}}*/
    2618 void FemModel::SealevelriseGeodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/
    2619 
    2620         /*serialized vectors:*/
    2621         IssmDouble* Sg=NULL;
    2622        
    2623         IssmDouble  eartharea=0;
    2624         IssmDouble  eartharea_cpu=0;
    2625 
    2626         int         ns,nsmax;
    2627        
    2628         /*Serialize vectors from previous iteration:*/
    2629         Sg=pSg->ToMPISerial();
    2630 
    2631         /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    2632         ns = elements->Size();
    2633        
    2634         /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
    2635         for(int i=0;i<ns;i++){
    2636                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2637                 eartharea_cpu += element->GetAreaSpherical();
    2638         }
    2639         ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2640         ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2641 
    2642         /*Figure out max of ns: */
    2643         ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    2644         ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2645 
    2646         /*Call the sea level rise core: */
    2647         for(int i=0;i<nsmax;i++){
    2648                 if(i<ns){
    2649                         Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2650                         element->SealevelriseGeodetic(pUp,pNorth,pEast,Sg,latitude,longitude,radius,xx,yy,zz,eartharea);
    2651                 }
    2652                 if(i%100==0){
    2653                         pUp->Assemble();
    2654                         pNorth->Assemble();
    2655                         pEast->Assemble();
    2656                 }
    2657         }
    2658        
    2659         /*One last time: */
    2660         pUp->Assemble();
    2661         pNorth->Assemble();
    2662         pEast->Assemble();
    2663 
    2664         /*Free ressources:*/
    2665         xDelete<IssmDouble>(Sg);
    2666         xDelete<IssmDouble>(latitude);
    2667         xDelete<IssmDouble>(longitude);
    2668         xDelete<IssmDouble>(radius);
    2669         xDelete<IssmDouble>(xx);
    2670         xDelete<IssmDouble>(yy);
    2671         xDelete<IssmDouble>(zz);
    2672 }
    2673 /*}}}*/
    2674 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* Sg) { /*{{{*/
    2675 
    2676         IssmDouble* Sg_serial=NULL;
    2677         IssmDouble  oceanvalue,oceanvalue_cpu;
    2678         IssmDouble  oceanarea,oceanarea_cpu;
    2679 
    2680         /*Serialize vectors from previous iteration:*/
    2681         Sg_serial=Sg->ToMPISerial();
    2682 
    2683         /*Initialize:*/
    2684         oceanvalue_cpu=0;
    2685         oceanarea_cpu=0;
    2686 
    2687         /*Go through elements, and add contribution from each element and divide by overall ocean area:*/
    2688         for(int i=0;i<elements->Size();i++){
    2689                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2690                 oceanarea_cpu += element->OceanArea();
    2691                 oceanvalue_cpu += element->OceanAverage(Sg_serial);
    2692         }
    2693         ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2694         ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2695        
    2696         ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2697         ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    2698 
    2699         /*Free ressources:*/
    2700         xDelete<IssmDouble>(Sg_serial);
    2701        
    2702         return oceanvalue/oceanarea;
    2703 }
    2704 /*}}}*/
    2705 #endif
    2706 void FemModel::HydrologyEPLupdateDomainx(IssmDouble* pEplcount){ /*{{{*/
    2707 
    2708         Vector<IssmDouble>* mask                                                        = NULL;
    2709         Vector<IssmDouble>* recurence                           = NULL;
    2710         Vector<IssmDouble>* active                                              = NULL;
    2711         IssmDouble*         serial_mask                         = NULL;
    2712         IssmDouble*         serial_rec                          = NULL;
    2713         IssmDouble*         serial_active                       = NULL;
    2714         IssmDouble*         old_active        = NULL;
    2715         int*                eplzigzag_counter = NULL;
    2716         int                 eplflip_lock;
    2717        
    2718         HydrologyDCEfficientAnalysis* effanalysis =  new HydrologyDCEfficientAnalysis();
    2719         HydrologyDCInefficientAnalysis* inefanalysis =  new HydrologyDCInefficientAnalysis();
    2720 
    2721         /*Step 1: update mask, the mask might be extended by residual and/or using downstream sediment head*/
    2722         mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
    2723         recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
    2724         this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum);
    2725         this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum);
    2726         GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum);
    2727        
    2728         for (int i=0;i<elements->Size();i++){
    2729                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2730                 effanalysis->HydrologyEPLGetMask(mask,recurence,eplzigzag_counter,element);
    2731         }
    2732         /*check for changes and increment zigzag counter, change the mask if necessary*/
    2733         recurence->Assemble();
    2734         serial_rec=recurence->ToMPISerial();
    2735         for (int i=0;i<nodes->Size();i++){
    2736                 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
    2737                 if(serial_rec[node->Sid()]==1.)eplzigzag_counter[node->Lid()] ++;
    2738                 if(eplzigzag_counter[node->Lid()]>eplflip_lock & eplflip_lock!=0){
    2739                         mask->SetValue(node->Sid(),old_active[node->Sid()],INS_VAL);
    2740                 }
    2741         }
    2742         this->parameters->SetParam(eplzigzag_counter,this->nodes->Size(),EplZigZagCounterEnum);
    2743         /*Assemble and serialize*/
    2744         mask->Assemble();
    2745         serial_mask=mask->ToMPISerial();       
    2746        
    2747         xDelete<int>(eplzigzag_counter);
    2748         xDelete<IssmDouble>(serial_rec);
    2749         xDelete<IssmDouble>(old_active);
    2750         delete mask;
    2751         delete recurence;
    2752 
    2753         /*Update Mask*/
    2754         InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum);
    2755         xDelete<IssmDouble>(serial_mask);
    2756         inefanalysis->ElementizeEplMask(this);
    2757         /*Step 2: update node activity. If one element is connected to mask=1, all nodes are active*/
    2758         active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
    2759         for (int i=0;i<elements->Size();i++){
    2760                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2761                 effanalysis->HydrologyEPLGetActive(active,element);
    2762         }
    2763 
    2764         /*Assemble and serialize*/
    2765         active->Assemble();
    2766         serial_active=active->ToMPISerial();
    2767         delete active;
    2768 
    2769         /*Update node activation accordingly*/
    2770         int counter =0;
    2771         for (int i=0;i<nodes->Size();i++){
    2772                 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
    2773                 if(node->InAnalysis(HydrologyDCEfficientAnalysisEnum)){
    2774                         if(serial_active[node->Sid()]==1.){
    2775                                 node->Activate();
    2776                                 if(!node->IsClone()) counter++;
    2777                         }
    2778                         else{
    2779                                 node->Deactivate();
    2780                         }
    2781                 }
    2782         }
    2783         xDelete<IssmDouble>(serial_active);
    2784         delete effanalysis;
    2785         delete inefanalysis;
    2786         int sum_counter;
    2787         ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2788         ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());               
    2789         counter=sum_counter;
    2790         *pEplcount = counter;
    2791         if(VerboseSolution()) _printf0_("   Number of active nodes in EPL layer: "<< counter <<"\n");
    2792 
    2793         /*Update dof indexings*/
    2794         this->UpdateConstraintsx();
    2795 
    2796 }
    2797 /*}}}*/
    2798 void FemModel::UpdateConstraintsL2ProjectionEPLx(IssmDouble* pL2count){ /*{{{*/
    2799 
    2800         Vector<IssmDouble>* active        = NULL;
    2801         IssmDouble*         serial_active = NULL;
    2802         HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis();
    2803 
    2804         /*update node activity. If one element is connected to mask=1, all nodes are active*/
    2805         active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
    2806         for (int i=0;i<elements->Size();i++){
    2807                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2808                 effanalysis->HydrologyEPLGetActive(active,element);
    2809         }
    2810 
    2811         /*Assemble and serialize*/
    2812         active->Assemble();
    2813         serial_active=active->ToMPISerial();
    2814         delete active;
    2815         delete effanalysis;
    2816 
    2817         /*Update node activation accordingly*/
    2818         int counter =0;
    2819         for (int i=0;i<nodes->Size();i++){
    2820                 Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
    2821                 if(node->InAnalysis(L2ProjectionEPLAnalysisEnum)){
    2822                         if(serial_active[node->Sid()]==1.){
    2823                                 node->Activate();
    2824                                 if(!node->IsClone()) counter++;
    2825                         }
    2826                         else{
    2827                                 node->Deactivate();
    2828                         }
    2829                 }
    2830         }
    2831         xDelete<IssmDouble>(serial_active);
    2832         int sum_counter;
    2833         ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    2834         ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());               
    2835         counter=sum_counter;
    2836         *pL2count = counter;
    2837         if(VerboseSolution()) _printf0_("   Number of active nodes L2 Projection: "<< counter <<"\n");
    2838 }
    2839 /*}}}*/
    2840 #ifdef _HAVE_JAVASCRIPT_
    2841 FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/
    2842         /*configuration: */
    2843         int  solution_type;
    2844         int  ierr;
    2845 
    2846         /*First things first, store the communicator, and set it as a global variable: */
    2847         IssmComm::SetComm(incomm);
    2848 
    2849         /*Start profiler: */
    2850         this->profiler=new Profiler();
    2851         profiler->Tag(START);
    2852 
    2853         /*From command line arguments, retrieve different filenames needed to create the FemModel: */
    2854         solution_type=StringToEnumx(solution);
    2855        
    2856         /*Create femmodel from input files: */
    2857         profiler->Tag(STARTINIT);
    2858         this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL);
    2859         profiler->Tag(FINISHINIT);
    2860        
    2861         /*Save communicator in the parameters dataset: */
    2862         this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum));
    2863 
    2864 }
    2865 /*}}}*/
    2866 void FemModel::CleanUpJs(char** poutput, size_t* psize){/*{{{*/
    2867 
    2868         /*Intermediary*/
    2869         FILE *output_fid;
    2870         GenericParam<char**>* outputbufferparam=NULL;
    2871         GenericParam<size_t*>* outputbuffersizeparam=NULL;
    2872         char** poutputbuffer;
    2873         size_t* poutputbuffersize;
    2874 
    2875        
    2876         /*Before we delete the profiler, report statistics for this run: */
    2877         profiler->Tag(FINISH);  //final tagging
    2878         _printf0_("\n");
    2879         _printf0_("   "<<setw(40)<<left<<"FemModel initialization elapsed time:"<<profiler->DeltaTime(STARTINIT,FINISHINIT) << "\n");
    2880         _printf0_("   "<<setw(40)<<left<<"Core solution elapsed time:"<<profiler->DeltaTime(STARTCORE,FINISHCORE) << "\n");
    2881         _printf0_("\n");
    2882         _printf0_("   Total elapsed time: "
    2883                                 <<profiler->DeltaTimeModHour(START,FINISH)<<" hrs "
    2884                                 <<profiler->DeltaTimeModMin(START,FINISH)<<" min "
    2885                                 <<profiler->DeltaTimeModSec(START,FINISH)<<" sec"
    2886                                 );
    2887         _printf0_("\n");
    2888        
    2889         /*Before we close the output file, recover the buffer and size:*/
    2890         outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum));
    2891         poutputbuffer=outputbufferparam->GetParameterValue();
    2892         outputbuffersizeparam = xDynamicCast<GenericParam<size_t*>*>(this->parameters->FindParamObject(OutputBufferSizePointerEnum));
    2893         poutputbuffersize=outputbuffersizeparam->GetParameterValue();
    2894 
    2895         /*Assign output values: */
    2896         *poutput=*poutputbuffer;
    2897         *psize=*poutputbuffersize;
    2898 }
    2899 /*}}}*/
    2900 void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
    2901 
    2902         /*intermediary*/
    2903         FILE       *IOMODEL = NULL;
    2904         FILE       *toolkitsoptionsfid = NULL;
    2905         FILE       *output_fid = NULL;
    2906         int         my_rank;
    2907         size_t      outputsize;
    2908         char       *outputbuffer;
    2909         const char *rootpath = "";   //needed for Dakota runs only, which we won't do here.
    2910 
    2911         /*recover my_rank:*/
    2912         my_rank=IssmComm::GetRank();
    2913 
    2914         /*Open input file descriptor on cpu 0: */
    2915         if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb");
    2916 
    2917         /*Open toolkits file descriptor: */
    2918         toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r");
    2919 
    2920         /*Now, go create FemModel:*/
    2921         this->InitFromFids((char*)rootpath,IOMODEL,toolkitsoptionsfid,in_solution_type,trace,X);
    2922 
    2923         /*Close input file and toolkits file descriptors: */
    2924         if(my_rank==0) fclose(IOMODEL);
    2925         fclose(toolkitsoptionsfid);
    2926 
    2927         /*Open output file once for all and add output file descriptor to parameters*/
    2928         output_fid=open_memstream(&outputbuffer,&outputsize);
    2929         if(output_fid==NULL)_error_("could not initialize output stream");
    2930         this->parameters->SetParam(output_fid,OutputFilePointerEnum);
    2931         this->parameters->AddObject(new GenericParam<char**>(&outputbuffer,OutputBufferPointerEnum));
    2932         this->parameters->AddObject(new GenericParam<size_t*>(&outputsize,OutputBufferSizePointerEnum));
    2933 
    2934 }/*}}}*/
    2935 #endif
    2936 
    2937 #ifdef _HAVE_NEOPZ_
    2938 void FemModel::InitializeAdaptiveRefinement(void){/*{{{*/
    2939        
    2940         /*Define variables*/
    2941         int my_rank                                             = IssmComm::GetRank();
    2942         this->amr                                               = NULL;//initialize amr as NULL
    2943         int numberofvertices                    = this->vertices->NumberOfVertices();
    2944         int numberofelements                    = this->elements->NumberOfElements();
    2945         int numberofsegments                    = 0; //used on matlab
    2946         IssmDouble* x                                   = NULL;
    2947         IssmDouble* y                                   = NULL;
    2948         IssmDouble* z                                   = NULL;
    2949         int* elements                                   = NULL;
    2950         int elementswidth                               = this->GetElementsWidth(); //just tria elements in this version. Itapopo:
    2951         int levelmax                                    = 0;
    2952         IssmDouble regionlevel1         = 0.;
    2953         IssmDouble regionlevelmax       = 0.;
    2954 
    2955         /*Get vertices coordinates of the coarse mesh (father mesh)*/
    2956         /*elements comes in Matlab indexing*/
    2957         this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements);
    2958        
    2959         /*Get amr parameters*/
    2960         this->parameters->FindParam(&levelmax,AmrLevelMaxEnum);
    2961         this->parameters->FindParam(&regionlevel1,AmrRegionLevel1Enum);
    2962         this->parameters->FindParam(&regionlevelmax,AmrRegionLevelMaxEnum);
    2963 
    2964         /*Create initial mesh (coarse mesh) in neopz data structure*/
    2965         /*Just CPU #0 should keep AMR object*/
    2966    this->SetRefPatterns();
    2967         if(my_rank==0){
    2968            bool ismisomip       = false;
    2969                 if(ismisomip){//itapopo
    2970                         TPZFileStream fstr;
    2971                         std::stringstream ss;
    2972                         int frictionlaw;
    2973                        
    2974                         this->parameters->FindParam(&frictionlaw,FrictionLawEnum);
    2975                
    2976                         ss      << levelmax;
    2977                         if(frictionlaw==1){
    2978                                 ss << "_viscous/amr.txt";
    2979                         }else if(frictionlaw==7){
    2980                                 ss << "_tsai/amr.txt";
    2981                         }else{
    2982                                 _error_("friction law not supported here.");
    2983                         }
    2984                        
    2985                         std::string AMRfile  = "/home/santos/Misomip2/L" + ss.str();
    2986                         fstr.OpenRead(AMRfile.c_str());
    2987                        
    2988                         TPZSaveable *sv         = TPZSaveable::Restore(fstr,0);
    2989                         this->amr                               = dynamic_cast<AdaptiveMeshRefinement*>(sv);
    2990                 }
    2991                 else{
    2992                         this->amr = new AdaptiveMeshRefinement();
    2993                         //this->amr->SetLevelMax(levelmax); //Set max level of refinement
    2994                         //this->amr->SetRegions(regionlevel1,regionlevelmax);
    2995                         this->amr->CreateInitialMesh(numberofvertices,numberofelements,numberofsegments,elementswidth,x,y,z,elements,NULL);
    2996                 }
    2997                 this->amr->SetLevelMax(levelmax); //Set max level of refinement
    2998                 this->amr->SetRegions(regionlevel1,regionlevelmax);
    2999         }
    3000 
    3001         /*Free the vectors*/
    3002         xDelete<IssmDouble>(x);
    3003         xDelete<IssmDouble>(y);
    3004         xDelete<IssmDouble>(z);
    3005         xDelete<int>(elements);
    3006 
    3007 }
    3008 /*}}}*/
    3009 void FemModel::SetRefPatterns(){/*{{{*/
    3010 
    3011    /*Initialize the global variable of refinement patterns*/
    3012    gRefDBase.InitializeUniformRefPattern(EOned);
    3013    gRefDBase.InitializeUniformRefPattern(ETriangle);
    3014 
    3015     //gRefDBase.InitializeRefPatterns();
    3016    /*Insert specifics patterns to ISSM core*/
    3017    std::string filepath  = REFPATTERNDIR;
    3018    std::string filename1 = filepath + "/2D_Triang_Rib_3.rpt";
    3019    std::string filename2 = filepath + "/2D_Triang_Rib_4.rpt";
    3020    std::string filename3 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_4.rpt";
    3021    std::string filename4 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_4_permuted.rpt";
    3022    std::string filename5 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_5.rpt";
    3023    std::string filename6 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_5_permuted.rpt";
    3024    std::string filename7 = filepath + "/2D_Triang_Rib_5.rpt";
    3025 
    3026    TPZAutoPointer<TPZRefPattern> refpat1 = new TPZRefPattern(filename1);
    3027    TPZAutoPointer<TPZRefPattern> refpat2 = new TPZRefPattern(filename2);
    3028    TPZAutoPointer<TPZRefPattern> refpat3 = new TPZRefPattern(filename3);
    3029    TPZAutoPointer<TPZRefPattern> refpat4 = new TPZRefPattern(filename4);
    3030    TPZAutoPointer<TPZRefPattern> refpat5 = new TPZRefPattern(filename5);
    3031    TPZAutoPointer<TPZRefPattern> refpat6 = new TPZRefPattern(filename6);
    3032    TPZAutoPointer<TPZRefPattern> refpat7 = new TPZRefPattern(filename7);
    3033 
    3034    if(!gRefDBase.FindRefPattern(refpat1)) gRefDBase.InsertRefPattern(refpat1);
    3035    if(!gRefDBase.FindRefPattern(refpat2)) gRefDBase.InsertRefPattern(refpat2);
    3036    if(!gRefDBase.FindRefPattern(refpat3)) gRefDBase.InsertRefPattern(refpat3);
    3037    if(!gRefDBase.FindRefPattern(refpat4)) gRefDBase.InsertRefPattern(refpat4);
    3038    if(!gRefDBase.FindRefPattern(refpat5)) gRefDBase.InsertRefPattern(refpat5);
    3039    if(!gRefDBase.FindRefPattern(refpat6)) gRefDBase.InsertRefPattern(refpat6);
    3040    if(!gRefDBase.FindRefPattern(refpat7)) gRefDBase.InsertRefPattern(refpat7);
    3041 }
    3042 /*}}}*/
    3043 void FemModel::ReMesh(void){/*{{{*/
    3044 
    3045         /*Variables*/
    3046         IssmDouble *newx                        = NULL;
    3047         IssmDouble *newy                        = NULL;
    3048         IssmDouble *newz                        = NULL;
    3049         int *newelementslist            = NULL;
    3050         int newnumberofvertices = -1;
    3051         int newnumberofelements = -1;
    3052         bool* my_elements                       = NULL;
    3053         int* my_vertices                        = NULL;
    3054         int elementswidth                       = this->GetElementsWidth();//just tria elements in this version
    3055 
    3056         /*Execute refinement and get the new mesh*/
    3057         /*newelementslist come in Matlab indexing*/
    3058         this->ExecuteRefinement(newnumberofvertices,newnumberofelements,&newx,&newy,&newz,&newelementslist);
    3059 
    3060         /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/
    3061         this->ElementsAndVerticesPartitioning(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,&my_elements,&my_vertices);
    3062 
    3063         if(this->loads->Size()!=0) _error_("not supported yet");
    3064 
    3065         /*Create vertices*/
    3066         Vertices* new_vertices=new Vertices();
    3067         this->CreateVertices(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,my_vertices,newx,newy,newz,new_vertices);
    3068  
    3069         /*Creating elements*/
    3070         /*Just Tria in this version*/
    3071         Elements* new_elements=new Elements();
    3072         this->CreateElements(newnumberofelements,elementswidth,newelementslist,my_elements,new_elements);
    3073 
    3074         /*Creating materials*/
    3075         Materials* new_materials=new Materials();
    3076         this->CreateMaterials(newnumberofelements,my_elements,new_materials);
    3077        
    3078         /*Creating nodes and constraints*/
    3079         /*Just SSA (2D) and P1 in this version*/
    3080         Nodes* new_nodes=new Nodes();
    3081         Constraints* new_constraints=new Constraints();
    3082 
    3083         int nodecounter=0;
    3084         int constraintcounter=0;
    3085         for(int i=0;i<this->nummodels;i++){//create nodes for each analysis in analysis_type_list
    3086        
    3087                 int analysis_enum = this->analysis_type_list[i];
    3088                
    3089                 /*As the domain is 2D, it is not necessary to create nodes for this analysis*/
    3090                 /*itapopo must verify if domain is not 3D. Only 2D in this version!*/
    3091                 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue;     
    3092                
    3093                 this->CreateNodes(newnumberofvertices,my_vertices,nodecounter,analysis_enum,new_nodes);
    3094                 if(analysis_enum==StressbalanceAnalysisEnum) this->CreateConstraints(newnumberofvertices,newnumberofelements,nodecounter,constraintcounter,newx,newy,my_vertices,new_constraints);
    3095                 this->UpdateElements(newnumberofelements,newelementslist,my_elements,nodecounter,i,new_elements);
    3096 
    3097                 if(new_nodes->Size()) nodecounter=new_nodes->MaximumId();
    3098                 constraintcounter = new_constraints->NumberOfConstraints();
    3099                 /*Make sure nodecounter is at least 0 (if no node exists, maxid will be -1*/
    3100                 _assert_(nodecounter>=0);
    3101         }
    3102 
    3103         new_elements->Presort();
    3104         new_nodes->Presort();
    3105         new_vertices->Presort();
    3106         this->loads->Presort();
    3107         new_materials->Presort();
    3108         new_constraints->Presort();
    3109 
    3110         /*reset hooks for elements, loads and nodes: */
    3111         new_elements->ResetHooks();
    3112         this->loads->ResetHooks();
    3113         new_materials->ResetHooks();
    3114 
    3115         /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
    3116         int analysis_type;
    3117         for(int i=0;i<this->nummodels;i++){
    3118                 analysis_type=this->analysis_type_list[i];
    3119                 //SetCurrentConfiguration(analysis_type);
    3120 
    3121                 this->analysis_counter=i;       
    3122                 /*Now, plug analysis_counter and analysis_type inside the parameters: */
    3123                 this->parameters->SetParam(this->analysis_counter,AnalysisCounterEnum);
    3124                 this->parameters->SetParam(analysis_type,AnalysisTypeEnum);
    3125                 this->parameters->SetParam(analysis_type,ConfigurationTypeEnum);
    3126 
    3127                 /*configure elements, loads and nodes, for this new analysis: */
    3128                 new_elements->SetCurrentConfiguration(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
    3129                 this->loads->SetCurrentConfiguration(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
    3130 
    3131                 /*take care of toolkits options, that depend on this analysis type (present only after model processor)*/
    3132                 if(this->parameters->Exist(ToolkitsOptionsStringsEnum)){
    3133                         ToolkitsOptionsFromAnalysis(this->parameters,analysis_type);
    3134                         if(VerboseSolver()) _printf0_("      toolkits Options set for analysis type: " << EnumToStringx(analysis_type) << "\n");
    3135                 }
    3136                
    3137                 ConfigureObjectsx(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
    3138                 if(i==0){
    3139                         VerticesDofx(new_vertices,this->parameters); //only call once, we only have one set of vertices
    3140                 }
    3141                 SpcNodesx(new_nodes,new_constraints,this->parameters,analysis_type);
    3142                 NodesDofx(new_nodes,this->parameters,analysis_type);
    3143         }
    3144 
    3145         /*Finally: interpolate all inputs and insert them into the new elements.*/
    3146         this->InterpolateInputs(new_vertices,new_elements);
    3147 
    3148         /*Delete old structure and set new pointers*/
    3149         delete this->vertices;          this->vertices          = new_vertices;
    3150         delete this->elements;          this->elements          = new_elements;
    3151         delete this->nodes;                     this->nodes                     = new_nodes;
    3152         delete this->constraints;       this->constraints       = new_constraints;
    3153         delete this->materials;         this->materials = new_materials;
    3154        
    3155         GetMaskOfIceVerticesLSMx(this);
    3156 
    3157         /*Insert MISMIP+ bed topography*/
    3158         if(false) this->BedrockFromMismipPlus();
    3159        
    3160         /*Adjust base, thickness and mask grounded ice leve set*/
    3161         if(true) this->AdjustBaseThicknessAndMask();
    3162 
    3163         /*Reset current configuration: */
    3164         analysis_type=this->analysis_type_list[this->analysis_counter];
    3165         SetCurrentConfiguration(analysis_type);
    3166 
    3167         /*Cleanup*/
    3168         xDelete<IssmDouble>(newx);
    3169         xDelete<IssmDouble>(newy);
    3170         xDelete<IssmDouble>(newz);
    3171         xDelete<int>(newelementslist);
    3172         xDelete<int>(my_vertices);
    3173         xDelete<bool>(my_elements);
    3174 
    3175         return;
    3176 
    3177 }
    3178 /*}}}*/
     2398
     2399/*AMR*/
    31792400void FemModel::BedrockFromMismipPlus(void){/*{{{*/
    31802401
     
    32452466                        }
    32462467
    3247                         if(abs(sl[i])>0) _error_("Sea level value not supported!");
     2468                        if(abs(sl[i])>0) _error_("Sea level value "<<sl[i]<<" not supported!");
    32482469                        /*update thickness and mask grounded ice level set*/
    32492470                        h[i]      = s[i]-b[i];
     
    32552476                element->AddInput(ThicknessEnum,&h[0],P1Enum);
    32562477                element->AddInput(BaseEnum,&b[0],P1Enum);
    3257 
    32582478        }
    32592479       
     
    32652485   xDelete<IssmDouble>(r);
    32662486   xDelete<IssmDouble>(sl);
    3267 
    3268         return;
    3269 }
    3270 /*}}}*/
    3271 void FemModel::WriteMeshInResults(void){/*{{{*/
    3272 
    3273         int step                                        = -1;
    3274         int numberofelements = -1;
    3275         int numberofvertices = -1;
    3276         IssmDouble time         = -1;
    3277         IssmDouble* x                   = NULL;
    3278         IssmDouble* y                   = NULL;
    3279         IssmDouble* z                   = NULL;
    3280         int* elementslist               = NULL;
    3281 
    3282         if(!this->elements || !this->vertices || !this->results || !this->parameters) return;
    3283          
    3284         parameters->FindParam(&step,StepEnum);
    3285         parameters->FindParam(&time,TimeEnum);
    3286         numberofelements=this->elements->NumberOfElements();
    3287         numberofvertices=this->vertices->NumberOfVertices();
    3288 
    3289         /*Get mesh. Elementslist comes in Matlab indexing*/
    3290         this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elementslist);
    3291 
    3292         /*Write mesh in Results*/
    3293         this->results->AddResult(new GenericExternalResult<int*>(this->results->Size()+1,MeshElementsEnum,
    3294                                                                                                                                                                         elementslist,numberofelements,this->GetElementsWidth(),step,time));
    3295 
    3296         this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshXEnum,
    3297                                                                                                                                                                         x,numberofvertices,1,step,time));
    3298 
    3299         this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshYEnum,
    3300                                                                                                                                                                         y,numberofvertices,1,step,time));
    3301        
    3302         //itapopo
    3303         if(IssmComm::GetRank()==0){
    3304                 TPZFileStream fstr;
    3305                 std::stringstream ss;
    3306                 int frictionlaw,levelmax;
    3307                 this->parameters->FindParam(&frictionlaw,FrictionLawEnum);
    3308                 this->parameters->FindParam(&levelmax,AmrLevelMaxEnum);
    3309                 ss << levelmax;
    3310                 if(frictionlaw==1){
    3311                         ss << "_viscous/amr.txt";
    3312                 }else if(frictionlaw==7){
    3313                         ss << "_tsai/amr.txt";
    3314                 }else{
    3315                         _error_("friction law not supported here.");
    3316                 }
    3317                 std::string AMRfile  = "/home/santos/Misomip2/L" + ss.str();
    3318                 fstr.OpenWrite(AMRfile.c_str());
    3319                 int withclassid = 1;
    3320                 this->amr->Write(fstr,withclassid);
    3321         }
    3322         //itapopo
    3323        
    3324         /*Cleanup*/
    3325         xDelete<IssmDouble>(x);
    3326         xDelete<IssmDouble>(y);
    3327         xDelete<IssmDouble>(z);
    3328         xDelete<int>(elementslist);
    3329 
    3330         return;
    33312487}
    33322488/*}}}*/
     
    33422498        }
    33432499        input_interpolations->Assemble();
    3344        
     2500
    33452501        /*Serialize and set output*/
    33462502        IssmDouble* input_interpolations_serial = input_interpolations->ToMPISerial();
     
    33742530                                                P1input_interp[numP1inputs] = inputinterp;
    33752531                                        }
    3376                                          numP1inputs++;
     2532                                        numP1inputs++;
    33772533                                        break;
    33782534                                case P0Enum:
     
    34212577                xDelete<IssmDouble>(vector);
    34222578        }
    3423        
     2579
    34242580        /*Old mesh coordinates*/
    34252581        IssmDouble *Xold     = NULL;
     
    34332589        IssmDouble* YC_new   = NULL;
    34342590        int        *Indexnew = NULL;
    3435        
     2591
    34362592        /*Get the old mesh*/
    34372593        this->GetMesh(this->vertices,this->elements,&Xold,&Yold,&Zold,&Indexold);
     
    34592615                                P0inputsold,numelementsold,numP0inputs,
    34602616                                XC_new,YC_new,numelementsnew,NULL);
    3461        
     2617
    34622618        /*Interpolate P1 inputs in the new mesh*/
    34632619        InterpFromMeshToMesh2dx(&P1inputsnew,Indexold,Xold,Yold,numverticesold,numelementsold,
    34642620                                P1inputsold,numverticesold,numP1inputs,
    34652621                                Xnew,Ynew,numverticesnew,NULL);
    3466        
     2622
    34672623        /*Insert P0 inputs into the new elements.*/
    34682624        vector=NULL;
    34692625        for(int i=0;i<numP0inputs;i++){
    3470                
     2626
    34712627                /*Get P0 input vector from the interpolated matrix*/
    34722628                vector=xNew<IssmDouble>(numelementsnew);
     
    35332689        xDelete<IssmDouble>(YC_new);
    35342690        xDelete<int>(Indexnew);
    3535 
    3536 }
    3537 /*}}}*/
    3538 void FemModel::ExecuteRefinement(int &numberofvertices,int &numberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist){/*{{{*/
    3539        
    3540         /*elements is in Matlab indexing*/
    3541         int my_rank                                             = IssmComm::GetRank();
    3542         int numberofsegments                    = -1;
    3543         IssmDouble* vx                                  = NULL; //itapopo this is not being used
    3544         IssmDouble* vy                                  = NULL; //itapopo this is not being used
    3545         IssmDouble* x                                   = NULL;
    3546         IssmDouble* y                                   = NULL;
    3547         IssmDouble* z                                   = NULL;
    3548         int* elementslist                               = NULL;
    3549         int* segments                                   = NULL;
    3550         IssmDouble* masklevelset        = NULL;
    3551         IssmDouble* pelementerror       = NULL;
    3552    const int elementswidth              = this->GetElementsWidth();//just 2D mesh, tria elements
    3553        
    3554         /*Solutions which will be used to refine the elements*/
    3555         this->GetGroundediceLevelSet(&masklevelset);//itapopo verificar se já existe um método igual a esse
    3556 
    3557         //Compute the ZZ error estimator per element
    3558         this->ZZErrorEstimator(&pelementerror);
    3559        
    3560         _printf0_("P Element error\n");
    3561         for(int i=0;i<this->elements->NumberOfElements();i++)   _printf0_(""<<pelementerror[i]<< "\n");
    3562         _printf0_("\n");
    3563 
    3564         if(my_rank==0){
    3565                 int type_process=1; //1: it refines father mesh. See AdaptiveMeshRefinement.h (.cpp)
    3566                 this->amr->ExecuteRefinement(type_process,vx,vy,masklevelset,
    3567                                                                                                 numberofvertices,numberofelements,numberofsegments,&x,&y,&z,&elementslist,&segments);
    3568                 if(numberofvertices<=0 || numberofelements<=0 /*|| newnumberofsegments<=0*/) _error_("Error in the refinement process.");
    3569         }
    3570         else{
    3571                 x=xNew<IssmDouble>(numberofvertices);
    3572                 y=xNew<IssmDouble>(numberofvertices);
    3573                 z=xNew<IssmDouble>(numberofvertices);
    3574                 elementslist=xNew<int>(numberofelements*this->GetElementsWidth());
    3575         }
    3576 
    3577         /*Send new mesh to others CPU*/
    3578         ISSM_MPI_Bcast(&numberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    3579         ISSM_MPI_Bcast(&numberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    3580         ISSM_MPI_Bcast(x,numberofvertices,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm());     
    3581         ISSM_MPI_Bcast(y,numberofvertices,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm());     
    3582         ISSM_MPI_Bcast(z,numberofvertices,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm());     
    3583         ISSM_MPI_Bcast(elementslist,numberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());     
    3584 
    3585         /*Assign the pointers*/
    3586         (*pelementslist) = elementslist; //Matlab indexing
    3587         (*px)                             = x;
    3588         (*py)                             = y;
    3589         (*pz)                             = z;
    3590 
     2691}
     2692/*}}}*/
     2693void FemModel::WriteMeshInResults(void){/*{{{*/
     2694
     2695        int step                                        = -1;
     2696        int numberofelements = -1;
     2697        int numberofvertices = -1;
     2698        IssmDouble time         = -1;
     2699        IssmDouble* x                   = NULL;
     2700        IssmDouble* y                   = NULL;
     2701        IssmDouble* z                   = NULL;
     2702        int* elementslist               = NULL;
     2703
     2704        if(!this->elements || !this->vertices || !this->results || !this->parameters) return;
     2705         
     2706        parameters->FindParam(&step,StepEnum);
     2707        parameters->FindParam(&time,TimeEnum);
     2708        numberofelements=this->elements->NumberOfElements();
     2709        numberofvertices=this->vertices->NumberOfVertices();
     2710
     2711        /*Get mesh. Elementslist comes in Matlab indexing*/
     2712        this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elementslist);
     2713
     2714        /*Write mesh in Results*/
     2715        printf("-------------- file: FemModel.cpp line: %i\n",__LINE__);
     2716        this->results->AddResult(new GenericExternalResult<int*>(this->results->Size()+1,MeshElementsEnum,
     2717                                        elementslist,numberofelements,this->GetElementsWidth(),step,time));
     2718
     2719        this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshXEnum,
     2720                                        x,numberofvertices,1,step,time));
     2721
     2722        this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshYEnum,
     2723                                        y,numberofvertices,1,step,time));
     2724       
     2725        //itapopo
     2726        #ifdef _HAVE_NEOPZ_
     2727        if(IssmComm::GetRank()==0){
     2728                TPZFileStream fstr;
     2729                std::stringstream ss;
     2730                int frictionlaw,levelmax;
     2731                this->parameters->FindParam(&frictionlaw,FrictionLawEnum);
     2732                this->parameters->FindParam(&levelmax,AmrLevelMaxEnum);
     2733                ss << levelmax;
     2734                if(frictionlaw==1){
     2735                        ss << "_viscous/amr.txt";
     2736                }else if(frictionlaw==7){
     2737                        ss << "_tsai/amr.txt";
     2738                }else{
     2739                        _error_("friction law not supported here.");
     2740                }
     2741                std::string AMRfile  = "/home/santos/Misomip2/L" + ss.str();
     2742                fstr.OpenWrite(AMRfile.c_str());
     2743                int withclassid = 1;
     2744                this->amr->Write(fstr,withclassid);
     2745        }
     2746        #endif
     2747        //itapopo
     2748       
    35912749        /*Cleanup*/
    3592         if(segments) xDelete<int>(segments);
    3593         xDelete<IssmDouble>(masklevelset);
    3594         xDelete<IssmDouble>(pelementerror);
    3595 
     2750        xDelete<IssmDouble>(x);
     2751        xDelete<IssmDouble>(y);
     2752        xDelete<IssmDouble>(z);
     2753        xDelete<int>(elementslist);
    35962754}
    35972755/*}}}*/
     
    36352793        connectivity=xNewZeroInit<int>(newnumberofvertices);
    36362794
    3637         for (int i=0;i<newnumberofelements;i++){
    3638                 for (int j=0;j<elementswidth;j++){
     2795        for(int i=0;i<newnumberofelements;i++){
     2796                for(int j=0;j<elementswidth;j++){
    36392797                        int vertexid = newelementslist[elementswidth*i+j];
    36402798                        _assert_(vertexid>0 && vertexid-1<newnumberofvertices);//Matlab indexing
     
    37222880        newmatpar->SetMid(newnumberofelements+1);
    37232881        materials->AddObject(newmatpar);//put it at the end of the materials       
    3724 
    37252882}
    37262883/*}}}*/
     
    39543111        delete vspcvxflag;
    39553112        delete vspcvyflag;
    3956 
    39573113}
    39583114/*}}}*/
     
    40533209        xDelete<int>(npart);       
    40543210        xDelete<int>(index);
    4055 
    40563211}
    40573212/*}}}*/
     
    41413296   xDelete<IssmDouble>(totalweight);
    41423297   xDelete<int>(elem_vertices);
    4143 
    41443298}
    41453299/*}}}*/
     
    42153369        xDelete<int>(elem_vertices);
    42163370        delete velementerror;
     3371}
     3372/*}}}*/
     3373
     3374#ifdef  _HAVE_DAKOTA_
     3375void FemModel::DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses){/*{{{*/
     3376
     3377        int        i,j;
     3378        int        my_rank;
     3379
     3380        /*intermediary: */
     3381        char   root[50];
     3382        int    index;
     3383        int    npart;
     3384        double femmodel_response;
     3385        int    flag;
     3386        double *vertex_response   = NULL;
     3387        double *qmu_response      = NULL;
     3388        double *responses_pointer = NULL;
     3389
     3390        /*retrieve npart: */
     3391        parameters->FindParam(&npart,QmuNumberofpartitionsEnum);
     3392        my_rank=IssmComm::GetRank();
     3393
     3394        /*save the d_responses pointer: */
     3395        responses_pointer=d_responses;
     3396
     3397        //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled.
     3398        //because we don't know the d_responses descriptors (the scaled ones) we can't key off them, so we will key off the responses_descriptors: */
     3399
     3400        for(i=0;i<numresponsedescriptors;i++){
     3401
     3402                flag=DescriptorIndex(root,&index,responses_descriptors[i]);
     3403
     3404                if(flag==ScaledEnum){
     3405
     3406                        /*this response was scaled. pick up the response from the inputs: */
     3407                        GetVectorFromInputsx(&vertex_response,this, StringToEnumx(root),VertexPIdEnum);
     3408
     3409                        /*Now, average it onto the partition nodes: */
     3410                        AverageOntoPartitionx(&qmu_response,elements,nodes,vertices,loads,materials,parameters,vertex_response);
     3411
     3412                        /*Copy onto our dakota responses: */
     3413                        if(my_rank==0){
     3414                                /*plug response: */
     3415                                for(j=0;j<npart;j++)responses_pointer[j]=qmu_response[j];
     3416
     3417                                /*increment response_pointer :*/
     3418                                responses_pointer+=npart;
     3419                        }
     3420
     3421                        /*Free ressources:*/
     3422                        xDelete<double>(vertex_response);
     3423                        xDelete<double>(qmu_response);
     3424
     3425                }
     3426                else if (flag==IndexedEnum){
     3427
     3428                        /*indexed response: plug index into parameters and call response module: */
     3429                        parameters->SetParam(index,IndexEnum);
     3430
     3431                        this->Responsex(&femmodel_response,root);
     3432
     3433                        if(my_rank==0){
     3434                                /*plug response: */
     3435                                responses_pointer[0]=femmodel_response;
     3436
     3437                                /*increment response_pointer :*/
     3438                                responses_pointer++;
     3439                        }
     3440                }
     3441                else if (flag==NodalEnum){
     3442                        _error_("nodal response functions not supported yet!");
     3443
     3444                        /*increment response_pointer :*/
     3445                        responses_pointer++;
     3446                }
     3447                else if (flag==RegularEnum){
     3448
     3449                        /*perfectly normal response function: */
     3450                        this->Responsex(&femmodel_response,root);
     3451
     3452                        if(my_rank==0){
     3453                                /*plug response: */
     3454                                responses_pointer[0]=femmodel_response;
     3455
     3456                                /*increment response_pointer :*/
     3457                                responses_pointer++;
     3458                        }
     3459                }
     3460                else _error_("flag type " << flag << " not supported yet for response analysis");
     3461        }
     3462
     3463        /*Synthesize echo: {{{*/
     3464        if(my_rank==0){
     3465                _printf_("   responses: " << d_numresponses << ": ");
     3466                for(i=0;i<d_numresponses-1;i++)_printf_(d_responses[i] << "|");
     3467                _printf_(d_responses[d_numresponses-1]);
     3468                _printf_("\n");
     3469        }
     3470        /*}}}*/
    42173471
    42183472}
    42193473/*}}}*/
    42203474#endif
     3475#ifdef _HAVE_GIAIVINS_
     3476void FemModel::Deflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y){ /*{{{*/
     3477
     3478        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     3479        for(int i=0;i<elements->Size();i++){
     3480                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3481                element->GiaDeflection(wg,dwgdt, x,y);
     3482        }
     3483}
     3484/*}}}*/
     3485#endif
     3486#ifdef _HAVE_ESA_
     3487void FemModel::EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* xx, IssmDouble* yy){/*{{{*/
     3488
     3489        int         ns,nsmax;
     3490       
     3491        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     3492        ns = elements->Size();
     3493       
     3494        /*Figure out max of ns: */
     3495        ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     3496        ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     3497
     3498        /*Call the esa geodetic core: */
     3499        for(int i=0;i<nsmax;i++){
     3500                if(i<ns){
     3501                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3502                        element->EsaGeodetic2D(pUp,pNorth,pEast,xx,yy);
     3503                }
     3504                if(i%100==0){
     3505                        pUp->Assemble();
     3506                        pNorth->Assemble();
     3507                        pEast->Assemble();
     3508                }
     3509        }
     3510       
     3511        /*One last time: */
     3512        pUp->Assemble();
     3513        pNorth->Assemble();
     3514        pEast->Assemble();
     3515
     3516        /*Free ressources:*/
     3517        xDelete<IssmDouble>(xx);
     3518        xDelete<IssmDouble>(yy);
     3519}
     3520/*}}}*/
     3521void FemModel::EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/
     3522
     3523        IssmDouble  eartharea=0;
     3524        IssmDouble  eartharea_cpu=0;
     3525
     3526        int         ns,nsmax;
     3527       
     3528        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     3529        ns = elements->Size();
     3530       
     3531        /*First, figure out the surface area of Earth: */
     3532        for(int i=0;i<ns;i++){
     3533                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3534                eartharea_cpu += element->GetAreaSpherical();
     3535        }
     3536        ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3537        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3538
     3539        /*Figure out max of ns: */
     3540        ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     3541        ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     3542
     3543        /*Call the esa geodetic core: */
     3544        for(int i=0;i<nsmax;i++){
     3545                if(i<ns){
     3546                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3547                        element->EsaGeodetic3D(pUp,pNorth,pEast,latitude,longitude,radius,xx,yy,zz,eartharea);
     3548                }
     3549                if(i%100==0){
     3550                        pUp->Assemble();
     3551                        pNorth->Assemble();
     3552                        pEast->Assemble();
     3553                }
     3554        }
     3555       
     3556        /*One last time: */
     3557        pUp->Assemble();
     3558        pNorth->Assemble();
     3559        pEast->Assemble();
     3560
     3561        /*Free ressources:*/
     3562        xDelete<IssmDouble>(latitude);
     3563        xDelete<IssmDouble>(longitude);
     3564        xDelete<IssmDouble>(radius);
     3565        xDelete<IssmDouble>(xx);
     3566        xDelete<IssmDouble>(yy);
     3567        xDelete<IssmDouble>(zz);
     3568}
     3569/*}}}*/
     3570#endif
     3571#ifdef _HAVE_SEALEVELRISE_
     3572void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius) { /*{{{*/
     3573
     3574        /*serialized vectors:*/
     3575        IssmDouble  eustatic       = 0.;
     3576        IssmDouble  eustatic_cpu   = 0.;
     3577        IssmDouble  eustatic_cpu_e = 0.;
     3578        IssmDouble  oceanarea      = 0.;
     3579        IssmDouble  oceanarea_cpu  = 0.;
     3580        IssmDouble  eartharea      = 0.;
     3581        IssmDouble  eartharea_cpu  = 0.;
     3582        int         ns,nsmax;
     3583       
     3584        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     3585        ns = elements->Size();
     3586
     3587        /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
     3588        for(int i=0;i<ns;i++){
     3589                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3590                oceanarea_cpu += element->OceanArea();
     3591                eartharea_cpu += element->GetAreaSpherical();
     3592        }
     3593        ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3594        ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3595        _assert_(oceanarea>0.);
     3596
     3597        ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3598        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3599
     3600        /*Figure out max of ns: */
     3601        ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     3602        ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     3603
     3604        /*Call the sea level rise core: */
     3605        for(int i=0;i<nsmax;i++){
     3606                if(i<ns){
     3607               
     3608                        if(VerboseConvergence())if(i%100==0)_printf0_("\r" << "      convolution progress: " << (double)i/(double)ns*100 << "%  ");
     3609               
     3610                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3611                        element->SealevelriseEustatic(pSgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);
     3612                        eustatic_cpu+=eustatic_cpu_e;
     3613                }
     3614                if(i%100==0)pSgi->Assemble();
     3615        }
     3616        if(VerboseConvergence())_printf0_("\n");
     3617               
     3618        /*One last time: */
     3619        pSgi->Assemble();
     3620
     3621        /*Sum all eustatic components from all cpus:*/
     3622        ISSM_MPI_Reduce (&eustatic_cpu,&eustatic,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3623        ISSM_MPI_Bcast(&eustatic,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3624        _assert_(!xIsNan<IssmDouble>(eustatic));
     3625
     3626        /*Assign output pointers:*/
     3627        *peustatic=eustatic;
     3628
     3629}
     3630/*}}}*/
     3631void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution){/*{{{*/
     3632
     3633        /*serialized vectors:*/
     3634        IssmDouble* Sg_old=NULL;
     3635       
     3636        IssmDouble  eartharea=0;
     3637        IssmDouble  eartharea_cpu=0;
     3638
     3639        int         ns,nsmax;
     3640       
     3641        /*Serialize vectors from previous iteration:*/
     3642        Sg_old=pSg_old->ToMPISerial();
     3643
     3644        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     3645        ns = elements->Size();
     3646
     3647        /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
     3648        for(int i=0;i<ns;i++){
     3649                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3650                eartharea_cpu += element->GetAreaSpherical();
     3651        }
     3652       
     3653        ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3654        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3655
     3656        /*Figure out max of ns: */
     3657        ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     3658        ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     3659
     3660        /*Call the sea level rise core: */
     3661        for(int i=0;i<nsmax;i++){
     3662                if(i<ns){
     3663                        if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf_("\r" << "      convolution progress: " << (double)i/(double)ns*100 << "%   ");
     3664                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3665                        element->SealevelriseNonEustatic(pSgo,Sg_old,latitude,longitude,radius,eartharea);
     3666                }
     3667                if(i%100==0)pSgo->Assemble();
     3668        }
     3669        if(verboseconvolution)if(VerboseConvergence())_printf_("\n");
     3670       
     3671        /*Free ressources:*/
     3672        xDelete<IssmDouble>(Sg_old);
     3673}
     3674/*}}}*/
     3675void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pSgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/
     3676
     3677        /*serialized vectors:*/
     3678        IssmDouble* Sg_old=NULL;
     3679        IssmDouble  eartharea=0;
     3680        IssmDouble  eartharea_cpu=0;
     3681        IssmDouble      tide_love_h, tide_love_k, fluid_love, moi_e, moi_p, omega, g;
     3682        IssmDouble      load_love_k2 = -0.30922675; //degree 2 load Love number
     3683        IssmDouble      m1, m2, m3;
     3684        IssmDouble      lati, longi, radi, value;
     3685
     3686        /*Serialize vectors from previous iteration:*/
     3687        Sg_old=pSg_old->ToMPISerial();
     3688
     3689        /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
     3690        for(int i=0;i<elements->Size();i++){
     3691                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3692                eartharea_cpu += element->GetAreaSpherical();
     3693        }
     3694        ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3695        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3696
     3697        IssmDouble moi_list[3]={0,0,0};
     3698        IssmDouble moi_list_cpu[3]={0,0,0};
     3699        for(int i=0;i<elements->Size();i++){
     3700                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3701                element->SealevelriseMomentOfInertia(&moi_list[0],Sg_old,eartharea);
     3702                moi_list_cpu[0] += moi_list[0];
     3703                moi_list_cpu[1] += moi_list[1];
     3704                moi_list_cpu[2] += moi_list[2];
     3705        }
     3706        ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3707        ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3708        //     
     3709        ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3710        ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3711        //     
     3712        ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3713        ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3714       
     3715        /*pull out some useful parameters: */
     3716        parameters->FindParam(&tide_love_h,SealevelriseTidalLoveHEnum);
     3717        parameters->FindParam(&tide_love_k,SealevelriseTidalLoveKEnum);
     3718        parameters->FindParam(&fluid_love,SealevelriseFluidLoveEnum);
     3719        parameters->FindParam(&moi_e,SealevelriseEquatorialMoiEnum);
     3720        parameters->FindParam(&moi_p,SealevelrisePolarMoiEnum);
     3721        parameters->FindParam(&omega,SealevelriseAngularVelocityEnum);
     3722
     3723        /*compute perturbation terms for angular velocity vector: */
     3724        m1 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[0];
     3725        m2 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[1];
     3726        m3 = -(1+load_love_k2)/moi_p * moi_list[2];     // term associated with fluid number (3-order-of-magnitude smaller) is negelected 
     3727
     3728        /* Green's function (1+k_2-h_2/g): checked against Glenn Milne's thesis Chapter 3 (eqs: 3.3-4, 3.10-11)
     3729         * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3)
     3730         * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered)
     3731         * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180]
     3732         */
     3733        for(int i=0;i<vertices->Size();i++){
     3734                int sid;
     3735                //Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i);
     3736                Vertex* vertex=xDynamicCast<Vertex*>(vertices->GetObjectByOffset(i));
     3737                sid=vertex->Sid();
     3738
     3739                lati=latitude[sid]/180*PI;      longi=longitude[sid]/180*PI; radi=radius[sid];
     3740
     3741                /*only first order terms are considered now: */
     3742                value=((1.0+tide_love_k-tide_love_h)/9.81)*pow(omega*radi,2.0)*
     3743                                                (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi)));
     3744       
     3745                pSgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times
     3746        }
     3747
     3748        /*Assemble mesh velocity*/
     3749        pSgo_rot->Assemble();
     3750       
     3751        /*Free ressources:*/
     3752        xDelete<IssmDouble>(Sg_old);
     3753       
     3754}
     3755/*}}}*/
     3756void FemModel::SealevelriseGeodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/
     3757
     3758        /*serialized vectors:*/
     3759        IssmDouble* Sg=NULL;
     3760       
     3761        IssmDouble  eartharea=0;
     3762        IssmDouble  eartharea_cpu=0;
     3763
     3764        int         ns,nsmax;
     3765       
     3766        /*Serialize vectors from previous iteration:*/
     3767        Sg=pSg->ToMPISerial();
     3768
     3769        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     3770        ns = elements->Size();
     3771       
     3772        /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
     3773        for(int i=0;i<ns;i++){
     3774                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3775                eartharea_cpu += element->GetAreaSpherical();
     3776        }
     3777        ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3778        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3779
     3780        /*Figure out max of ns: */
     3781        ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     3782        ISSM_MPI_Bcast(&nsmax,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     3783
     3784        /*Call the sea level rise core: */
     3785        for(int i=0;i<nsmax;i++){
     3786                if(i<ns){
     3787                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3788                        element->SealevelriseGeodetic(pUp,pNorth,pEast,Sg,latitude,longitude,radius,xx,yy,zz,eartharea);
     3789                }
     3790                if(i%100==0){
     3791                        pUp->Assemble();
     3792                        pNorth->Assemble();
     3793                        pEast->Assemble();
     3794                }
     3795        }
     3796       
     3797        /*One last time: */
     3798        pUp->Assemble();
     3799        pNorth->Assemble();
     3800        pEast->Assemble();
     3801
     3802        /*Free ressources:*/
     3803        xDelete<IssmDouble>(Sg);
     3804        xDelete<IssmDouble>(latitude);
     3805        xDelete<IssmDouble>(longitude);
     3806        xDelete<IssmDouble>(radius);
     3807        xDelete<IssmDouble>(xx);
     3808        xDelete<IssmDouble>(yy);
     3809        xDelete<IssmDouble>(zz);
     3810}
     3811/*}}}*/
     3812IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* Sg) { /*{{{*/
     3813
     3814        IssmDouble* Sg_serial=NULL;
     3815        IssmDouble  oceanvalue,oceanvalue_cpu;
     3816        IssmDouble  oceanarea,oceanarea_cpu;
     3817
     3818        /*Serialize vectors from previous iteration:*/
     3819        Sg_serial=Sg->ToMPISerial();
     3820
     3821        /*Initialize:*/
     3822        oceanvalue_cpu=0;
     3823        oceanarea_cpu=0;
     3824
     3825        /*Go through elements, and add contribution from each element and divide by overall ocean area:*/
     3826        for(int i=0;i<elements->Size();i++){
     3827                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3828                oceanarea_cpu += element->OceanArea();
     3829                oceanvalue_cpu += element->OceanAverage(Sg_serial);
     3830        }
     3831        ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3832        ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3833       
     3834        ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3835        ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     3836
     3837        /*Free ressources:*/
     3838        xDelete<IssmDouble>(Sg_serial);
     3839       
     3840        return oceanvalue/oceanarea;
     3841}
     3842/*}}}*/
     3843#endif
     3844void FemModel::HydrologyEPLupdateDomainx(IssmDouble* pEplcount){ /*{{{*/
     3845
     3846        Vector<IssmDouble>* mask                                                        = NULL;
     3847        Vector<IssmDouble>* recurence                           = NULL;
     3848        Vector<IssmDouble>* active                                              = NULL;
     3849        IssmDouble*         serial_mask                         = NULL;
     3850        IssmDouble*         serial_rec                          = NULL;
     3851        IssmDouble*         serial_active                       = NULL;
     3852        IssmDouble*         old_active        = NULL;
     3853        int*                eplzigzag_counter = NULL;
     3854        int                 eplflip_lock;
     3855       
     3856        HydrologyDCEfficientAnalysis* effanalysis =  new HydrologyDCEfficientAnalysis();
     3857        HydrologyDCInefficientAnalysis* inefanalysis =  new HydrologyDCInefficientAnalysis();
     3858
     3859        /*Step 1: update mask, the mask might be extended by residual and/or using downstream sediment head*/
     3860        mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
     3861        recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
     3862        this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum);
     3863        this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum);
     3864        GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum);
     3865       
     3866        for (int i=0;i<elements->Size();i++){
     3867                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3868                effanalysis->HydrologyEPLGetMask(mask,recurence,eplzigzag_counter,element);
     3869        }
     3870        /*check for changes and increment zigzag counter, change the mask if necessary*/
     3871        recurence->Assemble();
     3872        serial_rec=recurence->ToMPISerial();
     3873        for (int i=0;i<nodes->Size();i++){
     3874                Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
     3875                if(serial_rec[node->Sid()]==1.)eplzigzag_counter[node->Lid()] ++;
     3876                if(eplzigzag_counter[node->Lid()]>eplflip_lock & eplflip_lock!=0){
     3877                        mask->SetValue(node->Sid(),old_active[node->Sid()],INS_VAL);
     3878                }
     3879        }
     3880        this->parameters->SetParam(eplzigzag_counter,this->nodes->Size(),EplZigZagCounterEnum);
     3881        /*Assemble and serialize*/
     3882        mask->Assemble();
     3883        serial_mask=mask->ToMPISerial();       
     3884       
     3885        xDelete<int>(eplzigzag_counter);
     3886        xDelete<IssmDouble>(serial_rec);
     3887        xDelete<IssmDouble>(old_active);
     3888        delete mask;
     3889        delete recurence;
     3890
     3891        /*Update Mask*/
     3892        InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum);
     3893        xDelete<IssmDouble>(serial_mask);
     3894        inefanalysis->ElementizeEplMask(this);
     3895        /*Step 2: update node activity. If one element is connected to mask=1, all nodes are active*/
     3896        active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
     3897        for (int i=0;i<elements->Size();i++){
     3898                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3899                effanalysis->HydrologyEPLGetActive(active,element);
     3900        }
     3901
     3902        /*Assemble and serialize*/
     3903        active->Assemble();
     3904        serial_active=active->ToMPISerial();
     3905        delete active;
     3906
     3907        /*Update node activation accordingly*/
     3908        int counter =0;
     3909        for (int i=0;i<nodes->Size();i++){
     3910                Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
     3911                if(node->InAnalysis(HydrologyDCEfficientAnalysisEnum)){
     3912                        if(serial_active[node->Sid()]==1.){
     3913                                node->Activate();
     3914                                if(!node->IsClone()) counter++;
     3915                        }
     3916                        else{
     3917                                node->Deactivate();
     3918                        }
     3919                }
     3920        }
     3921        xDelete<IssmDouble>(serial_active);
     3922        delete effanalysis;
     3923        delete inefanalysis;
     3924        int sum_counter;
     3925        ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3926        ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());               
     3927        counter=sum_counter;
     3928        *pEplcount = counter;
     3929        if(VerboseSolution()) _printf0_("   Number of active nodes in EPL layer: "<< counter <<"\n");
     3930
     3931        /*Update dof indexings*/
     3932        this->UpdateConstraintsx();
     3933
     3934}
     3935/*}}}*/
     3936void FemModel::UpdateConstraintsL2ProjectionEPLx(IssmDouble* pL2count){ /*{{{*/
     3937
     3938        Vector<IssmDouble>* active        = NULL;
     3939        IssmDouble*         serial_active = NULL;
     3940        HydrologyDCEfficientAnalysis* effanalysis = new HydrologyDCEfficientAnalysis();
     3941
     3942        /*update node activity. If one element is connected to mask=1, all nodes are active*/
     3943        active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
     3944        for (int i=0;i<elements->Size();i++){
     3945                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     3946                effanalysis->HydrologyEPLGetActive(active,element);
     3947        }
     3948
     3949        /*Assemble and serialize*/
     3950        active->Assemble();
     3951        serial_active=active->ToMPISerial();
     3952        delete active;
     3953        delete effanalysis;
     3954
     3955        /*Update node activation accordingly*/
     3956        int counter =0;
     3957        for (int i=0;i<nodes->Size();i++){
     3958                Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
     3959                if(node->InAnalysis(L2ProjectionEPLAnalysisEnum)){
     3960                        if(serial_active[node->Sid()]==1.){
     3961                                node->Activate();
     3962                                if(!node->IsClone()) counter++;
     3963                        }
     3964                        else{
     3965                                node->Deactivate();
     3966                        }
     3967                }
     3968        }
     3969        xDelete<IssmDouble>(serial_active);
     3970        int sum_counter;
     3971        ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     3972        ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());               
     3973        counter=sum_counter;
     3974        *pL2count = counter;
     3975        if(VerboseSolution()) _printf0_("   Number of active nodes L2 Projection: "<< counter <<"\n");
     3976}
     3977/*}}}*/
     3978#ifdef _HAVE_JAVASCRIPT_
     3979FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/
     3980        /*configuration: */
     3981        int  solution_type;
     3982        int  ierr;
     3983
     3984        /*First things first, store the communicator, and set it as a global variable: */
     3985        IssmComm::SetComm(incomm);
     3986
     3987        /*Start profiler: */
     3988        this->profiler=new Profiler();
     3989        profiler->Tag(START);
     3990
     3991        /*From command line arguments, retrieve different filenames needed to create the FemModel: */
     3992        solution_type=StringToEnumx(solution);
     3993       
     3994        /*Create femmodel from input files: */
     3995        profiler->Tag(STARTINIT);
     3996        this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL);
     3997        profiler->Tag(FINISHINIT);
     3998       
     3999        /*Save communicator in the parameters dataset: */
     4000        this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum));
     4001
     4002}
     4003/*}}}*/
     4004void FemModel::CleanUpJs(char** poutput, size_t* psize){/*{{{*/
     4005
     4006        /*Intermediary*/
     4007        FILE *output_fid;
     4008        GenericParam<char**>* outputbufferparam=NULL;
     4009        GenericParam<size_t*>* outputbuffersizeparam=NULL;
     4010        char** poutputbuffer;
     4011        size_t* poutputbuffersize;
     4012
     4013       
     4014        /*Before we delete the profiler, report statistics for this run: */
     4015        profiler->Tag(FINISH);  //final tagging
     4016        _printf0_("\n");
     4017        _printf0_("   "<<setw(40)<<left<<"FemModel initialization elapsed time:"<<profiler->DeltaTime(STARTINIT,FINISHINIT) << "\n");
     4018        _printf0_("   "<<setw(40)<<left<<"Core solution elapsed time:"<<profiler->DeltaTime(STARTCORE,FINISHCORE) << "\n");
     4019        _printf0_("\n");
     4020        _printf0_("   Total elapsed time: "
     4021                                <<profiler->DeltaTimeModHour(START,FINISH)<<" hrs "
     4022                                <<profiler->DeltaTimeModMin(START,FINISH)<<" min "
     4023                                <<profiler->DeltaTimeModSec(START,FINISH)<<" sec"
     4024                                );
     4025        _printf0_("\n");
     4026       
     4027        /*Before we close the output file, recover the buffer and size:*/
     4028        outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum));
     4029        poutputbuffer=outputbufferparam->GetParameterValue();
     4030        outputbuffersizeparam = xDynamicCast<GenericParam<size_t*>*>(this->parameters->FindParamObject(OutputBufferSizePointerEnum));
     4031        poutputbuffersize=outputbuffersizeparam->GetParameterValue();
     4032
     4033        /*Assign output values: */
     4034        *poutput=*poutputbuffer;
     4035        *psize=*poutputbuffersize;
     4036}
     4037/*}}}*/
     4038void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
     4039
     4040        /*intermediary*/
     4041        FILE       *IOMODEL = NULL;
     4042        FILE       *toolkitsoptionsfid = NULL;
     4043        FILE       *output_fid = NULL;
     4044        int         my_rank;
     4045        size_t      outputsize;
     4046        char       *outputbuffer;
     4047        const char *rootpath = "";   //needed for Dakota runs only, which we won't do here.
     4048
     4049        /*recover my_rank:*/
     4050        my_rank=IssmComm::GetRank();
     4051
     4052        /*Open input file descriptor on cpu 0: */
     4053        if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb");
     4054
     4055        /*Open toolkits file descriptor: */
     4056        toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r");
     4057
     4058        /*Now, go create FemModel:*/
     4059        this->InitFromFids((char*)rootpath,IOMODEL,toolkitsoptionsfid,in_solution_type,trace,X);
     4060
     4061        /*Close input file and toolkits file descriptors: */
     4062        if(my_rank==0) fclose(IOMODEL);
     4063        fclose(toolkitsoptionsfid);
     4064
     4065        /*Open output file once for all and add output file descriptor to parameters*/
     4066        output_fid=open_memstream(&outputbuffer,&outputsize);
     4067        if(output_fid==NULL)_error_("could not initialize output stream");
     4068        this->parameters->SetParam(output_fid,OutputFilePointerEnum);
     4069        this->parameters->AddObject(new GenericParam<char**>(&outputbuffer,OutputBufferPointerEnum));
     4070        this->parameters->AddObject(new GenericParam<size_t*>(&outputsize,OutputBufferSizePointerEnum));
     4071
     4072}/*}}}*/
     4073#endif
     4074
     4075#ifdef _HAVE_BAMG_
     4076void FemModel::ReMeshBamg(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist){/*{{{*/
     4077
     4078        /*Output*/
     4079        IssmDouble *newx                        = NULL;
     4080        IssmDouble *newy                        = NULL;
     4081        IssmDouble *newz                        = NULL;
     4082        int *newelementslist            = NULL;
     4083        int newnumberofvertices = -1;
     4084        int newnumberofelements = -1;
     4085
     4086        /*Get Rank*/
     4087        int my_rank     = IssmComm::GetRank();
     4088
     4089        if(my_rank==0){
     4090                this->amrbamg->ExecuteRefinementBamg(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist);
     4091                if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the refinement process.");
     4092        }
     4093        else{
     4094                newx=xNew<IssmDouble>(newnumberofvertices);
     4095                newy=xNew<IssmDouble>(newnumberofvertices);
     4096                newz=xNew<IssmDouble>(newnumberofvertices);
     4097                newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
     4098        }
     4099
     4100        /*Send new mesh to others CPU*/
     4101        ISSM_MPI_Bcast(&newnumberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     4102        ISSM_MPI_Bcast(&newnumberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     4103        ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     4104        ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     4105        ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     4106        ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());       
     4107
     4108        /*Assign output pointers*/
     4109        *pnewnumberofvertices = newnumberofvertices;
     4110        *pnewnumberofelements = newnumberofelements;
     4111        *pnewx = newx;
     4112        *pnewy = newy;
     4113        *pnewz = newz;
     4114        *pnewelementslist = newelementslist;
     4115}
     4116/*}}}*/
     4117void FemModel::InitializeAdaptiveRefinementBamg(void){/*{{{*/
     4118
     4119        /*Define variables*/
     4120        int numberofvertices      = this->vertices->NumberOfVertices();
     4121        int numberofelements      = this->elements->NumberOfElements();
     4122        int numberofsegments      = 0; //used on matlab
     4123        IssmDouble* x             = NULL;
     4124        IssmDouble* y             = NULL;
     4125        IssmDouble* z             = NULL;
     4126        int* elements             = NULL;
     4127        int elementswidth         = this->GetElementsWidth(); //just tria elements in this version. Itapopo:
     4128        IssmDouble hmin,hmax,err;
     4129        int        fieldenum;
     4130
     4131   /*Get rank*/
     4132        int my_rank = IssmComm::GetRank();
     4133
     4134        /*Initialize field as NULL for now*/
     4135        this->amrbamg = NULL;
     4136
     4137        /*Get vertices coordinates of the coarse mesh (father mesh)*/
     4138        this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements);
     4139
     4140        /*Get amr parameters*/
     4141        this->parameters->FindParam(&hmin,AmrHminEnum);
     4142        this->parameters->FindParam(&hmax,AmrHmaxEnum);
     4143        this->parameters->FindParam(&fieldenum,AmrFieldEnum);
     4144        this->parameters->FindParam(&err,AmrErrEnum);
     4145
     4146        /*Create bamg data structures for bamg (only cpu 0)*/
     4147        if(my_rank==0){
     4148                /*Re-create original mesh and put it in bamg structure*/
     4149                this->amrbamg = new AmrBamg(hmin,hmax);
     4150                this->amrbamg->Initialize(elements,x,y,numberofvertices,numberofelements);
     4151        }
     4152
     4153        /*Free the vectors*/
     4154        xDelete<IssmDouble>(x);
     4155        xDelete<IssmDouble>(y);
     4156        xDelete<IssmDouble>(z);
     4157        xDelete<int>(elements);
     4158}
     4159/*}}}*/
     4160#endif
     4161
     4162#ifdef _HAVE_NEOPZ_
     4163void FemModel::ReMeshNeopz(int* pnumberofvertices,int* pnumberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist){/*{{{*/
     4164
     4165        /*elements is in Matlab indexing*/
     4166        int my_rank                                             = IssmComm::GetRank();
     4167        int numberofsegments                    = -1;
     4168        int numberofvertices,numberofelements;
     4169        IssmDouble* vx                                  = NULL; //itapopo this is not being used
     4170        IssmDouble* vy                                  = NULL; //itapopo this is not being used
     4171        IssmDouble* x                                   = NULL;
     4172        IssmDouble* y                                   = NULL;
     4173        IssmDouble* z                                   = NULL;
     4174        int* elementslist                               = NULL;
     4175        int* segments                                   = NULL;
     4176        IssmDouble* masklevelset        = NULL;
     4177        IssmDouble* pelementerror       = NULL;
     4178        const int elementswidth         = this->GetElementsWidth();//just 2D mesh, tria elements
     4179
     4180        /*Solutions which will be used to refine the elements*/
     4181        this->GetGroundediceLevelSet(&masklevelset);//itapopo verificar se já existe um método igual a esse
     4182
     4183        //Compute the ZZ error estimator per element
     4184        this->ZZErrorEstimator(&pelementerror);
     4185
     4186        _printf0_("P Element error\n");
     4187        for(int i=0;i<this->elements->NumberOfElements();i++)   _printf0_(""<<pelementerror[i]<< "\n");
     4188        _printf0_("\n");
     4189
     4190        if(my_rank==0){
     4191                int type_process=1; //1: it refines father mesh. See AdaptiveMeshRefinement.h (.cpp)
     4192                this->amr->ExecuteRefinement(type_process,vx,vy,masklevelset,
     4193                                        numberofvertices,numberofelements,numberofsegments,&x,&y,&z,&elementslist,&segments);
     4194                if(numberofvertices<=0 || numberofelements<=0 /*|| newnumberofsegments<=0*/) _error_("Error in the refinement process.");
     4195        }
     4196        else{
     4197                x=xNew<IssmDouble>(numberofvertices);
     4198                y=xNew<IssmDouble>(numberofvertices);
     4199                z=xNew<IssmDouble>(numberofvertices);
     4200                elementslist=xNew<int>(numberofelements*this->GetElementsWidth());
     4201        }
     4202
     4203        /*Send new mesh to others CPU*/
     4204        ISSM_MPI_Bcast(&numberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     4205        ISSM_MPI_Bcast(&numberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     4206        ISSM_MPI_Bcast(x,numberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());       
     4207        ISSM_MPI_Bcast(y,numberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());       
     4208        ISSM_MPI_Bcast(z,numberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());       
     4209        ISSM_MPI_Bcast(elementslist,numberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());     
     4210
     4211        /*Assign the pointers*/
     4212        (*pelementslist) = elementslist; //Matlab indexing
     4213        (*px)                             = x;
     4214        (*py)                             = y;
     4215        (*pz)                             = z;
     4216        *pnumberofelements = numberofelements;
     4217        *pnumberofvertices = numberofvertices;
     4218
     4219        /*Cleanup*/
     4220        if(segments) xDelete<int>(segments);
     4221        xDelete<IssmDouble>(masklevelset);
     4222        xDelete<IssmDouble>(pelementerror);
     4223
     4224}
     4225/*}}}*/
     4226void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/
     4227       
     4228        /*Define variables*/
     4229        int my_rank                                             = IssmComm::GetRank();
     4230        int numberofvertices                    = this->vertices->NumberOfVertices();
     4231        int numberofelements                    = this->elements->NumberOfElements();
     4232        int numberofsegments                    = 0; //used on matlab
     4233        IssmDouble* x                                   = NULL;
     4234        IssmDouble* y                                   = NULL;
     4235        IssmDouble* z                                   = NULL;
     4236        int* elements                                   = NULL;
     4237        int elementswidth                               = this->GetElementsWidth(); //just tria elements in this version. Itapopo:
     4238        int levelmax                                    = 0;
     4239        IssmDouble regionlevel1         = 0.;
     4240        IssmDouble regionlevelmax       = 0.;
     4241
     4242        /*Initialize field as NULL for now*/
     4243        this->amr = NULL;
     4244
     4245        /*Get vertices coordinates of the coarse mesh (father mesh)*/
     4246        /*elements comes in Matlab indexing*/
     4247        this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements);
     4248       
     4249        /*Get amr parameters*/
     4250        this->parameters->FindParam(&levelmax,AmrLevelMaxEnum);
     4251        this->parameters->FindParam(&regionlevel1,AmrRegionLevel1Enum);
     4252        this->parameters->FindParam(&regionlevelmax,AmrRegionLevelMaxEnum);
     4253
     4254        /*Create initial mesh (coarse mesh) in neopz data structure*/
     4255        /*Just CPU #0 should keep AMR object*/
     4256   this->SetRefPatterns();
     4257        if(my_rank==0){
     4258           bool ismisomip       = false;
     4259                if(ismisomip){//itapopo
     4260                        TPZFileStream fstr;
     4261                        std::stringstream ss;
     4262                        int frictionlaw;
     4263                       
     4264                        this->parameters->FindParam(&frictionlaw,FrictionLawEnum);
     4265               
     4266                        ss      << levelmax;
     4267                        if(frictionlaw==1){
     4268                                ss << "_viscous/amr.txt";
     4269                        }else if(frictionlaw==7){
     4270                                ss << "_tsai/amr.txt";
     4271                        }else{
     4272                                _error_("friction law not supported here.");
     4273                        }
     4274                       
     4275                        std::string AMRfile  = "/home/santos/Misomip2/L" + ss.str();
     4276                        fstr.OpenRead(AMRfile.c_str());
     4277                       
     4278                        TPZSaveable *sv         = TPZSaveable::Restore(fstr,0);
     4279                        this->amr                               = dynamic_cast<AdaptiveMeshRefinement*>(sv);
     4280                }
     4281                else{
     4282                        this->amr = new AdaptiveMeshRefinement();
     4283                        //this->amr->SetLevelMax(levelmax); //Set max level of refinement
     4284                        //this->amr->SetRegions(regionlevel1,regionlevelmax);
     4285                        this->amr->CreateInitialMesh(numberofvertices,numberofelements,numberofsegments,elementswidth,x,y,z,elements,NULL);
     4286                }
     4287                this->amr->SetLevelMax(levelmax); //Set max level of refinement
     4288                this->amr->SetRegions(regionlevel1,regionlevelmax);
     4289        }
     4290
     4291        /*Free the vectors*/
     4292        xDelete<IssmDouble>(x);
     4293        xDelete<IssmDouble>(y);
     4294        xDelete<IssmDouble>(z);
     4295        xDelete<int>(elements);
     4296}
     4297/*}}}*/
     4298void FemModel::SetRefPatterns(){/*{{{*/
     4299
     4300   /*Initialize the global variable of refinement patterns*/
     4301   gRefDBase.InitializeUniformRefPattern(EOned);
     4302   gRefDBase.InitializeUniformRefPattern(ETriangle);
     4303
     4304    //gRefDBase.InitializeRefPatterns();
     4305   /*Insert specifics patterns to ISSM core*/
     4306   std::string filepath  = REFPATTERNDIR;
     4307   std::string filename1 = filepath + "/2D_Triang_Rib_3.rpt";
     4308   std::string filename2 = filepath + "/2D_Triang_Rib_4.rpt";
     4309   std::string filename3 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_4.rpt";
     4310   std::string filename4 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_4_permuted.rpt";
     4311   std::string filename5 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_5.rpt";
     4312   std::string filename6 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_5_permuted.rpt";
     4313   std::string filename7 = filepath + "/2D_Triang_Rib_5.rpt";
     4314
     4315   TPZAutoPointer<TPZRefPattern> refpat1 = new TPZRefPattern(filename1);
     4316   TPZAutoPointer<TPZRefPattern> refpat2 = new TPZRefPattern(filename2);
     4317   TPZAutoPointer<TPZRefPattern> refpat3 = new TPZRefPattern(filename3);
     4318   TPZAutoPointer<TPZRefPattern> refpat4 = new TPZRefPattern(filename4);
     4319   TPZAutoPointer<TPZRefPattern> refpat5 = new TPZRefPattern(filename5);
     4320   TPZAutoPointer<TPZRefPattern> refpat6 = new TPZRefPattern(filename6);
     4321   TPZAutoPointer<TPZRefPattern> refpat7 = new TPZRefPattern(filename7);
     4322
     4323   if(!gRefDBase.FindRefPattern(refpat1)) gRefDBase.InsertRefPattern(refpat1);
     4324   if(!gRefDBase.FindRefPattern(refpat2)) gRefDBase.InsertRefPattern(refpat2);
     4325   if(!gRefDBase.FindRefPattern(refpat3)) gRefDBase.InsertRefPattern(refpat3);
     4326   if(!gRefDBase.FindRefPattern(refpat4)) gRefDBase.InsertRefPattern(refpat4);
     4327   if(!gRefDBase.FindRefPattern(refpat5)) gRefDBase.InsertRefPattern(refpat5);
     4328   if(!gRefDBase.FindRefPattern(refpat6)) gRefDBase.InsertRefPattern(refpat6);
     4329   if(!gRefDBase.FindRefPattern(refpat7)) gRefDBase.InsertRefPattern(refpat7);
     4330}
     4331/*}}}*/
     4332#endif
  • issm/trunk-jpl/src/c/classes/FemModel.h

    r21762 r21802  
    2222#ifdef _HAVE_NEOPZ_
    2323#include "./AdaptiveMeshRefinement.h"
     24#endif
     25#ifdef _HAVE_BAMG_
     26#include "./AmrBamg.h"
    2427#endif
    2528/*}}}*/
     
    4750                Vertices    *vertices;             //one set of vertices
    4851
     52                //FIXME: do we want only one class and have virtual functions? or keep 2 classes, at least rename AdaptiveMeshRefinement -> AmrNeopz
    4953                #ifdef _HAVE_NEOPZ_
    5054                AdaptiveMeshRefinement *amr;              //adaptive mesh refinement object. It keeps coarse mesh and execute refinement process
     55                #endif
     56
     57                #ifdef _HAVE_BAMG_
     58                AmrBamg *amrbamg; //adaptive mesh refinement object. It keeps coarse mesh and execute refinement process
    5159                #endif
    5260
     
    6169                FemModel* copy();
    6270                void Echo();
     71                int  GetElementsWidth(){return 3;};//just tria elements in this first version
    6372                void InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* petscfilename, char* lockfilename, char* restartfilename, const int solution_type,bool trace,IssmPDouble* X=NULL);
    6473                void InitFromFids(char* rootpath, FILE* IOMODEL, FILE* toolkitsoptionsfid, int in_solution_type, bool trace, IssmPDouble* X=NULL);
    6574                void Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction);
     75                void ReMesh(void);
    6676                void Restart(void);
    6777                void SetCurrentConfiguration(int configuration_type);
     
    146156                #endif
    147157
    148                 #ifdef _HAVE_NEOPZ_
    149                 /*Adaptive mesh refinement methods*/
    150                 void InitializeAdaptiveRefinement(void);
    151                 void ReMesh(void);
     158                /*AMR*/
    152159                void BedrockFromMismipPlus(void);
    153160                void AdjustBaseThicknessAndMask(void);
    154161                void GetMesh(Vertices* femmodel_vertices,Elements* femmodel_elements,IssmDouble** px, IssmDouble** py, IssmDouble** pz, int** pelementslist);
    155                 int GetElementsWidth(){return 3;};//just tria elements in this first version
    156                 void ExecuteRefinement(int &numberofvertices,int &numberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist);
    157162                void GetGroundediceLevelSet(IssmDouble** pmasklevelset);
    158163                void CreateVertices(int newnumberofvertices,int newnumberofelements,int elementswidth,int* newelementslist,int* my_vertices,IssmDouble* newx,IssmDouble* newy,IssmDouble* newz,Vertices* vertices);
     
    168173                void SmoothedDeviatoricStressTensor(IssmDouble** ptauxx,IssmDouble** ptauyy,IssmDouble** ptauxy); //nodal values, just for SSA-P1: TauXX, TauYY, TauXY
    169174                void ZZErrorEstimator(IssmDouble** pelementerror);
     175
     176                #ifdef _HAVE_BAMG_
     177                void ReMeshBamg(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist);
     178                void InitializeAdaptiveRefinementBamg(void);
     179                #endif
     180
     181                #ifdef _HAVE_NEOPZ_
     182                /*Adaptive mesh refinement methods*/
     183                void ReMeshNeopz(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist);
     184                void InitializeAdaptiveRefinementNeopz(void);
    170185                #endif
    171186};
    172                
    173187
    174188#endif
  • issm/trunk-jpl/src/c/classes/IoModel.cpp

    r21775 r21802  
    605605                                        if(strcmp(record_name,"md.materials.type")==0) integer = IoCodeToEnumMaterials(integer);
    606606                                        if(strcmp(record_name,"md.timestepping.type")==0) integer = IoCodeToEnumTimestepping(integer);
     607                                        if(strcmp(record_name,"md.amr.type")==0) integer = IoCodeToEnumAmr(integer);
    607608
    608609                                        /*Broadcast to other cpus*/
  • issm/trunk-jpl/src/c/cores/transient_core.cpp

    r21787 r21802  
    111111                                }
    112112                        }
    113                         if(VerboseSolution()) _printf0_("   computing thermal regime\n");
    114113                        thermal_core(femmodel);
    115114                }
     
    182181
    183182                /*Adaptive mesh refinement*/
    184                 #ifdef _HAVE_NEOPZ_
    185183                if(amr_frequency){
    186184                        if(save_results) femmodel->WriteMeshInResults();
    187                         if(step%amr_frequency==0 && time<finaltime) femmodel->ReMesh();//Do not refine the last step
    188                 }
    189                 #endif
     185                        if(step%amr_frequency==0 && time<finaltime){
     186                                if(VerboseSolution()) _printf0_("   refining mesh\n");
     187                                femmodel->ReMesh();//Do not refine the last step
     188                        }
     189                        //if(save_results){
     190                        //      printf("-------------- file: transient_core.cpp line: %i\n",__LINE__);
     191                        //      femmodel->WriteMeshInResults();
     192                        //      OutputResultsx(femmodel);
     193                        //}
     194                }
    190195        }
    191196       
  • issm/trunk-jpl/src/c/modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp

    r21792 r21802  
    2424        R2     r;
    2525        I2     I;
    26         int    i,j;
     26        int    i,j,k;
    2727        int    it;
    2828        int    i0,i1,i2;
     
    6464                if(y_data[i]<ymin) ymin=y_data[i];
    6565                if(y_data[i]>ymax) ymax=y_data[i];
     66        }
     67
     68        /*Create Single vertex to element connectivity*/
     69        int* connectivity = xNew<int>(nods_data);
     70        for(i=0;i<nels_data;i++){
     71                for(j=0;j<3;j++){
     72                        k = index_data[i*3+j]-1;
     73                        _assert_(k>=0 & k<nods_data);
     74                        connectivity[k]=i;
     75                }
    6676        }
    6777
     
    137147                        /*If we fall outside of the convex or outside of the mesh, return NaN*/
    138148                        if(tb.det<0 || reft[it]<0){
    139                                 for (j=0;j<N_data;j++){
    140                                         data_interp[i*N_data+j]=NAN;
    141                                 }
     149                                _assert_(i0>=0 & i0<nods_data);
     150                                it=connectivity[i0]; //or i1 or i2
     151                                _assert_(it>=0 && it<nels_data);
     152                                for(j=0;j<N_data;j++) data_interp[i*N_data+j]=data[N_data*it+j];
    142153                        }
    143154                        else{
     155                                /*Inside the mesh!*/
    144156                                if(it<0 || it>=nels_data){
    145157                                        _error_("Triangle number " << it << " not in [0 " << nels_data
    146158                                                                << "], report bug to developers (interpolation point: " <<x_interp[i]<<" "<<y_interp[i]<<")");
    147159                                }
    148                                 for (j=0;j<N_data;j++){
    149 
    150                                         data_interp[i*N_data+j]=data[N_data*it+j];
    151                                 }
     160                                for (j=0;j<N_data;j++) data_interp[i*N_data+j]=data[N_data*it+j];
    152161                        }
    153162                }
     
    158167        delete Th;
    159168        xDelete<long>(reft);
     169        xDelete<int>(connectivity);
    160170        *pdata_interp=data_interp;
    161171        return 1;
  • issm/trunk-jpl/src/c/modules/ModelProcessorx/CreateParameters.cpp

    r21787 r21802  
    2121        int         numoutputs,materialtype,smb_model,basalforcing_model,timestepping_type;
    2222        char**      requestedoutputs = NULL;
     23        char*       fieldname = NULL;
    2324        IssmDouble  time;
    2425
     
    6061        parameters->AddObject(iomodel->CopyConstantObject("md.inversion.type",InversionTypeEnum));
    6162        parameters->AddObject(iomodel->CopyConstantObject("md.calving.law",CalvingLawEnum));
    62         {/*This is specific to ice...*/
     63          {/*This is specific to ice...*/
    6364                parameters->AddObject(iomodel->CopyConstantObject("md.mesh.elementtype",MeshElementtypeEnum));
    6465                parameters->AddObject(iomodel->CopyConstantObject("md.steadystate.reltol",SteadystateReltolEnum));
     
    8182                parameters->AddObject(iomodel->CopyConstantObject("md.materials.rheology_law",MaterialsRheologyLawEnum));
    8283                parameters->AddObject(iomodel->CopyConstantObject("md.gia.cross_section_shape",GiaCrossSectionShapeEnum));
    83                 /*amr properties*/     
    84                 parameters->AddObject(iomodel->CopyConstantObject("md.amr.level_max",AmrLevelMaxEnum));
    85                 parameters->AddObject(iomodel->CopyConstantObject("md.amr.region_level_1",AmrRegionLevel1Enum));
    86                 parameters->AddObject(iomodel->CopyConstantObject("md.amr.region_level_max",AmrRegionLevelMaxEnum));
    8784
    8885                /*For stress balance only*/
     
    9592                if(iomodel->domaintype==Domain3DEnum)
    9693                 parameters->AddObject(iomodel->CopyConstantObject("md.mesh.numberoflayers",MeshNumberoflayersEnum));
    97         }
    98 
    99        
     94          }
     95
     96        /*amr properties*/     
     97        int amrtype,amr_frequency;
     98        iomodel->FindConstant(&amr_frequency,"md.transient.amr_frequency");
     99        if(solution_type==TransientSolutionEnum && amr_frequency){
     100                parameters->AddObject(iomodel->CopyConstantObject("md.amr.type",AmrTypeEnum));
     101                iomodel->FindConstant(&amrtype,"md.amr.type");
     102                switch(amrtype){
     103                        #ifdef _HAVE_NEOPZ_
     104                        case AmrNeopzEnum:
     105                                parameters->AddObject(iomodel->CopyConstantObject("md.amr.level_max",AmrLevelMaxEnum));
     106                                parameters->AddObject(iomodel->CopyConstantObject("md.amr.region_level_1",AmrRegionLevel1Enum));
     107                                parameters->AddObject(iomodel->CopyConstantObject("md.amr.region_level_max",AmrRegionLevelMaxEnum));
     108                                break;
     109                        #endif
     110
     111                        #ifdef _HAVE_BAMG_
     112                        case AmrBamgEnum:
     113                                parameters->AddObject(iomodel->CopyConstantObject("md.amr.hmin",AmrHminEnum));
     114                                parameters->AddObject(iomodel->CopyConstantObject("md.amr.hmax",AmrHmaxEnum));
     115                                parameters->AddObject(iomodel->CopyConstantObject("md.amr.err",AmrErrEnum));
     116                                /*Convert fieldname to enum and put it in params*/
     117                                iomodel->FindConstant(&fieldname,"md.amr.fieldname");
     118                                parameters->AddObject(new IntParam(AmrFieldEnum,StringToEnumx(fieldname)));
     119                                xDelete<char>(fieldname);
     120                                break;
     121                        #endif
     122
     123                        default:
     124                                _error_("Adaptive mesh refinement "<<EnumToStringx(amrtype)<<" not implemented yet");
     125                }
     126        }
     127
    100128        /*Basal forcing parameters*/
    101129        parameters->AddObject(iomodel->CopyConstantObject("md.basalforcings.model",BasalforcingsEnum));
     
    255283        ParseToolkitsOptionsx(parameters,toolkitsoptionsfid);
    256284
    257         #ifdef _HAVE_ADOLC_
     285        #ifdef _HAVE_ADOLC_
    258286        if(VerboseMProcessor()) _printf0_("   starting autodiff parameters \n");
    259287        CreateParametersAutodiff(parameters,iomodel);
  • issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h

    r21793 r21802  
    833833        /*}}}*/
    834834        /*Adaptive mesh refinement (AMR){{{*/
     835        TransientAmrFrequencyEnum,
     836        AmrTypeEnum,
     837        AmrNeopzEnum,
    835838        AmrLevelMaxEnum,
    836839        AmrRegionLevel1Enum,
    837840        AmrRegionLevelMaxEnum,
    838         TransientAmrFrequencyEnum,
     841        AmrBamgEnum,
     842        AmrHminEnum,
     843        AmrHmaxEnum,
     844        AmrFieldEnum,
     845        AmrErrEnum,
    839846        /*}}}*/
    840847        ParametersENDEnum,
  • issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp

    r21793 r21802  
    809809                case EsaRequestedOutputsEnum : return "EsaRequestedOutputs";
    810810                case EsaNumRequestedOutputsEnum : return "EsaNumRequestedOutputs";
     811                case TransientAmrFrequencyEnum : return "TransientAmrFrequency";
     812                case AmrTypeEnum : return "AmrType";
     813                case AmrNeopzEnum : return "AmrNeopz";
    811814                case AmrLevelMaxEnum : return "AmrLevelMax";
    812815                case AmrRegionLevel1Enum : return "AmrRegionLevel1";
    813816                case AmrRegionLevelMaxEnum : return "AmrRegionLevelMax";
    814                 case TransientAmrFrequencyEnum : return "TransientAmrFrequency";
     817                case AmrBamgEnum : return "AmrBamg";
     818                case AmrHminEnum : return "AmrHmin";
     819                case AmrHmaxEnum : return "AmrHmax";
     820                case AmrFieldEnum : return "AmrField";
     821                case AmrErrEnum : return "AmrErr";
    815822                case ParametersENDEnum : return "ParametersEND";
    816823                case XYEnum : return "XY";
  • issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp

    r21793 r21802  
    827827              else if (strcmp(name,"EsaRequestedOutputs")==0) return EsaRequestedOutputsEnum;
    828828              else if (strcmp(name,"EsaNumRequestedOutputs")==0) return EsaNumRequestedOutputsEnum;
     829              else if (strcmp(name,"TransientAmrFrequency")==0) return TransientAmrFrequencyEnum;
     830              else if (strcmp(name,"AmrType")==0) return AmrTypeEnum;
     831              else if (strcmp(name,"AmrNeopz")==0) return AmrNeopzEnum;
    829832              else if (strcmp(name,"AmrLevelMax")==0) return AmrLevelMaxEnum;
    830833              else if (strcmp(name,"AmrRegionLevel1")==0) return AmrRegionLevel1Enum;
    831834              else if (strcmp(name,"AmrRegionLevelMax")==0) return AmrRegionLevelMaxEnum;
    832               else if (strcmp(name,"TransientAmrFrequency")==0) return TransientAmrFrequencyEnum;
     835              else if (strcmp(name,"AmrBamg")==0) return AmrBamgEnum;
     836              else if (strcmp(name,"AmrHmin")==0) return AmrHminEnum;
     837              else if (strcmp(name,"AmrHmax")==0) return AmrHmaxEnum;
     838              else if (strcmp(name,"AmrField")==0) return AmrFieldEnum;
     839              else if (strcmp(name,"AmrErr")==0) return AmrErrEnum;
    833840              else if (strcmp(name,"ParametersEND")==0) return ParametersENDEnum;
    834841              else if (strcmp(name,"XY")==0) return XYEnum;
     
    868875              else if (strcmp(name,"Moulin")==0) return MoulinEnum;
    869876              else if (strcmp(name,"Pengrid")==0) return PengridEnum;
    870               else if (strcmp(name,"Penpair")==0) return PenpairEnum;
     877         else stage=8;
     878   }
     879   if(stage==8){
     880              if (strcmp(name,"Penpair")==0) return PenpairEnum;
    871881              else if (strcmp(name,"Profiler")==0) return ProfilerEnum;
    872882              else if (strcmp(name,"MatrixParam")==0) return MatrixParamEnum;
     
    875885              else if (strcmp(name,"NodeSId")==0) return NodeSIdEnum;
    876886              else if (strcmp(name,"ElementSId")==0) return ElementSIdEnum;
    877          else stage=8;
    878    }
    879    if(stage==8){
    880               if (strcmp(name,"VectorParam")==0) return VectorParamEnum;
     887              else if (strcmp(name,"VectorParam")==0) return VectorParamEnum;
    881888              else if (strcmp(name,"Riftfront")==0) return RiftfrontEnum;
    882889              else if (strcmp(name,"Segment")==0) return SegmentEnum;
     
    991998              else if (strcmp(name,"TotalGroundedBmb")==0) return TotalGroundedBmbEnum;
    992999              else if (strcmp(name,"TotalSmb")==0) return TotalSmbEnum;
    993               else if (strcmp(name,"P0")==0) return P0Enum;
     1000         else stage=9;
     1001   }
     1002   if(stage==9){
     1003              if (strcmp(name,"P0")==0) return P0Enum;
    9941004              else if (strcmp(name,"P0Array")==0) return P0ArrayEnum;
    9951005              else if (strcmp(name,"P1")==0) return P1Enum;
     
    9981008              else if (strcmp(name,"P1bubblecondensed")==0) return P1bubblecondensedEnum;
    9991009              else if (strcmp(name,"P2")==0) return P2Enum;
    1000          else stage=9;
    1001    }
    1002    if(stage==9){
    1003               if (strcmp(name,"P2bubble")==0) return P2bubbleEnum;
     1010              else if (strcmp(name,"P2bubble")==0) return P2bubbleEnum;
    10041011              else if (strcmp(name,"P2bubblecondensed")==0) return P2bubblecondensedEnum;
    10051012              else if (strcmp(name,"P2xP1")==0) return P2xP1Enum;
  • issm/trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.cpp

    r21787 r21802  
    128128        }
    129129}/*}}}*/
     130int IoCodeToEnumAmr(int enum_in){/*{{{*/
     131        switch(enum_in){
     132                case 1: return AmrBamgEnum;
     133                case 2: return AmrNeopzEnum;
     134                default: _error_("Marshalled AMR code \""<<enum_in<<"\" not supported yet");
     135        }
     136}/*}}}*/
    130137
    131138int IoCodeToEnumVertexEquation(int enum_in){/*{{{*/
  • issm/trunk-jpl/src/c/shared/io/Marshalling/IoCodeConversions.h

    r21773 r21802  
    1010int IoCodeToEnumMaterials(int enum_in);
    1111int IoCodeToEnumTimestepping(int enum_in);
     12int IoCodeToEnumAmr(int enum_in);
    1213
    1314int IoCodeToEnumVertexEquation(int enum_in);
  • issm/trunk-jpl/src/m/classes/amr.m

    r21674 r21802  
    5050                function marshall(self,prefix,md,fid) % {{{
    5151
    52                         scale = md.constants.yts;
     52                        WriteData(fid,prefix,'name','md.amr.type','data',2,'format','Integer');
    5353                        WriteData(fid,prefix,'object',self,'fieldname','level_max','format','Integer');
    5454                        WriteData(fid,prefix,'object',self,'fieldname','region_level_1','format','Double');
  • issm/trunk-jpl/src/m/classes/trans.js

    r21680 r21802  
    99
    1010                //full analysis: Stressbalance, Masstransport and Thermal but no groundingline migration for now
    11                 this.issmb           = 1;
    12                 this.ismasstransport = 1;
    13                 this.isstressbalance = 1;
    14                 this.isthermal       = 1;
    15                 this.isgroundingline = 0;
    16                 this.isgia           = 0;
     11                this.issmb             = 1;
     12                this.ismasstransport   = 1;
     13                this.isstressbalance   = 1;
     14                this.isthermal         = 1;
     15                this.isgroundingline   = 0;
     16                this.isgia             = 0;
    1717                this.isdamageevolution = 0;
    18                 this.ismovingfront   = 0;
    19                 this.ishydrology     = 0;
    20                 this.isslr           = 0;
    21                 this.iscoupler       = 0;
    22                 this.amr_frequency   = 1;
     18                this.ismovingfront     = 0;
     19                this.ishydrology       = 0;
     20                this.isslr             = 0;
     21                this.iscoupler         = 0;
     22                this.amr_frequency     = 0;
    2323
    2424                //default output
  • issm/trunk-jpl/src/m/classes/transient.m

    r21680 r21802  
    6868                        self.isoceancoupling = 0;
    6969                        self.iscoupler       = 0;
    70                         self.amr_frequency      = 1;
     70                        self.amr_frequency      = 0;
    7171
    7272                        %default output
  • issm/trunk-jpl/src/m/classes/transient.py

    r21680 r21802  
    8484               
    8585                #full analysis: Stressbalance, Masstransport and Thermal but no groundingline migration for now
    86                 self.issmb = True
    87                 self.ismasstransport = True
    88                 self.isstressbalance = True
    89                 self.isthermal       = True
    90                 self.isgroundingline = False
    91                 self.isgia           = False
    92                 self.isesa           = False
     86                self.issmb             = True
     87                self.ismasstransport   = True
     88                self.isstressbalance   = True
     89                self.isthermal         = True
     90                self.isgroundingline   = False
     91                self.isgia             = False
     92                self.isesa             = False
    9393                self.isdamageevolution = False
    94                 self.ismovingfront   = False
    95                 self.ishydrology     = False
    96                 self.isslr           = False
    97                 self.isoceancoupling = False
    98                 self.iscoupler       = False
    99                 self.amr_frequency      = 1
     94                self.ismovingfront     = False
     95                self.ishydrology       = False
     96                self.isslr             = False
     97                self.isoceancoupling   = False
     98                self.iscoupler         = False
     99                self.amr_frequency     = 0
    100100
    101101                #default output
Note: See TracChangeset for help on using the changeset viewer.