Ignore:
Timestamp:
08/28/18 09:45:51 (7 years ago)
Author:
Mathieu Morlighem
Message:

merged trunk-jpl and trunk for revision 23187

Location:
issm/trunk
Files:
61 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk

  • issm/trunk/src

  • issm/trunk/src/c/classes/AdaptiveMeshRefinement.cpp

    r22758 r23189  
    100100
    101101/*Mesh refinement methods*/
    102 void AdaptiveMeshRefinement::ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist){/*{{{*/
    103        
     102void AdaptiveMeshRefinement::ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int** pdatalist,double** pxylist,int** pelementslist){/*{{{*/
     103
    104104        /*IMPORTANT! pelementslist are in Matlab indexing*/
    105105        /*NEOPZ works only in C indexing*/
     
    118118        /*Intermediaries*/
    119119        bool verbose=VerboseSolution();
    120        
     120
    121121        /*Execute refinement*/
    122122        this->RefineMeshOneLevel(verbose,gl_distance,if_distance,deviatoricerror,thicknesserror);
    123    
     123
    124124        /*Get new geometric mesh in ISSM data structure*/
    125         this->GetMesh(this->previousmesh,pnewnumberofvertices,pnewnumberofelements,px,py,pelementslist);
     125        this->GetMesh(this->previousmesh,pdatalist,pxylist,pelementslist);
    126126
    127127        /*Verify the new geometry*/
    128         this->CheckMesh(pnewnumberofvertices,pnewnumberofelements,px,py,pelementslist);
     128        this->CheckMesh(pdatalist,pxylist,pelementslist);
    129129}
    130130/*}}}*/
    131131void AdaptiveMeshRefinement::RefineMeshOneLevel(bool &verbose,double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror){/*{{{*/
    132        
     132
    133133        /*Intermediaries*/
    134134        int nelem                                                       =-1;
     
    204204        }
    205205        /*}}}*/
    206        
     206
    207207        /*Now, detele the special elements{{{*/
    208208        if(this->refinement_type==1) this->DeleteSpecialElements(verbose,gmesh);
     
    216216        }
    217217        /*}}}*/
    218        
     218
    219219        /*Unrefinement process: loop over level of refinements{{{*/
    220220        if(verbose) _printf_("\tunrefinement process...\n");
    221221        if(verbose) _printf_("\ttotal: ");
    222222        count=0;
    223          
     223
    224224        nelem=gmesh->NElements();//must keep here
    225225        for(int i=0;i<nelem;i++){
     
    266266        gmesh->BuildConnectivity();
    267267        /*}}}*/
    268        
     268
    269269        /*Refinement process: loop over level of refinements{{{*/
    270270        if(verbose) _printf_("\trefinement process (level max = "<<this->level_max<<")\n");
     
    320320         * */
    321321        if(!geoel) _error_("geoel is NULL!\n");
    322        
     322
    323323        /*Output*/
    324324        int type=0;
    325325        int count=0;
    326        
     326
    327327        /*Intermediaries*/
    328328        TPZVec<TPZGeoEl*> sons;
    329        
     329
    330330        /*Loop over neighboors (sides 3, 4 and 5)*/
    331331        for(int j=3;j<6;j++){
     
    335335                if(sons.size()>4) count++; //if neighbour's level is > element level+1
    336336        }
    337        
     337
    338338        /*Verify and return*/
    339339        if(count>1) type=2;
    340340        else type=count;
    341        
     341
    342342        return type;
    343343}
     
    391391/*}}}*/
    392392void AdaptiveMeshRefinement::RefineMeshToAvoidHangingNodes(bool &verbose,TPZGeoMesh* gmesh){/*{{{*/
    393    
     393
    394394        /*Now, insert special elements to avoid hanging nodes*/
    395395        if(verbose) _printf_("\trefining to avoid hanging nodes (total: ");
    396        
     396
    397397        /*Intermediaries*/
    398398        int nelem=-1;
    399399        int count= 1;
    400        
     400
    401401        while(count>0){
    402402                nelem=gmesh->NElements();//must keep here
     
    449449}
    450450/*}}}*/
    451 void AdaptiveMeshRefinement::GetMesh(TPZGeoMesh* gmesh,int* nvertices,int* nelements,double** px,double** py, int** pelements){/*{{{*/
     451void AdaptiveMeshRefinement::GetMesh(TPZGeoMesh* gmesh,int** pdata,double** pxy, int** pelements){/*{{{*/
    452452
    453453        /* IMPORTANT! pelements are in Matlab indexing
     
    462462        int ntotalvertices              = gmesh->NNodes();
    463463        int* newelements                        = NULL;
    464         double* newmeshX                        = NULL;
    465         double* newmeshY                        = NULL;
     464        int* newdata                            = NULL;
     465        double* newmeshXY                       = NULL;
    466466        TPZGeoEl* geoel                 = NULL;
    467467        long* vertex_index2sid  = xNew<long>(ntotalvertices);
    468468        this->index2sid.clear(); this->index2sid.resize(gmesh->NElements());
    469469        this->sid2index.clear();
    470        
     470
    471471        /*Fill in the vertex_index2sid vector with non usual index value*/
    472472        for(int i=0;i<gmesh->NNodes();i++) vertex_index2sid[i]=-1;
    473        
     473
    474474        /*Fill in the this->index2sid vector with non usual index value*/
    475475        for(int i=0;i<gmesh->NElements();i++) this->index2sid[i]=-1;
    476        
     476
    477477        /*Get elements without sons and fill in the vertex_index2sid with used vertices (indexes) */
    478478        sid=0;
     
    494494        }
    495495
     496        /* Create new mesh structure and fill it */
    496497        nconformelements        = (int)this->sid2index.size();
    497498        nconformvertices        = (int)sid;
    498499        newelements                     = xNew<int>(nconformelements*this->GetNumberOfNodes());
    499         newmeshX                                = xNew<double>(nconformvertices);
    500    newmeshY                             = xNew<double>(nconformvertices);
     500        newmeshXY                       = xNew<double>(nconformvertices*2);
     501        newdata                         = xNew<int>(2);
     502        newdata[0]                      = nconformvertices;
     503        newdata[1]                      = nconformelements;
    501504
    502505        for(int i=0;i<ntotalvertices;i++){//over the TPZNode index (fill in the ISSM vertices coords)
     
    505508                TPZVec<REAL> coords(3,0.);
    506509                gmesh->NodeVec()[i].GetCoordinates(coords);
    507                 newmeshX[sid] = coords[0];
    508                 newmeshY[sid] = coords[1];
    509         }
    510                
     510                newmeshXY[2*sid]                = coords[0]; // X
     511                newmeshXY[2*sid+1]      = coords[1]; // Y
     512        }
     513
    511514        for(int i=0;i<this->sid2index.size();i++){//over the sid (fill the ISSM elements)
    512515                for(int j=0;j<this->GetNumberOfNodes();j++) {
     
    525528                c=newelements[i*this->GetNumberOfNodes()+2]-1;
    526529
    527                 xa=newmeshX[a]; ya=newmeshY[a];
    528                 xb=newmeshX[b]; yb=newmeshY[b];
    529                 xc=newmeshX[c]; yc=newmeshY[c];
     530                xa=newmeshXY[2*a]; ya=newmeshXY[2*a+1];
     531                xb=newmeshXY[2*b]; yb=newmeshXY[2*b+1];
     532                xc=newmeshXY[2*c]; yc=newmeshXY[2*c+1];
    530533
    531534                detJ=(xb-xa)*(yc-ya)-(xc-xa)*(yb-ya);
    532        
     535
    533536                /*verify and swap, if necessary*/
    534537                if(detJ<0) {
     
    539542
    540543        /*Setting outputs*/
    541         *nvertices      = nconformvertices;
    542         *nelements      = nconformelements;
    543         *px                     = newmeshX;
    544         *py                = newmeshY;
     544        *pdata          = newdata;
     545        *pxy               = newmeshXY;
    545546        *pelements      = newelements;
    546    
     547
    547548        /*Cleanup*/
    548549        xDelete<long>(vertex_index2sid);
     
    553554        /* IMPORTANT! elements come in Matlab indexing
    554555                NEOPZ works only in C indexing*/
    555        
     556
    556557        if(nvertices<=0) _error_("Impossible to create initial mesh: nvertices is <= 0!\n");
    557558   if(nelements<=0) _error_("Impossible to create initial mesh: nelements is <= 0!\n");
     
    560561    /*Verify and creating initial mesh*/
    561562   if(this->fathermesh || this->previousmesh) _error_("Initial mesh already exists!");
    562    
     563
    563564   this->fathermesh = new TPZGeoMesh();
    564565        this->fathermesh->NodeVec().Resize(nvertices);
     
    575576                this->fathermesh->NodeVec()[i].SetNodeId(i);
    576577        }
    577        
     578
    578579        /*Generate the elements*/
    579580        long index;
     
    603604/*}}}*/
    604605TPZGeoMesh* AdaptiveMeshRefinement::CreateRefPatternMesh(TPZGeoMesh* gmesh){/*{{{*/
    605        
     606
    606607        TPZGeoMesh *newgmesh = new TPZGeoMesh();
    607608   newgmesh->CleanUp();
    608    
     609
    609610   int nnodes  = gmesh->NNodes();
    610611        int nelem   = gmesh->NElements();
     
    616617        newgmesh->NodeVec().Resize(nnodes);
    617618   for(int i=0;i<nnodes;i++) newgmesh->NodeVec()[i] = gmesh->NodeVec()[i];
    618    
     619
    619620   //elements
    620621   for(int i=0;i<nelem;i++){
    621622        TPZGeoEl * geoel = gmesh->Element(i);
    622                
     623
    623624                if(!geoel){
    624625                        index=newgmesh->ElementVec().AllocateNewElement();
     
    626627                        continue;
    627628                }
    628      
     629
    629630                TPZManVector<long> elem(3,0);
    630631      for(int j=0;j<3;j++) elem[j] = geoel->NodeIndex(j);
    631      
     632
    632633      newgmesh->CreateGeoElement(ETriangle,elem,mat,index,reftype);
    633634                newgmesh->ElementVec()[index]->SetId(geoel->Id());
    634        
     635
    635636      TPZGeoElRefPattern<TPZGeoTriangle>* newgeoel = dynamic_cast<TPZGeoElRefPattern<TPZGeoTriangle>*>(newgmesh->ElementVec()[index]);
    636        
     637
    637638      //old neighbourhood
    638639      const int nsides = TPZGeoTriangle::NSides;
     
    653654         }
    654655      }
    655        
     656
    656657      //inserting in new element
    657658      for(int s = 0; s < nsides; s++){
     
    667668         tempEl->SetNeighbour(byside, tempSide);
    668669      }
    669        
     670
    670671      long fatherindex = geoel->FatherIndex();
    671672      if(fatherindex>-1) newgeoel->SetFather(fatherindex);
    672        
     673
    673674      if(!geoel->HasSubElement()) continue;
    674        
     675
    675676      int nsons = geoel->NSubElements();
    676677
    677678      TPZAutoPointer<TPZRefPattern> ref = gRefDBase.GetUniformRefPattern(ETriangle);
    678679      newgeoel->SetRefPattern(ref);
    679        
     680
    680681      for(int j=0;j<nsons;j++){
    681682        TPZGeoEl* son = geoel->SubElement(j);
     
    689690        /*Now, build connectivities*/
    690691        newgmesh->BuildConnectivity();
    691    
     692
    692693        return newgmesh;
    693694}
    694695/*}}}*/
    695 void AdaptiveMeshRefinement::CheckMesh(int* nvertices,int* nelements,double** px,double** py,int** pelements){/*{{{*/
     696void AdaptiveMeshRefinement::CheckMesh(int** pdata,double** pxy,int** pelements){/*{{{*/
    696697
    697698        /*Basic verification*/
    698         if(nvertices<=0) _error_("Impossible to continue: nvertices <=0!\n");
    699         if(nelements<=0) _error_("Impossible to continue: nelements <=0!\n");
    700         if(!px) _error_("Impossible to continue: px is NULL!\n");
    701         if(!py) _error_("Impossible to continue: py is NULL!\n");
     699        if(!pdata) _error_("Impossible to continue: pdata is NULL!\n");
     700        if(pdata[0]<=0) _error_("Impossible to continue: nvertices <=0!\n");
     701        if(pdata[1]<=0) _error_("Impossible to continue: nelements <=0!\n");
     702        if(!pxy) _error_("Impossible to continue: pxy is NULL!\n");
    702703        if(!pelements) _error_("Impossible to continue: pelements is NULL!\n");
    703 
    704         /*Verify if there are orphan nodes*/
    705         std::set<int> elemvertices;
    706         elemvertices.clear();
    707         for(int i=0;i<*nelements;i++){
    708                 for(int j=0;j<this->GetNumberOfNodes();j++) {
    709                         elemvertices.insert((*pelements)[i*this->GetNumberOfNodes()+j]);
    710                 }
    711         }
    712         if(elemvertices.size()!=*nvertices) _error_("Impossible to continue: elemvertices.size() != nvertices!\n");
    713        
    714         //Verify if there are inf or NaN in coords
    715         for(int i=0;i<*nvertices;i++){
    716                 if(std::isnan((*px)[i]) || std::isinf((*px)[i])) _error_("Impossible to continue: px i=" << i <<" is NaN or Inf!\n");
    717                 if(std::isnan((*py)[i]) || std::isinf((*py)[i])) _error_("Impossible to continue: py i=" << i <<" is NaN or Inf!\n");
    718         }
    719         for(int i=0;i<*nelements;i++){
    720                 for(int j=0;j<this->GetNumberOfNodes();j++){
    721                         if(std::isnan((*pelements)[i*GetNumberOfNodes()+j])) _error_("Impossible to continue: px i=" << i <<" is NaN!\n");
    722                         if(std::isinf((*pelements)[i*GetNumberOfNodes()+j])) _error_("Impossible to continue: px i=" << i <<" is Inf!\n");
    723                 }
    724         }
    725    
    726704}
    727705/*}}}*/
    728706void AdaptiveMeshRefinement::PrintGMeshVTK(TPZGeoMesh* gmesh,std::ofstream &file,bool matColor){/*{{{*/
    729    
     707
    730708        file.clear();
    731709        long nelements = gmesh->NElements();
     
    753731          MElementType elt = gel->Type();
    754732          int elNnodes = MElementType_NNodes(elt);
    755          
     733
    756734          size += (1+elNnodes);
    757735          connectivity << elNnodes;
    758          
     736
    759737          for(int t = 0; t < elNnodes; t++)
    760738          {
     
    765743                        }
    766744                        node << std::endl;
    767                        
     745
    768746                        actualNode++;
    769747                        connectivity << " " << actualNode;
    770748          }
    771749          connectivity << std::endl;
    772          
     750
    773751          int elType = this->GetVTK_ElType(gel);
    774752          type << elType << std::endl;
    775          
     753
    776754          if(matColor == true)
    777755          {
     
    782760                        material << gel->Index() << std::endl;
    783761          }
    784          
     762
    785763          nVALIDelements++;
    786764        }
     
    812790/*}}}*/
    813791int AdaptiveMeshRefinement::GetVTK_ElType(TPZGeoEl * gel){/*{{{*/
    814    
     792
    815793        MElementType pzElType = gel->Type();
    816    
     794
    817795    int elType = -1;
    818796    switch (pzElType)
     
    871849        DebugStop();
    872850    }
    873    
     851
    874852    return elType;
    875853}
    876854/*}}}*/
    877 
  • issm/trunk/src/c/classes/AdaptiveMeshRefinement.h

    r22758 r23189  
    6767        void CleanUp();
    6868        void Initialize();
    69         void ExecuteRefinement(int numberofpoints,double* xylist,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist);
    70         void ExecuteRefinement(int numberofpoints,double* xylist,double* deviatoricerror,double* thicknesserror,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist);
    71    void ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int* pnewnumberofvertices,int* pnewnumberofelements,double** px,double** py,int** pelementslist);
     69   void ExecuteRefinement(double* gl_distance,double* if_distance,double* deviatoricerror,double* thicknesserror,int** pdatalist,double** pxy,int** pelementslist);
    7270        void CreateInitialMesh(int &nvertices,int &nelements,double* x,double* y,int* elements);
    73         void CheckMesh(int* nvertices,int* nelements,double** px,double** py,int** pelements);
     71        void CheckMesh(int** pdata,double** pxy,int** pelements);
    7472        /*}}}*/
    7573private:
     
    8684        void RefineMeshToAvoidHangingNodes(bool &verbose,TPZGeoMesh* gmesh);
    8785        void DeleteSpecialElements(bool &verbose,TPZGeoMesh* gmesh);
    88         void GetMesh(TPZGeoMesh* gmesh,int* nvertices,int* nelements,double** px,double** py,int** pelements);
     86        void GetMesh(TPZGeoMesh* gmesh,int** pdata,double** pxy,int** pelements);
    8987        TPZGeoMesh* CreateRefPatternMesh(TPZGeoMesh* gmesh);
    9088   inline int GetElemMaterialID(){return 1;}
  • issm/trunk/src/c/classes/AmrBamg.cpp

    r22758 r23189  
    3434        this->deviatoricerror_groupthreshold    = -1;
    3535        this->deviatoricerror_maximum                           = -1;
    36        
     36
    3737        /*Geometry and mesh as NULL*/
    3838        this->geometry                                                                  = NULL;
     
    9898        delete Th;
    9999}/*}}}*/
    100 void AmrBamg::ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int* pnewnumberofvertices,int *pnewnumberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist){/*{{{*/
     100void AmrBamg::ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int** pdatalist,IssmDouble** pxylist,int** pelementslist){/*{{{*/
    101101
    102102        /*Intermediaries*/
     
    137137        this->options->hmaxVerticesSize[0] = 0;
    138138        this->options->hmaxVerticesSize[1] = 0;
    139        
     139
    140140        /*verify if the metric will be reseted or not*/
    141141        if(this->keepmetric==0){
     
    150150
    151151        /*Prepare output*/
    152         int nbv = meshout->VerticesSize[0];
    153         int nbt = meshout->TrianglesSize[0];
    154         IssmDouble *x = xNew<IssmDouble>(nbv);
    155         IssmDouble *y = xNew<IssmDouble>(nbv);
    156         IssmDouble *z = xNew<IssmDouble>(nbv);
     152        int nbv                         = meshout->VerticesSize[0];
     153        int nbt                         = meshout->TrianglesSize[0];
     154        int *datalist           = xNew<int>(2);
     155        IssmDouble *xylist= xNew<IssmDouble>(nbv*2);
     156        int* elementslist = xNew<int>(nbt*3);
     157
     158        datalist[0] = nbv;
     159        datalist[1] = nbt;
     160
    157161        for(int i=0;i<nbv;i++){
    158                 x[i] = meshout->Vertices[i*3+0];
    159                 y[i] = meshout->Vertices[i*3+1];
    160                 z[i] = 0.;
     162                xylist[2*i]             = meshout->Vertices[i*3+0];
     163                xylist[2*i+1]   = meshout->Vertices[i*3+1];
    161164        }
    162         int* elementslist= xNew<int>(nbt*3);
     165
    163166        for(int i=0;i<nbt;i++){
    164167                elementslist[3*i+0] = reCast<int>(meshout->Triangles[4*i+0]);
     
    167170        }
    168171
     172        /*Assign pointers*/
     173        *pdatalist              = datalist;
     174        *pxylist                        = xylist;
     175        *pelementslist = elementslist;
     176
    169177        /*Cleanup and return*/
    170178        delete geomout;
    171         *pnewnumberofvertices = nbv;
    172         *pnewnumberofelements = nbt;
    173         *px = x;
    174         *py = y;
    175         *pz = z;
    176         *pelementslist = elementslist;
    177179}/*}}}*/
    178180void AmrBamg::SetBamgOpts(IssmDouble hmin_in,IssmDouble hmax_in,IssmDouble err_in,IssmDouble gradation_in){/*{{{*/
    179181
    180182        if(!this->options) _error_("AmrBamg->options is NULL!");
    181        
     183
    182184        this->options->hmin     = hmin_in;
    183185        this->options->hmax     = hmax_in;
  • issm/trunk/src/c/classes/AmrBamg.h

    r22758 r23189  
    3535                /*General methods*/
    3636                void Initialize(int* elements,IssmDouble* x,IssmDouble* y,int numberofvertices,int numberofelements);
    37                 void ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int* pnewnumberofvertices,int *pnewnumberofelements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist);
     37                void ExecuteRefinementBamg(IssmDouble* field,IssmDouble* hmaxVertices,int** pdatalist,IssmDouble** pxylist,int** pelementslist);
    3838                void SetBamgOpts(IssmDouble hmin_in,IssmDouble hmax_in,IssmDouble err_in,IssmDouble gradation_in);
    3939
  • issm/trunk/src/c/classes/Cfdragcoeffabsgrad.cpp

    r22758 r23189  
    2323#include "../classes/gauss/Gauss.h"
    2424/*}}}*/
    25                
     25
    2626/*Cfdragcoeffabsgrad constructors, destructors :*/
    2727Cfdragcoeffabsgrad::Cfdragcoeffabsgrad(){/*{{{*/
     
    3232        this->misfit=0;
    3333        this->lock=0;
    34         this->datatime=0.;
    3534        this->timepassedflag = false;
    3635        this->last_time = 0.;
     
    3837}
    3938/*}}}*/
    40 Cfdragcoeffabsgrad::Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, IssmDouble in_datatime, bool in_timepassedflag){/*{{{*/
     39Cfdragcoeffabsgrad::Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, bool in_timepassedflag){/*{{{*/
    4140
    4241        this->definitionenum=in_definitionenum;
    43        
     42
    4443        this->name              = xNew<char>(strlen(in_name)+1);
    4544        xMemCpy<char>(this->name,in_name,strlen(in_name)+1);
    4645
    4746        this->weights_enum=in_weights_enum;
    48         this->datatime=in_datatime;
    4947        this->timepassedflag=in_timepassedflag;
    50        
     48
    5149        this->misfit=0;
    5250        this->lock=0;
     
    6159/*Object virtual function resolutoin: */
    6260Object* Cfdragcoeffabsgrad::copy() {/*{{{*/
    63         Cfdragcoeffabsgrad* mf = new Cfdragcoeffabsgrad(this->name,this->definitionenum, this->weights_enum,this->datatime,this->timepassedflag);
     61        Cfdragcoeffabsgrad* mf = new Cfdragcoeffabsgrad(this->name,this->definitionenum, this->weights_enum,this->timepassedflag);
    6462        mf->misfit=this->misfit;
    6563        mf->lock=this->lock;
     
    7472        _printf_(" Cfdragcoeffabsgrad: " << name << " " << this->definitionenum << "\n");
    7573        _printf_("    weights_enum: " << weights_enum << " " << EnumToStringx(weights_enum) << "\n");
    76         _printf_("    datatime: " << datatime << "\n");
    7774        _printf_("        timepassedflag: "<<timepassedflag<<"\n");
    7875}
     
    105102         /*diverse: */
    106103         IssmDouble time;
    107          
     104
    108105         /*recover time parameters: */
    109          femmodel->parameters->FindParam(&time,TimeEnum);
    110          if(time < last_time) timepassedflag = false;
    111          last_time = time;
    112 
    113106                 int i;
    114107                 IssmDouble J=0.;
    115108                 IssmDouble J_sum=0.;
    116109
    117          if(datatime<=time && !timepassedflag){
    118110                 for(i=0;i<femmodel->elements->Size();i++){
    119111                         Element* element=(Element*)femmodel->elements->GetObjectByOffset(i);
     
    124116                 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    125117                 J=J_sum;
    126                
     118
    127119                 timepassedflag = true;
    128120                 return J;
    129         }
    130          else return J;
    131121 }
    132122        /*}}}*/
     
    193183        return Jelem;
    194184}/*}}}*/
    195 
  • issm/trunk/src/c/classes/Cfdragcoeffabsgrad.h

    r22758 r23189  
    2020                char*       name;
    2121                int         weights_enum;
    22                 IssmDouble      datatime;
    2322                bool                    timepassedflag;
    2423                IssmDouble      last_time;
     
    2928                /*Cfdragcoeffabsgrad constructors, destructors :*/
    3029                Cfdragcoeffabsgrad();
    31                 Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, IssmDouble in_datatime, bool timepassedflag);
     30                Cfdragcoeffabsgrad(char* in_name, int in_definitionenum, int in_weights_enum, bool timepassedflag);
    3231                ~Cfdragcoeffabsgrad();
    3332               
  • issm/trunk/src/c/classes/Cfsurfacelogvel.cpp

    r22758 r23189  
    2323#include "../classes/gauss/Gauss.h"
    2424/*}}}*/
    25                
     25
    2626/*Cfsurfacelogvel constructors, destructors :*/
    2727Cfsurfacelogvel::Cfsurfacelogvel(){/*{{{*/
     
    4040
    4141        this->definitionenum=in_definitionenum;
    42        
     42
    4343        this->name              = xNew<char>(strlen(in_name)+1);
    4444        xMemCpy<char>(this->name,in_name,strlen(in_name)+1);
     
    4646        this->datatime=in_datatime;
    4747        this->timepassedflag=in_timepassedflag;
    48        
     48
    4949        this->misfit=0;
    5050        this->lock=0;
     
    100100/*}}}*/
    101101IssmDouble Cfsurfacelogvel::Response(FemModel* femmodel){/*{{{*/
    102                  
     102
    103103         /*diverse: */
    104104         IssmDouble time;
    105          
     105
    106106         /*recover time parameters: */
    107107         femmodel->parameters->FindParam(&time,TimeEnum);
     
    112112                 IssmDouble J=0.;
    113113                 IssmDouble J_sum=0.;
    114        
     114
    115115         if(datatime<=time && !timepassedflag){
    116116                 for(i=0;i<femmodel->elements->Size();i++){
     
    122122                 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    123123                 J=J_sum;
    124                
     124
    125125                 timepassedflag = true;
    126126                 return J;
     
    139139        IssmDouble vx,vy,vxobs,vyobs,weight;
    140140        IssmDouble* xyz_list = NULL;
    141        
     141
    142142        /*Get basal element*/
    143143        if(!element->IsOnSurface()) return 0.;
     
    160160        /* Get node coordinates*/
    161161        topelement->GetVerticesCoordinates(&xyz_list);
    162        
     162
    163163        /*Get model values*/
    164164        Input* vx_input     =topelement->GetInput(VxEnum);                                 _assert_(vx_input);
     
    174174        if(tempinput->ObjectEnum()!=DatasetInputEnum) _error_("don't know what to do");
    175175        datasetinput = (DatasetInput*)tempinput;
    176 
    177176
    178177        /* Start  looping on the number of gaussian points: */
     
    222221        return Jelem;
    223222}/*}}}*/
    224 
  • issm/trunk/src/c/classes/Cfsurfacesquare.cpp

    r22758 r23189  
    2323#include "../classes/gauss/Gauss.h"
    2424/*}}}*/
    25                
     25
    2626/*Cfsurfacesquare constructors, destructors :*/
    2727Cfsurfacesquare::Cfsurfacesquare(){/*{{{*/
     
    4343
    4444        this->definitionenum=in_definitionenum;
    45        
     45
    4646        this->name              = xNew<char>(strlen(in_name)+1);
    4747        xMemCpy<char>(this->name,in_name,strlen(in_name)+1);
     
    5252        this->datatime=in_datatime;
    5353        this->timepassedflag=in_timepassedflag;
    54        
     54
    5555        this->misfit=0;
    5656        this->lock=0;
     
    111111         /*diverse: */
    112112         IssmDouble time;
    113          
     113
    114114         /*recover time parameters: */
    115115         femmodel->parameters->FindParam(&time,TimeEnum);
     
    130130                 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    131131                 J=J_sum;
    132                
     132
    133133                 timepassedflag = true;
    134134                 return J;
     
    172172        /*Get input if it already exists*/
    173173        Input*  tempinput = topelement->GetInput(definitionenum);
    174        
     174
    175175        /*Cast it to a Datasetinput*/
    176176        if(tempinput->ObjectEnum()!=DatasetInputEnum) _error_("don't know what to do");
     
    214214        return Jelem;
    215215}/*}}}*/
    216 
  • issm/trunk/src/c/classes/Constraints/SpcStatic.cpp

    r22758 r23189  
    3737/*Object virtual functions definitions:*/
    3838Object* SpcStatic::copy() {/*{{{*/
    39        
     39
    4040        SpcStatic* spcstat = new SpcStatic(*this);
    4141
  • issm/trunk/src/c/classes/Dakota/IssmParallelDirectApplicInterface.cpp

    r22758 r23189  
    2020                int world_rank;
    2121                ISSM_MPI_Comm_rank(ISSM_MPI_COMM_WORLD,&world_rank);
    22                
     22
    2323                /*Build an femmodel if you are a slave, using the corresponding communicator:*/
    2424                if(world_rank!=0){
     
    3333                int world_rank;
    3434                ISSM_MPI_Comm_rank(ISSM_MPI_COMM_WORLD,&world_rank);
    35                
     35
    3636                if(world_rank!=0){
    3737
  • issm/trunk/src/c/classes/Elements/Element.cpp

    r22822 r23189  
    100100                        dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]);
    101101                }
    102 
    103102                /*Build strain rate tensor*/
    104103                eps[0][0] = dvx[0];             eps[0][1] = .5*(dvx[1]+dvy[0]); eps[0][2] = .5*(dvx[2]+dvz[0]);
     
    117116        /*Add Stress tensor components into inputs*/
    118117        this->AddInput(LambdaSEnum,lambdas,P1Enum);
    119        
     118
    120119        /*Clean up and return*/
    121120        delete gauss;
     
    172171      B_input=this->GetInput(MaterialsRheologyBEnum); _assert_(B_input);
    173172   }
    174        
     173
    175174        /* Start looping on the number of nodes: */
    176175        Gauss* gauss=this->NewGauss();
     
    196195
    197196                /* Compute threshold strain rate from threshold stress */
    198                 eps_0=pow(sigma_0/B,n); 
     197                eps_0=pow(sigma_0/B,n);
    199198
    200199                if(eps_eff>eps_0){
     
    262261                if(dim==2){
    263262                         /* epsilon=[exx,eyy,exy];*/
    264                         eps_xx[iv]=epsilon[0]; 
     263                        eps_xx[iv]=epsilon[0];
    265264                        eps_yy[iv]=epsilon[1];
    266265                        eps_xy[iv]=epsilon[2];
     
    270269                else{
    271270                        /*epsilon=[exx eyy ezz exy exz eyz]*/
    272                         eps_xx[iv]=epsilon[0]; 
     271                        eps_xx[iv]=epsilon[0];
    273272                        eps_yy[iv]=epsilon[1];
    274273                        eps_zz[iv]=epsilon[2];
    275                         eps_xy[iv]=epsilon[3]; 
     274                        eps_xy[iv]=epsilon[3];
    276275                        eps_xz[iv]=epsilon[4];
    277276                        eps_yz[iv]=epsilon[5];
     
    535534        IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(12*numvertices);
    536535        IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(12*numvertices);
     536        IssmDouble* TemperaturesReconstructed=xNew<IssmDouble>(12*numvertices);
     537        IssmDouble* PrecipitationsReconstructed=xNew<IssmDouble>(12*numvertices);
    537538        IssmDouble* tmp=xNew<IssmDouble>(numvertices);
    538539        IssmDouble Delta18oTime;
    539540        IssmDouble dpermil,f;
    540         IssmDouble time,yts,time_yr,month,time_clim;
     541        IssmDouble time,yts,time_yr,month,time_clim,time_climt,time_climp,del_clim;
    541542        bool isTemperatureScaled=true;
     543        bool isPrecipScaled=true;
    542544        this->parameters->FindParam(&time,TimeEnum);
    543545        this->parameters->FindParam(&yts,ConstantsYtsEnum);
    544546        this->parameters->FindParam(&f,SmbFEnum);
    545547        time_yr=floor(time/yts)*yts;
    546         time_clim=time_yr;
     548        time_clim=ceil(time/yts + 1e-10)*yts;
     549        time_climt=ceil(time/yts + 1e-10)*yts;
     550        time_climp=ceil(time/yts + 1e-10)*yts;
    547551
    548552        /*Get some pdd parameters*/
    549553        dpermil=this->matpar->GetMaterialParameter(SmbDpermilEnum);
     554
     555        this->parameters->FindParam(&isTemperatureScaled,SmbIstemperaturescaledEnum);
     556        this->parameters->FindParam(&isPrecipScaled,SmbIsprecipscaledEnum);
    550557
    551558        /*Recover present day temperature and precipitation*/
    552559        Input*     input=this->inputs->GetInput(SmbTemperaturesPresentdayEnum);    _assert_(input);
    553560        Input*     input2=this->inputs->GetInput(SmbPrecipitationsPresentdayEnum); _assert_(input2);
     561        Input*     input3=NULL;
     562        Input*     input4=NULL;
    554563        int offset;
    555564
    556         offset=dynamic_cast<TransientInput*>(input)->GetTimeInputOffset(time_yr);
    557         if (fmod(offset,12.)!=1){
    558                 time_clim=floor(dynamic_cast<TransientInput*>(input)->GetTimeByOffset(offset-fmod(offset,12.)+1)/yts)*yts;
     565        offset=dynamic_cast<TransientInput*>(input)->GetTimeInputOffset(time_clim);
     566        time_clim=dynamic_cast<TransientInput*>(input)->GetTimeByOffset(offset-11-fmod(offset-11,12.));
     567
     568        if(!isTemperatureScaled){
     569                input3=this->inputs->GetInput(SmbTemperaturesReconstructedEnum);           _assert_(input3);
     570                offset=dynamic_cast<TransientInput*>(input3)->GetTimeInputOffset(time_climt);
     571                time_climt=dynamic_cast<TransientInput*>(input3)->GetTimeByOffset(offset-11-fmod(offset-11,12.));
     572        }
     573        if(!isPrecipScaled){
     574                input4=this->inputs->GetInput(SmbPrecipitationsReconstructedEnum);         _assert_(input4);
     575                offset=dynamic_cast<TransientInput*>(input4)->GetTimeInputOffset(time_climp);
     576                time_climp=dynamic_cast<TransientInput*>(input4)->GetTimeByOffset(offset-11-fmod(offset-11,12.));
    559577        }
    560578
     
    566584                        input->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,time_clim+month/12.*yts);
    567585                        input2->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,time_clim+month/12.*yts);
    568 
    569586                        PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;
     587
     588                        if(!isTemperatureScaled){
     589                                input3->GetInputValue(&TemperaturesReconstructed[iv*12+month],gauss,time_climt+month/12.*yts);
     590                        }
     591                        if(!isPrecipScaled){
     592                                input4->GetInputValue(&PrecipitationsReconstructed[iv*12+month],gauss,time_climp+month/12.*yts);
     593                                PrecipitationsReconstructed[iv*12+month]=PrecipitationsReconstructed[iv*12+month]*yts;
     594                        }
     595
    570596                }
    571597        }
     
    573599        /*Recover interpolation parameters at time t*/
    574600        this->parameters->FindParam(&Delta18oTime,SmbDelta18oEnum,time);
    575         this->parameters->FindParam(&isTemperatureScaled,SmbIstemperaturescaledEnum);
    576601
    577602        /*Compute the temperature and precipitation*/
    578603        for(int iv=0;iv<numvertices;iv++){
    579                 ComputeD18OTemperaturePrecipitationFromPD(Delta18oTime,dpermil,isTemperatureScaled,f,
    580                                         &PrecipitationsPresentday[iv*12], &TemperaturesPresentday[iv*12],
     604                ComputeD18OTemperaturePrecipitationFromPD(Delta18oTime,dpermil,isTemperatureScaled,isPrecipScaled,
     605                                        f,&PrecipitationsPresentday[iv*12], &TemperaturesPresentday[iv*12],
     606                                        &PrecipitationsReconstructed[iv*12], &TemperaturesReconstructed[iv*12],
    581607                                        &monthlytemperatures[iv*12], &monthlyprec[iv*12]);
    582608        }
     
    623649        xDelete<IssmDouble>(TemperaturesPresentday);
    624650        xDelete<IssmDouble>(PrecipitationsPresentday);
     651        xDelete<IssmDouble>(TemperaturesReconstructed);
     652        xDelete<IssmDouble>(PrecipitationsReconstructed);
    625653        xDelete<IssmDouble>(tmp);
    626        
     654
    627655}
    628656/*}}}*/
     
    821849                int numnodes = this->GetNumberOfNodes();
    822850                for(int i=0;i<numnodes;i++) {
    823                         _printf_("nodes[" << i << "] = " << nodes[i]); 
     851                        _printf_("nodes[" << i << "] = " << nodes[i]);
    824852                        nodes[i]->Echo();
    825853                }
     
    10271055}
    10281056/*}}}*/
     1057void       Element::GetInputListOnVerticesAtTime(IssmDouble* pvalue, int enumtype, IssmDouble time){/*{{{*/
     1058
     1059        /*Recover input*/
     1060        Input* input=this->GetInput(enumtype);
     1061        if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
     1062
     1063        /*Fetch number vertices for this element*/
     1064        int numvertices = this->GetNumberOfVertices();
     1065
     1066        /*Checks in debugging mode*/
     1067        _assert_(pvalue);
     1068
     1069        /* Start looping on the number of vertices: */
     1070        Gauss*gauss=this->NewGauss();
     1071        for(int iv=0;iv<numvertices;iv++){
     1072                gauss->GaussVertex(iv);
     1073                input->GetInputValue(&pvalue[iv],gauss,time);
     1074        }
     1075
     1076        /*clean-up*/
     1077        delete gauss;
     1078}
     1079/*}}}*/
    10291080void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
    10301081
     
    10541105void       Element::GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug){/*{{{*/
    10551106
    1056 
    10571107        /*Get number of nodes for this element*/
    10581108        int numnodes = this->GetNumberOfNodes();
     
    10701120                if(ug[nodes[i]->GetDof(0,GsetEnum)] > input_max) input_max = ug[nodes[i]->GetDof(0,GsetEnum)];
    10711121        }
    1072 
    10731122
    10741123        /*Second loop to reassign min and max with local extrema*/
     
    11951244        epsilon_eff=1/sqrt(2.)*sqrt(epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]);
    11961245
    1197         /*Phi = Tr(sigma * eps) 
     1246        /*Phi = Tr(sigma * eps)
    11981247         *    = Tr(sigma'* eps)
    11991248         *    = 2 * eps_eff * sigma'_eff
     
    13101359}
    13111360/*}}}*/
     1361void       Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum,int type, IssmDouble time){/*{{{*/
     1362
     1363        /*Fetch number vertices for this element and allocate arrays*/
     1364        int         numvertices = this->GetNumberOfVertices();
     1365        int         numnodes    = this->GetNumberOfNodes();
     1366        int*        doflist     = NULL;
     1367        IssmDouble* values      = NULL;
     1368
     1369        switch(type){
     1370        case VertexPIdEnum:
     1371                doflist = xNew<int>(numvertices);
     1372                values = xNew<IssmDouble>(numvertices);
     1373                /*Fill in values*/
     1374                this->GetVertexPidList(doflist);
     1375                this->GetInputListOnVerticesAtTime(values,input_enum,time);
     1376                vector->SetValues(numvertices,doflist,values,INS_VAL);
     1377                break;
     1378        case VertexSIdEnum:
     1379                doflist = xNew<int>(numvertices);
     1380                values = xNew<IssmDouble>(numvertices);
     1381                /*Fill in values*/
     1382                this->GetVerticesSidList(doflist);
     1383                this->GetInputListOnVerticesAtTime(values,input_enum,time);
     1384                vector->SetValues(numvertices,doflist,values,INS_VAL);
     1385                break;
     1386        default:
     1387                _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
     1388        }
     1389
     1390        /*Clean up*/
     1391        xDelete<int>(doflist);
     1392        xDelete<IssmDouble>(values);
     1393
     1394}
     1395/*}}}*/
    13121396void       Element::GetVertexPidList(int* pidlist){/*{{{*/
    13131397
     
    13831467        return z;
    13841468}/*}}}*/
    1385 void       Element::GradientIndexing(int* indexing,int control_index,bool onsid){/*{{{*/
     1469void       Element::GradientIndexing(int* indexing,int control_index){/*{{{*/
    13861470
    13871471        /*Get number of controls*/
     
    13901474        parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
    13911475        parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum);
    1392 
    13931476
    13941477        /*Get number of vertices*/
     
    14151498                int M;
    14161499                parameters->FindParam(&M,ControlInputSizeMEnum);
    1417         /*get gradient indices*/
    1418                 if(onsid){
    1419                         for(int i=0;i<numvertices;i++){
    1420                                 indexing[i]=this->vertices[i]->Sid() + (control_index)*M;
    1421                         }
    1422                 }
    1423                 else{
    1424                         for(int i=0;i<numvertices;i++){
    1425                                 indexing[i]=this->vertices[i]->Pid() + (control_index)*M;
    1426                         }
     1500                /*get gradient indices*/
     1501                for(int i=0;i<numvertices;i++){
     1502                        indexing[i]=this->vertices[i]->Sid() + (control_index)*M;
    14271503                }
    14281504        }
     
    15101586/*}}}*/
    15111587void       Element::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){/*{{{*/
    1512    
     1588
    15131589    /*Intermediaries*/
    15141590    int i,t;
    1515    
     1591
    15161592    /*Branch on type of vector: nodal or elementary: */
    15171593    if(vector_type==1){ //nodal vector
    1518        
     1594
    15191595        int         numvertices = this->GetNumberOfVertices();
    15201596        int        *vertexids   = xNew<int>(numvertices);
    15211597        IssmDouble *values      = xNew<IssmDouble>(numvertices);
    1522        
     1598
    15231599        /*Recover vertices ids needed to initialize inputs*/
    15241600        _assert_(iomodel->elements);
     
    15261602            vertexids[i]=reCast<int>(iomodel->elements[numvertices*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
    15271603        }
    1528        
     1604
    15291605        /*Are we in transient or static? */
    15301606                  if(M==1){
     
    15701646                          _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
    15711647                  }
    1572        
     1648
    15731649        xDelete<IssmDouble>(values);
    15741650        xDelete<int>(vertexids);
    15751651    }
    15761652    else if(vector_type==2){ //element vector
    1577        
     1653
    15781654        IssmDouble value;
    1579        
     1655
    15801656        /*Are we in transient or static? */
    15811657        if(M==iomodel->numberofelements){
     
    16121688    }
    16131689    else if(vector_type==3){ //element vector
    1614        
     1690
    16151691        /*For right now we are static */
    16161692        if(M==iomodel->numberofelements){
     
    16371713
    16381714        /*Some sanity checks*/
    1639         _assert_(vector); 
    1640         _assert_(min_vector); 
    1641         _assert_(max_vector); 
     1715        _assert_(vector);
     1716        _assert_(min_vector);
     1717        _assert_(max_vector);
    16421718
    16431719        /*For now we only support nodal vectors*/
     
    16581734                        values_max[i] = max_vector[vertexids[i]-1];
    16591735                }
    1660                 this->AddControlInput(input_enum,values,min_vector,max_vector,P1Enum,id);
     1736                this->AddControlInput(input_enum,values,values_min,values_max,P1Enum,id);
    16611737        }
    16621738
     
    16711747                           TransientInput* grad_input = new TransientInput(ControlInputGradEnum);
    16721748                                for(int t=0;t<N;t++){
    1673                 for(int i=0;i<numvertices;i++){ 
     1749                for(int i=0;i<numvertices;i++){
    16741750                                                values[i]=vector[N*(vertexids[i]-1)+t];
    16751751                                                values_min[i] = min_vector[N*(vertexids[i]-1)+t];
     
    16781754                                        switch(this->ObjectEnum()){
    16791755                    case TriaEnum:
    1680                                                                         values_input->AddTimeInput(new TriaInput(input_enum,values,P1Enum)); 
    1681                                                                         mins_input->AddTimeInput(new TriaInput(ControlInputMinsEnum,values_min,P1Enum)); 
     1756                                                                        values_input->AddTimeInput(new TriaInput(input_enum,values,P1Enum));
     1757                                                                        mins_input->AddTimeInput(new TriaInput(ControlInputMinsEnum,values_min,P1Enum));
    16821758                                                                        maxs_input->AddTimeInput(new TriaInput(ControlInputMaxsEnum,values_max,P1Enum));
    16831759                                                                break;
    16841760                    case PentaEnum:
    1685                                                                         values_input->AddTimeInput(new PentaInput(input_enum,values,P1Enum)); 
    1686                                                                         mins_input->AddTimeInput(new PentaInput(ControlInputMinsEnum,values_min,P1Enum)); 
    1687                                                                         maxs_input->AddTimeInput(new PentaInput(ControlInputMaxsEnum,values_max,P1Enum)); 
     1761                                                                        values_input->AddTimeInput(new PentaInput(input_enum,values,P1Enum));
     1762                                                                        mins_input->AddTimeInput(new PentaInput(ControlInputMinsEnum,values_min,P1Enum));
     1763                                                                        maxs_input->AddTimeInput(new PentaInput(ControlInputMaxsEnum,values_max,P1Enum));
    16881764                                                                        break;
    16891765                    case TetraEnum:
    1690                                                                         values_input->AddTimeInput(new TetraInput(input_enum,values,P1Enum)); 
    1691                                                                         mins_input->AddTimeInput(new TetraInput(ControlInputMinsEnum,values_min,P1Enum)); 
    1692                                                                         maxs_input->AddTimeInput(new TetraInput(ControlInputMaxsEnum,values_max,P1Enum)); 
     1766                                                                        values_input->AddTimeInput(new TetraInput(input_enum,values,P1Enum));
     1767                                                                        mins_input->AddTimeInput(new TetraInput(ControlInputMinsEnum,values_min,P1Enum));
     1768                                                                        maxs_input->AddTimeInput(new TetraInput(ControlInputMaxsEnum,values_max,P1Enum));
    16931769                                                                        break;
    16941770                    default: _error_("Not implemented yet");
     
    17121788          * code: what type of data is in the vector (booleans, ints, doubles)
    17131789          */
    1714    
     1790
    17151791         /*Intermediaries*/
    17161792    int                                 i,t;
     
    17291805        }
    17301806
    1731 
    17321807    /*Branch on type of vector: nodal or elementary: */
    17331808    if(vector_type==1){ //nodal vector
    1734        
     1809
    17351810        int         numvertices = this->GetNumberOfVertices();
    17361811        int        *vertexids   = xNew<int>(numvertices);
    17371812        IssmDouble *values      = xNew<IssmDouble>(numvertices);
    1738        
     1813
    17391814        /*Recover vertices ids needed to initialize inputs*/
    17401815        _assert_(iomodel->elements);
     
    17421817            vertexids[i]=reCast<int>(iomodel->elements[numvertices*this->Sid()+i]); //ids for vertices are in the elements array from Matlab
    17431818        }
    1744        
     1819
    17451820        /*Are we in transient or static? */
    17461821                  if(M==1){
     
    17511826                    case TetraEnum: datasetinput->AddInput(new TetraInput(vector_enum,values,P0Enum),input_enum); break;
    17521827                    default: _error_("Not implemented yet");
    1753                                 } 
     1828                                }
    17541829                  }
    17551830                  else if(M==iomodel->numberofvertices){
     
    17991874                                          case TetraEnum: datasetinput->AddInput(new TetraInput(vector_enum,values,P0Enum),input_enum); break;
    18001875                                          default: _error_("Not implemented yet");
    1801                                   }       
     1876                                  }
    18021877                          }
    18031878                          else if(N==this->GetNumberOfNodes(P1xP2Enum)){
     
    18231898                          _error_("nodal vector is either numberofvertices or numberofvertices+1 long. Field provided (" << EnumToStringx(vector_enum) << ") is " << M << " long");
    18241899                  }
    1825        
     1900
    18261901        xDelete<IssmDouble>(values);
    18271902        xDelete<int>(vertexids);
    18281903    }
    18291904    else if(vector_type==2){ //element vector
    1830        
     1905
    18311906        IssmDouble value;
    1832        
     1907
    18331908        /*Are we in transient or static? */
    18341909        if(M==iomodel->numberofelements){
     
    18651940    }
    18661941    else if(vector_type==3){ //element vector
    1867        
     1942
    18681943        /*For right now we are static */
    18691944        if(M==iomodel->numberofelements){
     
    18821957void       Element::InputDuplicate(int original_enum,int new_enum){/*{{{*/
    18831958
    1884         if(!IsInput(original_enum)) _error_("Enum "<<EnumToStringx(original_enum)<<" is not in IsInput");
     1959        if(!IsInputEnum(original_enum)) _error_("Enum "<<EnumToStringx(original_enum)<<" is not in IsInput");
    18851960
    18861961        /*Call inputs method*/
     
    18921967
    18931968        /*Check that name is an element input*/
    1894         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     1969        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    18951970
    18961971        /*update input*/
     
    19011976
    19021977        /*Check that name is an element input*/
    1903         if(!IsInput(name)) return;
     1978        if(!IsInputEnum(name)) return;
    19041979
    19051980        /*update input*/
     
    19101985
    19111986        /*Check that name is an element input*/
    1912         if(!IsInput(name)) return;
     1987        if(!IsInputEnum(name)) return;
    19131988
    19141989        /*update input*/
     
    19221997        parameters->FindParam(&migration_style,GroundinglineMigrationEnum);
    19231998
    1924         if(migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){ //Floating if all nodes are floating
     1999        if(migration_style==SubelementMigrationEnum){ //Floating if all nodes are floating
    19252000                if(this->inputs->Max(MaskGroundediceLevelsetEnum) <= 0.) shelf=true;
    19262001                else shelf=false;
    19272002        }
    19282003        else if(migration_style==ContactEnum){
    1929                 if(this->inputs->Max(MaskGroundediceLevelsetEnum) > 0.) shelf=false;
    1930                 else shelf=true;
     2004                if(this->inputs->Min(MaskGroundediceLevelsetEnum) < 0.) shelf=true;
     2005                else shelf=false;
    19312006        }
    19322007        else if(migration_style==NoneEnum || migration_style==AggressiveMigrationEnum || migration_style==SoftMigrationEnum || migration_style==GroundingOnlyEnum){ //Floating if all nodes are floating
     
    19402015bool       Element::IsIceInElement(){/*{{{*/
    19412016        return (this->inputs->Min(MaskIceLevelsetEnum)<0.);
    1942 }
    1943 /*}}}*/
    1944 bool       Element::IsInput(int name){/*{{{*/
    1945         if (
    1946                                 name==ThicknessEnum ||
    1947                                 name==SurfaceEnum ||
    1948                                 name==BaseEnum ||
    1949                                 name==BedEnum ||
    1950                                 name==BalancethicknessThickeningRateEnum ||
    1951                                 name==BalancethicknessOmegaEnum ||
    1952                                 name==SigmaNNEnum ||
    1953                                 name==SurfaceSlopeXEnum ||
    1954                                 name==SurfaceSlopeYEnum ||
    1955                                 name==SmbMassBalanceEnum ||
    1956                                 name==SmbAccumulationEnum ||
    1957                                 name==SmbRunoffEnum ||
    1958                                 name==SmbMeltEnum ||
    1959                                 name==SmbRefreezeEnum ||
    1960                                 name==SmbEvaporationEnum ||
    1961                                 name==SmbCEnum ||
    1962                                 name==SmbTaEnum ||
    1963                                 name==SmbVEnum ||
    1964                                 name==SmbDswrfEnum ||
    1965                                 name==SmbDlwrfEnum ||
    1966                                 name==SmbPEnum ||
    1967                                 name==SmbEAirEnum ||
    1968                                 name==SmbPAirEnum ||
    1969                                 name==SmbVzEnum ||
    1970                                 name==SmbTzEnum ||
    1971                                 name==SmbTmeanEnum ||
    1972                                 name==SmbIsInitializedEnum ||
    1973                                 name==BasalforcingsGroundediceMeltingRateEnum ||
    1974                                 name==BasalforcingsFloatingiceMeltingRateEnum ||
    1975                                 name==BasalforcingsGeothermalfluxEnum ||
    1976                                 name==BalancethicknessSpcthicknessEnum ||
    1977                                 name==SurfaceAreaEnum||
    1978                                 name==DamageDEnum ||
    1979                                 name==DamageDbarEnum ||
    1980                                 name==PressureEnum ||
    1981                                 name==VxEnum ||
    1982                                 name==VyEnum ||
    1983                                 name==VzEnum ||
    1984                                 name==VxMeshEnum ||
    1985                                 name==VyMeshEnum ||
    1986                                 name==VzMeshEnum ||
    1987                                 name==InversionVxObsEnum ||
    1988                                 name==InversionVyObsEnum ||
    1989                                 name==InversionVzObsEnum ||
    1990                                 name==TemperatureEnum ||
    1991                                 name==TemperaturePDDEnum ||
    1992                                 name==EnthalpyEnum ||
    1993                                 name==EnthalpyPicardEnum ||
    1994                                 name==WaterfractionEnum||
    1995                                 name==WatercolumnEnum ||
    1996                                 name==FrictionCoefficientEnum ||
    1997                                 name==FrictionAsEnum ||
    1998                                 name==FrictionEffectivePressureEnum ||
    1999                                 name==MaskGroundediceLevelsetEnum ||
    2000                                 name==MaskIceLevelsetEnum ||
    2001                                 name==IceMaskNodeActivationEnum ||
    2002                                 name==LevelsetfunctionSlopeXEnum ||
    2003                                 name==LevelsetfunctionSlopeYEnum ||
    2004                                 name==LevelsetfunctionPicardEnum ||
    2005                                 name==CalvingCalvingrateEnum ||
    2006                                 name==CalvingMeltingrateEnum ||
    2007                                 name==GradientEnum ||
    2008                                 name==OldGradientEnum  ||
    2009                                 name==ConvergedEnum ||
    2010                                 name==MaterialsRheologyEEnum ||
    2011                                 name==MaterialsRheologyEbarEnum ||
    2012                                 name==MaterialsRheologyBEnum ||
    2013                                 name==MaterialsRheologyBbarEnum ||
    2014                                 name==MaterialsRheologyNEnum ||
    2015                                 name==MaterialsRheologyEcEnum ||
    2016                                 name==MaterialsRheologyEcbarEnum ||
    2017                                 name==MaterialsRheologyEsEnum ||
    2018                                 name==MaterialsRheologyEsbarEnum ||
    2019                                 name==SealevelEnum ||
    2020                                 name==SealevelUmotionEnum ||
    2021                                 name==SealevelNmotionEnum ||
    2022                                 name==SealevelEmotionEnum ||
    2023                                 name==SealevelAbsoluteEnum ||
    2024                                 name==SealevelEustaticEnum ||
    2025                                 name==SealevelriseDeltathicknessEnum ||
    2026                                 name==EsaUmotionEnum ||
    2027                                 name==EsaNmotionEnum ||
    2028                                 name==EsaEmotionEnum ||
    2029                                 name==EsaXmotionEnum ||
    2030                                 name==EsaYmotionEnum ||
    2031                                 name==EsaStrainratexxEnum ||
    2032                                 name==EsaStrainratexyEnum ||
    2033                                 name==EsaStrainrateyyEnum ||
    2034                                 name==EsaRotationrateEnum ||
    2035                                 name==EsaDeltathicknessEnum ||
    2036                                 name==GiaWEnum ||
    2037                                 name==GiadWdtEnum ||
    2038                                 name==SedimentHeadEnum ||
    2039                                 name==EplHeadEnum ||
    2040                                 name==SedimentHeadOldEnum ||
    2041                                 name==EplHeadOldEnum ||
    2042                                 name==StressIntensityFactorEnum ||
    2043                                 name==StrainRateparallelEnum ||
    2044                                 name==StrainRateperpendicularEnum ||
    2045                                 name==HydrologydcEplThicknessOldEnum ||
    2046                                 name==HydrologydcEplInitialThicknessEnum ||
    2047                                 name==HydrologydcEplThicknessEnum ||
    2048                                 name==HydrologydcMaskEplactiveNodeEnum ||
    2049                                 name==HydrologyHeadEnum ||
    2050                                 name==HydrologyHeadOldEnum ||           
    2051                                 name==StressbalanceConvergenceNumStepsEnum ||
    2052                                 name==MeshVertexonbaseEnum ||
    2053                                 name==FrictionPEnum ||
    2054                                 name==FrictionQEnum ||
    2055                                 name==FrictionCoefficientcoulombEnum ||
    2056                                 name==LoadingforceXEnum ||
    2057                                 name==LoadingforceYEnum ||
    2058                                 name==VelEnum ||
    2059                                 name==DeviatoricStressxxEnum ||
    2060                                 name==DeviatoricStressyyEnum ||
    2061                                 name==DeviatoricStressxyEnum ||
    2062                                 name==DeviatoricStressxzEnum ||
    2063                                 name==DeviatoricStressyzEnum ||
    2064                                 name==DeviatoricStresszzEnum ||
    2065                                 name==DeviatoricStresseffectiveEnum ||
    2066                                 name==VxAverageEnum ||
    2067                                 name==VyAverageEnum
    2068                                 ) {
    2069                                         return true;
    2070                                 }
    2071         else return false;
    20722017}
    20732018/*}}}*/
     
    21022047        this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
    21032048        xDelete<IssmDouble>(base);
     2049        xDelete<IssmDouble>(values);
     2050
     2051}/*}}}*/
     2052void       Element::SpatialLinearFloatingiceMeltingRate(){/*{{{*/
     2053
     2054        int numvertices      = this->GetNumberOfVertices();
     2055        IssmDouble* deepwatermelt     = xNew<IssmDouble>(numvertices);
     2056        IssmDouble* deepwaterel     = xNew<IssmDouble>(numvertices);
     2057        IssmDouble* upperwaterel     = xNew<IssmDouble>(numvertices);
     2058        IssmDouble* base     = xNew<IssmDouble>(numvertices);
     2059        IssmDouble* values   = xNew<IssmDouble>(numvertices);
     2060
     2061        this->GetInputListOnVertices(base,BaseEnum);
     2062        this->GetInputListOnVertices(deepwatermelt,BasalforcingsDeepwaterMeltingRateEnum);
     2063        this->GetInputListOnVertices(deepwaterel,BasalforcingsDeepwaterElevationEnum);
     2064        this->GetInputListOnVertices(upperwaterel,BasalforcingsUpperwaterElevationEnum);
     2065
     2066        for(int i=0;i<numvertices;i++){
     2067                if(base[i]>upperwaterel[i])      values[i]=0;
     2068                else if (base[i]<deepwaterel[i]) values[i]=deepwatermelt[i];
     2069                else values[i]=deepwatermelt[i]*(base[i]-upperwaterel[i])/(deepwaterel[i]-upperwaterel[i]);
     2070        }
     2071
     2072        this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum);
     2073        xDelete<IssmDouble>(base);
     2074        xDelete<IssmDouble>(deepwaterel);
     2075        xDelete<IssmDouble>(deepwatermelt);
     2076        xDelete<IssmDouble>(upperwaterel);
    21042077        xDelete<IssmDouble>(values);
    21052078
     
    21532126}/*}}}*/
    21542127void       Element::MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses){/*{{{*/
    2155        
     2128
    21562129        _assert_(this);
    21572130        if(marshall_direction==MARSHALLING_BACKWARD){
     
    21612134
    21622135        MARSHALLING_ENUM(ElementEnum);
    2163        
     2136
    21642137        MARSHALLING(id);
    21652138        MARSHALLING(sid);
     
    22002173        for(i=0;i<numvertices;i++){
    22012174                /* Contact FS*/
    2202                 if(migration_style == ContactEnum && phi_ungrounding[vertices[i]->Pid()]<10){
    2203                         phi[i]=phi_ungrounding[vertices[i]->Pid()]; 
     2175                if(migration_style == ContactEnum){
     2176                        phi[i]=phi_ungrounding[vertices[i]->Pid()];
    22042177                        if(phi[i]>=0.) b[i]=r[i];
    22052178                }
     
    22072180                /*Ice shelf: if bed below bathymetry, impose it at the bathymetry and update surface, elso do nothing */
    22082181                else if(phi[i]<=0.){
    2209                         if(b[i]<=r[i]){ 
     2182                        if(b[i]<=r[i]){
    22102183                                b[i]        = r[i];
    22112184                                s[i]        = b[i]+h[i];
     
    22182191                        if (bed_hydro>r[i]){
    22192192                                /*Unground only if the element is connected to the ice shelf*/
    2220                                 if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){
     2193                                if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum){
    22212194                                        s[i]        = (1-density)*h[i]+sl[i];
    22222195                                        b[i]        = -density*h[i]+sl[i];
     
    24672440        }
    24682441
    2469         /*Recover pdd factors at time t. 
    2470          *     This parameter is set, if the user wants to define the 
     2442        /*Recover pdd factors at time t.
     2443         *     This parameter is set, if the user wants to define the
    24712444         *     pdd factors regionally, if issetpddfac==1 in the d18opdd method */
    24722445        if (issetpddfac==1){
     
    25142487
    25152488        switch(this->ObjectEnum()){
    2516                 case TriaEnum: 
     2489                case TriaEnum:
    25172490                        // this->inputs->AddInput(new TriaInput(TemperatureEnum,&yearlytemperatures[0],P1Enum));
    25182491                        this->inputs->AddInput(new TriaInput(TemperaturePDDEnum,&yearlytemperatures[0],P1Enum));
     
    25492522                        this->InputExtrude(SmbMassBalanceEnum,-1);
    25502523                        break;
    2551                 case TetraEnum: 
     2524                case TetraEnum:
    25522525                        if(IsOnSurface()){
    25532526                                GetInputListOnVertices(&s[0],TemperatureEnum);
     
    25972570                case ViscousHeatingEnum: this->ViscousHeatingCreateInput(); break;
    25982571                case StressMaxPrincipalEnum: this->StressMaxPrincipalCreateInput(); break;
    2599                 case StressTensorxxEnum: 
    2600                 case StressTensorxyEnum: 
    2601                 case StressTensorxzEnum: 
    2602                 case StressTensoryyEnum: 
    2603                 case StressTensoryzEnum: 
     2572                case StressTensorxxEnum:
     2573                case StressTensorxyEnum:
     2574                case StressTensorxzEnum:
     2575                case StressTensoryyEnum:
     2576                case StressTensoryzEnum:
    26042577                case StressTensorzzEnum: this->ComputeStressTensor(); break;
    26052578                case StrainRatexxEnum:
     
    26102583                case StrainRatezzEnum:
    26112584                case StrainRateeffectiveEnum: this->ComputeStrainRate(); break;
    2612                 case DeviatoricStressxxEnum: 
    2613                 case DeviatoricStressxyEnum: 
    2614                 case DeviatoricStressxzEnum: 
    2615                 case DeviatoricStressyyEnum: 
    2616                 case DeviatoricStressyzEnum: 
    2617                 case DeviatoricStresszzEnum: 
     2585                case DeviatoricStressxxEnum:
     2586                case DeviatoricStressxyEnum:
     2587                case DeviatoricStressxzEnum:
     2588                case DeviatoricStressyyEnum:
     2589                case DeviatoricStressyzEnum:
     2590                case DeviatoricStresszzEnum:
    26182591                case DeviatoricStresseffectiveEnum: this->ComputeDeviatoricStressTensor(); break;
    26192592                case EsaStrainratexxEnum:
    2620                 case EsaStrainratexyEnum: 
    2621                 case EsaStrainrateyyEnum: 
     2593                case EsaStrainratexyEnum:
     2594                case EsaStrainrateyyEnum:
    26222595                case EsaRotationrateEnum: this->ComputeEsaStrainAndVorticity(); break;
    26232596                case SigmaNNEnum: this->ComputeSigmaNN(); break;
     
    28932866        if (!IsOnSurface()) return;
    28942867
    2895 
    28962868        /*Retrieve material properties and parameters:{{{ */
    28972869        rho_ice = matpar->GetMaterialParameter(MaterialsRhoIceEnum);
     
    29242896        /*}}}*/
    29252897        /*Retrieve inputs: {{{*/
    2926         Input* zTop_input=this->GetInput(SmbZTopEnum); _assert_(zTop_input); 
    2927         Input* dzTop_input=this->GetInput(SmbDzTopEnum); _assert_(dzTop_input); 
    2928         Input* dzMin_input=this->GetInput(SmbDzMinEnum); _assert_(dzMin_input); 
    2929         Input* zMax_input=this->GetInput(SmbZMaxEnum); _assert_(zMax_input); 
    2930         Input* zMin_input=this->GetInput(SmbZMinEnum); _assert_(zMin_input); 
    2931         Input* zY_input=this->GetInput(SmbZYEnum); _assert_(zY_input); 
     2898        Input* zTop_input=this->GetInput(SmbZTopEnum); _assert_(zTop_input);
     2899        Input* dzTop_input=this->GetInput(SmbDzTopEnum); _assert_(dzTop_input);
     2900        Input* dzMin_input=this->GetInput(SmbDzMinEnum); _assert_(dzMin_input);
     2901        Input* zMax_input=this->GetInput(SmbZMaxEnum); _assert_(zMax_input);
     2902        Input* zMin_input=this->GetInput(SmbZMinEnum); _assert_(zMin_input);
     2903        Input* zY_input=this->GetInput(SmbZYEnum); _assert_(zY_input);
    29322904        Input* Tmean_input=this->GetInput(SmbTmeanEnum); _assert_(Tmean_input);
    29332905        Input* C_input=this->GetInput(SmbCEnum); _assert_(C_input);
     
    29502922        dzTop_input->GetInputValue(&dzTop,gauss);
    29512923        dzMin_input->GetInputValue(&dzMin,gauss);
    2952         zMax_input->GetInputValue(&zMax,gauss); 
    2953         zMin_input->GetInputValue(&zMin,gauss); 
     2924        zMax_input->GetInputValue(&zMax,gauss);
     2925        zMin_input->GetInputValue(&zMin,gauss);
    29542926        zY_input->GetInputValue(&zY,gauss);
    29552927        Tmean_input->GetInputValue(&Tmean,gauss);
     
    30052977                        a = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)a[i]=aini[0];         //set albedo equal to fresh snow [fraction]
    30062978                        T = xNewZeroInit<IssmDouble>(m); for(int i=0;i<m;i++)T[i]=Tmean;         //set initial grid cell temperature to the annual mean temperature [K]
    3007                         /*/!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties) 
     2979                        /*/!\ Default value of T can not be retrived from SMBgemb.m (like other snow properties)
    30082980                         *    because don't know Tmean yet when set default values.
    30092981                         *    Default value of 0C given in SMBgemb.m is overwritten here with value of Tmean*/
     
    30663038        sumdz_add=0;
    30673039
    3068         //before starting loop, realize that the transient core runs this smb_core at time = time +deltaT. 
    3069         //go back to time - deltaT: 
     3040        //before starting loop, realize that the transient core runs this smb_core at time = time +deltaT.
     3041        //go back to time - deltaT:
    30703042        time-=dt;
    30713043
     
    30953067                if(isalbedo)albedo(&a,aIdx,re,d,cldFrac,aIce,aSnow,aValue,adThresh,T,W,P,EC,t0wet,t0dry,K,smb_dt,rho_ice,m,this->Sid());
    30963068
    3097 
    30983069                /*Distribution of absorbed short wave radation with depth:*/
    30993070                if(isshortwave)shortwave(&swf, swIdx, aIdx, dsw, a[0], d, dz, re,rho_ice,m,this->Sid());
     
    31053076                if(isthermal)thermo(&EC, &T, dz, d, swf, dlw, Ta, V, eAir, pAir, teValue, W[0], smb_dt, m, Vz, Tz, thermo_scaling,rho_ice,this->Sid());
    31063077
    3107                 /*Change in thickness of top cell due to evaporation/condensation  assuming same density as top cell. 
     3078                /*Change in thickness of top cell due to evaporation/condensation  assuming same density as top cell.
    31083079                 * need to fix this in case all or more of cell evaporates */
    31093080                dz[0] = dz[0] + EC / d[0];
     
    31193090                if(isdensification)densification(&d,&dz, T, re, denIdx, C, smb_dt, Tmean,rho_ice,m,this->Sid());
    31203091
    3121                 /*Calculate upward longwave radiation flux [W m-2] not used in energy balance. Calculated for every 
     3092                /*Calculate upward longwave radiation flux [W m-2] not used in energy balance. Calculated for every
    31223093                 * sub-time step in thermo equations*/
    31233094                ulw = 5.67E-8 * pow(T[0],4.0) * teValue;
     
    31303101
    31313102                /*Verbose some results in debug mode: {{{*/
    3132                 if(VerboseSmb() && 0){ 
    3133                         _printf_("smb log: count[" << count << "] m[" << m << "] " 
    3134                                                 << setprecision(16)   << "T[" << cellsum(T,m)  << "] " 
     3103                if(VerboseSmb() && 0){
     3104                        _printf_("smb log: count[" << count << "] m[" << m << "] "
     3105                                                << setprecision(16)   << "T[" << cellsum(T,m)  << "] "
    31353106                                                << "d[" << cellsum(d,m)  << "] "
    31363107                                                << "dz[" << cellsum(dz,m)  << "] "
     
    31553126
    31563127                /*Calculate total system mass:*/
    3157                 sumMass=0; 
     3128                sumMass=0;
    31583129                fac=0;
    31593130                for(int i=0;i<m;i++){
     
    32343205        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    32353206        vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    3236         epsilon[0] = dvx[0];    // normal strain rate x-direction 
    3237         epsilon[1] = dvy[1]; // normal strain rate y-direction 
    3238         epsilon[2] = 0.5*(dvx[1] + dvy[0]); // shear strain rate 
    3239         epsilon[3] = 0.5*(dvx[1] - dvy[0]); // rotation rate 
     3207        epsilon[0] = dvx[0];    // normal strain rate x-direction
     3208        epsilon[1] = dvy[1]; // normal strain rate y-direction
     3209        epsilon[2] = 0.5*(dvx[1] + dvy[0]); // shear strain rate
     3210        epsilon[3] = 0.5*(dvx[1] - dvy[0]); // rotation rate
    32403211
    32413212}/*}}}*/
  • issm/trunk/src/c/classes/Elements/Element.h

    r22758 r23189  
    9090                void               GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype);
    9191                void               GetInputListOnVertices(IssmDouble* pvalue,int enumtype);
     92                void               GetInputListOnVerticesAtTime(IssmDouble* pvalue,int enumtype,IssmDouble time);
    9293                void               GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue);
    9394                void               GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug);
     
    104105                void               GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int solutionenum);
    105106                void               GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum, int type);
     107                void               GetVectorFromInputs(Vector<IssmDouble>* vector, int name_enum, int type,IssmDouble time);
    106108                void                 GetVertexPidList(int* pidlist);
    107109                void               GetVerticesConnectivityList(int* connectivitylist);
     
    111113                IssmDouble         GetYcoord(IssmDouble* xyz_list,Gauss* gauss);
    112114                IssmDouble         GetZcoord(IssmDouble* xyz_list,Gauss* gauss);
    113                 void               GradientIndexing(int* indexing,int control_index,bool onsid=false);
     115                void               GradientIndexing(int* indexing,int control_index);
    114116                IssmDouble         GroundedArea(IssmDouble* mask, bool scaled);
    115117                bool               HasNodeOnBase();
     
    130132                bool               IsFloating();
    131133                bool               IsIceInElement();
    132                 bool                 IsInput(int name);
    133134                bool               IsLandInElement();
    134135                bool               IsWaterInElement();
    135136                void               LinearFloatingiceMeltingRate();
     137                void               SpatialLinearFloatingiceMeltingRate();
    136138                void               MantlePlumeGeothermalFlux();
    137139                void               MarshallElement(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction,int numanalyses);
     
    205207                virtual void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index)=0;
    206208                virtual void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum)=0;
    207                 virtual void       CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum){_error_("not implemented yet");};
     209                virtual void       CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum){_error_("not implemented yet");};
    208210                virtual void       ElementResponse(IssmDouble* presponse,int response_enum)=0;
    209211                virtual void       ElementSizes(IssmDouble* phx,IssmDouble* phy,IssmDouble* phz)=0;
    210212                virtual int        FiniteElement(void)=0;
    211213                virtual IssmDouble FloatingArea(bool scaled)=0;
    212                 virtual void       FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating)=0;
     214                virtual void       FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure)=0;
    213215                virtual Element*   GetBasalElement(void)=0;
    214216                virtual int        GetElementType(void)=0;
     
    225227                virtual int        GetNumberOfNodes(int enum_type)=0;
    226228                virtual int        GetNumberOfVertices(void)=0;
    227                 virtual void       GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset, bool onsid)=0;
    228                 virtual void       GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data, bool onsid)=0;
     229                virtual void       GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset)=0;
     230                virtual void       GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data)=0;
    229231                virtual void       GetVerticesCoordinatesBase(IssmDouble** xyz_list)=0;
    230232                virtual void       GetVerticesCoordinatesTop(IssmDouble** xyz_list)=0;
     
    281283                virtual void       PicoUpdateBoxid(int* pmax_boxid_basin)=0;
    282284                virtual void       PicoUpdateBox(int loopboxid)=0;
     285                virtual void       PicoComputeBasalMelt(void)=0;
    283286                virtual void       PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding)=0;
    284287                virtual int        PressureInterpolation()=0;
     
    286289                virtual void       ResetFSBasalBoundaryCondition()=0;
    287290                virtual void       ResetHooks()=0;
    288                 virtual void       ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};
    289291                virtual void       SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset,int N,int M)=0;
    290292                virtual void       SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0;
     
    315317                virtual void       ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input)=0;
    316318                virtual void       WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue){_error_("not implemented yet");};
    317                 virtual void       WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};
    318                 virtual void       ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0;
    319319
    320320                #ifdef _HAVE_GIAIVINS_
     
    333333                virtual void          SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0;
    334334                virtual void          SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea)=0;
    335                 virtual void          SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea)=0;
     335                virtual void          SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz)=0;
    336336                #endif
    337337
  • issm/trunk/src/c/classes/Elements/ElementHook.cpp

    r22758 r23189  
    104104
    105105        if(marshall_direction==MARSHALLING_BACKWARD){
    106                
     106
    107107                if (!hnodes_null)this->hnodes = new Hook*[numanalyses];
    108108                else this->hnodes=NULL;
     
    140140        _printf_(" ElementHook DeepEcho:\n");
    141141        _printf_("  numanalyses : "<< this->numanalyses <<"\n");
    142        
     142
    143143        _printf_("  hnodes:\n");
    144144        if(hnodes){
     
    149149        }
    150150        else _printf_("  hnodes = NULL\n");
    151        
     151
    152152        _printf_("  hvertices:\n");
    153153        if(hvertices) hvertices->DeepEcho();
    154154        else _printf_("  hvertices = NULL\n");
    155        
     155
    156156        _printf_("  hmaterial:\n");
    157157        if(hmaterial) hmaterial->DeepEcho();
     
    170170/*}}}*/
    171171void ElementHook::Echo(){/*{{{*/
    172        
     172
    173173        _printf_(" ElementHook Echo:\n");
    174174        _printf_("  numanalyses : "<< this->numanalyses <<"\n");
    175        
     175
    176176        _printf_("  hnodes:\n");
    177177        if(hnodes){
     
    181181        }
    182182        else _printf_("  hnodes = NULL\n");
    183        
     183
    184184        _printf_("  hvertices:\n");
    185185        if(hvertices) hvertices->Echo();
    186186        else _printf_("  hvertices = NULL\n");
    187        
     187
    188188        _printf_("  hmaterial:\n");
    189189        if(hmaterial) hmaterial->Echo();
  • issm/trunk/src/c/classes/Elements/Penta.cpp

    r22758 r23189  
    286286        IssmDouble  calvingratey[NUMVERTICES];
    287287        IssmDouble  calvingrate[NUMVERTICES];
    288 
    289288
    290289        /* Get node coordinates and dof list: */
     
    741740}
    742741/*}}}*/
    743 void       Penta::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){/*{{{*/
     742void       Penta::FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure){/*{{{*/
    744743
    745744        if(!IsOnBase()) return;
     
    747746        int approximation;
    748747        inputs->GetInputValue(&approximation,ApproximationEnum);
    749         if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum){
    750                 for(int i=0;i<NUMVERTICES;i++){
    751                         vertexgrounded->SetValue(vertices[i]->Pid(),+9999.,INS_VAL);
    752                         vertexfloating->SetValue(vertices[i]->Pid(),+9999.,INS_VAL);
     748        if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum || approximation==HOFSApproximationEnum){
     749                _error_("Cannot compute contact condition for non FS elements");
     750        }
     751
     752        /*Intermediaries*/
     753        IssmDouble* xyz_list = NULL;
     754        IssmDouble  bed_normal[3],base[NUMVERTICES],bed[NUMVERTICES],surface[NUMVERTICES],phi[NUMVERTICES];
     755        IssmDouble  water_pressure[NUMVERTICES],pressureice[NUMVERTICES],pressure[NUMVERTICES];
     756        IssmDouble  sigmaxx[NUMVERTICES],sigmayy[NUMVERTICES],sigmazz[NUMVERTICES],sigmaxy[NUMVERTICES];
     757        IssmDouble  sigmayz[NUMVERTICES],sigmaxz[NUMVERTICES],sigma_nn[NUMVERTICES];
     758        IssmDouble  viscosity,epsilon[NUMVERTICES];
     759        GetInputListOnVertices(&base[0],BaseEnum);
     760        GetInputListOnVertices(&bed[0],BedEnum);
     761        GetInputListOnVertices(&surface[0],SurfaceEnum);
     762        GetInputListOnVertices(&pressure[0],PressureEnum);
     763        GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum);
     764        IssmDouble rho_ice   = matpar->GetMaterialParameter(MaterialsRhoIceEnum);
     765        IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum);
     766        IssmDouble gravity   = matpar->GetMaterialParameter(ConstantsGEnum);
     767
     768        /* Get node coordinates and dof list: */
     769        GetVerticesCoordinates(&xyz_list);
     770
     771        /*Retrieve all inputs we will be needing: */
     772        Input* vx_input = inputs->GetInput(VxEnum); _assert_(vx_input);
     773        Input* vy_input = inputs->GetInput(VyEnum); _assert_(vy_input);
     774        Input* vz_input = inputs->GetInput(VzEnum); _assert_(vz_input);
     775
     776        /*1. Recover stresses at the base*/
     777        GaussPenta* gauss=new GaussPenta();
     778        for (int iv=0;iv<NUMVERTICES;iv++){
     779                gauss->GaussVertex(iv);
     780
     781                /*Compute strain rate viscosity and pressure: */
     782                this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
     783                this->material->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
     784                /*FIXME: this is for Hongju only*/
     785                //pressureice[iv]=gravity*rho_ice*(surface[iv]-base[iv]);
     786                //if (pressure[iv]/pressureice[iv]>1)   pressure[iv]=pressureice[iv];
     787
     788                /*Compute Stress*/
     789                sigmaxx[iv]=2*viscosity*epsilon[0]-pressure[iv]; // sigma = nu eps - pressure
     790                sigmayy[iv]=2*viscosity*epsilon[1]-pressure[iv];
     791                sigmazz[iv]=2*viscosity*epsilon[2]-pressure[iv];
     792                sigmaxy[iv]=2*viscosity*epsilon[3];
     793                sigmaxz[iv]=2*viscosity*epsilon[4];
     794                sigmayz[iv]=2*viscosity*epsilon[5];
     795        }
     796
     797        /*2. compute contact condition*/
     798        for(int i=0;i<NUMVERTICES;i++){
     799
     800                /*If was grounded*/
     801                if (phi[i]>=0.){
     802                        NormalBase(&bed_normal[0],xyz_list);
     803                        sigma_nn[i]=-1*(sigmaxx[i]*bed_normal[0]*bed_normal[0] + sigmayy[i]*bed_normal[1]*bed_normal[1] + sigmazz[i]*bed_normal[2]*bed_normal[2]+2*sigmaxy[i]*bed_normal[0]*bed_normal[1]+2*sigmaxz[i]*bed_normal[0]*bed_normal[2]+2*sigmayz[i]*bed_normal[1]*bed_normal[2]);
     804                        water_pressure[i]=-gravity*rho_water*base[i];
     805                        vertex_sigmann->SetValue(vertices[i]->Pid(),sigma_nn[i],ADD_VAL);
     806                        vertex_waterpressure->SetValue(vertices[i]->Pid(),water_pressure[i],ADD_VAL);
    753807                }
    754         }
    755         else {
    756                 /*Intermediaries*/
    757                 IssmDouble* xyz_list = NULL;
    758                 IssmDouble  pressure,water_pressure,sigma_nn,viscosity,bed,base;
    759                 IssmDouble  bed_normal[3];
    760                 IssmDouble  epsilon[6]; /* epsilon=[exx eyy ezz exy exz eyz];*/
    761                 IssmDouble  surface=0,value=0;
    762                 bool grounded;
    763 
    764                 /* Get node coordinates and dof list: */
    765                 GetVerticesCoordinates(&xyz_list);
    766 
    767                 /*Retrieve all inputs we will be needing: */
    768                 Input* pressure_input = inputs->GetInput(PressureEnum); _assert_(pressure_input);
    769                 Input* base_input     = inputs->GetInput(BaseEnum);     _assert_(base_input);
    770                 Input* bed_input      = inputs->GetInput(BedEnum);      _assert_(bed_input);
    771                 Input* vx_input       = inputs->GetInput(VxEnum);       _assert_(vx_input);
    772                 Input* vy_input       = inputs->GetInput(VyEnum);       _assert_(vy_input);
    773                 Input* vz_input       = inputs->GetInput(VzEnum);       _assert_(vz_input);
    774 
    775                 /*Create gauss point in the middle of the basal edge*/
    776                 Gauss* gauss=NewGaussBase(1);
    777                 gauss->GaussPoint(0);
    778 
    779                 if(!IsFloating()){
    780                         /*Check for basal force only if grounded and touching GL*/
    781                         this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
    782                         this->material->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
    783                         pressure_input->GetInputValue(&pressure, gauss);
    784                         base_input->GetInputValue(&base, gauss); _assert_(base<0.);
    785 
    786                         /*Compute Stress*/
    787                         IssmDouble sigma_xx=2.*viscosity*epsilon[0]-pressure;
    788                         IssmDouble sigma_yy=2.*viscosity*epsilon[1]-pressure;
    789                         IssmDouble sigma_zz=2.*viscosity*epsilon[2]-pressure;
    790                         IssmDouble sigma_xy=2.*viscosity*epsilon[3];
    791                         IssmDouble sigma_xz=2.*viscosity*epsilon[4];
    792                         IssmDouble sigma_yz=2.*viscosity*epsilon[5];
    793 
    794                         /*Get normal vector to the bed */
    795                         NormalBase(&bed_normal[0],xyz_list);
    796 
    797                         /*basalforce*/
    798                         sigma_nn = sigma_xx*bed_normal[0]*bed_normal[0] + sigma_yy*bed_normal[1]*bed_normal[1] + sigma_zz*bed_normal[2]*bed_normal[2]
    799                           + 2.*sigma_xy*bed_normal[0]*bed_normal[1] + 2.*sigma_xz*bed_normal[0]*bed_normal[2] + 2.*sigma_yz*bed_normal[1]*bed_normal[2];
    800 
    801                         /*Compute water pressure*/
    802                         IssmDouble rho_ice   = matpar->GetMaterialParameter(MaterialsRhoIceEnum);
    803                         IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    804                         IssmDouble gravity   = matpar->GetMaterialParameter(ConstantsGEnum);
    805                         water_pressure=gravity*rho_water*base;
    806 
    807                         /*Compare basal stress to water pressure and determine whether it should ground*/
    808                         if (sigma_nn<water_pressure) grounded=true;
    809                         else                         grounded=false;
     808
     809                /*If was floating*/
     810                else{
     811                        /*Tricky part:
     812                         * 1. if base is now touching, we put 1 for sigma_nn and leave water pressure at 0 so that the rest of the module will reground this vertex
     813                         * 2. if base is still above bed, water pressure is set as 1, sigma_nn is left as 0, so the GL module will keep it afloat*/
     814                        if(base[i]<bed[i]) vertex_sigmann->SetValue(vertices[i]->Pid(),+1.,ADD_VAL);
     815                        else vertex_waterpressure->SetValue(vertices[i]->Pid(),+1.,ADD_VAL);
    810816                }
    811                 else{
    812                         /*Check for basal elevation if floating*/
    813                         base_input->GetInputValue(&base, gauss);
    814                         bed_input->GetInputValue(&bed, gauss);
    815                         if(base<bed) grounded=true;
    816                         else          grounded=false;
    817                 }
    818                 for(int i=0;i<NUMVERTICES;i++){
    819                         if(grounded) vertexgrounded->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
    820                         else         vertexfloating->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
    821                 }
    822 
    823                 /*clean up*/
    824                 delete gauss;
    825                 xDelete<IssmDouble>(xyz_list);
    826         }
     817        }
     818
     819        /*clean up*/
     820        delete gauss;
     821        xDelete<IssmDouble>(xyz_list);
    827822}
    828823/*}}}*/
     
    10521047/*}}}*/
    10531048void       Penta::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    1054        
     1049
    10551050        /* Intermediaries */
    10561051        const int dim=3;
     
    11531148}
    11541149/*}}}*/
    1155 void       Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,bool onsid){/*{{{*/
     1150void       Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/
    11561151
    11571152        int vertexidlist[NUMVERTICES];
    11581153
    11591154        /*Get out if this is not an element input*/
    1160         if(!IsInput(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
     1155        if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
    11611156
    11621157        /*Prepare index list*/
    1163         GradientIndexing(&vertexidlist[0],control_index,onsid);
     1158        GradientIndexing(&vertexidlist[0],control_index);
    11641159
    11651160        /*Get input (either in element or material)*/
     
    11761171}
    11771172/*}}}*/
    1178 void       Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset,bool onsid){/*{{{*/
     1173void       Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset){/*{{{*/
    11791174
    11801175        int* idlist = NULL;
     
    11831178
    11841179        /*Get out if this is not an element input*/
    1185         if(!IsInput(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
     1180        if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
    11861181        Input* input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
    1187 
    11881182
    11891183        /*Cast to Controlinput*/
     
    12171211                                        idlist = xNew<int>(NUMVERTICES);
    12181212                                        values = xNew<IssmDouble>(NUMVERTICES);
    1219                                         GradientIndexing(&idlist[0],control_index,true);
     1213                                        GradientIndexing(&idlist[0],control_index);
    12201214                                        for(int i=0;i<NUMVERTICES;i++){
    12211215                                                values[i] = pentainput->values[i];
     
    16111605
    16121606        /*Add input to the element: */
    1613         this->inputs->AddInput(new PentaInput(enum_type,values,P1Enum));
     1607        this->inputs->AddInput(new PentaInput(enum_type,values,this->element_type));
    16141608
    16151609        /*Free ressources:*/
     
    16651659
    16661660        /*Check that name is an element input*/
    1667         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     1661        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    16681662
    16691663        switch(type){
     
    22882282}
    22892283/*}}}*/
    2290 void       Penta::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/
    2291 
    2292         /*Intermediaries*/
    2293         IssmDouble d,xn,yn;
    2294 
    2295         /*Get current levelset and vertex coordinates*/
    2296         IssmDouble ls[NUMVERTICES];
    2297         IssmDouble  xyz_list[NUMVERTICES][3];
    2298         ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    2299         GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
    2300 
    2301         /*Get distance from list of segments and reset ls*/
    2302         for(int j=0;j<NUMVERTICES;j++){
    2303                 IssmDouble dmin = 1.e+50;
    2304                 for(int i=0;i<numsegments;i++){
    2305                         IssmDouble x = xyz_list[j][0];
    2306                         IssmDouble y = xyz_list[j][1];
    2307                         IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);
    2308 
    2309                         /*Segment has a length of 0*/
    2310                         if(l2==0.){
    2311                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    2312                                 if(d<dmin) dmin = d;
    2313                                 continue;
    2314                         }
    2315 
    2316                         /*Consider the line extending the segment, parameterized as v + t (w - v).
    2317                          *We find projection of point p onto the line.
    2318                          *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
    2319                         IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;
    2320                         if(t < 0.0){
    2321                                 // Beyond the 'v' end of the segment
    2322                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    2323                         }
    2324                         else if (t > 1.0){
    2325                                 // Beyond the 'w' end of the segment
    2326                                 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
    2327                         }
    2328                         else{
    2329                                 // Projection falls on the segment
    2330                                 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
    2331                                 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
    2332                                 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
    2333                         }
    2334 
    2335                         if(d<dmin) dmin = d;
    2336                 }
    2337 
    2338                 /*Update signed distance*/
    2339                 dmin = sqrt(dmin);
    2340                 if(dmin>10000) dmin=10000;
    2341                 if(ls[j]>0){
    2342                         ls[j] = dmin;
    2343                 }
    2344                 else{
    2345                         ls[j] = - dmin;
    2346                 }
    2347         }
    2348 
    2349         /*Update Levelset*/
    2350         this->inputs->AddInput(new PentaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));
    2351 }
    2352 /*}}}*/
    23532284void       Penta::SetClone(int* minranks){/*{{{*/
    23542285
     
    23742305
    23752306        /*Get out if this is not an element input*/
    2376         if(!IsInput(control_enum)) return;
     2307        if(!IsInputEnum(control_enum)) return;
    23772308
    23782309        /*Prepare index list*/
     
    24162347
    24172348        /*Get out if this is not an element input*/
    2418         if(!IsInput(control_enum)) return;
     2349        if(!IsInputEnum(control_enum)) return;
    24192350
    24202351        /*Prepare index list*/
     
    26622593        Penta* penta=this;
    26632594        for(;;){
    2664        
     2595
    26652596                IssmDouble  xyz_list[NUMVERTICES][3];
    26662597                /* Get node coordinates and dof list: */
     
    26712602                Jdet[1]=(xyz_list[4][2]-xyz_list[1][2])*0.5;
    26722603                Jdet[2]=(xyz_list[5][2]-xyz_list[2][2])*0.5;
    2673        
     2604
    26742605                /*Retrieve all inputs we will need*/
    26752606                Input* vx_input=inputs->GetInput(VxEnum);                                  _assert_(vx_input);
     
    26822613                Input* surface_input=inputs->GetInput(SurfaceEnum);                                                             _assert_(surface_input);
    26832614                Input* thickness_input=inputs->GetInput(ThicknessEnum);                                                 _assert_(thickness_input);
    2684                
     2615
    26852616                /* Start looping on the number of 2D vertices: */
    26862617                for(int ig=0;ig<3;ig++){
     
    27112642                        delete gauss;
    27122643                }
    2713                        
     2644
    27142645                /*Stop if we have reached the surface/base*/
    27152646                if(penta->IsOnSurface()) break;
    2716                
     2647
    27172648                /*get upper Penta*/
    27182649                penta=penta->GetUpperPenta();
     
    34703401}
    34713402/*}}}*/
    3472 void       Penta::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    3473         /*Compute portion of the element that is grounded*/
    3474 
    3475         int         normal_orientation=0;
    3476         IssmDouble  s1,s2;
    3477         IssmDouble  levelset[NUMVERTICES];
    3478         IssmDouble* xyz_zero = xNew<IssmDouble>(4*3);
    3479 
    3480         /*Recover parameters and values*/
    3481         GetInputListOnVertices(&levelset[0],levelsetenum);
    3482 
    3483         if(levelset[0]*levelset[1]>0.){ //Nodes 0 and 1 are similar, so points must be found on segment 0-2 and 1-2
    3484                 /*Portion of the segments*/
    3485                 s1=levelset[2]/(levelset[2]-levelset[1]);
    3486                 s2=levelset[2]/(levelset[2]-levelset[0]);
    3487 
    3488                 if(levelset[2]<0.) normal_orientation=1; //orientation of quadrangle at base and top, depending on distribution of levelsetfunction
    3489                 /*New point 1*/
    3490                 xyz_zero[3*normal_orientation+0]=xyz_list[2*3+0]+s1*(xyz_list[1*3+0]-xyz_list[2*3+0]);
    3491                 xyz_zero[3*normal_orientation+1]=xyz_list[2*3+1]+s1*(xyz_list[1*3+1]-xyz_list[2*3+1]);
    3492                 xyz_zero[3*normal_orientation+2]=xyz_list[2*3+2]+s1*(xyz_list[1*3+2]-xyz_list[2*3+2]);
    3493 
    3494                 /*New point 0*/
    3495                 xyz_zero[3*(1-normal_orientation)+0]=xyz_list[2*3+0]+s2*(xyz_list[0*3+0]-xyz_list[2*3+0]);
    3496                 xyz_zero[3*(1-normal_orientation)+1]=xyz_list[2*3+1]+s2*(xyz_list[0*3+1]-xyz_list[2*3+1]);
    3497                 xyz_zero[3*(1-normal_orientation)+2]=xyz_list[2*3+2]+s2*(xyz_list[0*3+2]-xyz_list[2*3+2]);
    3498 
    3499                 /*New point 3*/
    3500                 xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[5*3+0]+s1*(xyz_list[4*3+0]-xyz_list[5*3+0]);
    3501                 xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[5*3+1]+s1*(xyz_list[4*3+1]-xyz_list[5*3+1]);
    3502                 xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[5*3+2]+s1*(xyz_list[4*3+2]-xyz_list[5*3+2]);
    3503 
    3504                 /*New point 4*/
    3505                 xyz_zero[3*(2+normal_orientation)+0]=xyz_list[5*3+0]+s2*(xyz_list[3*3+0]-xyz_list[5*3+0]);
    3506                 xyz_zero[3*(2+normal_orientation)+1]=xyz_list[5*3+1]+s2*(xyz_list[3*3+1]-xyz_list[5*3+1]);
    3507                 xyz_zero[3*(2+normal_orientation)+2]=xyz_list[5*3+2]+s2*(xyz_list[3*3+2]-xyz_list[5*3+2]);
    3508         }
    3509         else if(levelset[1]*levelset[2]>0.){ //Nodes 1 and 2 are similar, so points must be found on segment 0-1 and 0-2
    3510                 /*Portion of the segments*/
    3511                 s1=levelset[0]/(levelset[0]-levelset[2]);
    3512                 s2=levelset[0]/(levelset[0]-levelset[1]);
    3513 
    3514                 if(levelset[0]<0.) normal_orientation=1;
    3515                 /*New point 1*/
    3516                 xyz_zero[3*normal_orientation+0]=xyz_list[0*3+0]+s1*(xyz_list[2*3+0]-xyz_list[0*3+0]);
    3517                 xyz_zero[3*normal_orientation+1]=xyz_list[0*3+1]+s1*(xyz_list[2*3+1]-xyz_list[0*3+1]);
    3518                 xyz_zero[3*normal_orientation+2]=xyz_list[0*3+2]+s1*(xyz_list[2*3+2]-xyz_list[0*3+2]);
    3519 
    3520                 /*New point 2*/
    3521                 xyz_zero[3*(1-normal_orientation)+0]=xyz_list[0*3+0]+s2*(xyz_list[1*3+0]-xyz_list[0*3+0]);
    3522                 xyz_zero[3*(1-normal_orientation)+1]=xyz_list[0*3+1]+s2*(xyz_list[1*3+1]-xyz_list[0*3+1]);
    3523                 xyz_zero[3*(1-normal_orientation)+2]=xyz_list[0*3+2]+s2*(xyz_list[1*3+2]-xyz_list[0*3+2]);
    3524 
    3525                 /*New point 3*/
    3526                 xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[3*3+0]+s1*(xyz_list[5*3+0]-xyz_list[3*3+0]);
    3527                 xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[3*3+1]+s1*(xyz_list[5*3+1]-xyz_list[3*3+1]);
    3528                 xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[3*3+2]+s1*(xyz_list[5*3+2]-xyz_list[3*3+2]);
    3529 
    3530                 /*New point 4*/
    3531                 xyz_zero[3*(2+normal_orientation)+0]=xyz_list[3*3+0]+s2*(xyz_list[4*3+0]-xyz_list[3*3+0]);
    3532                 xyz_zero[3*(2+normal_orientation)+1]=xyz_list[3*3+1]+s2*(xyz_list[4*3+1]-xyz_list[3*3+1]);
    3533                 xyz_zero[3*(2+normal_orientation)+2]=xyz_list[3*3+2]+s2*(xyz_list[4*3+2]-xyz_list[3*3+2]);
    3534         }
    3535         else if(levelset[0]*levelset[2]>0.){ //Nodes 0 and 2 are similar, so points must be found on segment 1-0 and 1-2
    3536                 /*Portion of the segments*/
    3537                 s1=levelset[1]/(levelset[1]-levelset[0]);
    3538                 s2=levelset[1]/(levelset[1]-levelset[2]);
    3539 
    3540                 if(levelset[1]<0.) normal_orientation=1;
    3541                 /*New point 0*/
    3542                 xyz_zero[3*normal_orientation+0]=xyz_list[1*3+0]+s1*(xyz_list[0*3+0]-xyz_list[1*3+0]);
    3543                 xyz_zero[3*normal_orientation+1]=xyz_list[1*3+1]+s1*(xyz_list[0*3+1]-xyz_list[1*3+1]);
    3544                 xyz_zero[3*normal_orientation+2]=xyz_list[1*3+2]+s1*(xyz_list[0*3+2]-xyz_list[1*3+2]);
    3545 
    3546                 /*New point 2*/
    3547                 xyz_zero[3*(1-normal_orientation)+0]=xyz_list[1*3+0]+s2*(xyz_list[2*3+0]-xyz_list[1*3+0]);
    3548                 xyz_zero[3*(1-normal_orientation)+1]=xyz_list[1*3+1]+s2*(xyz_list[2*3+1]-xyz_list[1*3+1]);
    3549                 xyz_zero[3*(1-normal_orientation)+2]=xyz_list[1*3+2]+s2*(xyz_list[2*3+2]-xyz_list[1*3+2]);
    3550 
    3551                 /*New point 3*/
    3552                 xyz_zero[3*(2+1-normal_orientation)+0]=xyz_list[4*3+0]+s1*(xyz_list[3*3+0]-xyz_list[4*3+0]);
    3553                 xyz_zero[3*(2+1-normal_orientation)+1]=xyz_list[4*3+1]+s1*(xyz_list[3*3+1]-xyz_list[4*3+1]);
    3554                 xyz_zero[3*(2+1-normal_orientation)+2]=xyz_list[4*3+2]+s1*(xyz_list[3*3+2]-xyz_list[4*3+2]);
    3555 
    3556                 /*New point 4*/
    3557                 xyz_zero[3*(2+normal_orientation)+0]=xyz_list[4*3+0]+s2*(xyz_list[5*3+0]-xyz_list[4*3+0]);
    3558                 xyz_zero[3*(2+normal_orientation)+1]=xyz_list[4*3+1]+s2*(xyz_list[5*3+1]-xyz_list[4*3+1]);
    3559                 xyz_zero[3*(2+normal_orientation)+2]=xyz_list[4*3+2]+s2*(xyz_list[5*3+2]-xyz_list[4*3+2]);
    3560         }
    3561         else if(levelset[0]==0. && levelset[1]==0.){ //front is on point 0 and 1
    3562                 xyz_zero[3*0+0]=xyz_list[0*3+0];
    3563                 xyz_zero[3*0+1]=xyz_list[0*3+1];
    3564                 xyz_zero[3*0+2]=xyz_list[0*3+2];
    3565 
    3566                 /*New point 2*/
    3567                 xyz_zero[3*1+0]=xyz_list[1*3+0];
    3568                 xyz_zero[3*1+1]=xyz_list[1*3+1];
    3569                 xyz_zero[3*1+2]=xyz_list[1*3+2];
    3570 
    3571                 /*New point 3*/
    3572                 xyz_zero[3*2+0]=xyz_list[4*3+0];
    3573                 xyz_zero[3*2+1]=xyz_list[4*3+1];
    3574                 xyz_zero[3*2+2]=xyz_list[4*3+2];
    3575 
    3576                 /*New point 4*/
    3577                 xyz_zero[3*3+0]=xyz_list[3*3+0];
    3578                 xyz_zero[3*3+1]=xyz_list[3*3+1];
    3579                 xyz_zero[3*3+2]=xyz_list[3*3+2];
    3580         }
    3581         else if(levelset[0]==0. && levelset[2]==0.){ //front is on point 0 and 1
    3582                 xyz_zero[3*0+0]=xyz_list[2*3+0];
    3583                 xyz_zero[3*0+1]=xyz_list[2*3+1];
    3584                 xyz_zero[3*0+2]=xyz_list[2*3+2];
    3585 
    3586                 /*New point 2*/
    3587                 xyz_zero[3*1+0]=xyz_list[0*3+0];
    3588                 xyz_zero[3*1+1]=xyz_list[0*3+1];
    3589                 xyz_zero[3*1+2]=xyz_list[0*3+2];
    3590 
    3591                 /*New point 3*/
    3592                 xyz_zero[3*2+0]=xyz_list[3*3+0];
    3593                 xyz_zero[3*2+1]=xyz_list[3*3+1];
    3594                 xyz_zero[3*2+2]=xyz_list[3*3+2];
    3595 
    3596                 /*New point 4*/
    3597                 xyz_zero[3*3+0]=xyz_list[5*3+0];
    3598                 xyz_zero[3*3+1]=xyz_list[5*3+1];
    3599                 xyz_zero[3*3+2]=xyz_list[5*3+2];
    3600         }
    3601         else if(levelset[1]==0. && levelset[2]==0.){ //front is on point 0 and 1
    3602                 xyz_zero[3*0+0]=xyz_list[1*3+0];
    3603                 xyz_zero[3*0+1]=xyz_list[1*3+1];
    3604                 xyz_zero[3*0+2]=xyz_list[1*3+2];
    3605 
    3606                 /*New point 2*/
    3607                 xyz_zero[3*1+0]=xyz_list[2*3+0];
    3608                 xyz_zero[3*1+1]=xyz_list[2*3+1];
    3609                 xyz_zero[3*1+2]=xyz_list[2*3+2];
    3610 
    3611                 /*New point 3*/
    3612                 xyz_zero[3*2+0]=xyz_list[5*3+0];
    3613                 xyz_zero[3*2+1]=xyz_list[5*3+1];
    3614                 xyz_zero[3*2+2]=xyz_list[5*3+2];
    3615 
    3616                 /*New point 4*/
    3617                 xyz_zero[3*3+0]=xyz_list[4*3+0];
    3618                 xyz_zero[3*3+1]=xyz_list[4*3+1];
    3619                 xyz_zero[3*3+2]=xyz_list[4*3+2];
    3620         }
    3621         else _error_("Case not covered");
    3622 
    3623         /*Assign output pointer*/
    3624         *pxyz_zero= xyz_zero;
    3625 }
    3626 /*}}}*/
    36273403
    36283404#ifdef _HAVE_GIAIVINS_
     
    36423418
    36433419        /*Check that name is an element input*/
    3644         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     3420        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    36453421
    36463422        switch(type){
     
    36773453
    36783454        /*Check that name is an element input*/
    3679         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     3455        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    36803456
    36813457        switch(type){
  • issm/trunk/src/c/classes/Elements/Penta.h

    r22758 r23189  
    6666                int            FiniteElement(void);
    6767                IssmDouble     FloatingArea(bool scaled);
    68                 void           FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating);
     68                void           FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure);
    6969                IssmDouble     GetArea3D(void){_error_("not implemented yet!");};
    7070                IssmDouble     GetAreaSpherical(void){_error_("not implemented yet!");};
     
    8686                Penta*         GetLowerPenta(void);
    8787                Penta*         GetUpperPenta(void);
    88                 void           GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,bool onsid);
    89                 void           GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset,bool onsid);
     88                void           GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data);
     89                void           GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset);
    9090                void           GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
    9191                void           GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
     
    143143                void                            PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};
    144144                void                            PicoUpdateBox(int loopboxid){_error_("not implemented yet");};
     145                void                            PicoComputeBasalMelt(void){_error_("not implemented yet");};
    145146                void           PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding);
    146147                int            PressureInterpolation();
     
    148149                void           ResetFSBasalBoundaryCondition(void);
    149150                void           ResetHooks();
    150                 void           ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);
    151151                void             SetClone(int* minranks);
    152152                void           SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index,int offset, int N,int M);
     
    178178                void           VerticalSegmentIndicesBase(int** pindices,int* pnumseg);
    179179                void           ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
    180                 void           ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
    181180
    182181                #ifdef _HAVE_DAKOTA_
     
    198197                void    SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");};
    199198                void    SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");};
    200                 void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea){_error_("not implemented yet!");};
     199                void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");};
    201200                #endif
    202201
  • issm/trunk/src/c/classes/Elements/Seg.cpp

    r22758 r23189  
    104104        return seg;
    105105
    106 
    107106}
    108107/*}}}*/
     
    141140/*}}}*/
    142141void       Seg::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    143        
     142
    144143        /* Intermediaries */
    145144        int nrfrontnodes,index;
  • issm/trunk/src/c/classes/Elements/Seg.h

    r22758 r23189  
    7373                int         GetNumberOfNodes(int enum_type){_error_("not implemented yet");};
    7474                int         GetNumberOfVertices(void);
    75                 void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset,bool onsid){_error_("not implemented yet");};
    76                 void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,bool onsid){_error_("not implemented yet");};
     75                void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset){_error_("not implemented yet");};
     76                void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data){_error_("not implemented yet");};
    7777                void        GetVerticesCoordinates(IssmDouble** pxyz_list);
    7878                void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list){_error_("not implemented yet");};
     
    132132                void        PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};
    133133                void                    PicoUpdateBox(int loopboxid){_error_("not implemented yet");};
     134                void                    PicoComputeBasalMelt(void){_error_("not implemented yet");};
    134135                void        PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
    135136                int         PressureInterpolation(void){_error_("not implemented yet");};
     
    164165                void        VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");};
    165166                void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");};
    166                 void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");};
    167167                IssmDouble     GetArea3D(void){_error_("not implemented yet!");};
    168168                IssmDouble     GetAreaSpherical(void){_error_("not implemented yet!");};
     
    179179                void    SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");};
    180180                void    SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");};
    181                 void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea){_error_("not implemented yet!");};
     181                void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");};
    182182                IssmDouble    OceanArea(void){_error_("not implemented yet!");};
    183183                IssmDouble    OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");};
  • issm/trunk/src/c/classes/Elements/Tetra.cpp

    r22758 r23189  
    501501
    502502        /*Add input to the element: */
    503         this->inputs->AddInput(new TetraInput(enum_type,values,P1Enum));
     503        this->inputs->AddInput(new TetraInput(enum_type,values,this->element_type));
    504504
    505505        /*Free ressources:*/
     
    10291029}
    10301030/*}}}*/
    1031 void     Tetra::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    1032         /*Compute portion of the element that is grounded*/
    1033 
    1034         IssmDouble  levelset[NUMVERTICES];
    1035         IssmDouble* xyz_zero = xNew<IssmDouble>(3*3);
    1036 
    1037         /*Recover parameters and values*/
    1038         GetInputListOnVertices(&levelset[0],levelsetenum);
    1039 
    1040         if(levelset[0]==0. && levelset[1]==0. && levelset[2]==0.){
    1041                 xyz_zero[3*0+0]=xyz_list[0*3+0];
    1042                 xyz_zero[3*0+1]=xyz_list[0*3+1];
    1043                 xyz_zero[3*0+2]=xyz_list[0*3+2];
    1044 
    1045                 /*New point 2*/
    1046                 xyz_zero[3*1+0]=xyz_list[1*3+0];
    1047                 xyz_zero[3*1+1]=xyz_list[1*3+1];
    1048                 xyz_zero[3*1+2]=xyz_list[1*3+2];
    1049 
    1050                 /*New point 3*/
    1051                 xyz_zero[3*2+0]=xyz_list[2*3+0];
    1052                 xyz_zero[3*2+1]=xyz_list[2*3+1];
    1053                 xyz_zero[3*2+2]=xyz_list[2*3+2];
    1054         }
    1055         else if(levelset[0]==0. && levelset[1]==0. && levelset[3]==0.){
    1056                 xyz_zero[3*0+0]=xyz_list[0*3+0];
    1057                 xyz_zero[3*0+1]=xyz_list[0*3+1];
    1058                 xyz_zero[3*0+2]=xyz_list[0*3+2];
    1059 
    1060                 /*New point 2*/
    1061                 xyz_zero[3*1+0]=xyz_list[1*3+0];
    1062                 xyz_zero[3*1+1]=xyz_list[1*3+1];
    1063                 xyz_zero[3*1+2]=xyz_list[1*3+2];
    1064 
    1065                 /*New point 3*/
    1066                 xyz_zero[3*2+0]=xyz_list[3*3+0];
    1067                 xyz_zero[3*2+1]=xyz_list[3*3+1];
    1068                 xyz_zero[3*2+2]=xyz_list[3*3+2];
    1069         }
    1070         else if(levelset[1]==0. && levelset[2]==0. && levelset[3]==0.){
    1071                 xyz_zero[3*0+0]=xyz_list[1*3+0];
    1072                 xyz_zero[3*0+1]=xyz_list[1*3+1];
    1073                 xyz_zero[3*0+2]=xyz_list[1*3+2];
    1074 
    1075                 /*New point 2*/
    1076                 xyz_zero[3*1+0]=xyz_list[2*3+0];
    1077                 xyz_zero[3*1+1]=xyz_list[2*3+1];
    1078                 xyz_zero[3*1+2]=xyz_list[2*3+2];
    1079 
    1080                 /*New point 3*/
    1081                 xyz_zero[3*2+0]=xyz_list[3*3+0];
    1082                 xyz_zero[3*2+1]=xyz_list[3*3+1];
    1083                 xyz_zero[3*2+2]=xyz_list[3*3+2];
    1084         }
    1085         else if(levelset[2]==0. && levelset[0]==0. && levelset[3]==0.){
    1086                 xyz_zero[3*0+0]=xyz_list[2*3+0];
    1087                 xyz_zero[3*0+1]=xyz_list[2*3+1];
    1088                 xyz_zero[3*0+2]=xyz_list[2*3+2];
    1089 
    1090                 /*New point 2*/
    1091                 xyz_zero[3*1+0]=xyz_list[0*3+0];
    1092                 xyz_zero[3*1+1]=xyz_list[0*3+1];
    1093                 xyz_zero[3*1+2]=xyz_list[0*3+2];
    1094 
    1095                 /*New point 3*/
    1096                 xyz_zero[3*2+0]=xyz_list[3*3+0];
    1097                 xyz_zero[3*2+1]=xyz_list[3*3+1];
    1098                 xyz_zero[3*2+2]=xyz_list[3*3+2];
    1099         }
    1100         else _error_("Case not covered");
    1101 
    1102         /*Assign output pointer*/
    1103         *pxyz_zero= xyz_zero;
    1104 }
    1105 /*}}}*/
  • issm/trunk/src/c/classes/Elements/Tetra.h

    r22758 r23189  
    7979                int         GetNumberOfNodes(int enum_type){_error_("not implemented yet");};
    8080                int         GetNumberOfVertices(void);
    81                 void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset,bool onsid){_error_("not implemented yet");};
    82                 void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,bool onsid){_error_("not implemented yet");};
     81                void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset){_error_("not implemented yet");};
     82                void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data){_error_("not implemented yet");};
    8383                void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
    8484                void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
     
    140140                void                    PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};       
    141141                void                    PicoUpdateBox(int loopboxid){_error_("not implemented yet");};
     142                void                    PicoComputeBasalMelt(void){_error_("not implemented yet");};
    142143                void        PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");};
    143144                int         PressureInterpolation(void);
     
    173174                void        VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");};
    174175                void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
    175                 void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
    176176
    177177#ifdef _HAVE_GIAIVINS_
     
    186186                void    SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");};
    187187                void    SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea){_error_("not implemented yet!");};
    188                 void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea){_error_("not implemented yet!");};
     188                void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){_error_("not implemented yet!");};
    189189                IssmDouble    OceanArea(void){_error_("not implemented yet!");};
    190190                IssmDouble    OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");};
  • issm/trunk/src/c/classes/Elements/Tria.cpp

    r22822 r23189  
    106106        }
    107107        else tria->nodes = NULL;
    108        
     108
    109109        tria->vertices = (Vertex**)this->hvertices->deliverp();
    110110        tria->material = (Material*)this->hmaterial->delivers();
     
    115115/*}}}*/
    116116void Tria::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
    117        
     117
    118118        MARSHALLING_ENUM(TriaEnum);
    119        
     119
    120120        /*Call parent classes: */
    121121        ElementHook::Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     
    135135        /*Call inputs method*/
    136136        _assert_(this->inputs);
    137        
     137
    138138        int domaintype;
    139139        parameters->FindParam(&domaintype,DomainTypeEnum);
     
    185185
    186186        int        tria_vertex_ids[3];
    187        
     187
    188188        for(int k=0;k<3;k++){
    189189                tria_vertex_ids[k]=reCast<int>(iomodel->elements[3*this->Sid()+k]); //ids for vertices are in the elements array from Matlab
     
    328328/*}}}*/
    329329void       Tria::CalvingCrevasseDepth(){/*{{{*/
    330        
     330
    331331        IssmDouble  xyz_list[NUMVERTICES][3];
    332332        IssmDouble  calvingrate[NUMVERTICES];
     
    340340        /* Get node coordinates and dof list: */
    341341        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    342                
     342
    343343        /*Get the critical fraction of thickness surface and basal crevasses penetrate for calving onset*/
    344344        this->parameters->FindParam(&critical_fraction,CalvingCrevasseDepthEnum);
    345                
     345
    346346        IssmDouble rho_ice        = this->GetMaterialParameter(MaterialsRhoIceEnum);
    347347        IssmDouble rho_seawater   = this->GetMaterialParameter(MaterialsRhoSeawaterEnum);
     
    361361        Input*   s_xy_input              = inputs->GetInput(DeviatoricStressxyEnum);     _assert_(s_xy_input);
    362362        Input*   s_yy_input              = inputs->GetInput(DeviatoricStressyyEnum);     _assert_(s_yy_input);
    363        
     363
    364364        /*Loop over all elements of this partition*/
    365365        GaussTria* gauss=new GaussTria();
    366366        for (int iv=0;iv<NUMVERTICES;iv++){
    367367                gauss->GaussVertex(iv);
    368        
     368
    369369                H_input->GetInputValue(&thickness,gauss);
    370370                bed_input->GetInputValue(&bed,gauss);
     
    378378                s_xy_input->GetInputValue(&s_xy,gauss);
    379379                s_yy_input->GetInputValue(&s_yy,gauss);
    380                
     380
    381381                vel=sqrt(vx*vx+vy*vy)+1.e-14;
    382382
     
    384384                s2=(s_xx+s_yy)/2.-sqrt(pow((s_xx-s_yy)/2.,2)+pow(s_xy,2));
    385385                if(fabs(s2)>fabs(s1)){stmp=s2; s2=s1; s1=stmp;}
    386                
     386
    387387                Ho = thickness - (rho_seawater/rho_ice) * (-bed);
    388388                if(Ho<0.)  Ho=0.;
     
    399399                //      water_height = surface_crevasse[iv];
    400400                //}
    401                
     401
    402402                /*basal crevasse*/
    403403                //basal_crevasse[iv] = (rho_ice/(rho_seawater-rho_ice)) * (rheology_B * strainparallel * pow(straineffective,((1/rheology_n)-1)) / (rho_ice*constant_g) - Ho);
     
    405405                if (basal_crevasse[iv]<0.) basal_crevasse[iv]=0.;
    406406                if (bed>0.) basal_crevasse[iv] = 0.;
    407        
     407
    408408                H_surf = surface_crevasse[iv] + (rho_freshwater/rho_ice)*water_height - critical_fraction*float_depth;
    409409                H_surfbasal = (surface_crevasse[iv] + (rho_freshwater/rho_ice)*water_height + basal_crevasse[iv])-(critical_fraction*thickness);
    410                
     410
    411411                crevasse_depth[iv] = max(H_surf,H_surfbasal);
    412412        }
    413        
     413
    414414        this->inputs->AddInput(new TriaInput(SurfaceCrevasseEnum,&surface_crevasse[0],P1Enum));
    415415        this->inputs->AddInput(new TriaInput(BasalCrevasseEnum,&basal_crevasse[0],P1Enum));
     
    461461                else
    462462                        calvingrate[iv]=0.;
    463                
     463
    464464                calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14);
    465465                calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14);
     
    562562        IssmDouble  vorticity_xy[NUMVERTICES];
    563563        GaussTria*  gauss=NULL;
    564        
     564
    565565        /* Get node coordinates and dof list: */
    566566        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     
    569569        Input* vx_input=this->GetInput(EsaXmotionEnum); _assert_(vx_input);
    570570        Input* vy_input=this->GetInput(EsaYmotionEnum); _assert_(vy_input);
    571        
     571
    572572        /* Start looping on the number of vertices: */
    573573        gauss=new GaussTria();
     
    753753        if (input->ObjectEnum()!=ControlInputEnum) _error_("Input " << EnumToStringx(enum_type) << " is not a ControlInput");
    754754
    755         GradientIndexing(&gradidlist[0],control_index,true);
     755        GradientIndexing(&gradidlist[0],control_index);
    756756
    757757        for(int n=0;n<N;n++){
     
    773773        }
    774774
    775                
    776775}/*}}}*/
    777776void       Tria::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){/*{{{*/
     
    823822
    824823}/*}}}*/
    825 void       Tria::CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum){/*{{{*/
    826 
    827         /*Intermediaries*/
    828         IssmDouble d,xn,yn;
     824void       Tria::CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum){/*{{{*/
    829825
    830826        /*Get current field and vertex coordinates*/
    831         IssmDouble ls[NUMVERTICES];
    832         IssmDouble  xyz_list[NUMVERTICES][3];
    833         ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     827        IssmDouble ls[NUMVERTICES],distance;
    834828        GetInputListOnVertices(&ls[0],distanceenum);
    835829
    836830        /*Get distance from list of segments and reset ls*/
    837831        for(int j=0;j<NUMVERTICES;j++){
    838                 IssmDouble dmin = 1.e+50;
    839                 for(int i=0;i<numsegments;i++){
    840                         IssmDouble x = xyz_list[j][0];
    841                         IssmDouble y = xyz_list[j][1];
    842                         IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);
    843 
    844                         /*Segment has a length of 0*/
    845                         if(l2==0.){
    846                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    847                                 if(d<dmin) dmin = d;
    848                                 continue;
    849                         }
    850 
    851                         /*Consider the line extending the segment, parameterized as v + t (w - v).
    852                          *We find projection of point p onto the line.
    853                          *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
    854                         IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;
    855                         if(t < 0.0){
    856                                 // Beyond the 'v' end of the segment
    857                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    858                         }
    859                         else if (t > 1.0){
    860                                 // Beyond the 'w' end of the segment
    861                                 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
    862                         }
    863                         else{
    864                                 // Projection falls on the segment
    865                                 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
    866                                 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
    867                                 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
    868                         }
    869 
    870                         if(d<dmin) dmin = d;
    871                 }
    872 
    873                 /*Update signed distance*/
    874                 dmin = sqrt(dmin);
    875                 // if(dmin>10000) dmin=10000;
     832                distance=distances[this->vertices[j]->Lid()];
     833                if(xIsNan<IssmDouble>(distance)) _error_("NaN found in vector");
     834                if(xIsInf<IssmDouble>(distance)) _error_("Inf found in vector");
     835
     836                /*FIXME: do we really need this?*/
     837                if(distanceenum==MaskIceLevelsetEnum) if(distance>10000) distance=10000;
    876838                if(ls[j]>0){
    877                         ls[j] = dmin;
     839                        ls[j] = distance;
    878840                }
    879841                else{
    880                         ls[j] = - dmin;
     842                        ls[j] = - distance;
    881843                }
    882844        }
     
    10411003}
    10421004/*}}}*/
    1043 void       Tria::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){/*{{{*/
     1005void       Tria::FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure){/*{{{*/
    10441006
    10451007        if(!IsOnBase()) return;
     
    10491011
    10501012        if(approximation==HOApproximationEnum || approximation==SSAApproximationEnum || approximation==SSAHOApproximationEnum){
    1051                 for(int i=0;i<NUMVERTICES;i++){
    1052                         vertexgrounded->SetValue(vertices[i]->Pid(),+9999.,INS_VAL);
    1053                         vertexfloating->SetValue(vertices[i]->Pid(),+9999.,INS_VAL);
    1054                 }
    1055         }
    1056         else{
    1057                 /*Intermediaries*/
    1058                 IssmDouble* xyz_list = NULL;
    1059                 IssmDouble* xyz_list_base = NULL;
    1060                 IssmDouble  pressure,water_pressure,sigma_nn,viscosity,bed,base;
    1061                 IssmDouble  bed_normal[2];
    1062                 IssmDouble  epsilon[3]; /* epsilon=[exx,eyy,exy];*/
    1063                 IssmDouble  surface=0,value=0;
    1064                 bool grounded;
    1065 
    1066                 /* Get node coordinates and dof list: */
    1067                 GetVerticesCoordinates(&xyz_list);
    1068                 GetVerticesCoordinatesBase(&xyz_list_base);
    1069 
    1070                 /*Retrieve all inputs we will be needing: */
    1071                 Input* pressure_input = inputs->GetInput(PressureEnum); _assert_(pressure_input);
    1072                 Input* base_input     = inputs->GetInput(BaseEnum);     _assert_(base_input);
    1073                 Input* bed_input      = inputs->GetInput(BedEnum);      _assert_(bed_input);
    1074                 Input* vx_input       = inputs->GetInput(VxEnum);       _assert_(vx_input);
    1075                 Input* vy_input       = inputs->GetInput(VyEnum);       _assert_(vy_input);
    1076 
    1077                 /*Create gauss point in the middle of the basal edge*/
    1078                 Gauss* gauss=NewGaussBase(1);
    1079                 gauss->GaussPoint(0);
    1080 
    1081                 if(!IsFloating()){
    1082                         /*Check for basal force only if grounded and touching GL*/
    1083                         //              if(this->inputs->Min(MaskGroundediceLevelsetEnum)==0.){
    1084                         this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
    1085                         this->material->ViscosityFS(&viscosity,2,xyz_list,gauss,vx_input,vy_input,NULL);
    1086                         pressure_input->GetInputValue(&pressure, gauss);
    1087                         base_input->GetInputValue(&base, gauss);
    1088 
    1089                         /*Compute Stress*/
    1090                         IssmDouble sigma_xx=2.*viscosity*epsilon[0]-pressure;
    1091                         IssmDouble sigma_yy=2.*viscosity*epsilon[1]-pressure;
    1092                         IssmDouble sigma_xy=2.*viscosity*epsilon[2];
    1093 
    1094                         /*Get normal vector to the bed */
    1095                         NormalBase(&bed_normal[0],xyz_list_base);
    1096 
    1097                         /*basalforce*/
    1098                         sigma_nn = sigma_xx*bed_normal[0]*bed_normal[0] + sigma_yy*bed_normal[1]*bed_normal[1] + 2.*sigma_xy*bed_normal[0]*bed_normal[1];
    1099 
    1100                         /*Compute water pressure*/
    1101                         IssmDouble rho_ice   = matpar->GetMaterialParameter(MaterialsRhoIceEnum);
    1102                         IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    1103                         IssmDouble gravity   = matpar->GetMaterialParameter(ConstantsGEnum);
    1104                         water_pressure=gravity*rho_water*base;
    1105 
    1106                         /*Compare basal stress to water pressure and determine whether it should ground*/
    1107                         if (sigma_nn<water_pressure) grounded=true;
    1108                         else                         grounded=false;
    1109                 }
    1110                 else{
    1111                         /*Check for basal elevation if floating*/
    1112                         base_input->GetInputValue(&base, gauss);
    1113                         bed_input->GetInputValue(&bed, gauss);
    1114                         if(base<bed) grounded=true;
    1115                         else         grounded=false;
    1116                 }
    1117                 for(int i=0;i<NUMVERTICES;i++){
    1118                         if(grounded) vertexgrounded->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
    1119                         else         vertexfloating->SetValue(vertices[i]->Pid(),+1.,INS_VAL);
    1120                 }
    1121 
    1122                 /*clean up*/
    1123                 delete gauss;
    1124                 xDelete<IssmDouble>(xyz_list);
    1125                 xDelete<IssmDouble>(xyz_list_base);
    1126         }
     1013                _error_(" contact contiditon only works for FS elements");
     1014        }
     1015        /*Intermediaries*/
     1016        IssmDouble* xyz_list = NULL;
     1017        IssmDouble  bed_normal[2],base[NUMVERTICES],bed[NUMVERTICES],surface[NUMVERTICES],phi[NUMVERTICES];
     1018        IssmDouble  water_pressure[NUMVERTICES],pressureice[NUMVERTICES],pressure[NUMVERTICES];
     1019        IssmDouble  sigmaxx[NUMVERTICES],sigmayy[NUMVERTICES],sigmaxy[NUMVERTICES],sigma_nn[NUMVERTICES];
     1020        IssmDouble  viscosity,epsilon[NUMVERTICES];
     1021        GetInputListOnVertices(&base[0],BaseEnum);
     1022        GetInputListOnVertices(&bed[0],BedEnum);
     1023        GetInputListOnVertices(&surface[0],SurfaceEnum);
     1024        GetInputListOnVertices(&pressure[0],PressureEnum);
     1025        GetInputListOnVertices(&phi[0],MaskGroundediceLevelsetEnum);
     1026        IssmDouble rho_ice   = matpar->GetMaterialParameter(MaterialsRhoIceEnum);
     1027        IssmDouble rho_water = matpar->GetMaterialParameter(MaterialsRhoSeawaterEnum);
     1028        IssmDouble gravity   = matpar->GetMaterialParameter(ConstantsGEnum);
     1029
     1030        /* Get node coordinates and dof list: */
     1031        GetVerticesCoordinates(&xyz_list);
     1032        /*Retrieve all inputs we will be needing: */
     1033        Input* vx_input       = inputs->GetInput(VxEnum);       _assert_(vx_input);
     1034        Input* vy_input       = inputs->GetInput(VyEnum);       _assert_(vy_input);
     1035
     1036        /*1. Recover stresses at the base*/
     1037        GaussTria* gauss=new GaussTria();
     1038        for (int iv=0;iv<NUMVERTICES;iv++){
     1039                gauss->GaussVertex(iv);
     1040
     1041                /*Compute strain rate viscosity and pressure: */
     1042                this->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input);
     1043                this->material->ViscosityFS(&viscosity,2,xyz_list,gauss,vx_input,vy_input,NULL);
     1044                /*FIXME: this is for Hongju only*/
     1045        //      pressureice[iv]=gravity*rho_ice*(surface[iv]-base[iv]);
     1046        //      if (pressure[iv]/pressureice[iv]>1) pressure[iv]=pressureice[iv];
     1047
     1048                /*Compute Stress*/
     1049                sigmaxx[iv]=2*viscosity*epsilon[0]-pressure[iv];
     1050                sigmayy[iv]=2*viscosity*epsilon[1]-pressure[iv];
     1051                sigmaxy[iv]=2*viscosity*epsilon[2];
     1052        }
     1053
     1054        /*2. compute contact condition*/
     1055        for(int i=0;i<NUMVERTICES;i++){
     1056                /*If was grounded*/
     1057                if (phi[i]>=0.){
     1058                        NormalBase(&bed_normal[0],xyz_list);
     1059                        sigma_nn[i]=-1*(sigmaxx[i]*bed_normal[0]*bed_normal[0] + sigmayy[i]*bed_normal[1]*bed_normal[1]+2*sigmaxy[i]*bed_normal[0]*bed_normal[1]);
     1060                        water_pressure[i]=-gravity*rho_water*base[i];
     1061                        vertex_sigmann->SetValue(vertices[i]->Pid(),sigma_nn[i],ADD_VAL);
     1062                        vertex_waterpressure->SetValue(vertices[i]->Pid(),water_pressure[i],ADD_VAL);
     1063                }
     1064                /*If was floating*/
     1065                else{   
     1066                        /*Tricky part:
     1067                         * 1. if base is now touching, we put 1 for sigma_nn and leave water pressure at 0 so that the rest of the module will reground this vertex
     1068                         * 2. if base is still above bed, water pressure is set as 1, sigma_nn is left as 0, so the GL module will keep it afloat*/
     1069                        if(base[i]<bed[i]) vertex_sigmann->SetValue(vertices[i]->Pid(),+1.,ADD_VAL);
     1070                        vertex_waterpressure->SetValue(vertices[i]->Pid(),+1.,ADD_VAL);
     1071                }
     1072        }
     1073
     1074        /*clean up*/
     1075        delete gauss;
     1076        xDelete<IssmDouble>(xyz_list);
    11271077}
    11281078/*}}}*/
     
    13541304
    13551305        }
    1356         else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum){
     1306        else if(domaintype==Domain2DhorizontalEnum || domaintype==Domain3DEnum || domaintype==Domain3DsurfaceEnum){
    13571307                /*Check that not all nodes are grounded or floating*/
    13581308                if(gl[0]>0 && gl[1]>0 && gl[2]>0){ // All grounded
     
    14291379
    14301380                        /*Compute fraction of grounded element*/
    1431                         GetJacobianDeterminant(&area_init, xyz_list,NULL);
    1432                         GetJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL);
     1381                        if(domaintype==Domain3DsurfaceEnum){ //hack, need to be implemented in a Tria 3D
     1382                                GetJacobianDeterminant3D(&area_init, xyz_list,NULL);
     1383                                GetJacobianDeterminant3D(&area_grounded, &xyz_bis[0][0],NULL);
     1384                        }
     1385                        else{
     1386                                GetJacobianDeterminant(&area_init, xyz_list,NULL);
     1387                                GetJacobianDeterminant(&area_grounded, &xyz_bis[0][0],NULL);
     1388                        }
    14331389                        if(mainlyfloating==true) area_grounded=area_init-area_grounded;
    14341390                        phi=area_grounded/area_init;
     
    14431399/*}}}*/
    14441400void       Tria::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    1445        
     1401
    14461402        /* Intermediaries */
    14471403        int i, dir,nrfrontnodes;
     
    15321488}/*}}}*/
    15331489void       Tria::GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level){/*{{{*/
    1534        
     1490
    15351491        /* GetLevelsetIntersection computes:
    15361492         * 1. indices of element, sorted in [iceverts, noiceverts] in counterclockwise fashion,
     
    16081564/*}}}*/
    16091565void       Tria::GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* gl){/*{{{*/
    1610        
     1566
    16111567        /*Computeportion of the element that has a positive levelset*/
    16121568
     
    16891645}
    16901646/*}}}*/
    1691 void       Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,bool onsid){/*{{{*/
     1647void       Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/
    16921648
    16931649        int vertexidlist[NUMVERTICES];
     
    16951651
    16961652        /*Get out if this is not an element input*/
    1697         if(!IsInput(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
     1653        if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
    16981654
    16991655        /*Prepare index list*/
    1700         GradientIndexing(&vertexidlist[0],control_index,onsid);
     1656        GradientIndexing(&vertexidlist[0],control_index);
    17011657
    17021658        /*Get input (either in element or material)*/
     
    17111667}
    17121668/*}}}*/
    1713 void       Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset, bool onsid){/*{{{*/
     1669void       Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data,int offset){/*{{{*/
    17141670
    17151671        int* idlist = NULL;
     
    17181674
    17191675        /*Get out if this is not an element input*/
    1720         if(!IsInput(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
     1676        if(!IsInputEnum(control_enum)) _error_("Enum "<<EnumToStringx(control_enum)<<" is not in IsInput");
    17211677        Input* input=(Input*)this->inputs->GetInput(control_enum);   _assert_(input);
    17221678
    17231679        parameters->FindParam(&M,NULL,ControlInputSizeMEnum);
    1724        
     1680
    17251681        /*Cast to Controlinput*/
    17261682        if(input->ObjectEnum()!=ControlInputEnum) _error_("input " << EnumToStringx(control_enum) << " is not a ControlInput");
    17271683        ControlInput* controlinput = xDynamicCast<ControlInput*>(input);
    1728        
     1684
    17291685        if(strcmp(data,"value")==0){
    17301686                input  = controlinput->values;
     
    17431699        }
    17441700        /*Check what input we are dealing with*/
    1745        
     1701
    17461702        switch(input->ObjectEnum()){
    17471703                case TriaInputEnum:
     
    17531709                                idlist = xNew<int>(NUMVERTICES);
    17541710                                values = xNew<IssmDouble>(NUMVERTICES);
    1755                                 GradientIndexing(&idlist[0],control_index,true);
     1711                                GradientIndexing(&idlist[0],control_index);
    17561712                                for(int i=0;i<NUMVERTICES;i++){
    17571713                                        values[i] = triainput->values[i];
     
    17601716                                break;
    17611717                          }
    1762                        
     1718
    17631719                case TransientInputEnum:
    17641720                                {
     
    19051861
    19061862        if(!IsIceInElement())return 0.;
     1863        //if(!(this->inputs->Max(MaskIceLevelsetEnum)<0)) return 0;
    19071864
    19081865        int domaintype;
     
    20241981        base_input->GetInputAverage(&bed);
    20251982        bed_input->GetInputAverage(&bathymetry);
    2026        
     1983
    20271984        /*Return: */
    20281985        return base*(surface-bed+min(rho_water/rho_ice*bathymetry,0.));
     
    20682025        if(control_analysis && ad_analysis) iomodel->FindConstant(&num_control_type,"md.autodiff.num_independent_objects");
    20692026        if(control_analysis && ad_analysis) iomodel->FindConstant(&num_responses,"md.autodiff.num_dependent_objects");
    2070 
    2071 
    20722027
    20732028        /*Recover vertices ids needed to initialize inputs*/
     
    22212176
    22222177        /*Add input to the element: */
    2223         this->inputs->AddInput(new TriaInput(enum_type,values,P1Enum));
     2178        this->inputs->AddInput(new TriaInput(enum_type,values,this->element_type));
    22242179
    22252180        /*Free ressources:*/
     
    22312186
    22322187        /*Check that name is an element input*/
    2233         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     2188        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    22342189
    22352190        int         numnodes;
     
    22382193
    22392194        switch(type){
    2240         case VertexPIdEnum:
    2241                 values = xNew<IssmDouble>(NUMVERTICES);
    2242                 for(int i=0;i<NUMVERTICES;i++){
    2243                         values[i]=vector[this->vertices[i]->Pid()];
    2244                 }
    2245                 /*update input*/
    2246                 this->inputs->AddInput(new TriaInput(name,values,P1Enum));
    2247                 break;
    2248 
    2249         case VertexSIdEnum:
    2250                 values = xNew<IssmDouble>(NUMVERTICES);
    2251                 for(int i=0;i<NUMVERTICES;i++){
    2252                         values[i]=vector[this->vertices[i]->Sid()];
    2253                 }
    2254                 /*update input*/
    2255                 this->inputs->AddInput(new TriaInput(name,values,P1Enum));
    2256                 break;
    2257 
    2258         case NodesEnum:
    2259                 /*Get number of nodes and dof list: */
    2260                 numnodes = this->NumberofNodes(this->element_type);
    2261                 values   = xNew<IssmDouble>(numnodes);
    2262                 GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    2263 
    2264                 for(int i=0;i<numnodes;i++){
    2265                         values[i]=vector[doflist[i]];
    2266                         if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
    2267                         if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
    2268                 }
    2269                 this->inputs->AddInput(new TriaInput(name,values,this->element_type));
    2270                 break;
    2271 
    2272         case NodeSIdEnum:
    2273                 /*Get number of nodes and dof list: */
    2274                 numnodes = this->NumberofNodes(this->element_type);
    2275                 values   = xNew<IssmDouble>(numnodes);
    2276 
    2277                 for(int i=0;i<numnodes;i++){
    2278                         values[i]=vector[nodes[i]->Sid()];
    2279                         if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
    2280                         if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
    2281                 }
    2282                 this->inputs->AddInput(new TriaInput(name,values,this->element_type));
    2283                 break;
    2284 
    2285         default:
    2286                 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
     2195                case VertexLIdEnum:
     2196                        values = xNew<IssmDouble>(NUMVERTICES);
     2197                        for(int i=0;i<NUMVERTICES;i++){
     2198                                values[i]=vector[this->vertices[i]->Lid()];
     2199                                if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
     2200                                if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
     2201                        }
     2202                        /*update input*/
     2203                        this->inputs->AddInput(new TriaInput(name,values,P1Enum));
     2204                        break;
     2205
     2206                case VertexPIdEnum:
     2207                        values = xNew<IssmDouble>(NUMVERTICES);
     2208                        for(int i=0;i<NUMVERTICES;i++){
     2209                                values[i]=vector[this->vertices[i]->Pid()];
     2210                                if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
     2211                                if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
     2212                        }
     2213                        /*update input*/
     2214                        this->inputs->AddInput(new TriaInput(name,values,P1Enum));
     2215                        break;
     2216
     2217                case VertexSIdEnum:
     2218                        values = xNew<IssmDouble>(NUMVERTICES);
     2219                        for(int i=0;i<NUMVERTICES;i++){
     2220                                values[i]=vector[this->vertices[i]->Sid()];
     2221                                if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
     2222                                if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
     2223                        }
     2224                        /*update input*/
     2225                        this->inputs->AddInput(new TriaInput(name,values,P1Enum));
     2226                        break;
     2227
     2228                case NodesEnum:
     2229                        /*Get number of nodes and dof list: */
     2230                        numnodes = this->NumberofNodes(this->element_type);
     2231                        values   = xNew<IssmDouble>(numnodes);
     2232                        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     2233
     2234                        for(int i=0;i<numnodes;i++){
     2235                                values[i]=vector[doflist[i]];
     2236                                if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
     2237                                if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
     2238                        }
     2239                        this->inputs->AddInput(new TriaInput(name,values,this->element_type));
     2240                        break;
     2241
     2242                case NodeSIdEnum:
     2243                        /*Get number of nodes and dof list: */
     2244                        numnodes = this->NumberofNodes(this->element_type);
     2245                        values   = xNew<IssmDouble>(numnodes);
     2246
     2247                        for(int i=0;i<numnodes;i++){
     2248                                values[i]=vector[nodes[i]->Sid()];
     2249                                if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in vector");
     2250                                if(xIsInf<IssmDouble>(values[i])) _error_("Inf found in vector");
     2251                        }
     2252                        this->inputs->AddInput(new TriaInput(name,values,this->element_type));
     2253                        break;
     2254
     2255                default:
     2256                        _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
    22872257        }
    22882258
     
    24202390/*}}}*/
    24212391IssmDouble Tria::Masscon(IssmDouble* levelset){ /*{{{*/
    2422 
    24232392
    24242393        /*intermediary: */
     
    24342403        IssmDouble  fraction1,fraction2;
    24352404        bool        mainlynegative=true;
    2436        
     2405
    24372406        /*Output:*/
    24382407        volume=0;
     
    24432412        /*Retrieve inputs required:*/
    24442413        thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input);
    2445        
     2414
    24462415        /*Retrieve material parameters: */
    24472416        rho_ice=matpar->GetMaterialParameter(MaterialsRhoIceEnum);
     
    24522421                values[i]=levelset[this->vertices[i]->Sid()];
    24532422        }
    2454                
     2423
    24552424        /*Ok, use the level set values to figure out where we put our gaussian points:*/
    24562425        this->GetLevelsetPositivePart(&point1,&fraction1,&fraction2,&mainlynegative,values);
     
    29042873        dist_cf_input->GetInputValue(&dist_cf,gauss);
    29052874        delete gauss;
    2906        
     2875
    29072876        /*Ensure values are positive for floating ice*/
    29082877        dist_gl = fabs(dist_gl);
     
    29222891                }
    29232892        }
    2924         if(boxid==-1){_error_("No boxid found for element " << this->Sid() << "!");}
     2893        if(boxid==-1) _error_("No boxid found for element " << this->Sid() << "!");
    29252894
    29262895        this->inputs->AddInput(new IntInput(BasalforcingsPicoBoxIdEnum, boxid));       
     
    29372906        IssmDouble gamma_T, overturning_coeff, thickness;
    29382907        IssmDouble pressure, T_star,p_coeff, q_coeff;
     2908        bool       isplume;
    29392909
    29402910        /*Get variables*/
     
    29592929        this->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);
    29602930        this->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);
     2931        this->parameters->FindParam(&isplume, BasalforcingsPicoIsplumeEnum);
    29612932        Input* thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input);
    29622933        _assert_(basinid<=num_basins);
    29632934
    2964    IssmDouble* boxareas = xNew<IssmDouble>(num_basins*maxbox);
     2935   IssmDouble* boxareas = NULL;
    29652936        this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum);
     2937        _assert_(M==num_basins*maxbox);
    29662938
    29672939        IssmDouble area_boxi        = boxareas[basinid*maxbox+boxid];
     
    29942966
    29952967                        /* To avoid negatives under the square root */
    2996                         if((0.25*pow(p_coeff,2)-q_coeff)<0){
    2997                                 q_coeff = 0.25*p_coeff*p_coeff;
    2998                         }
     2968                        if((0.25*pow(p_coeff,2)-q_coeff)<0) q_coeff = 0.25*p_coeff*p_coeff;
    29992969
    30002970                        Tocs[i] = toc_farocean-(-0.5*p_coeff+sqrt(0.25*pow(p_coeff,2)-q_coeff));
    30012971                        Socs[i] = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Tocs[i]);
    30022972                        potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;
    3003                         basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
     2973                        if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
    30042974                        overturnings[i] = overturning_coeff*rho_star*(Beta*(soc_farocean-Socs[i])-alpha*(toc_farocean-Tocs[i]));
    30052975                }
    30062976
    3007                 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
     2977                if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
    30082978                this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum);
    30092979                this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum);
     
    30383008                        Socs[i]  = mean_soc-mean_soc*((mean_toc-Tocs[i])/(nu*lambda));
    30393009                        potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;
    3040                         basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
    3041                 }
    3042 
    3043                 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
     3010                        if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);
     3011                }
     3012
     3013                if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
    30443014                this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum);
    30453015                this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum);
     
    30563026}
    30573027/*}}}*/
     3028void       Tria::PicoComputeBasalMelt(void){/*{{{*/
     3029
     3030        if(!this->IsIceInElement() || !this->IsFloating()) return;
     3031
     3032   IssmDouble E0, Cd, CdT, YT, lam1, lam2, lam3, M0, CdTS0, y1, y2, x0;
     3033        IssmDouble Tf_gl, YTS, CdTS, G1, G2, G3, g_alpha, M, l, X_hat, M_hat;
     3034        IssmDouble alpha, zgl, Toc, Soc, z_base, yts, slopex, slopey;
     3035
     3036        /*Get variables*/
     3037        E0    = 3.6e-2;        //Entrainment coefficient
     3038        Cd    = 2.5e-3;        //Drag coefficient
     3039        CdT   = 1.1e-3;        //Turbulent heat exchange coefficient
     3040        YT    = CdT/sqrt(Cd);  //Heat exchange coefficient
     3041        lam1  = -5.73e-2;      //Freezing point-salinity coefficient (degrees C)
     3042        lam2  = 8.32e-2;       //Freezing point offset (degrees C)
     3043        lam3  = 7.61e-4;       //Freezing point-depth coefficient (K m-1)
     3044        M0    = 10.;           //Melt-rate parameter (m yr-1 C-2)
     3045        CdTS0 = 6e-4;          //Heat exchange parameter
     3046        y1    = 0.545;         //Heat exchange parameter
     3047        y2    = 3.5e-5;        //Heat exchange parameter
     3048        x0    = 0.56;          //Dimentionless scaling factor
     3049
     3050        /*Define arrays*/
     3051        IssmDouble basalmeltrates_shelf[NUMVERTICES];  //Basal melt-rate
     3052        //IssmDouble slope[NUMVERTICES];                 //Basal slope
     3053
     3054        /*Polynomial coefficients*/
     3055        IssmDouble p[12];
     3056        p[0]  =  0.1371330075095435;
     3057        p[1]  =  5.527656234709359E1;
     3058        p[2]  = -8.951812433987858E2;
     3059        p[3]  =  8.927093637594877E3;
     3060        p[4]  = -5.563863123811898E4;
     3061        p[5]  =  2.218596970948727E5;
     3062        p[6]  = -5.820015295669482E5;
     3063        p[7]  =  1.015475347943186E6;
     3064        p[8]  = -1.166290429178556E6;
     3065        p[9]  =  8.466870335320488E5;
     3066        p[10] = -3.520598035764990E5;
     3067        p[11] =  6.387953795485420E4;
     3068
     3069        /*Get inputs*/
     3070   Input* zgl_input            = this->GetInput(GroundinglineHeightEnum);                     _assert_(zgl_input);
     3071        Input* toc_input            = this->GetInput(BasalforcingsPicoSubShelfOceanTempEnum);      _assert_(toc_input);
     3072        Input* soc_input            = this->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum);  _assert_(soc_input);
     3073        Input* base_input           = this->GetInput(BaseEnum);                                    _assert_(base_input);
     3074        Input* baseslopex_input     = this->GetInput(BaseSlopeXEnum);                              _assert_(baseslopex_input);
     3075        Input* baseslopey_input     = this->GetInput(BaseSlopeYEnum);                              _assert_(baseslopey_input);
     3076        this->FindParam(&yts, ConstantsYtsEnum);
     3077
     3078        /*Loop over the number of vertices in this element*/
     3079        Gauss* gauss=this->NewGauss();
     3080        for(int i=0;i<NUMVERTICES;i++){
     3081                gauss->GaussVertex(i);
     3082
     3083                /*Get inputs*/
     3084      zgl_input->GetInputValue(&zgl,gauss);
     3085                toc_input->GetInputValue(&Toc,gauss); //(K)
     3086                soc_input->GetInputValue(&Soc,gauss);
     3087                base_input->GetInputValue(&z_base,gauss);
     3088                baseslopex_input->GetInputValue(&slopex,gauss);
     3089                baseslopey_input->GetInputValue(&slopey,gauss);
     3090
     3091                /*Compute ice shelf base slope*/
     3092                alpha = sqrt(slopex*slopex + slopey*slopey);
     3093
     3094                /*Make necessary conversions*/
     3095                Toc = Toc-273.15;
     3096                alpha = atan(alpha);         
     3097                if(zgl>z_base) zgl=z_base-10;
     3098
     3099                /*Low bound for Toc to ensure X_hat is between 0 and 1*/
     3100                if(Toc<lam1*Soc+lam2) Toc=lam1*Soc+lam2;
     3101
     3102                /*Compute parameters needed for melt-rate calculation*/
     3103                Tf_gl = lam1*Soc+lam2+lam3*zgl;                                              //Characteristic freezing point
     3104                YTS = YT*(y1+y2*(((Toc-Tf_gl)*E0*sin(alpha))/(lam3*(CdTS0+E0*sin(alpha))))); //Effective heat exchange coefficient
     3105                CdTS = sqrt(Cd)*YTS;                                                         //Heat exchange coefficient
     3106                G1 = sqrt(sin(alpha)/(Cd+E0*sin(alpha)));                                    //Geometric factor
     3107                G2 = sqrt(CdTS/(CdTS+E0*sin(alpha)));                                        //Geometric factor
     3108                G3 = (E0*sin(alpha))/(CdTS+E0*sin(alpha));                                   //Geometric factor
     3109      g_alpha = G1*G2*G3;                                                          //Melt scaling factor
     3110                M = M0*g_alpha*pow((Toc-Tf_gl),2);                                           //Melt-rate scale
     3111                l = ((Toc-Tf_gl)*(x0*CdTS+E0*sin(alpha)))/(lam3*x0*(CdTS+E0*sin(alpha)));    //Length scale
     3112                X_hat = (z_base-zgl)/l;                                                      //Dimentionless coordinate system
     3113
     3114                /*Compute polynomial fit*/
     3115                M_hat = 0.;                                                                  //Reset summation variable for each node
     3116                for(int ii=0;ii<12;ii++) {
     3117                 M_hat += p[ii]*pow(X_hat,ii);                                               //Polynomial fit
     3118           }
     3119
     3120                /*Compute melt-rate*/
     3121                basalmeltrates_shelf[i] = (M*M_hat)/yts;                                     //Basal melt-rate (m/s)
     3122        }
     3123   /*Save computed melt-rate*/
     3124   this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);
     3125
     3126   /*Cleanup and return*/
     3127        delete gauss;
     3128}/*}}}*/
    30583129void       Tria::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){/*{{{*/
    30593130
     
    31223193        }
    31233194
    3124 
    31253195}
    31263196/*}}}*/
     
    31933263}
    31943264/*}}}*/
    3195 void       Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/
    3196 
    3197         /*Intermediaries*/
    3198         IssmDouble d,xn,yn;
    3199 
    3200         /*Get current levelset and vertex coordinates*/
    3201         IssmDouble ls[NUMVERTICES];
    3202         IssmDouble  xyz_list[NUMVERTICES][3];
    3203         ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    3204         GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
    3205 
    3206         /*Get distance from list of segments and reset ls*/
    3207         for(int j=0;j<NUMVERTICES;j++){
    3208                 IssmDouble dmin = 1.e+50;
    3209                 for(int i=0;i<numsegments;i++){
    3210                         IssmDouble x = xyz_list[j][0];
    3211                         IssmDouble y = xyz_list[j][1];
    3212                         IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]);
    3213 
    3214                         /*Segment has a length of 0*/
    3215                         if(l2==0.){
    3216                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    3217                                 if(d<dmin) dmin = d;
    3218                                 continue;
    3219                         }
    3220 
    3221                         /*Consider the line extending the segment, parameterized as v + t (w - v).
    3222                          *We find projection of point p onto the line.
    3223                          *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
    3224                         IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2;
    3225                         if(t < 0.0){
    3226                                 // Beyond the 'v' end of the segment
    3227                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    3228                         }
    3229                         else if (t > 1.0){
    3230                                 // Beyond the 'w' end of the segment
    3231                                 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
    3232                         }
    3233                         else{
    3234                                 // Projection falls on the segment
    3235                                 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
    3236                                 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
    3237                                 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
    3238                         }
    3239 
    3240                         if(d<dmin) dmin = d;
    3241                 }
    3242 
    3243                 /*Update signed distance*/
    3244                 dmin = sqrt(dmin);
    3245                 if(dmin>10000) dmin=10000;
    3246                 if(ls[j]>0){
    3247                         ls[j] = dmin;
    3248                 }
    3249                 else{
    3250                         ls[j] = - dmin;
    3251                 }
    3252         }
    3253 
    3254         /*Update Levelset*/
    3255         this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));
    3256 }
    3257 /*}}}*/
    32583265void       Tria::SetClone(int* minranks){/*{{{*/
    32593266
     
    32653272        IssmDouble  values[NUMVERTICES];
    32663273        int         idlist[NUMVERTICES],control_init;
    3267 
    32683274
    32693275        /*Get Domain type*/
     
    32853291
    32863292        /*Get out if this is not an element input*/
    3287         if(!IsInput(control_enum)) return;
    3288        
     3293        if(!IsInputEnum(control_enum)) return;
     3294
    32893295        Input* input     = (Input*)this->inputs->GetInput(control_enum);   _assert_(input);
    32903296        if(input->ObjectEnum()!=ControlInputEnum){
     
    33183324        IssmDouble  values[NUMVERTICES];
    33193325        int         vertexpidlist[NUMVERTICES],control_init;
    3320 
    33213326
    33223327        /*Get Domain type*/
     
    33383343
    33393344        /*Get out if this is not an element input*/
    3340         if(!IsInput(control_enum)) return;
     3345        if(!IsInputEnum(control_enum)) return;
    33413346
    33423347        /*hrepare index list*/
     
    39543959        _assert_(fieldvalue==0.); //field value != 0 not implemented yet
    39553960
    3956         /*1. check that we do cross fieldvalue in this element*/
    3957         Input* input = inputs->GetInput(fieldenum);
    3958         if(!input) _error_("Cannot calculate distance to "<<EnumToStringx(fieldenum)<<", input not found");
    3959         IssmDouble minvalue = input->Min();
    3960         IssmDouble maxvalue = input->Max();
    3961         if(minvalue>fieldvalue || maxvalue<fieldvalue) return;
    3962 
    3963         /* check #2: If only one vertex is on fieldvalue, there is no segment here */
     3961        /*Get field on vertices (we do not allow for higher order elements!!)*/
    39643962        IssmDouble lsf[NUMVERTICES];
    39653963        this->GetInputListOnVertices(&lsf[0],fieldenum);
    3966         int nrice=0;       
    3967         for(int i=0;i<NUMVERTICES;i++) if(lsf[i]==fieldvalue) nrice++;
    3968         if(nrice==1) return;
    3969 
    3970         /*2. Write segments*/
    3971         IssmDouble* xyz_list_zero = NULL;
     3964
     3965        /*1. check that we do cross fieldvalue in this element*/
     3966        IssmDouble minvalue = lsf[0];
     3967        IssmDouble maxvalue = lsf[0];
     3968        for(int i=1;i<NUMVERTICES;i++){
     3969                if(lsf[i]>maxvalue) maxvalue = lsf[i];
     3970                if(lsf[i]<minvalue) minvalue = lsf[i];
     3971        }
     3972        if(minvalue>fieldvalue) return;
     3973        if(maxvalue<fieldvalue) return;
     3974
     3975        /*2. Find coordinates of where levelset crosses 0*/
     3976        int         numiceverts;
     3977        IssmDouble  s[2],x[2],y[2];
     3978        int        *indices = NULL;
     3979        this->GetLevelsetIntersection(&indices, &numiceverts,&s[0],fieldenum,fieldvalue);
     3980        _assert_(numiceverts);
     3981
     3982        /*3 Write coordinates*/
    39723983        IssmDouble  xyz_list[NUMVERTICES][3];
    39733984        ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
    3974         this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0],fieldenum);
    3975         if(xyz_list_zero){
    3976                 IssmDouble x[2],y[2];
    3977                 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0];
    3978                 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1];
    3979                 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
    3980         }
    3981         xDelete<IssmDouble>(xyz_list_zero);
    3982 }
    3983 /*}}}*/
    3984 void       Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/
    3985 
    3986         if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return;
    3987 
    3988         IssmDouble* xyz_list_zero = NULL;
    3989         IssmDouble  xyz_list[NUMVERTICES][3];
    3990         ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
    3991         this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum);
    3992         if(xyz_list_zero){
    3993                 IssmDouble x[2];
    3994                 IssmDouble y[2];
    3995                 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0];
    3996                 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1];
    3997                 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
    3998         }
    3999         xDelete<IssmDouble>(xyz_list_zero);
    4000 
    4001 //      IssmDouble ls[NUMVERTICES];
    4002 //      IssmDouble  xyz_list[NUMVERTICES][3];
    4003 //
    4004 //      if(IsIceInElement()){
    4005 //
    4006 //              /*Retrieve all inputs and parameters*/
    4007 //              GetInputListOnVertices(&ls[0],levelset_enum);
    4008 //
    4009 //              /*If the level set is awlays <0, there is no ice front here*/
    4010 //              bool iszerols= false;
    4011 //              if(IsIceInElement()){
    4012 //                      if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){
    4013 //                              iszerols = true;
    4014 //                      }
    4015 //              }
    4016 //
    4017 //              if(iszerols){
    4018 //                      /*OK we have one segment!*/
    4019 //                      ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    4020 //                      int count = 0;
    4021 //                      IssmDouble x[2];
    4022 //                      IssmDouble y[2];
    4023 //
    4024 //                      for(int i=0;i<NUMVERTICES,i++){
    4025 //                              int index1 = i;
    4026 //                              int index1 = (i+1)%3;
    4027 //                              if(ls[index1]<=0 && ls[index2]>=0){
    4028 //
    4029 //                              }
    4030 //
    4031 //                      }
    4032 //                      Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false);
    4033 //              }
    4034 //
    4035 //      }
    4036 //
    4037 //      _error_("STOP");
    4038 }
    4039 /*}}}*/
    4040 void       Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    4041         /* Return coordinates where levelset intersects element edges.
    4042          * Attention: In case that no intersection exists, NULL pointer is returned.*/
    4043 
    4044         /*Intermediaries*/
    4045         const int dim=3;
    4046         int numiceverts;
    4047         int i, n, e, counter;
    4048         IssmDouble s[2];
    4049         int* indices=NULL;
    4050         IssmDouble* xyz_zero=NULL;
    4051 
    4052         this->GetLevelsetIntersection(&indices, &numiceverts, s,levelsetenum,0.);
    4053        
    4054         //TODO: check if for 2 iceverts front segment is oriented in CCW way
    4055        
    4056         if(numiceverts>0) xyz_zero=xNew<IssmDouble>(2*dim);
    4057         if((numiceverts>0)&&(numiceverts<NUMVERTICES)){
    4058                 counter=0;
    4059                 for(i=0;i<numiceverts;i++){     // iterate over ice vertices
    4060                         for(n=numiceverts;n<NUMVERTICES;n++){ // iterate over no-ice vertices
    4061                                 for(e=0;e<dim;e++){ // spatial direction
    4062                                         int ind_ice             =dim*indices[i]+e;
    4063                                         int ind_noice   =dim*indices[n]+e;
    4064                                         int ind                 =dim*counter+e;
    4065                                         xyz_zero[ind]=xyz_list[ind_ice]+s[counter]*(xyz_list[ind_noice]-xyz_list[ind_ice]);
    4066                                 }
     3985        int counter = 0;
     3986        if((numiceverts>0) && (numiceverts<NUMVERTICES)){
     3987                for(int i=0;i<numiceverts;i++){
     3988                        for(int n=numiceverts;n<NUMVERTICES;n++){ // iterate over no-ice vertices
     3989                                x[counter] = xyz_list[indices[i]][0]+s[counter]*(xyz_list[indices[n]][0]-xyz_list[indices[i]][0]);
     3990                                y[counter] = xyz_list[indices[i]][1]+s[counter]*(xyz_list[indices[n]][1]-xyz_list[indices[i]][1]);
    40673991                                counter++;
    40683992                        }
     
    40703994        }
    40713995        else if(numiceverts==NUMVERTICES){ //NUMVERTICES ice vertices: calving front lies on element edge
    4072                 IssmDouble lsf[NUMVERTICES];
    4073                 this->GetInputListOnVertices(&lsf[0],levelsetenum);
    4074                 counter=0;
    4075                 for(i=0;i<NUMVERTICES;i++){
     3996
     3997                for(int i=0;i<NUMVERTICES;i++){
    40763998                        if(lsf[indices[i]]==0.){
    4077                                 for(e=0;e<dim;e++)      xyz_zero[dim*counter+e]=xyz_list[dim*indices[i]+e];
     3999                                x[counter]=xyz_list[indices[i]][0];
     4000                                y[counter]=xyz_list[indices[i]][1];
    40784001                                counter++;
    40794002                        }
    40804003                        if(counter==2) break;
    40814004                }
    4082         }
     4005                if(counter==1){
     4006                        /*We actually have only 1 vertex on levelset, write a single point as a segment*/
     4007                        x[counter]=x[0];
     4008                        y[counter]=y[0];
     4009                        counter++;
     4010                }
     4011        }
     4012        else{
     4013                _error_("not sure what's going on here...");
     4014        }
     4015
     4016        /*4. Write segment*/
    40834017        _assert_(counter==2);
    4084 
    4085         /*Cleanup & return*/
     4018        segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
     4019
     4020        /*Cleanup and return*/
    40864021        xDelete<int>(indices);
    4087         *pxyz_zero=xyz_zero;
    40884022}
    40894023/*}}}*/
     
    42314165        IssmDouble* H_elastic_precomputed = NULL;
    42324166        int         M, hemi;
    4233        
     4167
    42344168        /*computation of Green functions:*/
    42354169        IssmDouble* U_elastic= NULL;
     
    42384172        IssmDouble* X_elastic= NULL;
    42394173        IssmDouble* Y_elastic= NULL;
    4240        
     4174
    42414175        /*optimization:*/
    42424176        bool store_green_functions=false;
     
    42464180        if (!deltathickness_input)_error_("delta thickness input needed to compute elastic adjustment!");
    42474181        deltathickness_input->GetInputAverage(&I);
    4248                
     4182
    42494183        /*early return if we are not on the (ice) loading point: */
    42504184        if(I==0) return;
     
    42594193        /*which hemisphere? for north-south, east-west components*/
    42604194        this->parameters->FindParam(&hemi,EsaHemisphereEnum);
    4261        
     4195
    42624196        /*compute area of element:*/
    42634197        area=GetArea();
     
    43184252                Y_values[i]+=3*rho_ice/rho_earth*area/(4*PI*pow(earth_radius,2))*I*Y_elastic[i];
    43194253                X_values[i]+=3*rho_ice/rho_earth*area/(4*PI*pow(earth_radius,2))*I*X_elastic[i];
    4320                
     4254
    43214255                /*North-south, East-west components */
    43224256                if (hemi == -1) {
     
    43414275        pX->SetValues(gsize,indices,X_values,ADD_VAL);
    43424276        pY->SetValues(gsize,indices,Y_values,ADD_VAL);
    4343        
     4277
    43444278        /*free ressources:*/
    43454279        xDelete<int>(indices);
     
    43714305        IssmDouble* H_elastic_precomputed = NULL;
    43724306        int         M;
    4373        
     4307
    43744308        /*computation of Green functions:*/
    43754309        IssmDouble* U_elastic= NULL;
    43764310        IssmDouble* N_elastic= NULL;
    43774311        IssmDouble* E_elastic= NULL;
    4378        
     4312
    43794313        /*optimization:*/
    43804314        bool store_green_functions=false;
     
    43844318        if (!deltathickness_input)_error_("delta thickness input needed to compute elastic adjustment!");
    43854319        deltathickness_input->GetInputAverage(&I);
    4386                
     4320
    43874321        /*early return if we are not on the (ice) loading point: */
    43884322        if(I==0) return;
     
    44834417                N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);
    44844418                E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);
    4485                
     4419
    44864420                /*Elastic component  (from Eq 17 in Adhikari et al, GMD 2015): */
    44874421                int index=reCast<int,IssmDouble>(alpha/PI*(M-1));
     
    44984432        pNorth->SetValues(gsize,indices,N_values,ADD_VAL);
    44994433        pEast->SetValues(gsize,indices,E_values,ADD_VAL);
    4500        
     4434
    45014435        /*free ressources:*/
    45024436        xDelete<int>(indices);
     
    45194453
    45204454        if(IsWaterInElement()){
    4521                
     4455
    45224456                IssmDouble area;
    45234457
     
    45364470/*}}}*/
    45374471void    Tria::SealevelriseMomentOfInertia(IssmDouble* dI_list,IssmDouble* Sg_old,IssmDouble eartharea){/*{{{*/
    4538 
    45394472        /*early return if we are not on an ice cap OR ocean:*/
    45404473        if(!(this->inputs->Max(MaskIceLevelsetEnum)<0) && !IsWaterInElement()){
     
    45934526        if(IsWaterInElement()){
    45944527                IssmDouble rho_water, S;
    4595                
     4528
    45964529                /*recover material parameters: */
    45974530                rho_water=matpar->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
    4598        
     4531
    45994532                /*From Sg_old, recover water sea level rise:*/
    46004533                S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg_old[this->vertices[i]->Sid()]/NUMVERTICES;
    4601                
     4534
    46024535                /* Perturbation terms for moment of inertia (moi_list):
    46034536                 * computed analytically (see Wu & Peltier, eqs 10 & 32)
     
    46114544        else if(this->inputs->Max(MaskIceLevelsetEnum)<0){
    46124545                IssmDouble rho_ice, I;
    4613                
     4546
    46144547                /*recover material parameters: */
    46154548                rho_ice=matpar->GetMaterialParameter(MaterialsRhoIceEnum);
    4616        
     4549
    46174550                /*Compute ice thickness change: */
    46184551                Input*  deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum);
    46194552                if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!");
    46204553                deltathickness_input->GetInputAverage(&I);
    4621                
     4554
    46224555                dI_list[0] = -4*PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*cos(longe))/eartharea;
    46234556                dI_list[1] = -4*PI*(rho_ice*I*area)*pow(re,4)*(sin(late)*cos(late)*sin(longe))/eartharea;
    46244557                dI_list[2] = +4*PI*(rho_ice*I*area)*pow(re,4)*(1-pow(sin(late),2))/eartharea;
    46254558        }
    4626        
     4559
    46274560        return;
    46284561}/*}}}*/
     
    46384571        IssmDouble late,longe,re;
    46394572        IssmDouble lati,longi,ri;
     4573        bool notfullygrounded=false;
    46404574
    46414575        /*elastic green function:*/
     
    46454579        /*ice properties: */
    46464580        IssmDouble rho_ice,rho_water,rho_earth;
     4581
     4582        /*constants:*/
     4583        IssmDouble constant=0;
    46474584
    46484585        /*Initialize eustatic component: do not skip this step :):*/
     
    46534590        bool computeelastic= true;
    46544591        bool scaleoceanarea= false;
    4655        
     4592
    46564593        /*early return if we are not on an ice cap:*/
    4657         if(!(this->inputs->Max(MaskIceLevelsetEnum)<0)){
     4594        if(!(this->inputs->Max(MaskIceLevelsetEnum)<=0)){
     4595                constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum));
    46584596                *peustatic=0; //do not forget to assign this pointer, otherwise, global eustatic will be garbage!
    46594597                return;
    46604598        }
     4599
     4600        /*early return if we are fully floating: */
     4601        if (this->inputs->Max(MaskGroundediceLevelsetEnum)<=0){
     4602                constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum));
     4603                *peustatic=0; //do not forget to assign this pointer, otherwise, global eustatic will be garbage!
     4604                return;
     4605        }
     4606
     4607        /*If we are here, we are on ice that is fully grounded or half-way to floating: */
     4608        if ((this->inputs->Min(MaskGroundediceLevelsetEnum))<0){
     4609                notfullygrounded=true; //used later on.
     4610        }
     4611
     4612        /*Inform mask: */
     4613        constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticMaskEnum,&constant,P0Enum));
    46614614
    46624615        /*recover material parameters: */
     
    46814634
    46824635        /* Where is the centroid of this element?:{{{*/
    4683        
     4636
    46844637        /*retrieve coordinates: */
    46854638        ::GetVerticesCoordinates(&llr_list[0][0],this->vertices,NUMVERTICES,spherical);
    4686        
     4639
    46874640        IssmDouble minlong=400;
    46884641        IssmDouble maxlong=-20;
     
    46984651                if (llr_list[2][1]==0)llr_list[2][1]=360;
    46994652        }
    4700        
     4653
    47014654        // correction at the north pole
    47024655        if(llr_list[0][0]==0)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0;
    47034656        if(llr_list[1][0]==0)llr_list[1][1]=(llr_list[0][1]+llr_list[2][1])/2.0;
    47044657        if(llr_list[2][0]==0)llr_list[2][1]=(llr_list[0][1]+llr_list[1][1])/2.0;
    4705                        
     4658
    47064659        //correction at the south pole
    47074660        if(llr_list[0][0]==180)llr_list[0][1]=(llr_list[1][1]+llr_list[2][1])/2.0;
     
    47194672        /*}}}*/
    47204673
    4721         /*Compute area of element:*/
     4674        /*Compute area of element. Scale it by grounded fraction if not fully grounded: */
    47224675        area=GetAreaSpherical();
     4676        if(notfullygrounded){
     4677                IssmDouble phi=0;
     4678                IssmDouble xyz_list[NUMVERTICES][3];
     4679                ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     4680
     4681                phi=this->GetGroundedPortion(&xyz_list[0][0]); //watch out, this only works because of the Thales theorem! We are in 3D, but this routine is inherently for 2D trias
     4682                area*=phi;
     4683        }
    47234684
    47244685        /*Compute ice thickness change: */
    47254686        Input*  deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum);
    47264687        if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!");
    4727         deltathickness_input->GetInputAverage(&I);
     4688
     4689        /*If we are fully grounded, take the average over the element: */
     4690        if(!notfullygrounded)deltathickness_input->GetInputAverage(&I);
     4691        else{
     4692                IssmDouble total_weight=0;
     4693                bool mainlyfloating = true;
     4694                int         point1;
     4695                IssmDouble  fraction1,fraction2;
     4696
     4697                /*Recover portion of element that is grounded*/
     4698                this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);
     4699                Gauss* gauss = this->NewGauss(point1,fraction1,fraction2,mainlyfloating,2);
     4700
     4701                /* Start  looping on the number of gaussian points and average over these gaussian points: */
     4702                total_weight=0;
     4703                I=0;
     4704                for(int ig=gauss->begin();ig<gauss->end();ig++){
     4705                        IssmDouble Ig=0;
     4706                        gauss->GaussPoint(ig);
     4707                        deltathickness_input->GetInputValue(&Ig,gauss);
     4708                        I+=Ig*gauss->weight;
     4709                        total_weight+=gauss->weight;
     4710                }
     4711                I=I/total_weight;
     4712                delete gauss;
     4713        }
    47284714
    47294715        /*Compute eustatic compoent:*/
     
    47624748                }
    47634749                pSgi->SetValues(gsize,indices,values,ADD_VAL);
    4764                
     4750
    47654751                /*free ressources:*/
    47664752                xDelete<IssmDouble>(values);
    47674753                xDelete<int>(indices);
    47684754        }
    4769        
     4755
    47704756        /*Assign output pointer:*/
    47714757        _assert_(!xIsNan<IssmDouble>(eustatic));
     
    47874773        IssmDouble minlong=400;
    47884774        IssmDouble maxlong=-20;
     4775        IssmDouble constant=0;
    47894776
    47904777        /*precomputed elastic green functions:*/
    47914778        IssmDouble* G_elastic_precomputed = NULL;
    47924779        int         M;
    4793        
     4780
    47944781        /*computation of Green functions:*/
    47954782        IssmDouble* G_elastic= NULL;
     
    48074794
    48084795        /*early return if we are not on the ocean:*/
    4809         if (!IsWaterInElement())return;
     4796        if (!IsWaterInElement()){
     4797                constant=0; this->inputs->AddInput(new TriaInput(SealevelEustaticOceanMaskEnum,&constant,P0Enum));
     4798                return;
     4799        }
     4800        constant=1; this->inputs->AddInput(new TriaInput(SealevelEustaticOceanMaskEnum,&constant,P0Enum));
    48104801
    48114802        /*recover computational flags: */
     
    48644855        longe=longe/180*PI;
    48654856        /*}}}*/
    4866        
     4857
    48674858        if(computeelastic){
    4868        
     4859
    48694860                /*recover elastic green function:*/
    48704861                DoubleVecParam* parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseGElasticEnum)); _assert_(parameter);
     
    49044895                }
    49054896        }
    4906        
     4897
    49074898        pSgo->SetValues(gsize,indices,values,ADD_VAL);
    49084899
     
    49184909}
    49194910/*}}}*/
    4920 void    Tria::SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea){ /*{{{*/
     4911void    Tria::SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz){ /*{{{*/
    49214912
    49224913        /*diverse:*/
     
    49374928        IssmDouble* H_elastic_precomputed = NULL;
    49384929        int         M;
    4939        
     4930
    49404931        /*computation of Green functions:*/
    49414932        IssmDouble* U_elastic= NULL;
    49424933        IssmDouble* N_elastic= NULL;
    49434934        IssmDouble* E_elastic= NULL;
     4935        DoubleVecParam* U_parameter = NULL;
     4936        DoubleVecParam* H_parameter = NULL;
     4937        IssmDouble* U_values=NULL;
     4938        IssmDouble* N_values=NULL;
     4939        IssmDouble* E_values=NULL;
    49444940
    49454941        /*optimization:*/
     
    49534949        if(!(this->inputs->Max(MaskIceLevelsetEnum)<0) && !IsWaterInElement()) return;
    49544950
     4951        /*early return if we are fully floating: */
     4952        if (this->inputs->Max(MaskGroundediceLevelsetEnum)<=0)return;
     4953
    49554954        /*recover computational flags: */
    49564955        this->parameters->FindParam(&computerigid,SealevelriseRigidEnum);
    49574956        this->parameters->FindParam(&computeelastic,SealevelriseElasticEnum);
    4958        
     4957
    49594958        /*early return if elastic not requested:*/
    49604959        if(!computeelastic) return;
     
    50165015
    50175016        /*recover elastic Green's functions for displacement:*/
    5018         DoubleVecParam* U_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(U_parameter);
    5019         DoubleVecParam* H_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(H_parameter);
     5017        U_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseUElasticEnum)); _assert_(U_parameter);
    50205018        U_parameter->GetParameterValueByPointer(&U_elastic_precomputed,&M);
    5021         H_parameter->GetParameterValueByPointer(&H_elastic_precomputed,&M);
     5019        if(horiz){
     5020                H_parameter = static_cast<DoubleVecParam*>(this->parameters->FindParamObject(SealevelriseHElasticEnum)); _assert_(H_parameter);
     5021                H_parameter->GetParameterValueByPointer(&H_elastic_precomputed,&M);
     5022        }
    50225023
    50235024        /*From Sg, recover water sea level rise:*/
    50245025        S=0; for(int i=0;i<NUMVERTICES;i++) S+=Sg[this->vertices[i]->Sid()]/NUMVERTICES;
    5025        
     5026
    50265027        /*Compute ice thickness change: */
    50275028        Input*  deltathickness_input=inputs->GetInput(SealevelriseDeltathicknessEnum);
    50285029        if (!deltathickness_input)_error_("delta thickness input needed to compute sea level rise!");
    50295030        deltathickness_input->GetInputAverage(&I);
    5030                
     5031
    50315032        /*initialize: */
    50325033        U_elastic=xNewZeroInit<IssmDouble>(gsize);
    5033         N_elastic=xNewZeroInit<IssmDouble>(gsize);
    5034         E_elastic=xNewZeroInit<IssmDouble>(gsize);
     5034        if(horiz){
     5035                N_elastic=xNewZeroInit<IssmDouble>(gsize);
     5036                E_elastic=xNewZeroInit<IssmDouble>(gsize);
     5037        }
    50355038
    50365039        int* indices=xNew<int>(gsize);
    5037         IssmDouble* U_values=xNewZeroInit<IssmDouble>(gsize);
    5038         IssmDouble* N_values=xNewZeroInit<IssmDouble>(gsize);
    5039         IssmDouble* E_values=xNewZeroInit<IssmDouble>(gsize);
     5040        U_values=xNewZeroInit<IssmDouble>(gsize);
     5041        if(horiz){
     5042                N_values=xNewZeroInit<IssmDouble>(gsize);
     5043                E_values=xNewZeroInit<IssmDouble>(gsize);
     5044        }
    50405045        IssmDouble alpha;
    50415046        IssmDouble delPhi,delLambda;
     
    50625067                }
    50635068                dx = x_element-x; dy = y_element-y; dz = z_element-z;
    5064                 N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);
    5065                 E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);
    5066                
     5069                if(horiz){
     5070                        N_azim = (-z*x*dx-z*y*dy+(pow(x,2)+pow(y,2))*dz) /pow((pow(x,2)+pow(y,2))*(pow(x,2)+pow(y,2)+pow(z,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);
     5071                        E_azim = (-y*dx+x*dy) /pow((pow(x,2)+pow(y,2))*(pow(dx,2)+pow(dy,2)+pow(dz,2)),0.5);
     5072                }
     5073
    50675074                /*Elastic component  (from Eq 17 in Adhikari et al, GMD 2015): */
    50685075                int index=reCast<int,IssmDouble>(alpha/PI*(M-1));
    50695076                U_elastic[i] += U_elastic_precomputed[index];
    5070                 N_elastic[i] += H_elastic_precomputed[index]*N_azim;
    5071                 E_elastic[i] += H_elastic_precomputed[index]*E_azim;
     5077                if(horiz){
     5078                        N_elastic[i] += H_elastic_precomputed[index]*N_azim;
     5079                        E_elastic[i] += H_elastic_precomputed[index]*E_azim;
     5080                }
    50725081
    50735082                /*Add all components to the pUp solution vectors:*/
    50745083                if(this->inputs->Max(MaskIceLevelsetEnum)<0){
    50755084                        U_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*U_elastic[i];
    5076                         N_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*N_elastic[i];
    5077                         E_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*E_elastic[i];
     5085                        if(horiz){
     5086                                N_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*N_elastic[i];
     5087                                E_values[i]+=3*rho_ice/rho_earth*area/eartharea*I*E_elastic[i];
     5088                        }
    50785089                }
    50795090                else if(IsWaterInElement()) {
    50805091                        U_values[i]+=3*rho_water/rho_earth*area/eartharea*S*U_elastic[i];
    5081                         N_values[i]+=3*rho_water/rho_earth*area/eartharea*S*N_elastic[i];
    5082                         E_values[i]+=3*rho_water/rho_earth*area/eartharea*S*E_elastic[i];
     5092                        if(horiz){
     5093                                N_values[i]+=3*rho_water/rho_earth*area/eartharea*S*N_elastic[i];
     5094                                E_values[i]+=3*rho_water/rho_earth*area/eartharea*S*E_elastic[i];
     5095                        }
    50835096                }
    50845097        }
    50855098        pUp->SetValues(gsize,indices,U_values,ADD_VAL);
    5086         pNorth->SetValues(gsize,indices,N_values,ADD_VAL);
    5087         pEast->SetValues(gsize,indices,E_values,ADD_VAL);
     5099        if(horiz){
     5100                pNorth->SetValues(gsize,indices,N_values,ADD_VAL);
     5101                pEast->SetValues(gsize,indices,E_values,ADD_VAL);
     5102        }
    50885103
    50895104        /*free ressources:*/
    50905105        xDelete<int>(indices);
    5091         xDelete<IssmDouble>(U_values); xDelete<IssmDouble>(N_values); xDelete<IssmDouble>(E_values);
    5092         xDelete<IssmDouble>(U_elastic); xDelete<IssmDouble>(N_elastic); xDelete<IssmDouble>(E_elastic);
     5106        xDelete<IssmDouble>(U_values);
     5107        xDelete<IssmDouble>(U_elastic);
     5108        if(horiz){
     5109                xDelete<IssmDouble>(N_values); xDelete<IssmDouble>(E_values);
     5110                xDelete<IssmDouble>(N_elastic); xDelete<IssmDouble>(E_elastic);
     5111        }
    50935112
    50945113        return;
     
    51065125
    51075126        /*Check that name is an element input*/
    5108         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     5127        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    51095128
    51105129        switch(type){
     
    51415160
    51425161        /*Check that name is an element input*/
    5143         if(!IsInput(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
     5162        if(!IsInputEnum(name)) _error_("Enum "<<EnumToStringx(name)<<" is not in IsInput");
    51445163
    51455164        switch(type){
  • issm/trunk/src/c/classes/Elements/Tria.h

    r22758 r23189  
    6666                void        ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index);
    6767                void        ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum);
    68                 void        CreateDistanceInputFromSegmentlist(IssmDouble* segments,int numsegments,int distanceenum);
     68                void        CreateDistanceInputFromSegmentlist(IssmDouble* distances,int distanceenum);
    6969                int         EdgeOnBaseIndex();
    7070                void        EdgeOnBaseIndices(int* pindex1,int* pindex);
     
    7575                int         FiniteElement(void);
    7676                IssmDouble  FloatingArea(bool scaled);
    77                 void        FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating);
     77                void        FSContactMigration(Vector<IssmDouble>* vertex_sigmann,Vector<IssmDouble>* vertex_waterpressure);
    7878                Element*    GetBasalElement(void){_error_("not implemented yet");};
    7979                void        GetLevelsetPositivePart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlynegative,IssmDouble* levelsetvalues);
     
    8686                int         GetNumberOfNodes(int enum_type);
    8787                int         GetNumberOfVertices(void);
    88                 void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset,bool onsid);
    89                 void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,bool onsid);
     88                void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data,int offset);
     89                void        GetVectorFromControlInputs(Vector<IssmDouble>* gradient,int control_enum,int control_index,const char* data);
    9090                void        GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
    9191                void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
     
    114114                void        PicoUpdateBoxid(int* pmax_boxid_basin);
    115115                void        PicoUpdateBox(int loopboxid);
     116                void        PicoComputeBasalMelt(void);
    116117                void        PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding);
    117118                int         PressureInterpolation();
     
    143144                void        VerticalSegmentIndicesBase(int** pindices,int* pnumseg){_error_("not implemented yet");};
    144145                void                    WriteFieldIsovalueSegment(DataSet* segments,int fieldenum,IssmDouble fieldvalue);
    145                 void                    WriteLevelsetSegment(DataSet* segments);
    146                 void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
    147146
    148147                #ifdef _HAVE_GIAIVINS_
     
    159158                void    SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea);
    160159                void    SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble eartharea);
    161                 void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea);
     160                void    SealevelriseGeodetic(Vector<IssmDouble>* pUp,Vector<IssmDouble>* pNorth,Vector<IssmDouble>* pEast,IssmDouble* Sg,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble* xx,IssmDouble* yy,IssmDouble* zz,IssmDouble eartharea,int horiz);
    162161                #endif
    163162                /*}}}*/
  • issm/trunk/src/c/classes/Elements/TriaRef.cpp

    r21341 r23189  
    116116        Matrix2x2Determinant(Jdet,&J[0][0]);
    117117        if(*Jdet<0) _error_("negative jacobian determinant!");
     118
     119}
     120/*}}}*/
     121void TriaRef::GetJacobianDeterminant3D(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
     122        /*The Jacobian determinant is constant over the element, discard the gaussian points.
     123         * J is assumed to have been allocated of size NDOF2xNDOF2.*/
     124        IssmDouble J[2][2];
     125
     126        /*Get Jacobian*/
     127        GetJacobian(&J[0][0],xyz_list,gauss);
     128
     129        /*Get Determinant*/
     130        Matrix2x2Determinant(Jdet,&J[0][0]);
    118131
    119132}
  • issm/trunk/src/c/classes/Elements/TriaRef.h

    r21341 r23189  
    2020                void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss);
    2121                void GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss);
     22                void GetJacobianDeterminant3D(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss);
    2223                void GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,Gauss* gauss);
    2324                void GetNodalFunctions(IssmDouble* basis,Gauss* gauss,int finiteelement);
  • issm/trunk/src/c/classes/ExternalResults/GenericExternalResult.h

    r22822 r23189  
    623623        /*Specific instantiations for IssmDouble*: */
    624624#if defined(_HAVE_ADOLC_) && !defined(_WRAPPERS_)  //We hook off this specific specialization when not running ADOLC, otherwise we get a redeclaration with the next specialization.
     625template <> inline GenericExternalResult<IssmDouble*>::~GenericExternalResult(){ /*{{{*/
     626        xDelete<char>(result_name);
     627        xDelete<IssmDouble>(value);
     628} /*}}}*/
    625629        template <> inline void GenericExternalResult<IssmDouble*>::WriteData(FILE* fid,bool io_gather){ /*{{{*/
    626630
     
    743747        }
    744748        /*}}}*/
     749template <> inline GenericExternalResult<Vector<IssmDouble>*>::~GenericExternalResult(){ /*{{{*/
     750        xDelete<char>(this->result_name);
     751        delete value;
     752} /*}}}*/
    745753#endif
    746754        template <> inline int GenericExternalResult<Vector<IssmPDouble>*>::ObjectEnum(void){ /*{{{*/
  • issm/trunk/src/c/classes/FemModel.cpp

    r22758 r23189  
    8383   /*AMR stuff*/
    8484        this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
     85        this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
    8586        #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
    8687        this->amr = NULL;
     
    9091        #endif
    9192        #if !defined(_HAVE_ADOLC_)
    92         if(amr_frequency){
     93        if(amr_frequency && solution_type==TransientSolutionEnum){
    9394                /*Verifications. AMR supports SSA, P1 and horizontal 2D domain*/
    9495                bool isSSA;
     
    136137        bool traceon=true;
    137138        this->profiler=NULL; /*avoid leak, as we are not using the profiler ever in ad control run. */
    138        
    139         /*Store the communicator, but do not set it as a global variable, as this has already 
     139
     140        /*Store the communicator, but do not set it as a global variable, as this has already
    140141         * been done by the FemModel that called this copy constructor: */
    141142        IssmComm::SetComm(incomm);
     
    152153        this->amrbamg = NULL;
    153154        #endif
    154        
     155
    155156        /*Save communicator in the parameters dataset: */
    156157        this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum));
     
    182183        if(parameters)delete parameters;
    183184        if(results)delete results;
    184        
     185
    185186        #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_ADOLC_)
    186187        if(amr)delete amr;
     
    206207        /*First, recover the name of the restart file: */
    207208        parameters->FindParam(&restartfilename,RestartFileNameEnum);
    208        
     209
    209210        /*Open file for writing: */
    210211        restartfid=pfopen(restartfilename,"wb");
     
    215216        /*Create buffer to hold marshalled femmodel: */
    216217        this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE);
    217         femmodel_buffer=xNew<char>(femmodel_size); 
     218        femmodel_buffer=xNew<char>(femmodel_size);
    218219        /*Keep track of initial position of femmodel_buffer: */
    219220        femmodel_buffer_ini=femmodel_buffer;
    220        
     221
    221222        /*Marshall:*/
    222223        this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD);
     
    242243        char *lockfilename   = NULL;
    243244        bool  waitonlock     = false;
    244 
    245245
    246246        /*Write lock file if requested: */
     
    376376}/*}}}*/
    377377void FemModel::InitFromFids(char* rootpath, FILE* IOMODEL, FILE* toolkitsoptionsfid, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
    378        
     378
    379379        /*Initialize internal data: */
    380380        this->solution_type    = in_solution_type;
    381381        this->analysis_counter = nummodels-1;   //point to last analysis_type carried out.
    382382        this->results          = new Results(); //not initialized by CreateDataSets
    383        
     383
    384384        /*create IoModel */
    385385        IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);
     
    399399                if(VerboseMProcessor()) _printf0_("      configuring element and loads\n");
    400400                ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters);
    401                
     401
    402402                if(i==0){
    403403                        if(VerboseMProcessor()) _printf0_("      creating vertex PIDs\n");
    404                         VerticesDofx(vertices,parameters); 
     404                        VerticesDofx(vertices,parameters);
    405405
    406406                        if(VerboseMProcessor()) _printf0_("      detecting active vertices\n");
    407                         GetMaskOfIceVerticesLSMx(this);
     407                        GetMaskOfIceVerticesLSMx0(this);
    408408                }
    409409
    410410                if(VerboseMProcessor()) _printf0_("      resolving node constraints\n");
    411                 SpcNodesx(nodes,constraints,parameters,analysis_type_list[i]); 
     411                SpcNodesx(nodes,constraints,parameters,analysis_type_list[i]);
    412412
    413413                if(VerboseMProcessor()) _printf0_("      creating nodal degrees of freedom\n");
     
    487487        FILE* restartfid=NULL;
    488488        char* restartfilename = NULL;
    489         int   femmodel_size=0; 
    490         int   fread_return=0; 
     489        int   femmodel_size=0;
     490        int   fread_return=0;
    491491        char* femmodel_buffer=NULL;
    492492        char* femmodel_buffer_ini=NULL;
     
    513513
    514514        /*Figure out size of buffer to be read: */
    515         fseek(restartfid, 0L, SEEK_END); 
     515        fseek(restartfid, 0L, SEEK_END);
    516516        femmodel_size = ftell(restartfid);
    517517        fseek(restartfid, 0L, SEEK_SET);
    518518
    519519        /*Allocate buffer: */
    520         femmodel_buffer=xNew<char>(femmodel_size); 
     520        femmodel_buffer=xNew<char>(femmodel_size);
    521521
    522522        /*Read buffer from file: */
     
    539539void FemModel::SetCurrentConfiguration(int configuration_type,int analysis_type){/*{{{*/
    540540
    541         /*Use configuration_type to setup the analysis counter, the configurations of objects etc ... but use 
    542          * analysis_type to drive the element numerics. This allows for use of 1 configuration_type for several 
    543          * analyses. For example: do a SurfaceSlopeX, SurfaceSlopeY, BedSlopeX and BedSlopeY analysis using the 
     541        /*Use configuration_type to setup the analysis counter, the configurations of objects etc ... but use
     542         * analysis_type to drive the element numerics. This allows for use of 1 configuration_type for several
     543         * analyses. For example: do a SurfaceSlopeX, SurfaceSlopeY, BedSlopeX and BedSlopeY analysis using the
    544544         * Slope configuration.*/
    545545        int found=-1;
     
    660660                        analyses_temp[numanalyses++]=MasstransportAnalysisEnum;
    661661                        analyses_temp[numanalyses++]=ExtrudeFromBaseAnalysisEnum;
     662
    662663                        break;
    663664
     
    700701                        analyses_temp[numanalyses++]=EsaAnalysisEnum;
    701702                        break;
    702                
     703
    703704                case SealevelriseSolutionEnum:
    704705                        analyses_temp[numanalyses++]=SealevelriseAnalysisEnum;
     
    753754                        if(ismasstransport || isgroundingline){
    754755                                analyses_temp[numanalyses++]=MasstransportAnalysisEnum;
     756                                int  basalforcing_model;
     757                                iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
     758                                if(basalforcing_model==BasalforcingsPicoEnum){
     759                                        bool isplume;
     760                                        iomodel->FindConstant(&isplume,"md.basalforcings.isplume");
     761                                        if(isplume){
     762                                                analyses_temp[numanalyses++]=GLheightadvectionAnalysisEnum;
     763                                        }
     764                                }
    755765                        }
    756766                        if(issmb) analyses_temp[numanalyses++]=SmbAnalysisEnum;
     
    761771                        if(ishydrology){
    762772                                analyses_temp[numanalyses++]=HydrologyShreveAnalysisEnum;
    763                                 analyses_temp[numanalyses++]=HydrologySommersAnalysisEnum;
     773                                analyses_temp[numanalyses++]=HydrologyShaktiAnalysisEnum;
     774                                analyses_temp[numanalyses++]=HydrologyPismAnalysisEnum;
    764775                                analyses_temp[numanalyses++]=HydrologyDCInefficientAnalysisEnum;
    765776                                analyses_temp[numanalyses++]=HydrologyDCEfficientAnalysisEnum;
     
    825836
    826837        /*run solution core: */
    827         profiler->Start(CORE);   
    828         solutioncore(this); 
     838        profiler->Start(CORE);
     839        solutioncore(this);
    829840        profiler->Stop(CORE);
    830841
    831842        /*run AD core if needed: */
    832         profiler->Start(ADCORE); 
    833         ad_core(this);     
     843        profiler->Start(ADCORE);
     844        ad_core(this);
    834845        profiler->Stop(ADCORE);
    835846
     
    10331044                segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1];
    10341045        }
     1046
    10351047        ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
    10361048        delete segments;
     
    10391051
    10401052        /*3: Add distance input to all elements*/
    1041         for(int i=0;i<elements->Size();i++){
    1042                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    1043                 if(!element->IsOnBase()) continue;
    1044                 element->CreateDistanceInputFromSegmentlist(allsegmentlist,numseg,distanceenum);
    1045         }
    1046 
    1047 
    1048         /*Extrude if necessary*/
    1049         int elementtype;
    1050         this->parameters->FindParam(&elementtype,MeshElementtypeEnum);
    1051         if(elementtype==PentaEnum){
    1052                 InputExtrudex(this,distanceenum,-1);
    1053         }
    1054         else if(elementtype==TriaEnum){
    1055                 /*no need to extrude*/
    1056         }
    1057         else{
    1058                 _error_("not implemented yet");
    1059         }
     1053        IssmDouble* distances = xNew<IssmDouble>(vertices->Size());
     1054        IssmDouble  d,xn,yn,dmin;
     1055        int         last = -1;
     1056        for(int v=0;v<vertices->Size();v++){
     1057
     1058                Vertex* vertex=dynamic_cast<Vertex*>(this->vertices->GetObjectByOffset(v));
     1059                IssmDouble x = vertex->x;
     1060                IssmDouble y = vertex->y;
     1061
     1062                /*Most of the time the last checked segment is the closest so start with that one*/
     1063                if(last>0){
     1064                        dmin = pow(allsegmentlist[4*last+0] - x,2) + pow(y-allsegmentlist[4*last+1],2);
     1065                }
     1066                else{
     1067                        dmin = 1.e+50;
     1068                }
     1069
     1070                for(int i=0;i<numseg;i++){
     1071
     1072                        /*Skip if tip is more than 10xdmin away*/
     1073                        if(pow(allsegmentlist[4*i+0] - x,2)>10*dmin) continue;
     1074                        if(pow(allsegmentlist[4*i+1] - y,2)>10*dmin) continue;
     1075
     1076                        IssmDouble l2 = (allsegmentlist[4*i+2]-allsegmentlist[4*i+0])*(allsegmentlist[4*i+2]-allsegmentlist[4*i+0]) + (allsegmentlist[4*i+3]-allsegmentlist[4*i+1])*(allsegmentlist[4*i+3]-allsegmentlist[4*i+1]);
     1077
     1078                        /*Segment has a length of 0*/
     1079                        if(l2==0.){
     1080                                d = (x-allsegmentlist[4*i+0])*(x-allsegmentlist[4*i+0])+(y-allsegmentlist[4*i+1])*(y-allsegmentlist[4*i+1]);
     1081                                if(d<dmin){
     1082                                        dmin = d;
     1083                                        last = i;
     1084                                }
     1085                                continue;
     1086                        }
     1087
     1088                        /*Consider the line extending the segment, parameterized as v + t (w - v).
     1089                         *We find projection of point p onto the line.
     1090                         *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
     1091                        IssmDouble t = ((x-allsegmentlist[4*i+0])*(allsegmentlist[4*i+2]-allsegmentlist[4*i+0]) + (y-allsegmentlist[4*i+1])*(allsegmentlist[4*i+3]-allsegmentlist[4*i+1]))/l2;
     1092                        if(t < 0.0){
     1093                                // Beyond the 'v' end of the segment
     1094                                d = (x-allsegmentlist[4*i+0])*(x-allsegmentlist[4*i+0])+(y-allsegmentlist[4*i+1])*(y-allsegmentlist[4*i+1]);
     1095                        }
     1096                        else if (t > 1.0){
     1097                                // Beyond the 'w' end of the segment
     1098                                d = (x-allsegmentlist[4*i+2])*(x-allsegmentlist[4*i+2])+(y-allsegmentlist[4*i+3])*(y-allsegmentlist[4*i+3]);
     1099                        }
     1100                        else{
     1101                                // Projection falls on the segment
     1102                                xn = allsegmentlist[4*i+0] + t * (allsegmentlist[4*i+2] - allsegmentlist[4*i+0]);
     1103                                yn = allsegmentlist[4*i+1] + t * (allsegmentlist[4*i+3] - allsegmentlist[4*i+1]);
     1104                                d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
     1105                        }
     1106
     1107                        if(d<dmin){
     1108                                dmin = d;
     1109                                last = i;
     1110                        }
     1111                }
     1112
     1113                /*Update signed distance*/
     1114                _assert_(vertex->lid<vertices->Size());
     1115                distances[vertex->lid] = sqrt(dmin);
     1116        }
     1117
     1118        for(int i=0;i<this->elements->Size();i++){
     1119                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1120                element->CreateDistanceInputFromSegmentlist(distances,distanceenum);
     1121        }
     1122        //InputUpdateFromVectorx(this,distances,distanceenum,VertexLIdEnum);
    10601123
    10611124        /*Clean up and return*/
     1125        xDelete<IssmDouble>(distances);
    10621126        xDelete<IssmDouble>(allsegmentlist);
    10631127}/*}}}*/
     
    11211185        /*Broadcast and plug into response: */
    11221186        ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
    1123         ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm()); 
     1187        ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm());
    11241188
    11251189        /*Assign output pointers: */
     
    12681332        num_segments = mdims_array[counter-1];
    12691333
    1270         /*Go through segments, and then elements, and figure out which elements belong to a segment. 
     1334        /*Go through segments, and then elements, and figure out which elements belong to a segment.
    12711335         * When we find one, use the element to compute the mass flux on the segment: */
    12721336        for(i=0;i<num_segments;i++){
     
    13151379        /*Figure out maximum across the cluster: */
    13161380        ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1317         ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1381        ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    13181382        maxabsvx=node_maxabsvx;
    13191383
     
    13391403        /*Figure out maximum across the cluster: */
    13401404        ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1341         ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1405        ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    13421406        maxabsvy=node_maxabsvy;
    13431407
     
    13631427        /*Figure out maximum across the cluster: */
    13641428        ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1365         ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1429        ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    13661430        maxabsvz=node_maxabsvz;
    13671431
     
    14061470        /*Figure out maximum across the cluster: */
    14071471        ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1408         ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1472        ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    14091473        maxvel=node_maxvel;
    14101474
     
    14301494        /*Figure out maximum across the cluster: */
    14311495        ISSM_MPI_Reduce(&maxvx,&node_maxvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1432         ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1496        ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    14331497        maxvx=node_maxvx;
    14341498
     
    14541518        /*Figure out maximum across the cluster: */
    14551519        ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1456         ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1520        ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    14571521        maxvy=node_maxvy;
    14581522
     
    14781542        /*Figure out maximum across the cluster: */
    14791543        ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1480         ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1544        ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    14811545        maxvz=node_maxvz;
    14821546
     
    15021566        /*Figure out minimum across the cluster: */
    15031567        ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1504         ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1568        ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    15051569        minvel=node_minvel;
    15061570
     
    15261590        /*Figure out minimum across the cluster: */
    15271591        ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1528         ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1592        ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    15291593        minvx=node_minvx;
    15301594
     
    15501614        /*Figure out minimum across the cluster: */
    15511615        ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1552         ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1616        ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    15531617        minvy=node_minvy;
    15541618
     
    15741638        /*Figure out minimum across the cluster: */
    15751639        ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1576         ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1640        ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    15771641        minvz=node_minvz;
    15781642
     
    16191683                        omega_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
    16201684
    1621                         /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
     1685                        /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
    16221686                        //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
    16231687                        J+=weight*1/2*pow(dp[0]*dp[0]+dp[1]*dp[1],2)*Jdet*gauss->weight;
     
    16781742                        omega0_input->GetInputValue(&p0,gauss);
    16791743
    1680                         /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
     1744                        /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
    16811745                        //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
    16821746                        J+=weight*1/2*pow(p - p0,2)*Jdet*gauss->weight;
     
    19021966                                                ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    19031967                                                ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    1904                                                
     1968
    19051969                                                if(results_on_nodes){
    19061970
     
    19341998
    19351999                                                        }
    1936                                                         if (!isarray){
     2000                                                        if(!isarray){
    19372001                                                                Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size);
    19382002
     
    19552019                                                                IssmDouble* values    = xNewZeroInit<IssmDouble>(nlines*ncols);
    19562020                                                                IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols);
    1957                                                                
     2021
    19582022                                                                /*Fill-in matrix*/
    19592023                                                                for(int j=0;j<elements->Size();j++){
     
    19642028                                                                ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
    19652029                                                                xDelete<IssmDouble>(values);
    1966                                                                
     2030
    19672031                                                                if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time));
    19682032                                                                xDelete<IssmDouble>(allvalues);
     
    20052069void FemModel::ResetLevelset(void){/*{{{*/
    20062070
    2007         /*recover my_rank:*/
    2008         int my_rank   = IssmComm::GetRank();
    2009         int num_procs = IssmComm::GetSize();
    2010 
    2011         /*Get domain type (2d or 3d)*/
    2012         int domaintype;
    2013         this->parameters->FindParam(&domaintype,DomainTypeEnum);
    2014        
    2015         /*1: go throug all elements of this partition and figure out how many
    2016          * segments we have (corresopnding to levelset = 0)*/
    2017         DataSet* segments=new DataSet();
    2018         for(int i=0;i<elements->Size();i++){
    2019                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2020                 if(!element->IsOnBase()) continue;
    2021                 Element* basalelement = element->SpawnBasalElement();
    2022                 basalelement->WriteLevelsetSegment(segments);
    2023                 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
    2024         }
    2025 
    2026         /*2: now get the segments from all partitions*/
    2027         int  segcount=segments->Size();
    2028         int* allsegcount=xNew<int>(num_procs);
    2029         ISSM_MPI_Gather(&segcount,1,ISSM_MPI_INT,allsegcount,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2030         ISSM_MPI_Bcast(allsegcount,num_procs,ISSM_MPI_INT,0,IssmComm::GetComm());
    2031 
    2032         /* Every cpu should start its own dof count at the end of the dofcount from cpu-1*/
    2033         int numseg_offset=0;
    2034         int numseg=0;
    2035         for(int i=0;i<my_rank;  i++) numseg_offset+=allsegcount[i];
    2036         for(int i=0;i<num_procs;i++) numseg+=allsegcount[i];
    2037         IssmDouble* segmentlist    = xNewZeroInit<IssmDouble>(4*numseg);
    2038         IssmDouble* allsegmentlist = xNewZeroInit<IssmDouble>(4*numseg);
    2039         for(int i=0;i<segments->Size();i++){
    2040                 Contour<IssmDouble>* segment=(Contour<IssmDouble>*)segments->GetObjectByOffset(i);
    2041                 _assert_(segment->nods == 2);
    2042                 segmentlist[(numseg_offset+i)*4 + 0] = segment->x[0];
    2043                 segmentlist[(numseg_offset+i)*4 + 1] = segment->y[0];
    2044                 segmentlist[(numseg_offset+i)*4 + 2] = segment->x[1];
    2045                 segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1];
    2046         }
    2047         ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
    2048         delete segments;
    2049         xDelete<IssmDouble>(segmentlist);
    2050         xDelete<int>(allsegcount);
    2051 
    2052         /*3: update levelset for all elements*/
    2053         for(int i=0;i<elements->Size();i++){
    2054                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2055                 if(!element->IsOnBase()) continue;
    2056                 element->ResetLevelsetFromSegmentlist(allsegmentlist,numseg);
    2057         }
    2058 
    2059 
    2060         /*Extrude if necessary*/
    2061         int elementtype;
    2062         this->parameters->FindParam(&elementtype,MeshElementtypeEnum);
    2063         if(elementtype==PentaEnum){
    2064                 InputExtrudex(this,MaskIceLevelsetEnum,-1);
    2065         }
    2066         else if(elementtype==TriaEnum){
    2067                 /*no need to extrude*/
    2068         }
    2069         else{
    2070                 _error_("not implemented yet");
    2071         }
    2072 
    2073         /*Clean up and return*/
    2074         xDelete<IssmDouble>(allsegmentlist);
     2071        this->DistanceToFieldValue(MaskIceLevelsetEnum,0.,MaskIceLevelsetEnum);
    20752072
    20762073}
     
    21322129                case VelEnum:                            this->ElementResponsex(responses,VelEnum); break;
    21332130                case FrictionCoefficientEnum:            NodalValuex(responses, FrictionCoefficientEnum,elements,nodes, vertices, loads, materials, parameters); break;
    2134                 default: 
     2131                default:
    21352132                        if(response_descriptor_enum>=Outputdefinition1Enum && response_descriptor_enum <=Outputdefinition100Enum){
    21362133                                IssmDouble double_result = OutputDefinitionsResponsex(this,response_descriptor_enum);
    21372134                                *responses=double_result;
    21382135                        }
    2139                         else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!"); 
    2140                         break; 
     2136                        else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!");
     2137                        break;
    21412138        }
    21422139
     
    22692266                        thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
    22702267
    2271                         /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
     2268                        /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
    22722269                        J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
    22732270                }
     
    24602457        analysis->UpdateConstraints(this);
    24612458        delete analysis;
    2462        
     2459
    24632460        /*Second, constraints might be time dependent: */
    2464         SpcNodesx(nodes,constraints,parameters,analysis_type); 
     2461        SpcNodesx(nodes,constraints,parameters,analysis_type);
    24652462
    24662463        /*Now, update degrees of freedoms: */
     
    24732470        IssmDouble         *surface = NULL;
    24742471        IssmDouble         *bed     = NULL;
    2475                        
     2472
    24762473        if(VerboseSolution()) _printf0_("   updating vertices positions\n");
    24772474
     
    25122509
    25132510/*AMR*/
    2514 #if !defined(_HAVE_ADOLC_) 
     2511#if !defined(_HAVE_ADOLC_)
    25152512void FemModel::ReMesh(void){/*{{{*/
    25162513
     
    25222519        int newnumberofvertices = -1;
    25232520        int newnumberofelements = -1;
    2524         bool* my_elements                       = NULL; 
     2521        bool* my_elements                       = NULL;
    25252522        int* my_vertices                        = NULL;
    25262523        int elementswidth       = this->GetElementsWidth();//just tria elements in this version
     
    25282525        bool isgroundingline;
    25292526
    2530         /*Branch to specific amr depending on requested method*/       
     2527        /*Branch to specific amr depending on requested method*/
    25312528        this->parameters->FindParam(&amrtype,AmrTypeEnum);
    25322529        switch(amrtype){
     
    25412538                default: _error_("not implemented yet");
    25422539        }
    2543        
     2540
    25442541        /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/
    25452542        this->ElementsAndVerticesPartitioning(newnumberofvertices,newnumberofelements,elementswidth,newelementslist,&my_elements,&my_vertices);
     
    25722569
    25732570                /*As the domain is 2D, it is not necessary to create nodes for this analysis*/
    2574                 if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue;   
     2571                if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue;
    25752572
    25762573                this->CreateNodes(newnumberofvertices,my_vertices,nodecounter,analysis_enum,new_nodes);
     
    26022599                //SetCurrentConfiguration(analysis_type);
    26032600
    2604                 this->analysis_counter=i;       
     2601                this->analysis_counter=i;
    26052602                /*Now, plug analysis_counter and analysis_type inside the parameters: */
    26062603                this->parameters->SetParam(this->analysis_counter,AnalysisCounterEnum);
     
    26192616
    26202617                ConfigureObjectsx(new_elements,this->loads,new_nodes,new_vertices,new_materials,this->parameters);
    2621                 if(i==0){ 
     2618                if(i==0){
    26222619                        VerticesDofx(new_vertices,this->parameters); //only call once, we only have one set of vertices
    26232620                }
     
    26362633        delete this->materials;         this->materials = new_materials;
    26372634
    2638         GetMaskOfIceVerticesLSMx(this);
     2635        GetMaskOfIceVerticesLSMx0(this);
    26392636
    26402637        /*Insert MISMIP+ bed topography FIXME it could be stay in another place*/
     
    26632660        /*Insert bedrock from mismip+ setup*/
    26642661        /*This was used to Misomip project/simulations*/
    2665        
     2662
    26662663        if(VerboseSolution())_printf0_("        call Mismip bedrock adjust module\n");
    26672664
     
    26802677                        by              = 500./(1.+exp((-2./4000.)*(y-80000./2.-24000.)))+500./(1.+exp((2./4000.)*(y-80000./2.+24000.)));
    26812678                        r[i]    = max(bx+by,-720.);
    2682                 }       
     2679                }
    26832680                /*insert new bedrock*/
    26842681                element->AddInput(BedEnum,&r[0],P1Enum);
     
    26932690
    26942691        if(VerboseSolution())_printf0_("        call adjust base and thickness module\n");
    2695        
     2692
    26962693        int     numvertices = this->GetElementsWidth();
    26972694   IssmDouble rho_water,rho_ice,density,base_float;
     
    27052702        for(int el=0;el<this->elements->Size();el++){
    27062703                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(el));
    2707        
     2704
    27082705                element->GetInputListOnVertices(&s[0],SurfaceEnum);
    27092706                element->GetInputListOnVertices(&r[0],BedEnum);
     
    27172714                        base_float = rho_ice*s[i]/(rho_ice-rho_water);
    27182715                        if(r[i]>base_float){
    2719                                 b[i] = r[i];                   
    2720                         } 
     2716                                b[i] = r[i];
     2717                        }
    27212718                        else {
    2722                                 b[i] = base_float;     
    2723                         } 
     2719                                b[i] = base_float;
     2720                        }
    27242721
    27252722                        if(fabs(sl[i])>0) _error_("Sea level value "<<sl[i]<<" not supported!");
    27262723                        /*update thickness and mask grounded ice level set*/
    27272724                        h[i]      = s[i]-b[i];
    2728                         phi[i]  = h[i]+r[i]/density;   
     2725                        phi[i]  = h[i]+r[i]/density;
    27292726                }
    27302727
     
    27342731                element->AddInput(BaseEnum,&b[0],P1Enum);
    27352732        }
    2736        
     2733
    27372734   /*Delete*/
    27382735   xDelete<IssmDouble>(phi);
     
    27622759        Vector<IssmDouble>* input_interpolations        = NULL;
    27632760        IssmDouble* input_interpolations_serial = NULL;
    2764    int* pos                                                                                             = NULL; 
     2761   int* pos                                                                                             = NULL;
    27652762        IssmDouble value                                                                        = 0;
    27662763
     
    27822779                        P0input_interp = xNew<int>(numP0inputs);
    27832780                        P1input_enums  = xNew<int>(numP1inputs);
    2784                         P1input_interp = xNew<int>(numP1inputs);       
     2781                        P1input_interp = xNew<int>(numP1inputs);
    27852782                }
    27862783                numP0inputs = 0;
     
    28142811                }
    28152812        }
    2816        
    2817         /*Get P0 and P1 inputs over the elements*/     
     2813
     2814        /*Get P0 and P1 inputs over the elements*/
    28182815        pos             = xNew<int>(elementswidth);
    28192816        vP0inputs= new Vector<IssmDouble>(numberofelements*numP0inputs);
     
    28212818        for(int i=0;i<this->elements->Size();i++){
    28222819                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    2823                
     2820
    28242821                /*Get P0 inputs*/
    28252822                for(int j=0;j<numP0inputs;j++){
    2826                         TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j]));         
     2823                        TriaInput* input=xDynamicCast<TriaInput*>(element->GetInput(P0input_enums[j]));
    28272824                        input->GetInputAverage(&value);
    28282825                        pos[0]=element->Sid()*numP0inputs+j;
    2829                         /*Insert input in the vector*/ 
     2826                        /*Insert input in the vector*/
    28302827                        vP0inputs->SetValues(1,pos,&value,INS_VAL);
    28312828                }
    2832                
     2829
    28332830                /*Get P1 inputs*/
    28342831                for(int j=0;j<numP1inputs;j++){
     
    28372834                        pos[1]=element->vertices[1]->Sid()*numP1inputs+j;
    28382835                        pos[2]=element->vertices[2]->Sid()*numP1inputs+j;
    2839                         /*Insert input in the vector*/ 
    2840                         vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL); 
     2836                        /*Insert input in the vector*/
     2837                        vP1inputs->SetValues(elementswidth,pos,input->values,INS_VAL);
    28412838                }
    28422839        }
     
    28472844        P0inputs=vP0inputs->ToMPISerial();
    28482845        P1inputs=vP1inputs->ToMPISerial();
    2849        
     2846
    28502847        /*Assign pointers*/
    2851         *pnumP0inputs           = numP0inputs; 
    2852         *pP0inputs                      = P0inputs; 
     2848        *pnumP0inputs           = numP0inputs;
     2849        *pP0inputs                      = P0inputs;
    28532850        *pP0input_enums = P0input_enums;
    28542851        *pP0input_interp        = P0input_interp;
    2855         *pnumP1inputs           = numP1inputs; 
    2856         *pP1inputs                      = P1inputs; 
     2852        *pnumP1inputs           = numP1inputs;
     2853        *pP1inputs                      = P1inputs;
    28572854        *pP1input_enums = P1input_enums;
    2858         *pP1input_interp        = P1input_interp;       
     2855        *pP1input_interp        = P1input_interp;
    28592856
    28602857        /*Cleanup*/
     
    28672864/*}}}*/
    28682865void FemModel::InterpolateInputs(Vertices* newfemmodel_vertices,Elements* newfemmodel_elements){/*{{{*/
    2869        
     2866
    28702867        int numberofelements                    = this->elements->NumberOfElements();   //global, entire old mesh
    28712868        int newnumberofelements         = newfemmodel_elements->Size();                 //just on the new partition
     
    28832880        int* P1input_enums                      = NULL;
    28842881        int* P1input_interp                     = NULL;
    2885         IssmDouble* values                      = NULL; 
     2882        IssmDouble* values                      = NULL;
    28862883   IssmDouble* vector           = NULL;
    28872884        IssmDouble* x                                   = NULL;//global, entire old mesh
     
    28952892        IssmDouble* newyc                               = NULL;//just on the new partition
    28962893        int* newelementslist                    = NULL;//just on the new partition
    2897         int* sidtoindex                         = NULL;//global vertices sid to partition index 
     2894        int* sidtoindex                         = NULL;//global vertices sid to partition index
    28982895
    28992896        /*Get old P0 and P1  inputs (entire mesh)*/
     
    29282925
    29292926        /*Insert P0 and P1 inputs into the new elements (just on the new partition)*/
    2930         values=xNew<IssmDouble>(elementswidth); 
     2927        values=xNew<IssmDouble>(elementswidth);
    29312928        for(int i=0;i<newfemmodel_elements->Size();i++){//just on the new partition
    29322929                Element* element=xDynamicCast<Element*>(newfemmodel_elements->GetObjectByOffset(i));
    29332930                /*newP0inputs is just on the new partition*/
    29342931                for(int j=0;j<numP0inputs;j++){
    2935                         switch(P0input_interp[j]){     
     2932                        switch(P0input_interp[j]){
    29362933                                case P0Enum:
    29372934                                case DoubleInputEnum:
    29382935                                        element->AddInput(new DoubleInput(P0input_enums[j],newP0inputs[i*numP0inputs+j]));
    29392936                                        break;
    2940                                 case IntInputEnum: 
     2937                                case IntInputEnum:
    29412938                                        element->AddInput(new IntInput(P0input_enums[j],reCast<int>(newP0inputs[i*numP0inputs+j])));
    29422939                                        break;
     
    29562953                }
    29572954        }
    2958        
     2955
    29592956        /*Cleanup*/
    29602957        xDelete<IssmDouble>(P0inputs);
     
    29952992
    29962993        if(!this->elements || !this->vertices || !this->results || !this->parameters) return;
    2997          
     2994
    29982995        parameters->FindParam(&step,StepEnum);
    29992996        parameters->FindParam(&time,TimeEnum);
     
    30133010        this->results->AddResult(new GenericExternalResult<IssmDouble*>(this->results->Size()+1,MeshYEnum,
    30143011                                        y,numberofvertices,1,step,time));
    3015        
     3012
    30163013        /*Cleanup*/
    30173014        xDelete<IssmDouble>(x);
     
    30743071   /*Assemble*/
    30753072        vmasklevelset->Assemble();
    3076        
     3073
    30773074        /*Serialize and set output*/
    30783075        (*pmasklevelset)=vmasklevelset->ToMPISerial();
     
    30883085
    30893086        /*newelementslist is in Matlab indexing*/
    3090        
     3087
    30913088        /*Creating connectivity table*/
    30923089        int* connectivity=NULL;
     
    30993096                        connectivity[vertexid-1]+=1;//Matlab to C indexing
    31003097                }
    3101         }       
     3098        }
    31023099
    31033100        /*Create vertex and insert in vertices*/
    31043101        for(int i=0;i<newnumberofvertices;i++){
    31053102                if(my_vertices[i]){
    3106                         Vertex *newvertex=new Vertex(); 
     3103                        Vertex *newvertex=new Vertex();
    31073104                        newvertex->id=i+1;
    31083105                        newvertex->sid=i;
     
    31153112                        newvertex->connectivity=connectivity[i];
    31163113                        newvertex->clone=false;//itapopo check this
    3117                         vertices->AddObject(newvertex); 
    3118                 } 
     3114                        vertices->AddObject(newvertex);
     3115                }
    31193116        }
    31203117
     
    31433140                        }
    31443141                        else newtria->element_type_list=NULL;
    3145                        
     3142
    31463143                        /*Element hook*/
    31473144                        int matpar_id=newnumberofelements+1; //retrieve material parameter id (last pointer in femodel->materials)
     
    31493146                        /*retrieve vertices ids*/
    31503147                        int* vertex_ids=xNew<int>(elementswidth);
    3151                         for(int j=0;j<elementswidth;j++)        vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing 
     3148                        for(int j=0;j<elementswidth;j++)        vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing
    31523149                        /*Setting the hooks*/
    31533150                        newtria->numanalyses =this->nummodels;
     
    31613158                        /*Clean up*/
    31623159                        xDelete<int>(vertex_ids);
    3163                         elements->AddObject(newtria);   
    3164                 } 
     3160                        elements->AddObject(newtria);
     3161                }
    31653162        }
    31663163
     
    31723169        for(int i=0;i<newnumberofelements;i++){
    31733170                if(my_elements[i]){
    3174                         materials->AddObject(new Matice(i+1,i,MaticeEnum));     
    3175                 } 
    3176         }
    3177        
     3171                        materials->AddObject(new Matice(i+1,i,MaticeEnum));
     3172                }
     3173        }
     3174
    31783175        /*Add new constant material property to materials, at the end: */
    31793176        Matpar *newmatpar=static_cast<Matpar*>(this->materials->GetObjectByOffset(this->materials->Size()-1)->copy());
    31803177        newmatpar->SetMid(newnumberofelements+1);
    3181         materials->AddObject(newmatpar);//put it at the end of the materials       
     3178        materials->AddObject(newmatpar);//put it at the end of the materials
    31823179}
    31833180/*}}}*/
     
    31863183        int lid=0;
    31873184        for(int j=0;j<newnumberofvertices;j++){
    3188                 if(my_vertices[j]){                             
    3189                        
    3190                         Node* newnode=new Node();       
    3191                        
     3185                if(my_vertices[j]){
     3186
     3187                        Node* newnode=new Node();
     3188
    31923189                        /*id: */
    31933190                        newnode->id=nodecounter+j+1;
     
    31953192                        newnode->lid=lid++;
    31963193                        newnode->analysis_enum=analysis_enum;
    3197                        
     3194
    31983195                        /*Initialize coord_system: Identity matrix by default*/
    31993196                        for(int k=0;k<3;k++) for(int l=0;l<3;l++) newnode->coord_system[k][l]=0.0;
    32003197                        for(int k=0;k<3;k++) newnode->coord_system[k][k]=1.0;
    3201                        
     3198
    32023199                        /*indexing:*/
    32033200                        newnode->indexingupdate=true;
    3204                        
     3201
    32053202                        Analysis* analysis=EnumToAnalysis(analysis_enum);
    32063203                        int *doftypes=NULL;
     
    32163213                        /*Stressbalance Horiz*/
    32173214                        if(analysis_enum==StressbalanceAnalysisEnum){
    3218                                 // itapopo this code is rarely used. 
     3215                                // itapopo this code is rarely used.
    32193216                                /*Coordinate system provided, convert to coord_system matrix*/
    32203217                                //XZvectorsToCoordinateSystem(&this->coord_system[0][0],&iomodel->Data(StressbalanceReferentialEnum)[j*6]);
     
    32313228        if(!femmodel_vertices) _error_("GetMesh: vertices are NULL.");
    32323229        if(!femmodel_elements) _error_("GetMesh: elements are NULL.");
    3233        
     3230
    32343231        int numberofvertices = femmodel_vertices->NumberOfVertices();
    32353232        int numberofelements = femmodel_elements->NumberOfElements();
     
    32373234        IssmDouble* x                   = NULL;
    32383235        IssmDouble* y                   = NULL;
    3239         IssmDouble* z                   = NULL; 
     3236        IssmDouble* z                   = NULL;
    32403237        int* elementslist       = NULL;
    32413238        int* elem_vertices      = NULL;
     
    32463243        /*Get vertices coordinates*/
    32473244        VertexCoordinatesx(&x,&y,&z,femmodel_vertices,false) ;
    3248        
     3245
    32493246        /*Get element vertices*/
    32503247        elem_vertices                           = xNew<int>(elementswidth);
     
    32613258        vid3->SetValue(element->sid,elem_vertices[2],INS_VAL);
    32623259   }
    3263                
     3260
    32643261        /*Assemble*/
    32653262   vid1->Assemble();
     
    32713268   id2 = vid2->ToMPISerial();
    32723269        id3 = vid3->ToMPISerial();
    3273        
     3270
    32743271        /*Construct elements list*/
    32753272        elementslist=xNew<int>(numberofelements*elementswidth);
     
    32803277                elementslist[elementswidth*i+2] = reCast<int>(id3[i])+1; //InterpMesh wants Matlab indexing
    32813278        }
    3282        
     3279
    32833280        /*Assign pointers*/
    32843281        *px                             = x;
     
    33013298        if(!femmodel_vertices) _error_("GetMesh: vertices are NULL.");
    33023299        if(!femmodel_elements) _error_("GetMesh: elements are NULL.");
    3303        
     3300
    33043301        int numberofvertices                    = femmodel_vertices->Size();    //number of vertices of this partition
    33053302        int numbertotalofvertices       = femmodel_vertices->NumberOfVertices();        //number total of vertices (entire mesh)
     
    33083305        IssmDouble* x                                   = NULL;
    33093306        IssmDouble* y                                   = NULL;
    3310         IssmDouble* z                                   = NULL; 
     3307        IssmDouble* z                                   = NULL;
    33113308        int* elementslist                               = NULL;
    33123309        int* sidtoindex                         = NULL;
    33133310        int* elem_vertices                      = NULL;
    3314        
     3311
    33153312        /*Get vertices coordinates of this partition*/
    33163313        sidtoindex      = xNewZeroInit<int>(numbertotalofvertices);//entire mesh, all vertices
     
    33183315        y                               = xNew<IssmDouble>(numberofvertices);//just this partitio;
    33193316        z                               = xNew<IssmDouble>(numberofvertices);//just this partitio;
    3320        
     3317
    33213318        /*Go through in this partition (vertices)*/
    33223319        for(int i=0;i<numberofvertices;i++){//just this partition
    3323                 Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i);       
     3320                Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i);
    33243321                /*Attention: no spherical coordinates*/
    33253322                x[i]=vertex->GetX();
     
    33343331        elementslist = xNew<int>(numberofelements*elementswidth);
    33353332        if(numberofelements*elementswidth<0) _error_("numberofelements negative.");
    3336        
     3333
    33373334        for(int i=0;i<numberofelements;i++){//just this partition
    33383335        Element* element=xDynamicCast<Element*>(femmodel_elements->GetObjectByOffset(i));
     
    33413338                elementslist[elementswidth*i+1] = sidtoindex[elem_vertices[1]]+1; //InterpMesh wants Matlab indexing
    33423339                elementslist[elementswidth*i+2] = sidtoindex[elem_vertices[2]]+1; //InterpMesh wants Matlab indexing
    3343         }       
    3344                
     3340        }
     3341
    33453342        /*Assign pointers*/
    33463343        *px                             = x;
     
    33483345        *pz                             = z;
    33493346        *pelementslist = elementslist; //Matlab indexing. InterMesh uses this type.
    3350         *psidtoindex    = sidtoindex;  //it is ncessary to insert inputs 
     3347        *psidtoindex    = sidtoindex;  //it is ncessary to insert inputs
    33513348
    33523349        /*Cleanup*/
     
    33593356        /*OTHERS CONSTRAINTS MUST BE IMPLEMENTED*/
    33603357        if(analysis_enum!=StressbalanceAnalysisEnum) return;
    3361        
     3358
    33623359        int numberofnodes_analysistype= this->nodes->NumberOfNodes(analysis_enum);
    3363         int dofpernode                                          = 2;                                                                                                            //vx and vy 
     3360        int dofpernode                                          = 2;                                                                                                            //vx and vy
    33643361        int numberofcols                                        = dofpernode*2;                                                                         //to keep dofs and flags in the vspc vector
    33653362        int numberofvertices                            = this->vertices->NumberOfVertices();                   //global, entire old mesh
     
    33853382        newy=xNew<IssmDouble>(newnumberofvertices);//just the new partition
    33863383        for(int i=0;i<newnumberofvertices;i++){//just the new partition
    3387                 Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i);     
     3384                Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i);
    33883385                /*Attention: no spherical coordinates*/
    33893386                newx[i]=vertex->GetX();
     
    33933390        /*Get spcvx and spcvy of old mesh*/
    33943391        for(int i=0;i<this->constraints->Size();i++){
    3395                
     3392
    33963393                Constraint* constraint=(Constraint*)constraints->GetObjectByOffset(i);
    33973394                if(!constraint->InAnalysis(analysis_enum)) _error_("AMR create constraints for "<<EnumToStringx(analysis_enum)<<" not supported yet!\n");
     
    34003397                int dof                                 = spcstatic->GetDof();
    34013398                int node                                        = spcstatic->GetNodeId();
    3402                 IssmDouble spcvalue     = spcstatic->GetValue(); 
     3399                IssmDouble spcvalue     = spcstatic->GetValue();
    34033400                int nodeindex                   = node-1;
    3404                
     3401
    34053402                /*vx and vx flag insertion*/
    34063403                if(dof==0) {//vx
    34073404                        vspc->SetValue(nodeindex*numberofcols,spcvalue,INS_VAL);    //vx
    34083405                        vspc->SetValue(nodeindex*numberofcols+dofpernode,1,INS_VAL);//vxflag
    3409                 } 
     3406                }
    34103407                /*vy and vy flag insertion*/
    34113408                if(dof==1){//vy
     
    34233420                                                                spc,numberofvertices,numberofcols,
    34243421                                                                newx,newy,newnumberofvertices,NULL);
    3425        
     3422
    34263423        /*Now, insert the interpolated constraints in the data set (constraints)*/
    34273424        count=0;
     
    34403437                /*spcvy*/
    34413438                if(!xIsNan<IssmDouble>(newspc[i*numberofcols+1]) && newspc[i*numberofcols+dofpernode+1]>(1-eps) ){
    3442                         newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum)); 
     3439                        newfemmodel_constraints->AddObject(new SpcStatic(constraintcounter+count+1,nodecounter+vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum));
    34433440                        //add count'th spc, on node i+1, setting dof 1 to vx.
    34443441                        count++;
     
    34973494        bool *my_elements = NULL;
    34983495        int *my_vertices  = NULL;
    3499        
    3500         _assert_(newnumberofvertices>0); 
    3501         _assert_(newnumberofelements>0); 
     3496
     3497        _assert_(newnumberofvertices>0);
     3498        _assert_(newnumberofelements>0);
    35023499        epart=xNew<int>(newnumberofelements);
    35033500        npart=xNew<int>(newnumberofvertices);
    35043501   index=xNew<int>(elementswidth*newnumberofelements);
    3505    
     3502
    35063503        for (int i=0;i<newnumberofelements;i++){
    35073504        for (int j=0;j<elementswidth;j++){
     
    35233520                for (int i=0;i<newnumberofvertices;i++) npart[i]=0;
    35243521        }
    3525         else _error_("At least one processor is required");         
     3522        else _error_("At least one processor is required");
    35263523
    35273524        my_vertices=xNew<int>(newnumberofvertices);
     
    35333530        for(int i=0;i<newnumberofelements;i++){
    35343531                /*!All elements have been partitioned above, only deal with elements for this cpu: */
    3535                 if(my_rank==epart[i]){ 
     3532                if(my_rank==epart[i]){
    35363533                        my_elements[i]=true;
    3537                         /*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use 
    3538                          *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing) 
    3539                          into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices 
     3534                        /*Now that we are here, we can also start building the list of vertices belonging to this cpu partition: we use
     3535                         *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing)
     3536                         into the vertices coordinates. If we start plugging 1 into my_vertices for each index[n][i] (i=0:2), then my_vertices
    35403537                         will hold which vertices belong to this partition*/
    35413538                        for(int j=0;j<elementswidth;j++){
    3542                                 _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing 
     3539                                _assert_(newelementslist[elementswidth*i+j]-1<newnumberofvertices);//newelementslist is in Matlab indexing
    35433540                                my_vertices[newelementslist[elementswidth*i+j]-1]=1;//newelementslist is in Matlab indexing
    35443541                        }
     
    35523549        /*Free ressources:*/
    35533550        xDelete<int>(epart);
    3554         xDelete<int>(npart);       
     3551        xDelete<int>(npart);
    35553552        xDelete<int>(index);
    35563553}
    35573554/*}}}*/
    35583555void FemModel::SmoothedDeviatoricStressTensor(IssmDouble** ptauxx,IssmDouble** ptauyy,IssmDouble** ptauxy){/*{{{*/
    3559        
     3556
    35603557        int elementswidth                                                       = this->GetElementsWidth();//just 2D mesh, tria elements
    35613558   int numberofvertices                                         = this->vertices->NumberOfVertices();
    35623559   IssmDouble weight                                            = 0.;
    3563         IssmDouble*     tauxx                                                   = NULL; 
    3564         IssmDouble*     tauyy                                                   = NULL; 
    3565         IssmDouble*     tauxy                                                   = NULL; 
     3560        IssmDouble*     tauxx                                                   = NULL;
     3561        IssmDouble*     tauyy                                                   = NULL;
     3562        IssmDouble*     tauxy                                                   = NULL;
    35663563   IssmDouble* totalweight                              = NULL;
    35673564        IssmDouble* deviatoricstressxx          = xNew<IssmDouble>(elementswidth);
     
    35733570   Vector<IssmDouble>* vectauxy                 = new Vector<IssmDouble>(numberofvertices);
    35743571   Vector<IssmDouble>* vectotalweight   = new Vector<IssmDouble>(numberofvertices);
    3575        
     3572
    35763573        /*Update the Deviatoric Stress tensor over the elements*/
    35773574        this->DeviatoricStressx();
    3578        
     3575
    35793576   /*Calculate the Smoothed Deviatoric Stress tensor*/
    35803577        for(int i=0;i<this->elements->Size();i++){
     
    36213618        /*Divide for the total weight*/
    36223619        for(int i=0;i<numberofvertices;i++){
    3623                 _assert_(totalweight[i]>0);     
     3620                _assert_(totalweight[i]>0);
    36243621                tauxx[i] = tauxx[i]/totalweight[i];
    36253622                tauyy[i] = tauyy[i]/totalweight[i];
     
    36463643void FemModel::ZZErrorEstimator(IssmDouble** pelementerror){/*{{{*/
    36473644
    3648         /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor. 
     3645        /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor.
    36493646         * Ref.: Zienkiewicz and Zhu, A Simple Error Estimator and Adaptive Procedure for Practical Engineering Analysis, Int. J. Numer. Meth. Eng, 1987*/
    36503647
     
    36663663        /*Get smoothed deviatoric stress tensor*/
    36673664        this->SmoothedDeviatoricStressTensor(&smoothedtauxx,&smoothedtauyy,&smoothedtauxy);
    3668        
     3665
    36693666        /*Integrate the error over elements*/
    36703667   for(int i=0;i<this->elements->Size();i++){
     
    36743671      element->GetInputListOnVertices(tauxy,DeviatoricStressxyEnum);
    36753672      element->GetVerticesSidList(elem_vertices);
    3676                
     3673
    36773674                /*Integrate*/
    36783675                element->GetVerticesCoordinates(&xyz_list);
     
    36893686                                ftxy+=(tauxy[n]-smoothedtauxy[elem_vertices[n]])*basis[n];
    36903687                        }
    3691                         error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2 
    3692                 }
    3693                 /*Set the error in the global vector*/ 
     3688                        error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2
     3689                }
     3690                /*Set the error in the global vector*/
    36943691      sid=element->Sid();
    36953692                error = sqrt(error);//sqrt(e^2)
     
    37053702   /*Serialize and set output*/
    37063703   (*pelementerror)=velementerror->ToMPISerial();
    3707        
     3704
    37083705        /*Cleanup*/
    37093706        xDelete<IssmDouble>(smoothedtauxx);
     
    37493746      Tria* triaelement = xDynamicCast<Tria*>(element);
    37503747      weight            = triaelement->GetArea();//the tria area is a choice for the weight
    3751      
     3748
    37523749                /*dH/dx*/
    37533750      vecdHdx->SetValue(elem_vertices[0],weight*GradH[0],ADD_VAL);
     
    38173814   /*Get smoothed deviatoric stress tensor*/
    38183815   this->SmoothedGradThickness(&smoothed_dHdx,&smoothed_dHdy);
    3819    
     3816
    38203817        /*Integrate the error over elements*/
    38213818   for(int i=0;i<this->elements->Size();i++){
     
    39033900        IssmDouble* x                                   = NULL;
    39043901        IssmDouble* y                                   = NULL;
    3905         IssmDouble* z                                   = NULL; 
     3902        IssmDouble* z                                   = NULL;
    39063903        IssmDouble* xyz_list                    = NULL;
    39073904        IssmDouble x1,y1,x2,y2,x3,y3;
     
    39123909      //element->GetVerticesSidList(elem_vertices);
    39133910      int sid = element->Sid();
    3914                 element->GetVerticesCoordinates(&xyz_list); 
     3911                element->GetVerticesCoordinates(&xyz_list);
    39153912                x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1];
    39163913                x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1];
     
    39453942                _error_("level set type not implemented yet!");
    39463943        }
    3947        
     3944
    39483945        /*Outputs*/
    39493946        IssmDouble* zerolevelset_points                 = NULL;
    39503947        int npoints                                                                             = 0;
    3951        
     3948
    39523949        /*Intermediaries*/
    39533950        int elementswidth                       = this->GetElementsWidth();
     
    39623959        int count,sid;
    39633960        IssmDouble xc,yc,x1,y1,x2,y2,x3,y3;
    3964        
     3961
    39653962        /*Use the element center coordinate if level set is zero (grounding line or ice front), otherwise set NAN*/
    39663963   for(int i=0;i<this->elements->Size();i++){
     
    39693966                element->GetVerticesSidList(elem_vertices);
    39703967                sid= element->Sid();
    3971                 element->GetVerticesCoordinates(&xyz_list); 
     3968                element->GetVerticesCoordinates(&xyz_list);
    39723969                x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1];
    39733970                x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1];
    39743971                x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1];
    39753972                xc      = NAN;
    3976                 yc      = NAN; 
     3973                yc      = NAN;
    39773974        Tria* tria      = xDynamicCast<Tria*>(element);
    39783975                if(tria->IsIceInElement()){/*verify if there is ice in the element*/
    3979                         if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. || 
     3976                        if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. ||
    39803977                                abs(levelset[0]*levelset[1])<DBL_EPSILON || abs(levelset[0]*levelset[2])<DBL_EPSILON) {
    39813978                                xc=(x1+x2+x3)/3.;
     
    40074004                }
    40084005        }
    4009        
     4006
    40104007        /*Assign outputs*/
    40114008        numberofpoints                          = npoints;
     
    40474044        responses_pointer=d_responses;
    40484045
    4049         //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 
     4046        //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled.
    40504047        //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: */
    40514048
     
    41404137
    41414138        int         ns,nsmax;
    4142        
     4139
    41434140        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    41444141        ns = elements->Size();
    4145        
     4142
    41464143        /*Figure out max of ns: */
    41474144        ISSM_MPI_Reduce(&ns,&nsmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     
    41624159                }
    41634160        }
    4164        
     4161
    41654162        /*One last time: */
    41664163        pUp->Assemble();
     
    41814178
    41824179        int         ns,nsmax;
    4183        
     4180
    41844181        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    41854182        ns = elements->Size();
    4186        
    4187         /*First, figure out the surface area of Earth: */ 
     4183
     4184        /*First, figure out the surface area of Earth: */
    41884185        for(int i=0;i<ns;i++){
    41894186                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     
    42094206                }
    42104207        }
    4211        
     4208
    42124209        /*One last time: */
    42134210        pUp->Assemble();
     
    42264223#endif
    42274224#ifdef _HAVE_SEALEVELRISE_
    4228 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius) { /*{{{*/
     4225void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pRSLgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop) { /*{{{*/
    42294226
    42304227        /*serialized vectors:*/
     
    42374234        IssmDouble  eartharea_cpu  = 0.;
    42384235        int         ns,nsmax;
    4239        
     4236
    42404237        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    42414238        ns = elements->Size();
     
    42614258        for(int i=0;i<nsmax;i++){
    42624259                if(i<ns){
    4263                
    4264                         if(VerboseConvergence())if(i%100==0)_printf0_("\r" << "      convolution progress: " << (double)i/(double)ns*100 << "%  ");
    4265                
     4260
     4261                        if(VerboseConvergence())if(i%100==0)_printf0_("\r" << "              convolution progress: " << (double)i/(double)ns*100 << "%  ");
     4262
    42664263                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    4267                         element->SealevelriseEustatic(pSgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);
     4264                        element->SealevelriseEustatic(pRSLgi,&eustatic_cpu_e,latitude,longitude,radius,oceanarea,eartharea);
    42684265                        eustatic_cpu+=eustatic_cpu_e;
    42694266                }
    4270                 if(i%100==0)pSgi->Assemble();
     4267                if(i%loop==0)pRSLgi->Assemble();
    42714268        }
    42724269        if(VerboseConvergence())_printf0_("\n");
    4273                
     4270
    42744271        /*One last time: */
    4275         pSgi->Assemble();
     4272        pRSLgi->Assemble();
    42764273
    42774274        /*Sum all eustatic components from all cpus:*/
     
    42854282}
    42864283/*}}}*/
    4287 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution){/*{{{*/
     4284void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pRSLgo, Vector<IssmDouble>* pRSLg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, bool verboseconvolution,int loop){/*{{{*/
    42884285
    42894286        /*serialized vectors:*/
    4290         IssmDouble* Sg_old=NULL;
    4291        
     4287        IssmDouble* RSLg_old=NULL;
     4288
    42924289        IssmDouble  eartharea=0;
    42934290        IssmDouble  eartharea_cpu=0;
    42944291
    42954292        int         ns,nsmax;
    4296        
     4293
    42974294        /*Serialize vectors from previous iteration:*/
    4298         Sg_old=pSg_old->ToMPISerial();
     4295        RSLg_old=pRSLg_old->ToMPISerial();
    42994296
    43004297        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
     
    43064303                eartharea_cpu += element->GetAreaSpherical();
    43074304        }
    4308        
     4305
    43094306        ISSM_MPI_Reduce (&eartharea_cpu,&eartharea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    43104307        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     
    43174314        for(int i=0;i<nsmax;i++){
    43184315                if(i<ns){
    4319                         if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf_("\r" << "      convolution progress: " << (double)i/(double)ns*100 << "%   ");
     4316                        if(verboseconvolution)if(VerboseConvergence())if(i%100==0)_printf0_("\r" << "              convolution progress: " << (double)i/(double)ns*100 << "%   ");
    43204317                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    4321                         element->SealevelriseNonEustatic(pSgo,Sg_old,latitude,longitude,radius,eartharea);
    4322                 }
    4323                 if(i%100==0)pSgo->Assemble();
    4324         }
    4325         if(verboseconvolution)if(VerboseConvergence())_printf_("\n");
    4326        
     4318                        element->SealevelriseNonEustatic(pRSLgo,RSLg_old,latitude,longitude,radius,eartharea);
     4319                }
     4320                if(i%loop==0)pRSLgo->Assemble();
     4321        }
     4322        if(verboseconvolution)if(VerboseConvergence())_printf0_("\n");
     4323
    43274324        /*Free ressources:*/
    4328         xDelete<IssmDouble>(Sg_old);
    4329 }
    4330 /*}}}*/
    4331 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pSgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/
     4325        xDelete<IssmDouble>(RSLg_old);
     4326}
     4327/*}}}*/
     4328void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius){/*{{{*/
    43324329
    43334330        /*serialized vectors:*/
    4334         IssmDouble* Sg_old=NULL;
     4331        IssmDouble* RSLg_old=NULL;
    43354332        IssmDouble  eartharea=0;
    43364333        IssmDouble  eartharea_cpu=0;
    43374334        IssmDouble      tide_love_h, tide_love_k, fluid_love, moi_e, moi_p, omega, g;
    4338         IssmDouble      load_love_k2 = -0.30922675; //degree 2 load Love number 
    4339         IssmDouble      m1, m2, m3; 
    4340         IssmDouble      lati, longi, radi, value; 
     4335        IssmDouble      load_love_k2 = -0.30922675; //degree 2 load Love number
     4336        IssmDouble      m1, m2, m3;
     4337        IssmDouble      lati, longi, radi, value;
    43414338
    43424339        /*Serialize vectors from previous iteration:*/
    4343         Sg_old=pSg_old->ToMPISerial();
     4340        RSLg_old=pRSLg_old->ToMPISerial();
    43444341
    43454342        /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
     
    43514348        ISSM_MPI_Bcast(&eartharea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    43524349
    4353         IssmDouble moi_list[3]={0,0,0}; 
    4354         IssmDouble moi_list_cpu[3]={0,0,0}; 
     4350        IssmDouble moi_list[3]={0,0,0};
     4351        IssmDouble moi_list_cpu[3]={0,0,0};
    43554352        for(int i=0;i<elements->Size();i++){
    43564353                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    4357                 element->SealevelriseMomentOfInertia(&moi_list[0],Sg_old,eartharea);
    4358                 moi_list_cpu[0] += moi_list[0]; 
    4359                 moi_list_cpu[1] += moi_list[1]; 
    4360                 moi_list_cpu[2] += moi_list[2]; 
     4354                element->SealevelriseMomentOfInertia(&moi_list[0],RSLg_old,eartharea);
     4355                moi_list_cpu[0] += moi_list[0];
     4356                moi_list_cpu[1] += moi_list[1];
     4357                moi_list_cpu[2] += moi_list[2];
    43614358        }
    43624359        ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    43634360        ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4364         //     
     4361        //
    43654362        ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    43664363        ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4367         //     
     4364        //
    43684365        ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    43694366        ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4370        
     4367
    43714368        /*pull out some useful parameters: */
    43724369        parameters->FindParam(&tide_love_h,SealevelriseTidalLoveHEnum);
     
    43784375
    43794376        /*compute perturbation terms for angular velocity vector: */
    4380         m1 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[0]; 
    4381         m2 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[1]; 
    4382         m3 = -(1+load_love_k2)/moi_p * moi_list[2];     // term associated with fluid number (3-order-of-magnitude smaller) is negelected 
     4377        m1 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[0];
     4378        m2 = 1/(1-tide_love_k/fluid_love) * (1+load_love_k2)/(moi_p-moi_e) * moi_list[1];
     4379        m3 = -(1+load_love_k2)/moi_p * moi_list[2];     // term associated with fluid number (3-order-of-magnitude smaller) is negelected
    43834380
    43844381        /* Green's function (1+k_2-h_2/g): checked against Glenn Milne's thesis Chapter 3 (eqs: 3.3-4, 3.10-11)
    4385          * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3) 
    4386          * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered) 
    4387          * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180] 
     4382         * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3)
     4383         * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered)
     4384         * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180]
    43884385         */
    43894386        for(int i=0;i<vertices->Size();i++){
     
    43954392                lati=latitude[sid]/180*PI;      longi=longitude[sid]/180*PI; radi=radius[sid];
    43964393
    4397                 /*only first order terms are considered now: */ 
     4394                /*only first order terms are considered now: */
    43984395                value=((1.0+tide_love_k-tide_love_h)/9.81)*pow(omega*radi,2.0)*
    4399                                                 (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi))); 
    4400        
    4401                 pSgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times
     4396                                                (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi)));
     4397
     4398                pRSLgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times
    44024399        }
    44034400
    44044401        /*Assemble mesh velocity*/
    4405         pSgo_rot->Assemble();
    4406        
     4402        pRSLgo_rot->Assemble();
     4403
    44074404        /*Assign output pointers:*/
    4408         *pIxz=moi_list[0];
    4409         *pIyz=moi_list[1];
    4410         *pIzz=moi_list[2];
     4405        if(pIxz)*pIxz=moi_list[0];
     4406        if(pIyz)*pIyz=moi_list[1];
     4407        if(pIzz)*pIzz=moi_list[2];
    44114408
    44124409        /*Free ressources:*/
    4413         xDelete<IssmDouble>(Sg_old);
    4414        
    4415 }
    4416 /*}}}*/
    4417 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){/*{{{*/
     4410        xDelete<IssmDouble>(RSLg_old);
     4411
     4412}
     4413/*}}}*/
     4414void FemModel::SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pRSLg, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz,int loop,int horiz){/*{{{*/
    44184415
    44194416        /*serialized vectors:*/
    4420         IssmDouble* Sg=NULL;
    4421        
     4417        IssmDouble* RSLg=NULL;
     4418
    44224419        IssmDouble  eartharea=0;
    44234420        IssmDouble  eartharea_cpu=0;
    44244421
    44254422        int         ns,nsmax;
    4426        
     4423
    44274424        /*Serialize vectors from previous iteration:*/
    4428         Sg=pSg->ToMPISerial();
     4425        RSLg=pRSLg->ToMPISerial();
    44294426
    44304427        /*Go through elements, and add contribution from each element to the deflection vector wg:*/
    44314428        ns = elements->Size();
    4432        
     4429
    44334430        /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
    44344431        for(int i=0;i<ns;i++){
     
    44464443        for(int i=0;i<nsmax;i++){
    44474444                if(i<ns){
     4445                        if(VerboseConvergence())if(i%100==0)_printf0_("\r" << "              convolution progress: " << (double)i/(double)ns*100 << "%  ");
    44484446                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    4449                         element->SealevelriseGeodetic(pUp,pNorth,pEast,Sg,latitude,longitude,radius,xx,yy,zz,eartharea);
    4450                 }
    4451                 if(i%100==0){
     4447                        element->SealevelriseGeodetic(pUp,pNorth,pEast,RSLg,latitude,longitude,radius,xx,yy,zz,eartharea,horiz);
     4448                }
     4449                if(i%loop==0){
    44524450                        pUp->Assemble();
    4453                         pNorth->Assemble();
    4454                         pEast->Assemble();
    4455                 }
    4456         }
    4457        
     4451                        if (horiz){
     4452                                pNorth->Assemble();
     4453                                pEast->Assemble();
     4454                        }
     4455                }
     4456        }
     4457
    44584458        /*One last time: */
    44594459        pUp->Assemble();
    4460         pNorth->Assemble();
    4461         pEast->Assemble();
     4460        if(horiz){
     4461                pNorth->Assemble();
     4462                pEast->Assemble();
     4463        }
     4464        if(VerboseConvergence())_printf0_("\n");
    44624465
    44634466        /*Free ressources:*/
    4464         xDelete<IssmDouble>(Sg);
    4465         xDelete<IssmDouble>(latitude);
    4466         xDelete<IssmDouble>(longitude);
    4467         xDelete<IssmDouble>(radius);
    4468         xDelete<IssmDouble>(xx);
    4469         xDelete<IssmDouble>(yy);
    4470         xDelete<IssmDouble>(zz);
    4471 }
    4472 /*}}}*/
    4473 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* Sg) { /*{{{*/
    4474 
    4475         IssmDouble* Sg_serial=NULL;
     4467        xDelete<IssmDouble>(RSLg);
     4468}
     4469/*}}}*/
     4470IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* RSLg) { /*{{{*/
     4471
     4472        IssmDouble* RSLg_serial=NULL;
    44764473        IssmDouble  oceanvalue,oceanvalue_cpu;
    44774474        IssmDouble  oceanarea,oceanarea_cpu;
    44784475
    44794476        /*Serialize vectors from previous iteration:*/
    4480         Sg_serial=Sg->ToMPISerial();
     4477        RSLg_serial=RSLg->ToMPISerial();
    44814478
    44824479        /*Initialize:*/
     
    44884485                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    44894486                oceanarea_cpu += element->OceanArea();
    4490                 oceanvalue_cpu += element->OceanAverage(Sg_serial);
     4487                oceanvalue_cpu += element->OceanAverage(RSLg_serial);
    44914488        }
    44924489        ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    44934490        ISSM_MPI_Bcast(&oceanarea,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4494        
     4491
    44954492        ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    44964493        ISSM_MPI_Bcast(&oceanvalue,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    44974494
    44984495        /*Free ressources:*/
    4499         xDelete<IssmDouble>(Sg_serial);
    4500        
     4496        xDelete<IssmDouble>(RSLg_serial);
     4497
    45014498        return oceanvalue/oceanarea;
    45024499}
     
    45144511        int*                eplzigzag_counter = NULL;
    45154512        int                 eplflip_lock;
    4516        
     4513
    45174514        HydrologyDCEfficientAnalysis* effanalysis =  new HydrologyDCEfficientAnalysis();
    45184515        HydrologyDCInefficientAnalysis* inefanalysis =  new HydrologyDCInefficientAnalysis();
     
    45214518        mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
    45224519        recurence=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCEfficientAnalysisEnum));
    4523         this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum); 
    4524         this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum); 
     4520        this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum);
     4521        this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum);
    45254522        GetVectorFromInputsx(&old_active,this,HydrologydcMaskEplactiveNodeEnum,NodeSIdEnum);
    4526        
     4523
    45274524        for (int i=0;i<elements->Size();i++){
    45284525                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     
    45424539        /*Assemble and serialize*/
    45434540        mask->Assemble();
    4544         serial_mask=mask->ToMPISerial();       
    4545        
     4541        serial_mask=mask->ToMPISerial();
     4542
    45464543        xDelete<int>(eplzigzag_counter);
    45474544        xDelete<IssmDouble>(serial_rec);
     
    45854582        int sum_counter;
    45864583        ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    4587         ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());               
     4584        ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    45884585        counter=sum_counter;
    45894586        *pEplcount = counter;
    45904587        if(VerboseSolution()) _printf0_("   Number of active nodes in EPL layer: "<< counter <<"\n");
     4588
     4589        /*Update dof indexings*/
     4590        this->UpdateConstraintsx();
     4591
     4592}
     4593/*}}}*/
     4594void FemModel::HydrologyIDSupdateDomainx(IssmDouble* pIDScount){ /*{{{*/
     4595
     4596        bool                isthermal;
     4597        Vector<IssmDouble>* mask                                = NULL;
     4598        Vector<IssmDouble>* active                              = NULL;
     4599        IssmDouble*         serial_mask = NULL;
     4600        IssmDouble*         serial_active       = NULL;
     4601
     4602        HydrologyDCInefficientAnalysis* inefanalysis =  new HydrologyDCInefficientAnalysis();
     4603        parameters->FindParam(&isthermal,TransientIsthermalEnum);
     4604
     4605        /*When solving a thermal model we update the thawed nodes*/
     4606        if(isthermal){
     4607                /*Step 1: update mask, the mask correspond to thawed nodes (that have a meltingrate)*/
     4608                mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum));
     4609
     4610                for (int i=0;i<elements->Size();i++){
     4611                        Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     4612                        inefanalysis->HydrologyIDSGetMask(mask,element);
     4613                }
     4614                /*Assemble and serialize*/
     4615                mask->Assemble();
     4616                serial_mask=mask->ToMPISerial();
     4617                delete mask;
     4618        }
     4619        /*for other cases we just grab the mask from the initialisation value*/
     4620        else{
     4621                GetVectorFromInputsx(&serial_mask,this,HydrologydcMaskThawedNodeEnum,NodeSIdEnum);
     4622        }
     4623        /*Update Mask and elementize*/
     4624        InputUpdateFromVectorx(this,serial_mask,HydrologydcMaskThawedNodeEnum,NodeSIdEnum);
     4625        xDelete<IssmDouble>(serial_mask);
     4626        inefanalysis->ElementizeIdsMask(this);
     4627
     4628        /*get node mask coherent with element mask*/
     4629        active=new Vector<IssmDouble>(nodes->NumberOfNodes(HydrologyDCInefficientAnalysisEnum));
     4630        for (int i=0;i<elements->Size();i++){
     4631                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     4632                inefanalysis->HydrologyIdsGetActive(active,element);
     4633        }
     4634
     4635        /*Assemble and serialize*/
     4636        active->Assemble();
     4637        serial_active=active->ToMPISerial();
     4638        delete active;
     4639
     4640        /*Update node activation accordingly*/
     4641        int counter =0;
     4642        for (int i=0;i<nodes->Size();i++){
     4643                Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
     4644                if(node->InAnalysis(HydrologyDCInefficientAnalysisEnum)){
     4645                        if(serial_active[node->Sid()]==1.){
     4646                                node->Activate();
     4647                                if(!node->IsClone()) counter++;
     4648                        }
     4649                        else{
     4650                                node->Deactivate();
     4651                        }
     4652                }
     4653        }
     4654
     4655        xDelete<IssmDouble>(serial_active);
     4656        delete inefanalysis;
     4657        int sum_counter;
     4658        ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     4659        ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     4660        counter=sum_counter;
     4661        *pIDScount = counter;
     4662        if(VerboseSolution()) _printf0_("   Number of active nodes in IDS layer: "<< counter <<"\n");
    45914663
    45924664        /*Update dof indexings*/
     
    46314703        int sum_counter;
    46324704        ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    4633         ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());               
     4705        ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    46344706        counter=sum_counter;
    46354707        *pL2count = counter;
     
    47164788}
    47174789/*}}}*/
    4718 #ifdef _HAVE_JAVASCRIPT_ 
     4790#ifdef _HAVE_JAVASCRIPT_
    47194791FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/
    47204792        /*configuration: */
     
    47314803        /*From command line arguments, retrieve different filenames needed to create the FemModel: */
    47324804        solution_type=StringToEnumx(solution);
    4733        
     4805
    47344806        /*Create femmodel from input files: */
    47354807        profiler->Start(MPROCESSOR);
    47364808        this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL);
    47374809        profiler->Stop(MPROCESSOR);
    4738        
     4810
    47394811        /*Save communicator in the parameters dataset: */
    47404812        this->parameters->AddObject(new GenericParam<ISSM_MPI_Comm>(incomm,FemModelCommEnum));
     
    47514823        size_t* poutputbuffersize;
    47524824
    4753        
    47544825        /*Before we delete the profiler, report statistics for this run: */
    47554826        profiler->Stop(TOTAL);  //final tagging
     
    47644835                                );
    47654836        _printf0_("\n");
    4766        
     4837
    47674838        /*Before we close the output file, recover the buffer and size:*/
    47684839        outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum));
     
    48044875
    48054876        /*Open output file once for all and add output file descriptor to parameters*/
    4806         output_fid=open_memstream(&outputbuffer,&outputsize); 
     4877        output_fid=open_memstream(&outputbuffer,&outputsize);
    48074878        if(output_fid==NULL)_error_("could not initialize output stream");
    48084879        this->parameters->SetParam(output_fid,OutputFilePointerEnum);
     
    48204891        IssmDouble *newy                        = NULL;
    48214892        IssmDouble *newz                        = NULL;
     4893        IssmDouble *newxylist   = NULL;
    48224894        int *newelementslist            = NULL;
     4895        int* newdatalist        = NULL;
    48234896        int newnumberofvertices = -1;
    48244897        int newnumberofelements = -1;
     
    48454918                /*Initialize hmaxvertices with NAN*/
    48464919                hmaxvertices_serial=xNew<IssmDouble>(numberofvertices);
    4847                 for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN; 
     4920                for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN;
    48484921                /*Fill hmaxvertices*/
    48494922                if(this->amrbamg->groundingline_distance>0)             this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskGroundediceLevelsetEnum);
     
    48524925                if(this->amrbamg->deviatoricerror_threshold>0)  this->GethmaxVerticesFromEstimators(hmaxvertices_serial,DeviatoricStressErrorEstimatorEnum);
    48534926        }
    4854        
     4927
    48554928        if(my_rank==0){
    4856                 this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist);
    4857                 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the refinement process.");
    4858         }
    4859 
    4860         /*Cleanup*/
    4861         xDelete<IssmDouble>(vector_serial);
    4862         xDelete<IssmDouble>(hmaxvertices_serial);
    4863         delete vector;
    4864 
    4865         /*Send new mesh to others CPU*/
    4866         ISSM_MPI_Bcast(&newnumberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    4867         ISSM_MPI_Bcast(&newnumberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    4868         if(my_rank){
    4869                 newx=xNew<IssmDouble>(newnumberofvertices);
    4870                 newy=xNew<IssmDouble>(newnumberofvertices);
    4871                 newz=xNew<IssmDouble>(newnumberofvertices);
    4872                 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
    4873         }
    4874         ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4875         ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4876         ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    4877         ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());       
    4878 
    4879         /*Assign output pointers*/
    4880         *pnewnumberofvertices = newnumberofvertices;
    4881         *pnewnumberofelements = newnumberofelements;
    4882         *pnewx = newx;
    4883         *pnewy = newy;
    4884         *pnewz = newz;
    4885         *pnewelementslist = newelementslist;
     4929                this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newdatalist,&newxylist,&newelementslist);
     4930                if(newdatalist[0]<=0 || newdatalist[1]<=0) _error_("Error in the refinement process.");
     4931        }
     4932
     4933   /*Send new mesh to others CPU's*/
     4934   if(my_rank) newdatalist=xNew<int>(2);
     4935   ISSM_MPI_Bcast(newdatalist,2,ISSM_MPI_INT,0,IssmComm::GetComm());
     4936   newnumberofvertices=newdatalist[0];
     4937   newnumberofelements=newdatalist[1];
     4938   if(my_rank){
     4939      newxylist      =xNew<IssmDouble>(newnumberofvertices*2);
     4940      newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
     4941   }
     4942   ISSM_MPI_Bcast(newxylist,newnumberofvertices*2,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     4943   ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());
     4944
     4945        /*Reorganize the data*/
     4946   newx=xNew<IssmDouble>(newnumberofvertices);
     4947   newy=xNew<IssmDouble>(newnumberofvertices);
     4948   newz=xNewZeroInit<IssmDouble>(newnumberofvertices);
     4949   for(int i=0;i<newnumberofvertices;i++){
     4950      newx[i] = newxylist[2*i];
     4951      newy[i] = newxylist[2*i+1];
     4952   }
     4953
     4954   /*Assign output pointers*/
     4955   *pnewnumberofvertices = newnumberofvertices;
     4956   *pnewnumberofelements = newnumberofelements;
     4957   *pnewx = newx;
     4958   *pnewy = newy;
     4959   *pnewz = newz;
     4960   *pnewelementslist = newelementslist;
     4961
     4962   /*Cleanup*/
     4963   xDelete<int>(newdatalist);
     4964   xDelete<IssmDouble>(newxylist);
     4965   xDelete<IssmDouble>(vector_serial);
     4966   xDelete<IssmDouble>(hmaxvertices_serial);
     4967   delete vector;
    48864968}
    48874969/*}}}*/
     
    49084990        /*Create bamg data structures for bamg*/
    49094991        this->amrbamg = new AmrBamg();
    4910        
     4992
    49114993        /*Get amr parameters*/
    49124994        this->parameters->FindParam(&hmin,AmrHminEnum);
     
    49325014
    49335015        /*Re-create original mesh and put it in bamg structure (only cpu 0)*/
    4934         if(my_rank==0){ 
     5016        if(my_rank==0){
    49355017                this->amrbamg->Initialize(elements,x,y,numberofvertices,numberofelements);
    49365018        }
     
    49465028
    49475029        if(!hmaxvertices) _error_("hmaxvertices is NULL!\n");
    4948        
     5030
    49495031        /*Intermediaries*/
    49505032        int numberofvertices                     = this->vertices->NumberOfVertices();
     
    49535035
    49545036        switch(levelset_type){
    4955                 case MaskGroundediceLevelsetEnum: 
     5037                case MaskGroundediceLevelsetEnum:
    49565038                        threshold       = this->amrbamg->groundingline_distance;
    49575039                        resolution      = this->amrbamg->groundingline_resolution;
     
    49675049        this->GetVerticeDistanceToZeroLevelSet(&verticedistance,levelset_type);
    49685050        if(!verticedistance) _error_("verticedistance is NULL!\n");
    4969        
     5051
    49705052        /*Fill hmaxVertices*/
    49715053        for(int i=0;i<numberofvertices;i++){
     
    49815063/*}}}*/
    49825064void FemModel::GethmaxVerticesFromEstimators(IssmDouble* hmaxvertices,int errorestimator_type){/*{{{*/
    4983    
     5065
    49845066        if(!hmaxvertices) _error_("hmaxvertices is NULL!\n");
    49855067
     
    49895071        int numberofvertices                                            = this->vertices->NumberOfVertices();
    49905072        IssmDouble* maxlength                                   = xNew<IssmDouble>(numberofelements);
    4991         IssmDouble* error_vertices                              = xNewZeroInit<IssmDouble>(numberofvertices);   
     5073        IssmDouble* error_vertices                              = xNewZeroInit<IssmDouble>(numberofvertices);
    49925074        IssmDouble* error_elements                              = NULL;
    49935075        IssmDouble* x                                                           = NULL;
     
    50025084        /*Fill variables*/
    50035085        switch(errorestimator_type){
    5004                 case ThicknessErrorEstimatorEnum: 
     5086                case ThicknessErrorEstimatorEnum:
    50055087                        threshold               = this->amrbamg->thicknesserror_threshold;
    50065088                        groupthreshold  = this->amrbamg->thicknesserror_groupthreshold;
     
    50275109        case ThicknessErrorEstimatorEnum:                       this->amrbamg->thicknesserror_maximum   = maxerror;break;
    50285110        case DeviatoricStressErrorEstimatorEnum:        this->amrbamg->deviatoricerror_maximum = maxerror;break;
    5029         }       
     5111        }
    50305112        }
    50315113
    50325114        /*Get mesh*/
    50335115        this->GetMesh(this->vertices,this->elements,&x,&y,&z,&index);
    5034        
     5116
    50355117        /*Fill error_vertices (this is the sum of all elements connected to the vertex)*/
    50365118        for(int i=0;i<numberofelements;i++){
     
    50465128                error_vertices[v2]+=error_elements[i];
    50475129                error_vertices[v3]+=error_elements[i];
    5048         }       
     5130        }
    50495131
    50505132        /*Fill hmaxvertices with the criteria*/
     
    50605142                        }
    50615143                }
    5062                 /*Now, fill the hmaxvertices if requested*/       
     5144                /*Now, fill the hmaxvertices if requested*/
    50635145                if(refine){
    50645146                        for(int j=0;j<elementswidth;j++){
     
    50905172        /*Output*/
    50915173        IssmDouble* verticedistance;
    5092        
     5174
    50935175        /*Intermediaries*/
    50945176   int numberofvertices       = this->vertices->NumberOfVertices();
     
    51025184        /*Get vertices coordinates*/
    51035185        VertexCoordinatesx(&x,&y,&z,this->vertices,false) ;
    5104        
    5105         /*Get points which level set is zero (center of elements with zero level set)*/ 
     5186
     5187        /*Get points which level set is zero (center of elements with zero level set)*/
    51065188        this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type);
    51075189
     
    51125194                for(int j=0;j<numberofpoints;j++){
    51135195                        distance=sqrt((x[i]-levelset_points[2*j])*(x[i]-levelset_points[2*j])+(y[i]-levelset_points[2*j+1])*(y[i]-levelset_points[2*j+1]));
    5114                         verticedistance[i]=min(distance,verticedistance[i]);           
    5115                 }
    5116         }       
     5196                        verticedistance[i]=min(distance,verticedistance[i]);
     5197                }
     5198        }
    51175199
    51185200        /*Assign the pointer*/
     
    51335215        /*pnewelementslist keep vertices in Matlab indexing*/
    51345216   int my_rank                                          = IssmComm::GetRank();
    5135    int numberofelements                 = this->elements->NumberOfElements();
    51365217        IssmDouble* gl_distance         = NULL;
    51375218        IssmDouble* if_distance         = NULL;
     
    51415222   IssmDouble* newy                             = NULL;
    51425223   IssmDouble* newz                             = NULL;
     5224        IssmDouble* newxylist           = NULL;
    51435225   int* newelementslist                 = NULL;
    5144    int newnumberofvertices              = -1;
     5226        int* newdatalist                                = NULL;
     5227        int newnumberofvertices         = -1;
    51455228        int newnumberofelements         = -1;
    51465229
     
    51485231        if(this->amr->groundingline_distance>0)         this->GetElementDistanceToZeroLevelSet(&gl_distance,MaskGroundediceLevelsetEnum);
    51495232   if(this->amr->icefront_distance>0)                           this->GetElementDistanceToZeroLevelSet(&if_distance,MaskIceLevelsetEnum);
    5150    if(this->amr->thicknesserror_threshold>0)            this->ThicknessZZErrorEstimator(&thicknesserror);       
    5151         if(this->amr->deviatoricerror_threshold>0)      this->ZZErrorEstimator(&deviatoricerror);       
    5152        
     5233   if(this->amr->thicknesserror_threshold>0)            this->ThicknessZZErrorEstimator(&thicknesserror);
     5234        if(this->amr->deviatoricerror_threshold>0)      this->ZZErrorEstimator(&deviatoricerror);
     5235
    51535236        if(my_rank==0){
    51545237                this->amr->ExecuteRefinement(gl_distance,if_distance,deviatoricerror,thicknesserror,
    5155                                                                                                 &newnumberofvertices,&newnumberofelements,&newx,&newy,&newelementslist);
    5156                 newz=xNewZeroInit<IssmDouble>(newnumberofvertices);
    5157                 if(newnumberofvertices<=0 || newnumberofelements<=0) _error_("Error in the ReMeshNeopz.");
    5158         }
    5159 
    5160         /*Send new mesh to others CPU*/
    5161         ISSM_MPI_Bcast(&newnumberofvertices,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    5162         ISSM_MPI_Bcast(&newnumberofelements,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    5163         if(my_rank){
    5164                 newx=xNew<IssmDouble>(newnumberofvertices);
    5165                 newy=xNew<IssmDouble>(newnumberofvertices);
    5166                 newz=xNew<IssmDouble>(newnumberofvertices);
    5167                 newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
    5168         }
    5169         ISSM_MPI_Bcast(newx,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    5170         ISSM_MPI_Bcast(newy,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    5171         ISSM_MPI_Bcast(newz,newnumberofvertices,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    5172         ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());       
    5173 
    5174         /*Assign the pointers*/
    5175         (*pnewelementslist)     = newelementslist; //Matlab indexing
    5176         (*pnewx)                                        = newx;
    5177         (*pnewy)                                        = newy;
    5178         (*pnewz)                                        = newz;
    5179         *pnewnumberofvertices= newnumberofvertices;
    5180         *pnewnumberofelements= newnumberofelements;
     5238                                                                                                &newdatalist,&newxylist,&newelementslist);
     5239                if(newdatalist[0]<=0 || newdatalist[1]<=0) _error_("Error in the ReMeshNeopz.");       
     5240        }
     5241
     5242        /*Send new mesh to others CPU's*/
     5243        if(my_rank) newdatalist=xNew<int>(2);
     5244   ISSM_MPI_Bcast(newdatalist,2,ISSM_MPI_INT,0,IssmComm::GetComm());
     5245   newnumberofvertices=newdatalist[0];
     5246   newnumberofelements=newdatalist[1];
     5247   if(my_rank){
     5248      newxylist      =xNew<IssmDouble>(newnumberofvertices*2);
     5249      newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
     5250   }
     5251   ISSM_MPI_Bcast(newxylist,newnumberofvertices*2,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     5252   ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());
     5253
     5254   /*Reorganize the data*/
     5255   newx=xNew<IssmDouble>(newnumberofvertices);
     5256   newy=xNew<IssmDouble>(newnumberofvertices);
     5257   newz=xNewZeroInit<IssmDouble>(newnumberofvertices);
     5258   for(int i=0;i<newnumberofvertices;i++){
     5259      newx[i] = newxylist[2*i];
     5260      newy[i] = newxylist[2*i+1];
     5261   }
     5262
     5263        /*Assign the pointers*/
     5264   (*pnewelementslist)  = newelementslist; //Matlab indexing
     5265   (*pnewx)             = newx;
     5266   (*pnewy)             = newy;
     5267   (*pnewz)             = newz;
     5268   *pnewnumberofvertices= newnumberofvertices;
     5269   *pnewnumberofelements= newnumberofelements;
    51815270
    51825271        /*Cleanup*/
    5183         xDelete<IssmDouble>(deviatoricerror);
    5184         xDelete<IssmDouble>(thicknesserror);
    5185         xDelete<IssmDouble>(gl_distance);
    5186         xDelete<IssmDouble>(if_distance);
     5272   xDelete<int>(newdatalist);
     5273   xDelete<IssmDouble>(newxylist);
     5274   xDelete<IssmDouble>(deviatoricerror);
     5275   xDelete<IssmDouble>(thicknesserror);
     5276   xDelete<IssmDouble>(gl_distance);
     5277   xDelete<IssmDouble>(if_distance);
    51875278}
    51885279/*}}}*/
    51895280void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/
    5190        
     5281
    51915282        /*Define variables*/
    51925283        int my_rank                                                                             = IssmComm::GetRank();
     
    51975288        IssmDouble* z                                                                   = NULL;
    51985289        int* elements                                                                   = NULL;
    5199        
     5290
    52005291        /*Initialize field as NULL for now*/
    52015292        this->amr = NULL;
     
    52055296        this->GetMesh(this->vertices,this->elements,&x,&y,&z,&elements);
    52065297
    5207         /*Create initial mesh (coarse mesh) in neopz data structure*/ 
     5298        /*Create initial mesh (coarse mesh) in neopz data structure*/
    52085299        /*Just CPU #0 should keep AMR object*/
    52095300   /*Initialize refinement pattern*/
    52105301        this->SetRefPatterns();
    52115302        this->amr = new AdaptiveMeshRefinement();
    5212         this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster) 
     5303        this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster)
    52135304        /*Get amr parameters*/
    52145305        this->parameters->FindParam(&this->amr->level_max,AmrLevelMaxEnum);
     
    52235314        this->parameters->FindParam(&this->amr->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum);
    52245315        this->parameters->FindParam(&this->amr->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum);
    5225         if(my_rank==0){ 
     5316        if(my_rank==0){
    52265317                this->amr->CreateInitialMesh(numberofvertices,numberofelements,x,y,elements);
    52275318        }
     
    52445335        /*Output*/
    52455336        IssmDouble* elementdistance;
    5246        
     5337
    52475338        /*Intermediaries*/
    52485339   int numberofelements                                                 = this->elements->NumberOfElements();
     
    52535344        IssmDouble xc,yc,x1,y1,x2,y2,x3,y3;
    52545345        int numberofpoints;
    5255        
    5256         /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/     
     5346
     5347        /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/
    52575348        this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type);
    52585349
     
    52605351      Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    52615352      int sid = element->Sid();
    5262                 element->GetVerticesCoordinates(&xyz_list); 
     5353                element->GetVerticesCoordinates(&xyz_list);
    52635354                x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1];
    52645355                x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1];
     
    52705361                for(int j=0;j<numberofpoints;j++){
    52715362                        distance =sqrt((xc-levelset_points[2*j])*(xc-levelset_points[2*j])+(yc-levelset_points[2*j+1])*(yc-levelset_points[2*j+1]));
    5272                         mindistance=min(distance,mindistance);         
     5363                        mindistance=min(distance,mindistance);
    52735364                }
    52745365                velementdistance->SetValue(sid,mindistance,INS_VAL);
    52755366                xDelete<IssmDouble>(xyz_list);
    5276         }       
     5367        }
    52775368
    52785369   /*Assemble*/
  • issm/trunk/src/c/classes/FemModel.h

    r22758 r23189  
    11/*
    2  * FemModel.h: 
     2 * FemModel.h:
    33 */
    44
     
    4747                Nodes       *nodes;                //one set of nodes
    4848                Parameters  *parameters;           //one set of parameters, independent of the analysis_type
    49                 Results     *results;              //results that cannot be fit into the elements 
     49                Results     *results;              //results that cannot be fit into the elements
    5050                Vertices    *vertices;             //one set of vertices
    5151
     
    8080                void Solve(void);
    8181
    82                 /*Modules*/ 
     82                /*Modules*/
    8383                void BalancethicknessMisfitx(IssmDouble* pV);
    8484                void CalvingRateVonmisesx();
     
    139139                #endif
    140140                #ifdef _HAVE_SEALEVELRISE_
    141                 void SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius);
    142                 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution);
    143                 void SealevelriseRotationalFeedback(Vector<IssmDouble>* pSgo_rot, Vector<IssmDouble>* pSg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius);
    144                 void SealevelriseGeodetic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz);
     141                void SealevelriseEustatic(Vector<IssmDouble>* pSgi, IssmDouble* peustatic, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,int loop);
     142                void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius,bool verboseconvolution,int loop);
     143                void SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius);
     144                void SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pSg_old, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz,int loop,int horiz);
    145145                IssmDouble SealevelriseOceanAverage(Vector<IssmDouble>* Sg);
    146146                #endif
    147147                void HydrologyEPLupdateDomainx(IssmDouble* pEplcount);
     148                void HydrologyIDSupdateDomainx(IssmDouble* pIDScount);
    148149                void TimeAdaptx(IssmDouble* pdt);
    149150                void UpdateConstraintsExtrudeFromBasex();
  • issm/trunk/src/c/classes/IoModel.cpp

    r22758 r23189  
    130130
    131131        this->my_elements=NULL;
     132        this->my_faces=NULL;
     133        this->my_edges=NULL;
    132134        this->my_vertices=NULL;
    133135
     
    157159        bool autodiff=false;
    158160        bool iscontrol=false;
    159        
     161
    160162        /*First, keep track of the file handle: */
    161163        this->fid=iomodel_handle;
     
    192194        /*Initialize permanent data: */
    193195        this->my_elements = NULL;
     196        this->my_faces = NULL;
     197        this->my_edges = NULL;
    194198        this->my_vertices = NULL;
    195199
     
    236240
    237241        xDelete<bool>(this->my_elements);
     242        xDelete<bool>(this->my_faces);
     243        xDelete<bool>(this->my_edges);
    238244        xDelete<int>(this->my_vertices);
    239245
     
    422428        this->FetchData(&autodiff,"md.autodiff.isautodiff");
    423429        this->FetchData(&iscontrol,"md.inversion.iscontrol");
    424        
     430
    425431        if(trace || (autodiff && !iscontrol)){
    426432
     
    506512
    507513        char** stringarray=*pstringarray;
    508        
     514
    509515        if(numstrings){
    510516                for(int i=0;i<numstrings;i++){
     
    597603                                        /*Read the integer and broadcast it to other cpus:*/
    598604                                        if(fread(&integer,sizeof(int),1,this->fid)!=1) _error_("could not read integer ");
    599                                        
     605
    600606                                        /*Convert codes to Enums if needed*/
    601607                                        if(strcmp(record_name,"md.smb.model")==0) integer = IoCodeToEnumSMB(integer);
     
    662668                                        } else if(strcmp(record_name,"md.thermal.fe")==0){
    663669                                                this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
     670                                        } else if(strcmp(record_name,"md.levelset.fe")==0){
     671                                                this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
    664672                                        } else if(strcmp(record_name,"md.groundingline.migration")==0){
     673                                                this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
     674                                        } else if(strcmp(record_name,"md.groundingline.friction_interpolation")==0){
     675                                                this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
     676                                        } else if(strcmp(record_name,"md.groundingline.melt_interpolation")==0){
    665677                                                this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
    666678                                        } else if(strcmp(record_name,"md.masstransport.hydrostatic_adjustment")==0){
     
    805817                                                } else if(strcmp(record_name,"md.thermal.fe")==0){
    806818                                                        this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
     819                                                } else if(strcmp(record_name,"md.levelset.fe")==0){
     820                                                        this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
    807821                                                } else if(strcmp(record_name,"md.groundingline.migration")==0){
     822                                                        this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
     823                                                } else if(strcmp(record_name,"md.groundingline.friction_interpolation")==0){
     824                                                        this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
     825                                                } else if(strcmp(record_name,"md.groundingline.melt_interpolation")==0){
    808826                                                        this->AddConstant(new IoConstant(StringToEnumx(string),record_name));
    809827                                                } else if(strcmp(record_name,"md.masstransport.hydrostatic_adjustment")==0){
     
    955973        /*recover my_rank:*/
    956974        int my_rank=IssmComm::GetRank();
    957        
     975
    958976        /*Set file pointer to beginning of the data: */
    959977        fid=this->SetFilePointerToData(&code,NULL,data_name);
     
    11261144                }
    11271145        }
    1128          
     1146
    11291147        /*output: */
    11301148        int          M,N;
     
    18171835                                /*check we are indeed finding a string, not something else: */
    18181836                                if(codes[i]!=4)_error_("expecting a string for \""<<data_name<<"\"");
    1819                
     1837
    18201838                                /*We have to read a string from disk. First read the dimensions of the string, then the string: */
    18211839                                fsetpos(fid,file_positions+i);
     
    18461864        xDelete<int>(codes);
    18471865        xDelete<fpos_t>(file_positions);
    1848        
     1866
    18491867        /*Assign output pointers: */
    18501868        *pstrings=strings;
     
    18671885        /*recover my_rank:*/
    18681886        int my_rank=IssmComm::GetRank();
    1869        
     1887
    18701888        /*Get file pointers to beginning of the data (multiple instances of it): */
    18711889        file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name);
     
    18821900
    18831901                                if(code!=2)_error_("expecting an integer for \""<<data_name<<"\"");
    1884                                
     1902
    18851903                                /*We have to read a integer from disk. First read the dimensions of the integer, then the integer: */
    18861904                                fsetpos(fid,file_positions+i);
     
    18951913                }
    18961914        }
    1897                        
     1915
    18981916        /*Free ressources:*/
    18991917        xDelete<fpos_t>(file_positions);
     
    19201938        /*recover my_rank:*/
    19211939        int my_rank=IssmComm::GetRank();
    1922        
     1940
    19231941        /*Get file pointers to beginning of the data (multiple instances of it): */
    19241942        file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name);
     
    19351953
    19361954                                if(code!=3)_error_("expecting a double for \""<<data_name<<"\"");
    1937                                
     1955
    19381956                                /*We have to read a double from disk: */
    19391957                                fsetpos(fid,file_positions+i);
     
    19481966                }
    19491967        }
    1950                        
     1968
    19511969        /*Free ressources:*/
    19521970        xDelete<fpos_t>(file_positions);
     
    19771995        /*recover my_rank:*/
    19781996        int my_rank=IssmComm::GetRank();
    1979        
     1997
    19801998        /*Get file pointers to beginning of the data (multiple instances of it): */
    19811999        file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name);
     
    20062024                        }
    20072025                        ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2008 
    20092026
    20102027                        /*Now allocate matrix: */
     
    20312048                        else
    20322049                                matrix=NULL;
    2033                        
    2034                        
     2050
    20352051                        /*Assign: */
    20362052                        mdims[i]=M;
     
    20392055                }
    20402056        }
    2041                        
     2057
    20422058        /*Free ressources:*/
    20432059        xDelete<fpos_t>(file_positions);
     
    20812097        /*recover my_rank:*/
    20822098        int my_rank=IssmComm::GetRank();
    2083        
     2099
    20842100        /*Get file pointers to beginning of the data (multiple instances of it): */
    20852101        file_positions=this->SetFilePointersToData(&codes,NULL,&num_instances,data_name);
     
    21102126                        }
    21112127                        ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2112 
    21132128
    21142129                        /*Now allocate matrix: */
     
    21362151                        else
    21372152                                integer_matrix=NULL;
    2138                        
    2139                        
     2153
    21402154                        /*Assign: */
    21412155                        mdims[i]=M;
     
    21442158                }
    21452159        }
    2146                        
     2160
    21472161        /*Free ressources:*/
    21482162        xDelete<fpos_t>(file_positions);
     
    23682382                        vector_types   = xNew<int>(num_instances);
    23692383                }
    2370        
     2384
    23712385                /*Reset FILE* position to the beginning of the file, and start again, this time saving the data information
    23722386                 * as we find it: */
     
    24112425                                vector_types[counter] = vector_type;
    24122426                                fgetpos(fid,file_positions+counter);
    2413                                
     2427
    24142428                                /*backup and skip over the record, as we have more work to do: */
    24152429                                if(5<=record_code && record_code<=7) fseek(fid,-sizeof(int),SEEK_CUR);
    24162430                                fseek(fid,-sizeof(int),SEEK_CUR);
    24172431                                fseek(fid,-sizeof(int),SEEK_CUR);
    2418                                
     2432
    24192433                                /*increment counter: */
    24202434                                counter++;
  • issm/trunk/src/c/classes/IoModel.h

    r22758 r23189  
    6464                /*Partitioning*/
    6565                bool *my_elements;
     66                bool *my_faces;
     67                bool *my_edges;
    6668                int  *my_vertices;
    6769
  • issm/trunk/src/c/classes/Loads/Friction.cpp

    r22758 r23189  
    1313#include "../classes.h"
    1414#include "shared/shared.h"
    15 /*}}}*/ 
     15/*}}}*/
    1616
    1717/*Constructors/destructors*/
     
    6060
    6161        /*diverse: */
    62         int         CoupledFlag;
    6362        IssmDouble  q_exp;
    6463        IssmDouble  C_param;
    6564        IssmDouble  As;
    66         IssmDouble  Neff;
    6765        IssmDouble  n;
    6866        IssmDouble  alpha;
     
    7068        IssmDouble  vx,vy,vz,vmag;
    7169        IssmDouble  alpha_complement;
    72         IssmDouble  base,sealevel,thickness;
    7370
    7471        /*Recover parameters: */
    7572        element->GetInputValue(&q_exp,FrictionQEnum);
    7673        element->GetInputValue(&C_param,FrictionCEnum);
    77 
    7874        element->GetInputValue(&As,gauss,FrictionAsEnum);
    7975        element->GetInputValue(&n,gauss,MaterialsRheologyNEnum);
    80         element->GetInputValue(&thickness, gauss,ThicknessEnum);
    81         element->GetInputValue(&base, gauss,BaseEnum);
    82         element->GetInputValue(&sealevel, gauss,SealevelEnum);
    83 
    84         IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    85         IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
    86         IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
    87         element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum);
    88 
    89         switch(CoupledFlag){
    90                 case 0:
    91                         Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel));
    92                         break;
    93                 case 1:
    94                         element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum);
    95                         break;
    96                 case 2:
    97                         element->GetInputValue(&Neff,gauss,EffectivePressureEnum);
    98                         break;
    99                 default:
    100                         _error_("not supported");
    101         }
    102 
    103         if(Neff<0)Neff=0;
     76
     77        /*Get effective pressure*/
     78        IssmDouble Neff = EffectivePressure(gauss);
    10479
    10580        //We need the velocity magnitude to evaluate the basal stress:
     
    174149void Friction::GetAlphaViscousComplement(IssmDouble* palpha_complement, Gauss* gauss){/*{{{*/
    175150
    176         /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p. 
    177          * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 
     151        /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p.
     152         * FrictionGetAlphaComplement is used in control methods on drag, and it computes:
    178153         * alpha_complement= Neff ^r * vel ^s*/
    179154
    180155        /*diverse: */
    181         int         CoupledFlag;
    182156        IssmDouble  r,s;
    183157        IssmDouble  vx,vy,vz,vmag;
    184158        IssmDouble  drag_p,drag_q;
    185         IssmDouble  Neff;
    186159        IssmDouble  drag_coefficient;
    187         IssmDouble  base,thickness,sealevel;
    188160        IssmDouble  alpha_complement;
    189161
     
    191163        element->GetInputValue(&drag_p,FrictionPEnum);
    192164        element->GetInputValue(&drag_q,FrictionQEnum);
    193         element->GetInputValue(&thickness, gauss,ThicknessEnum);
    194         element->GetInputValue(&base, gauss,BaseEnum);
    195         element->GetInputValue(&sealevel, gauss,SealevelEnum);
    196165        element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
    197         IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    198         IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
    199         IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
    200         element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum);
    201         //compute r and q coefficients: */
     166
     167        /*compute r and q coefficients: */
    202168        r=drag_q/drag_p;
    203169        s=1./drag_p;
    204170
    205         //From base and thickness, compute effective pressure when drag is viscous, or get Neff from forcing or coupled to hydrologymodel:
    206         switch(CoupledFlag){
    207                 case 0:
    208                         Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel));
    209                         break; 
    210                 case 1:
    211                         element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum);
    212                         break;
    213                 case 2:
    214                         element->GetInputValue(&Neff,gauss,EffectivePressureEnum);
    215                         break;
    216                 default:
    217                         _error_("not supported");
    218         }
    219         if(Neff<0)Neff=0;
     171        /*Get effective pressure*/
     172        IssmDouble Neff = EffectivePressure(gauss);
    220173
    221174        //We need the velocity magnitude to evaluate the basal stress:
     
    242195        /*Check to prevent dividing by zero if vmag==0*/
    243196        if(vmag==0. && (s-1.)<0.) alpha_complement=0.;
    244         else alpha_complement=pow(Neff,r)*pow(vmag,(s-1));_assert_(!xIsNan<IssmDouble>(alpha_complement));
     197        else alpha_complement=pow(Neff,r)*pow(vmag,(s-1));
     198
     199        _assert_(!xIsNan<IssmDouble>(alpha_complement));
     200        _assert_(!xIsInf<IssmDouble>(alpha_complement));
    245201
    246202        /*Assign output pointers:*/
     
    273229                        break;
    274230                case 8:
    275                         GetAlpha2Sommers(palpha2,gauss);
     231                        GetAlpha2Shakti(palpha2,gauss);
    276232                        break;
    277233                case 9:
    278234                        GetAlpha2Josh(palpha2,gauss);
    279235                        break;
     236                case 10:
     237                        GetAlpha2PISM(palpha2,gauss);
     238                        break;
    280239          default:
    281240                        _error_("Friction law "<< this->law <<" not supported");
     
    285244void Friction::GetAlpha2Coulomb(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
    286245
    287         /*This routine calculates the basal friction coefficient 
     246        /*This routine calculates the basal friction coefficient
    288247          alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p**/
    289248
    290249        /*diverse: */
    291         int         CoupledFlag;
    292250        IssmDouble  r,s;
    293251        IssmDouble  drag_p, drag_q;
    294         IssmDouble  Neff;
    295252        IssmDouble  thickness,base,floatation_thickness,sealevel;
    296253        IssmDouble  vx,vy,vz,vmag;
     
    306263        element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
    307264        element->GetInputValue(&drag_coefficient_coulomb, gauss,FrictionCoefficientcoulombEnum);
    308         IssmDouble rho_water        = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    309         IssmDouble rho_ice          = element->GetMaterialParameter(MaterialsRhoIceEnum);
    310         IssmDouble gravity          = element->GetMaterialParameter(ConstantsGEnum);
    311         element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum);
     265        IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
     266        IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
     267        IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
    312268
    313269        //compute r and q coefficients: */
     
    315271        s=1./drag_p;
    316272
    317         //From base and thickness, compute effective pressure when drag is viscous:
    318         switch(CoupledFlag){
    319                 case 0:
    320                         Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel));
    321                         break; 
    322                 case 1:
    323                         element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum);
    324                         break;
    325                 case 2:
    326                         element->GetInputValue(&Neff,gauss,EffectivePressureEnum);
    327                         break;
    328                 default:
    329                         _error_("not supported");
    330         }
    331 
    332         if(Neff<0)Neff=0;
    333 
     273        /*Get effective pressure*/
     274        IssmDouble Neff = EffectivePressure(gauss);
     275
     276        /*Compute velocity magnitude*/
    334277        switch(dim){
    335278                case 1:
     
    370313void Friction::GetAlpha2Hydro(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
    371314
    372         /*This routine calculates the basal friction coefficient 
     315        /*This routine calculates the basal friction coefficient
    373316                Based on Gagliardini 2007, needs a good effective pressure computation
    374317                Not tested so far so use at your own risks
     
    378321
    379322        /*diverse: */
    380         int         CoupledFlag;
    381323        IssmDouble  q_exp;
    382324        IssmDouble  C_param;
    383325        IssmDouble  As;
    384 
    385         IssmDouble  Neff;
    386326        IssmDouble  n;
    387327
     
    391331        IssmDouble  vx,vy,vz,vmag;
    392332        IssmDouble  alpha2;
    393         IssmDouble  base,thickness,sealevel;
    394333
    395334        /*Recover parameters: */
     
    398337        element->GetInputValue(&As,gauss,FrictionAsEnum);
    399338        element->GetInputValue(&n,gauss,MaterialsRheologyNEnum);
    400         element->GetInputValue(&thickness, gauss,ThicknessEnum);
    401         element->GetInputValue(&base, gauss,BaseEnum);
    402         element->GetInputValue(&sealevel, gauss,SealevelEnum);
    403         IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    404         IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
    405         IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
    406         element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum);
    407        
    408         switch(CoupledFlag){
    409                 case 0:
    410                         Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel));
    411                         break; 
    412                 case 1:
    413                         element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum);
    414                         break;
    415                 case 2:
    416                         element->GetInputValue(&Neff,gauss,EffectivePressureEnum);
    417                         break;
    418                 default:
    419                         _error_("not supported");
    420         }
    421 
    422         if(Neff<0)Neff=0;
    423 
     339
     340        /*Get effective pressure*/
     341        IssmDouble Neff = EffectivePressure(gauss);
     342
     343        /*Compute velocity magnitude*/
    424344        switch(dim){
    425345                case 1:
     
    453373        Gamma=(Chi/(1. + alpha * pow(Chi,q_exp)));
    454374        /*Check to prevent dividing by zero if vmag==0*/
    455         if(vmag==0.) alpha2=0.; 
     375        if(vmag==0.) alpha2=0.;
    456376        else    if (Neff==0) alpha2=0.0;
    457377        else    alpha2=Neff * C_param * pow(Gamma,1./n) * 1/vmag;
     
    461381        *palpha2=alpha2;
    462382}/*}}}*/
    463 void Friction::GetAlpha2Sommers(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
     383void Friction::GetAlpha2Shakti(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
    464384
    465385        /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff, with Neff=rho_ice*g*thickness+rho_ice*g*(head-base)*/
     
    570490void Friction::GetAlpha2Viscous(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
    571491
    572         /*This routine calculates the basal friction coefficient 
     492        /*This routine calculates the basal friction coefficient
    573493          alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p**/
    574494
    575495        /*diverse: */
    576         int         CoupledFlag;
    577496        IssmDouble  r,s;
    578497        IssmDouble  drag_p, drag_q;
    579         IssmDouble  Neff;
    580         IssmDouble  thickness,base,sealevel;
    581498        IssmDouble  vx,vy,vz,vmag;
    582499        IssmDouble  drag_coefficient;
     
    586503        element->GetInputValue(&drag_p,FrictionPEnum);
    587504        element->GetInputValue(&drag_q,FrictionQEnum);
    588         element->GetInputValue(&thickness, gauss,ThicknessEnum);
    589         element->GetInputValue(&base, gauss,BaseEnum);
    590         element->GetInputValue(&sealevel, gauss,SealevelEnum);
    591505        element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
    592         IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
    593         IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
    594         IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
    595         element->parameters->FindParam(&CoupledFlag,FrictionCouplingEnum);
    596         //compute r and q coefficients: */
     506
     507        /*compute r and q coefficients: */
    597508        r=drag_q/drag_p;
    598509        s=1./drag_p;
    599510
    600         //From base and thickness, compute effective pressure when drag is viscous, or get Neff from forcing:
    601         switch(CoupledFlag){
    602                 case 0:
    603                         Neff=gravity*(rho_ice*thickness+rho_water*(base-sealevel));
    604                         break;
    605                 case 1:
    606                         element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum);
    607                         break;
    608                 case 2:
    609                         element->GetInputValue(&Neff,gauss,EffectivePressureEnum);
    610                         break;
    611                 default:
    612                         _error_("not supported");
    613         }
    614         if(Neff<0)Neff=0;
    615 
     511        /*Get effective pressure*/
     512        IssmDouble Neff = EffectivePressure(gauss);
     513
     514        /*Compute velocity magnitude*/
    616515        switch(dim){
    617516                case 1:
     
    644543void Friction::GetAlpha2WaterLayer(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
    645544
    646         /*This routine calculates the basal friction coefficient 
     545        /*This routine calculates the basal friction coefficient
    647546          alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*base, r=q/p and s=1/p**/
    648547
     
    776675        *palpha2=alpha2;
    777676}/*}}}*/
     677void Friction::GetAlpha2PISM(IssmDouble* palpha2, Gauss* gauss){/*{{{*/
     678        /*Here, we want to parameterize the friction using a pseudoplastic friction law,
     679         * computing the basal shear stress as
     680         *
     681         * alpha2 = tau_c (u_b/(abs(u_b)^(1-q)*u_0^q))
     682         *
     683         * The yield stress tau_c is a function of the effective pressure N
     684         * using a Mohr-Coloumb criterion, so that
     685         * tau_c = tan(phi)*N,
     686         * where phi is the till friction angle, representing sediment strength
     687         *
     688         * The effective pressure is given by Eq. (5) in Aschwanden et al. 2016:
     689         *
     690         * N = delta * P0 * 10^((e_0/Cc)(1-(W/Wmax)))
     691         *
     692         * W is calculated by a non-conserving hydrology model in HydrologyPismAnalysis.cpp
     693         *
     694         * see Aschwanden et al. 2016 and Bueler and Brown, 2009 for more details
     695         */
     696
     697        /*compute ice overburden pressure P0*/
     698        IssmDouble thickness,base,P0;
     699        element->GetInputValue(&thickness, gauss,ThicknessEnum);
     700        element->GetInputValue(&base, gauss,BaseEnum);
     701        //element->GetInputValue(&sealevel, gauss,SealevelEnum);
     702        IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
     703        IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
     704        P0 = gravity*rho_ice*thickness;
     705
     706        /*Compute effective pressure*/
     707        IssmDouble  N,delta,W,Wmax,e0,Cc;
     708        element->parameters->FindParam(&delta,FrictionDeltaEnum);
     709        element->parameters->FindParam(&e0,FrictionVoidRatioEnum);
     710        element->GetInputValue(&Cc,gauss,FrictionSedimentCompressibilityCoefficientEnum);
     711        element->GetInputValue(&W,gauss,WatercolumnEnum);
     712        element->GetInputValue(&Wmax,gauss,HydrologyWatercolumnMaxEnum);
     713
     714        /*Check that water column height is within 0 and upper bound, correct if needed*/
     715        if(W>Wmax) W=Wmax;
     716        if(W<0)    W=0.;
     717
     718        N = delta*P0*pow(10.,(e0/Cc)*(1.-W/Wmax));
     719
     720        /*Get till friction angles, defined by user [deg]*/
     721        IssmDouble phi;
     722        element->GetInputValue(&phi,gauss,FrictionTillFrictionAngleEnum);
     723
     724        /*Convert till friction angle from user-defined deg to rad, which Matlab uses*/
     725        phi = phi*PI/180.;
     726
     727        /*Compute yield stress following a Mohr-Colomb criterion*/
     728        IssmDouble tau_c = N*tan(phi);
     729
     730        /*Compute basal speed*/
     731        IssmDouble ub;
     732        element->GetInputValue(&ub,gauss,VelEnum);
     733
     734        /*now compute alpha^2*/
     735        IssmDouble u0,q;
     736        element->parameters->FindParam(&u0,FrictionThresholdSpeedEnum);
     737        element->parameters->FindParam(&q,FrictionPseudoplasticityExponentEnum);
     738        IssmDouble alpha2 = tau_c/(pow(ub+1.e-10,1.-q)*pow(u0,q));
     739
     740        /*Final checks in debuging mode*/
     741        _assert_(!xIsNan<IssmDouble>(alpha2));
     742        _assert_(!xIsInf<IssmDouble>(alpha2));
     743
     744        /*Assign output pointers:*/
     745        *palpha2=alpha2;
     746}/*}}}*/
     747
     748IssmDouble Friction::EffectivePressure(Gauss* gauss){/*{{{*/
     749        /*Get effective pressure as a function of  flag */
     750
     751        /*diverse: */
     752        int         coupled_flag;
     753        IssmDouble  thickness,base,sealevel;
     754        IssmDouble  p_ice,p_water;
     755        IssmDouble  Neff;
     756
     757        /*Recover parameters: */
     758        element->parameters->FindParam(&coupled_flag,FrictionCouplingEnum);
     759
     760        /*From base and thickness, compute effective pressure when drag is viscous, or get Neff from forcing:*/
     761        switch(coupled_flag){
     762                case 0:{
     763                                         element->GetInputValue(&thickness, gauss,ThicknessEnum);
     764                                         element->GetInputValue(&base, gauss,BaseEnum);
     765                                         element->GetInputValue(&sealevel, gauss,SealevelEnum);
     766                                         IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
     767                                         IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
     768                                         IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
     769                                         p_ice   = gravity*rho_ice*thickness;
     770                                         p_water = rho_water*gravity*(sealevel-base);
     771                                         Neff = p_ice - p_water;
     772                                 }
     773                          break;
     774                case 1:{
     775                                         element->GetInputValue(&thickness, gauss,ThicknessEnum);
     776                                         IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
     777                                         IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
     778                                         p_ice   = gravity*rho_ice*thickness;
     779                                         p_water = 0.;
     780                                         Neff = p_ice - p_water;
     781                                 }
     782                          break;
     783                case 2:{
     784                                         element->GetInputValue(&thickness, gauss,ThicknessEnum);
     785                                         element->GetInputValue(&base, gauss,BaseEnum);
     786                                         element->GetInputValue(&sealevel, gauss,SealevelEnum);
     787                                         IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
     788                                         IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
     789                                         IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
     790                                         p_ice   = gravity*rho_ice*thickness;
     791                                         p_water = max(0.,rho_water*gravity*(sealevel-base));
     792                                         Neff = p_ice - p_water;
     793                                 }
     794                          break;
     795                case 3:
     796                        element->GetInputValue(&Neff,gauss,FrictionEffectivePressureEnum);
     797                        break;
     798                case 4:
     799                        element->GetInputValue(&Neff,gauss,EffectivePressureEnum);
     800                        break;
     801                default:
     802                        _error_("not supported");
     803        }
     804
     805        /*Make sure Neff is positive*/
     806        if(Neff<0.) Neff=0.;
     807
     808        /*Return effective pressure*/
     809        return Neff;
     810
     811}/*}}}*/
  • issm/trunk/src/c/classes/Loads/Friction.h

    r21729 r23189  
    3737                void  GetAlpha2Hydro(IssmDouble* palpha2,Gauss* gauss);
    3838                void  GetAlpha2Josh(IssmDouble* palpha2,Gauss* gauss);
    39                 void  GetAlpha2Sommers(IssmDouble* palpha2,Gauss* gauss);
     39                void  GetAlpha2Shakti(IssmDouble* palpha2,Gauss* gauss);
    4040                void  GetAlpha2Temp(IssmDouble* palpha2,Gauss* gauss);
    4141                void  GetAlpha2Viscous(IssmDouble* palpha2,Gauss* gauss);
     
    4343                void  GetAlpha2Weertman(IssmDouble* palpha2,Gauss* gauss);
    4444                void  GetAlpha2WeertmanTemp(IssmDouble* palpha2,Gauss* gauss);
     45                void  GetAlpha2PISM(IssmDouble* palpha2,Gauss* gauss);
     46
     47                IssmDouble EffectivePressure(Gauss* gauss);
    4548};
    4649
  • issm/trunk/src/c/classes/Loads/Moulin.cpp

    r21341 r23189  
    178178
    179179        switch(analysis_type){
    180                
    181         case HydrologySommersAnalysisEnum:
    182                 pe = this->CreatePVectorHydrologySommers();
     180
     181        case HydrologyShaktiAnalysisEnum:
     182                pe = this->CreatePVectorHydrologyShakti();
    183183                break;
    184184        case HydrologyDCInefficientAnalysisEnum:
     
    337337/*}}}*/
    338338
    339 ElementVector* Moulin::CreatePVectorHydrologySommers(void){/*{{{*/
     339ElementVector* Moulin::CreatePVectorHydrologyShakti(void){/*{{{*/
    340340
    341341        /*If this node is not the master node (belongs to another partition of the
     
    395395        IssmDouble moulin_load,dt;
    396396        ElementVector* pe=new ElementVector(&node,1,this->parameters);
    397        
     397
    398398        this->element->GetInputValue(&moulin_load,node,HydrologydcBasalMoulinInputEnum);
    399399        parameters->FindParam(&dt,TimesteppingTimeStepEnum);
    400        
     400
    401401        pe->values[0]=moulin_load*dt;
    402402        /*Clean up and return*/
  • issm/trunk/src/c/classes/Loads/Moulin.h

    r21341 r23189  
    8080                /*}}}*/
    8181
    82                 ElementVector* CreatePVectorHydrologySommers(void);
     82                ElementVector* CreatePVectorHydrologyShakti(void);
    8383                ElementVector* CreatePVectorHydrologyDCInefficient(void);
    8484                ElementVector* CreatePVectorHydrologyDCEfficient(void);
  • issm/trunk/src/c/classes/Loads/Neumannflux.cpp

    r21341 r23189  
    3030/*}}}*/
    3131Neumannflux::Neumannflux(int neumannflux_id,int i,IoModel* iomodel,int* segments,int in_analysis_type){/*{{{*/
    32 
    3332
    3433        /*Some sanity checks*/
     
    190189        /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
    191190        switch(analysis_type){
    192                 case HydrologySommersAnalysisEnum:
     191                case HydrologyShaktiAnalysisEnum:
    193192                        /*Nothing!*/
    194193                        break;
     
    213212
    214213        switch(analysis_type){
    215                 case HydrologySommersAnalysisEnum:
    216                         pe=CreatePVectorHydrologySommers();
     214                case HydrologyShaktiAnalysisEnum:
     215                        pe=CreatePVectorHydrologyShakti();
    217216                        break;
    218217                default:
     
    346345
    347346/*Neumannflux management*/
    348 ElementVector* Neumannflux::CreatePVectorHydrologySommers(void){/*{{{*/
     347ElementVector* Neumannflux::CreatePVectorHydrologyShakti(void){/*{{{*/
    349348
    350349        /* constants*/
  • issm/trunk/src/c/classes/Loads/Neumannflux.h

    r21341 r23189  
    7373                /*}}}*/
    7474                /*Neumannflux management:{{{*/
    75                 ElementVector* CreatePVectorHydrologySommers(void);
     75                ElementVector* CreatePVectorHydrologyShakti(void);
    7676                /*}}}*/
    7777
  • issm/trunk/src/c/classes/Loads/Pengrid.cpp

    r21341 r23189  
    170170void  Pengrid::Configure(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){/*{{{*/
    171171
    172         /*Take care of hooking up all objects for this load, ie links the objects in the hooks to their respective 
     172        /*Take care of hooking up all objects for this load, ie links the objects in the hooks to their respective
    173173         * datasets, using internal ids and offsets hidden in hooks: */
    174174        hnode->configure(nodesin);
     
    195195        /*No loads applied, do nothing, originaly used for moulin input: */
    196196        return;
    197        
     197
    198198}
    199199/*}}}*/
     
    416416void           Pengrid::ConstraintActivateHydrologyDCInefficient(int* punstable){/*{{{*/
    417417
    418         //   The penalty is stable if it doesn't change during two consecutive iterations.   
     418        //   The penalty is stable if it doesn't change during two consecutive iterations.
    419419        int        unstable=0;
    420420        int        new_active;
     
    422422        IssmDouble pressure;
    423423        IssmDouble h;
    424         IssmDouble h_max;       
     424        IssmDouble h_max;
    425425        HydrologyDCInefficientAnalysis* inefanalysis = NULL;
    426426
     
    440440        /*Get sediment water head h*/
    441441        inefanalysis = new HydrologyDCInefficientAnalysis();
    442         element->GetInputValue(&h,node,SedimentHeadEnum);
     442        element->GetInputValue(&h,node,SedimentHeadHydrostepEnum);
    443443        inefanalysis->GetHydrologyDCInefficientHmax(&h_max,element,node);
    444444        parameters->FindParam(&penalty_lock,HydrologydcPenaltyLockEnum);
     
    476476void           Pengrid::ConstraintActivateThermal(int* punstable){/*{{{*/
    477477
    478         //   The penalty is stable if it doesn't change during to successive iterations.   
     478        //   The penalty is stable if it doesn't change during to successive iterations.
    479479        IssmDouble pressure;
    480480        IssmDouble temperature;
  • issm/trunk/src/c/classes/Materials/Matestar.cpp

    r22758 r23189  
    109109
    110110        if(marshall_direction==MARSHALLING_BACKWARD)helement=new Hook();
    111        
     111
    112112        MARSHALLING_ENUM(MatestarEnum);
    113113        MARSHALLING(mid);
  • issm/trunk/src/c/classes/Materials/Matice.cpp

    r22758 r23189  
    135135        //if(helement) helement->DeepEcho();
    136136        //else _printf_("   helement = NULL\n");
    137        
     137
    138138        _printf_("   element:\n");
    139139        _printf_("     note: element not printed to avoid recursion.\n");
     
    143143/*}}}*/
    144144void      Matice::Echo(void){/*{{{*/
    145        
     145
    146146        _printf_("Matice:\n");
    147147        _printf_("   mid: " << mid << "\n");
    148148        _printf_("   isdamaged: " << isdamaged << "\n");
    149149        _printf_("   isenhanced: " << isenhanced << "\n");
    150        
     150
    151151        /*helement and element Echo were commented to avoid recursion.*/
    152152        /*Example: element->Echo calls matice->Echo which calls element->Echo etc*/
     
    155155        //if(helement) helement->Echo();
    156156        //else _printf_("   helement = NULL\n");
    157        
     157
    158158        _printf_("   element:\n");
    159159        _printf_("     note: element not printed to avoid recursion.\n");
     
    167167
    168168        if(marshall_direction==MARSHALLING_BACKWARD)helement=new Hook();
    169        
     169
    170170        MARSHALLING_ENUM(MaticeEnum);
    171171        MARSHALLING(mid);
     
    541541        IssmDouble exx,eyy,exy,exz,eyz;
    542542
    543 
    544543        if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) &&
    545544                                (epsilon[3]==0) && (epsilon[4]==0)){
  • issm/trunk/src/c/classes/Materials/Matlitho.cpp

    r22758 r23189  
    3737        this->radius=xNew<IssmDouble>(this->numlayers+1);
    3838        xMemCpy<IssmDouble>(this->radius, iomodel->Data("md.materials.radius"),this->numlayers+1);
    39        
     39
    4040        this->viscosity=xNew<IssmDouble>(this->numlayers);
    4141        xMemCpy<IssmDouble>(this->viscosity, iomodel->Data("md.materials.viscosity"),this->numlayers);
    42        
     42
    4343        this->lame_lambda=xNew<IssmDouble>(this->numlayers);
    4444        xMemCpy<IssmDouble>(this->lame_lambda, iomodel->Data("md.materials.lame_lambda"),this->numlayers);
    45        
     45
    4646        this->lame_mu=xNew<IssmDouble>(this->numlayers);
    4747        xMemCpy<IssmDouble>(this->lame_mu, iomodel->Data("md.materials.lame_mu"),this->numlayers);
     
    6161        this->issolid=xNew<IssmDouble>(this->numlayers);
    6262        xMemCpy<IssmDouble>(this->issolid, iomodel->Data("md.materials.issolid"),this->numlayers);
    63        
     63
    6464        /*isburgersd= xNew<IssmDouble>(this->numlayers);
    6565        this->isburgers=xNew<bool>(this->numlayers);
    6666        xMemCpy<IssmDouble>(isburgersd, iomodel->Data("md.materials.isburgers"),this->numlayers);
    6767        for (int i=0;i<this->numlayers;i++)this->isburgers[i]=reCast<bool,IssmDouble>(isburgersd[i]);
    68        
     68
    6969        issolidd= xNew<IssmDouble>(this->numlayers);
    7070        this->issolid=xNew<bool>(this->numlayers);
    7171        xMemCpy<IssmDouble>(issolidd, iomodel->Data("md.materials.issolid"),this->numlayers);
    7272        for (int i=0;i<this->numlayers;i++)this->issolid[i]=reCast<bool,IssmDouble>(issolidd[i]);*/
    73        
     73
    7474        /*free ressources: */
    7575        xDelete<IssmDouble>(isburgersd);
     
    7878/*}}}*/
    7979Matlitho::~Matlitho(){/*{{{*/
    80        
     80
    8181        xDelete<IssmDouble>(radius);
    8282        xDelete<IssmDouble>(viscosity);
  • issm/trunk/src/c/classes/Materials/Matpar.cpp

    r22758 r23189  
    5959        mantle_shear_modulus      = 0;
    6060        mantle_density            = 0;
    61        
     61
    6262        earth_density             = 0;
    6363
     
    149149                                /*Nothing to add*/
    150150                        }
    151                         else if(hydrology_model==HydrologysommersEnum){
     151                        else if(hydrology_model==HydrologyshaktiEnum){
     152                                /*Nothing to add*/
     153                        }
     154                        else if(hydrology_model==HydrologypismEnum){
    152155                                /*Nothing to add*/
    153156                        }
     
    250253                                                        /*Nothing to add*/
    251254                                                }
    252                                                 else if(hydrology_model==HydrologysommersEnum){
     255                                                else if(hydrology_model==HydrologyshaktiEnum){
    253256                                                        /*Nothing to add*/
    254257                                                }
     
    338341        matpar->mantle_shear_modulus=this->mantle_shear_modulus;
    339342        matpar->mantle_density=this->mantle_density;
    340        
     343
    341344        matpar->earth_density=this->earth_density;
    342345
     
    439442        MARSHALLING(mantle_shear_modulus);
    440443        MARSHALLING(mantle_density);
    441        
     444
    442445        //slr:
    443446        MARSHALLING(earth_density);
  • issm/trunk/src/c/classes/Materials/Matpar.h

    r22758 r23189  
    118118                void       ViscosityBHO(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,IssmDouble eps_eff){_error_("not supported");};
    119119                void       ViscosityBSSA(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,IssmDouble eps_eff){_error_("not supported");};
     120                void       ViscosityBFS(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not supported");};
     121                void       ViscosityBHO(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){_error_("not supported");};
     122                void       ViscosityBSSA(IssmDouble* pmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){_error_("not supported");};
    120123                /*}}}*/
    121124                /*Numerics: {{{*/
  • issm/trunk/src/c/classes/Misfit.cpp

    r22758 r23189  
    2323#include "../classes/gauss/Gauss.h"
    2424/*}}}*/
    25                
     25
    2626/*Misfit constructors, destructors :*/
    2727Misfit::Misfit(){/*{{{*/
     
    4242
    4343        this->definitionenum=in_definitionenum;
    44        
     44
    4545        this->name              = xNew<char>(strlen(in_name)+1);
    4646        xMemCpy<char>(this->name,in_name,strlen(in_name)+1);
     
    4848        this->timeinterpolation = xNew<char>(strlen(in_timeinterpolation)+1);
    4949        xMemCpy<char>(this->timeinterpolation,in_timeinterpolation,strlen(in_timeinterpolation)+1);
    50                                
     50
    5151        this->model_enum=in_model_enum;
    5252        this->observation_enum=in_observation_enum;
    5353        this->weights_enum=in_weights_enum;
    5454        this->local=in_local;
    55        
     55
    5656        this->misfit=0;
    5757        this->lock=0;
     
    111111/*}}}*/
    112112IssmDouble Misfit::Response(FemModel* femmodel){/*{{{*/
    113                  
     113
    114114         /*diverse: */
    115115         IssmDouble time,starttime,finaltime;
    116116         IssmDouble dt;
    117          
     117
    118118         /*recover time parameters: */
    119119         femmodel->parameters->FindParam(&starttime,TimesteppingStartTimeEnum);
     
    130130                 IssmDouble all_area_t;
    131131
    132        
    133132                 /*If we are locked, return time average: */
    134133                 if(this->lock)return misfit/(time-starttime);
     
    144143                 area_t=all_area_t;
    145144                 misfit_t=all_misfit_t;
    146                  
     145
    147146                 /*Divide by surface area if not nill!: */
    148147                 if (area_t!=0) misfit_t=misfit_t/area_t;
     
    164163                 IssmDouble* weights= NULL;
    165164                 int msize,osize,wsize;
    166                  
     165
    167166                 /*Are we transient?:*/
    168167                 if (time==0){
    169168                         IssmDouble misfit_t=0.;
    170                          
     169
    171170                         /*get global vectors: */
    172171                         GetVectorFromInputsx(&model,&msize,femmodel,model_enum);
     
    190189                 }
    191190                 else{
    192                          
     191
    193192                         IssmDouble misfit_t=0.;
    194193                         IssmDouble all_misfit_t=0.;
     
    201200                         GetVectorFromInputsx(&observation,&osize,femmodel,observation_enum);_assert_(msize==osize);
    202201                         GetVectorFromInputsx(&weights,&wsize,femmodel,weights_enum); _assert_(wsize==msize);
    203                          
     202
    204203                         int count=0;
    205204                         for (int i=0;i<msize;i++){
     
    215214                         /*Do we lock? i.e. are we at final_time? :*/
    216215                         if(time==finaltime)this->lock=1;
    217                          
     216
    218217                         /*Free ressources:*/
    219218                         xDelete<IssmDouble>(model);
     
    227226         } /*}}}*/
    228227         else{ /*global computation: {{{ */
    229                  
     228
    230229                 IssmDouble model, observation;
    231                  
     230
    232231                 /*If we are locked, return time average: */
    233232                 if(this->lock)return misfit/(time-starttime);
     
    239238                 Input* input = element->GetInput(observation_enum); _assert_(input);
    240239                 input->GetInputAverage(&observation);
    241                  
     240
    242241                 /*Add this time's contribution to curent misfit: */
    243242                 misfit+=dt*(model-observation);
    244                  
     243
    245244                 /*Do we lock? i.e. are we at final_time? :*/
    246245                 if(time==finaltime)this->lock=1;
    247                  
     246
    248247                 /*What we return is the value of misfit / time: */
    249248                 return misfit/(time-starttime);
  • issm/trunk/src/c/classes/Nodalvalue.cpp

    r22758 r23189  
    8787/*}}}*/
    8888IssmDouble Nodalvalue::Response(FemModel* femmodel){/*{{{*/
    89        
     89
    9090         /*output:*/
    9191         IssmDouble value;
  • issm/trunk/src/c/classes/Node.cpp

    r21729 r23189  
    498498/*}}}*/
    499499void  Node::SetApproximation(int in_approximation){/*{{{*/
    500        
     500
    501501        this->approximation = in_approximation;
    502502}
  • issm/trunk/src/c/classes/Nodes.cpp

    r21341 r23189  
    349349        ISSM_MPI_Allreduce((void*)&flag,(void*)&allflag,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
    350350
    351         if(allflag){
    352                 return true;
    353         }
    354         else{
    355                 return false;
    356         }
    357 }
    358 /*}}}*/
     351        if(allflag) return true;
     352        else        return false;
     353}
     354/*}}}*/
  • issm/trunk/src/c/classes/Numberedcostfunction.cpp

    r22758 r23189  
    88#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
    99#endif
    10 
    1110
    1211/*Headers:*/
     
    3029
    3130/*}}}*/
    32                
     31
    3332/*Numberedcostfunction constructors, destructors :*/
    3433Numberedcostfunction::Numberedcostfunction(){/*{{{*/
     
    110109/*}}}*/
    111110IssmDouble Numberedcostfunction::Response(FemModel* femmodel){/*{{{*/
    112        
     111
    113112         _assert_(number_cost_functions>0 && number_cost_functions<1e3);
    114113
     
    157156 }
    158157 /*}}}*/
    159 
  • issm/trunk/src/c/classes/Params/BoolParam.cpp

    r21341 r23189  
    6363}
    6464/*}}}*/
    65                
  • issm/trunk/src/c/classes/Params/DataSetParam.cpp

    r22758 r23189  
    5555
    5656        if(marshall_direction==MARSHALLING_BACKWARD)value=new DataSet();
    57        
     57
    5858        MARSHALLING_ENUM(DataSetParamEnum);
    5959        MARSHALLING(enum_type);
  • issm/trunk/src/c/classes/Params/DoubleMatArrayParam.cpp

    r21341 r23189  
    233233}
    234234/*}}}*/
    235                
  • issm/trunk/src/c/classes/Params/DoubleMatParam.cpp

    r21341 r23189  
    116116/*DoubleMatParam specific routines:*/
    117117void  DoubleMatParam::GetParameterValueByPointer(IssmDouble** pIssmDoublearray,int* pM,int* pN){/*{{{*/
    118        
     118
    119119        /*Assign output pointers:*/
    120120        if(pM) *pM=M;
  • issm/trunk/src/c/classes/Params/DoubleVecParam.cpp

    r22758 r23189  
    116116/*DoubleVecParam specific routines:*/
    117117void  DoubleVecParam::GetParameterValueByPointer(IssmDouble** pIssmDoublearray,int* pM){/*{{{*/
    118        
     118
    119119        /*Assign output pointers:*/
    120120        if(pM) *pM=M;
  • issm/trunk/src/c/classes/Params/IntParam.cpp

    r21341 r23189  
    6464}
    6565/*}}}*/
    66 
  • issm/trunk/src/c/classes/Params/StringArrayParam.cpp

    r22758 r23189  
    8383
    8484        MARSHALLING_ENUM(StringArrayParamEnum);
    85        
     85
    8686        MARSHALLING(enum_type);
    8787        MARSHALLING(numstrings);
  • issm/trunk/src/c/classes/Params/StringParam.cpp

    r22758 r23189  
    5555
    5656        if(marshall_direction==MARSHALLING_FORWARD || marshall_direction == MARSHALLING_SIZE)size=strlen(value)+1;
    57        
     57
    5858        MARSHALLING_ENUM(StringParamEnum);
    5959        MARSHALLING(enum_type);
  • issm/trunk/src/c/classes/Profiler.cpp

    r22758 r23189  
    100100        if(this->running[tag]) _error_("Tag "<<tag<<" has not been stopped");
    101101
    102 
    103102        #ifdef _HAVE_MPI_
    104103        return this->time[tag];
     
    143142        _assert_(tag<MAXIMUMSIZE);
    144143        if(this->running[tag]) _error_("Tag "<<tag<<" is already running");
    145 
    146144
    147145        /*If mpisync requested, make sure all the cpus are at the same point in the execution: */
     
    184182        if(!this->running[tag]) _error_("Tag "<<tag<<" is not running");
    185183
    186 
    187184        /*If mpisync requested, make sure all the cpus are at the same point in the execution: */
    188185        if(!dontmpisync){
  • issm/trunk/src/c/classes/Regionaloutput.cpp

    r22758 r23189  
    155155}
    156156/*}}}*/
    157 
  • issm/trunk/src/c/classes/Vertex.cpp

    r22822 r23189  
    2020}
    2121/*}}}*/
    22 Vertex::Vertex(int vertex_id, int vertex_sid,int i, IoModel* iomodel){/*{{{*/
     22Vertex::Vertex(int vertex_id, int vertex_sid,int vertex_lid,int i, IoModel* iomodel){/*{{{*/
    2323
    2424        this->id           = vertex_id;
    2525        this->sid          = vertex_sid;
    2626        this->pid          = UNDEF;
     27        this->lid          = vertex_lid;
    2728
    2829        _assert_(iomodel->Data("md.mesh.x") && iomodel->Data("md.mesh.y") && iomodel->Data("md.mesh.z"));
     
    6061        this->connectivity = iomodel->numbernodetoelementconnectivity[i];
    6162
    62 }
    63 /*}}}*/
     63}/*}}}*/
    6464Vertex::~Vertex(){/*{{{*/
    6565        return;
     
    8484        _printf_("   sid: " << sid << "\n");
    8585        _printf_("   pid: " << pid << "\n");
     86        _printf_("   lid: " << lid << "\n");
    8687        _printf_("   x: " << x << "\n");
    8788        _printf_("   y: " << y << "\n");
     
    104105        MARSHALLING(sid);
    105106        MARSHALLING(pid);
     107        MARSHALLING(lid);
    106108        MARSHALLING(x);
    107109        MARSHALLING(y);
     
    113115/*}}}*/
    114116int Vertex::ObjectEnum(void){/*{{{*/
    115 
    116117        return VertexEnum;
    117 
    118 }
    119 /*}}}*/
     118}/*}}}*/
    120119
    121120/*Vertex management: */
     
    172171/*}}}*/
    173172int        Vertex::Pid(void){ return pid; }/*{{{*/
     173/*}}}*/
     174int        Vertex::Lid(void){ return lid; }/*{{{*/
    174175/*}}}*/
    175176void       Vertex::SetClone(int* minranks){/*{{{*/
  • issm/trunk/src/c/classes/Vertex.h

    r22822 r23189  
    2525                int        sid;          // "serial" id (rank of this vertex if the dataset was on 1 cpu)
    2626                int        pid;          // "parallel" id
     27                int        lid;          // "local" id
    2728                IssmDouble x;
    2829                IssmDouble y;
     
    3637                /*Vertex constructors, destructors {{{*/
    3738                Vertex();
    38                 Vertex(int id, int sid, int i, IoModel* iomodel);
     39                Vertex(int id, int sid,int lid,int i, IoModel* iomodel);
    3940                ~Vertex();
    4041                /*}}}*/
     
    5960                void       OffsetPids(int pidcount);
    6061                int        Pid(void);
     62                int        Lid(void);
    6163                void       SetClone(int* minranks);
    6264                void       ShowTruePids(int* borderpids);
  • issm/trunk/src/c/classes/gauss/GaussSeg.cpp

    r21341 r23189  
    3131        this->numgauss = order;
    3232        GaussLegendreLinear(&pcoords1,&pweights,order);
    33        
     33
    3434        this->coords1=xNew<IssmDouble>(numgauss);
    3535        this->weights=xNew<IssmDouble>(numgauss);
  • issm/trunk/src/c/classes/kriging/Observations.cpp

    r22758 r23189  
    741741        xDelete<IssmPDouble>(counter);
    742742}/*}}}*/
    743 
Note: See TracChangeset for help on using the changeset viewer.