Changeset 20810


Ignore:
Timestamp:
06/27/16 09:22:48 (9 years ago)
Author:
agscott1
Message:

Started alphabetizing function names under src/classes

Location:
issm/trunk-jpl/src/c/classes
Files:
56 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/Constraints/SpcDynamic.cpp

    r19254 r20810  
    7171int     SpcDynamic::Id(void){ return sid; }/*{{{*/
    7272/*}}}*/
    73 int     SpcDynamic::ObjectEnum(void){/*{{{*/
    74 
    75         return SpcDynamicEnum;
    76 
    77 }
    78 /*}}}*/
    7973void    SpcDynamic::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
    8074
     
    8882        MARSHALLING(isset);
    8983        MARSHALLING(penalty);
     84
     85}
     86/*}}}*/
     87int     SpcDynamic::ObjectEnum(void){/*{{{*/
     88
     89        return SpcDynamicEnum;
    9090
    9191}
  • issm/trunk-jpl/src/c/classes/Constraints/SpcDynamic.h

    r19254 r20810  
    3434                void    Echo();
    3535                int     Id();
     36                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3637                int     ObjectEnum();
    37                 void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3838
    3939                /*Constraint virtual functions definitions*/
  • issm/trunk-jpl/src/c/classes/Constraints/SpcStatic.cpp

    r19254 r20810  
    7373int     SpcStatic::Id(void){ return sid; }/*{{{*/
    7474/*}}}*/
    75 int     SpcStatic::ObjectEnum(void){/*{{{*/
    76 
    77         return SpcStaticEnum;
    78 
    79 }
    80 /*}}}*/
    8175void    SpcStatic::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
    8276
     
    8983        MARSHALLING(analysis_type);
    9084        MARSHALLING(penalty);
     85
     86}
     87/*}}}*/
     88int     SpcStatic::ObjectEnum(void){/*{{{*/
     89
     90        return SpcStaticEnum;
    9191
    9292}
  • issm/trunk-jpl/src/c/classes/Constraints/SpcStatic.h

    r19216 r20810  
    2929                /*}}}*/
    3030                /*Object virtual functions definitions:{{{ */
     31                Object* copy();
     32                void  DeepEcho();
    3133                void  Echo();
    32                 void  DeepEcho();
    3334                int   Id();
     35                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3436                int   ObjectEnum();
    35                 Object* copy();
    36                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3737                /*}}}*/
    3838                /*Constraint virtual functions definitions: {{{*/
     
    4343                /*}}}*/
    4444                /*SpcStatic management:{{{ */
     45                int    GetDof();
    4546                int    GetNodeId();
    46                 int    GetDof();
    4747                IssmDouble GetValue();
    4848                /*}}}*/
  • issm/trunk-jpl/src/c/classes/Constraints/SpcTransient.cpp

    r19256 r20810  
    7979}
    8080/*}}}*/
    81 int     SpcTransient::ObjectEnum(void){/*{{{*/
    82 
    83         return SpcTransientEnum;
    84 
    85 }
    86 /*}}}*/
    8781void    SpcTransient::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
    8882
     
    106100}
    107101/*}}}*/
     102int     SpcTransient::ObjectEnum(void){/*{{{*/
     103
     104        return SpcTransientEnum;
     105
     106}
     107/*}}}*/
    108108
    109109/*Constraint virtual functions definitions:*/
  • issm/trunk-jpl/src/c/classes/Constraints/SpcTransient.h

    r19254 r20810  
    3535                void    Echo();
    3636                int     Id();
     37                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3738                int     ObjectEnum();
    38                 void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3939                /*}}}*/
    4040                /*Constraint virtual functions definitions: {{{*/
  • issm/trunk-jpl/src/c/classes/Contour.h

    r19198 r20810  
    5252
    5353                /*Object virtual function resolutoin: */
     54                Object* copy() {/*{{{*/
     55
     56                        Contour* contour = new Contour(this->id,this->nods,this->x,this->y,this->closed);
     57
     58                        return (Object*) contour;
     59                }
     60                /*}}}*/
     61                void DeepEcho(void){/*{{{*/
     62                        this->Echo();
     63                }
     64                /*}}}*/
    5465                void Echo(void){/*{{{*/
    5566                        _printf_(" Contour: " << id << "\n");
     
    6475                }
    6576                /*}}}*/
    66                 void DeepEcho(void){/*{{{*/
    67                         this->Echo();
    68                 }
    69                 /*}}}*/
    7077                int Id(void){/*{{{*/
    7178                        return id;
    72                 }
    73                 /*}}}*/
    74                 int ObjectEnum(void){/*{{{*/
    75                         return ContourEnum;
    76                 }
    77                 /*}}}*/
    78                 Object* copy() {/*{{{*/
    79 
    80                         Contour* contour = new Contour(this->id,this->nods,this->x,this->y,this->closed);
    81 
    82                         return (Object*) contour;
    8379                }
    8480                /*}}}*/
     
    8783                }
    8884                /*}}}*/
     85                int ObjectEnum(void){/*{{{*/
     86                        return ContourEnum;
     87                }
     88                /*}}}*/
    8989
    9090};
  • issm/trunk-jpl/src/c/classes/DependentObject.cpp

    r18064 r20810  
    3636
    3737/*Object virtual functions definitions:*/
     38Object* DependentObject::copy(void) { /*{{{*/
     39        return new DependentObject(name,type,index);
     40} /*}}}*/
     41void DependentObject::DeepEcho(void){/*{{{*/
     42        this->Echo();
     43}
     44/*}}}*/
    3845void DependentObject::Echo(void){/*{{{*/
    3946
     
    4956}
    5057/*}}}*/
    51 void DependentObject::DeepEcho(void){/*{{{*/
    52         this->Echo();
    53 }
    54 /*}}}*/
    5558int    DependentObject::Id(void){ return -1; }/*{{{*/
    5659/*}}}*/
     
    6164}
    6265/*}}}*/
    63 Object* DependentObject::copy(void) { /*{{{*/
    64         return new DependentObject(name,type,index);
    65 } /*}}}*/
    6666
    6767/*DependentObject methods: */
  • issm/trunk-jpl/src/c/classes/DependentObject.h

    r19198 r20810  
    2727                /*}}}*/
    2828                /*Object virtual functions definitions:{{{ */
     29                Object* copy(void);
     30                void  DeepEcho();
    2931                void  Echo();
    30                 void  DeepEcho();
    3132                int   Id();
    3233                int   ObjectEnum();
    33                 Object* copy(void);
    3434                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/
    3535                        _error_("not implemented yet!");
  • issm/trunk-jpl/src/c/classes/DofIndexing.cpp

    r20462 r20810  
    214214
    215215/*Some of the Object functionality: */
    216 void DofIndexing::Echo(void){/*{{{*/
     216void DofIndexing::Activate(void){/*{{{*/
     217
     218        this->active = true;
     219
     220        /*Constrain to 0. at this point*/
     221        for(int i=0;i<this->gsize;i++){
     222                this->f_set[i]    = true;
     223                this->s_set[i]    = false;
     224                this->svalues[i]  = 0.;
     225        }
     226        return;
     227}
     228/*}}}*/
     229void DofIndexing::Deactivate(void){/*{{{*/
     230        this->active = false;
     231
     232        /*Constrain to 0. at this point*/
     233        for(int i=0;i<this->gsize;i++){
     234                this->f_set[i]    = false;
     235                this->s_set[i]    = true;
     236                this->svalues[i]  = 0.;
     237        }
     238        return;
     239}
     240/*}}}*/
     241void DofIndexing::DeepEcho(void){/*{{{*/
     242
     243        int i;
    217244
    218245        _printf_("DofIndexing:\n");
     
    223250        _printf_("   active: " << active << "\n");
    224251        _printf_("   freeze: " << freeze << "\n");
    225 }
    226 /*}}}*/
    227 void DofIndexing::DeepEcho(void){/*{{{*/
    228 
    229         int i;
     252
     253        _printf_("   set membership: f,s sets \n");
     254        for(i=0;i<gsize;i++){
     255                _printf_("      dof " << i << ": " <<(f_set[i]?"true":"false")<< " " <<(s_set[i]?"true":"false") << "\n");
     256        }
     257
     258        _printf_("   svalues (" << this->ssize << "): |");
     259        for(i=0;i<this->gsize;i++){
     260                if(this->s_set[i])_printf_(" " << svalues[i] << " |");
     261        }
     262        _printf_("\n");
     263
     264        if(doftype){
     265                _printf_("   doftype: |");
     266                for(i=0;i<gsize;i++){
     267                        _printf_(" " << doftype[i] << " |");
     268                }
     269                _printf_("\n");
     270        }
     271        else _printf_("   doftype: NULL\n");
     272
     273        _printf_("   g_doflist (" << this->gsize << "): |");
     274        for(i=0;i<this->gsize;i++){
     275                _printf_(" " << gdoflist[i] << " |");
     276        }
     277        _printf_("\n");
     278
     279        _printf_("   f_doflist (" << this->fsize << "): |");
     280        for(i=0;i<this->fsize;i++){
     281                _printf_(" " << fdoflist[i] << " |");
     282        }
     283        _printf_("\n");
     284
     285        _printf_("   s_doflist (" << this->ssize << "): |");
     286        for(i=0;i<this->ssize;i++){
     287                _printf_(" " << sdoflist[i] << " |");
     288        }
     289        _printf_("\n");
     290}               
     291/*}}}*/
     292void DofIndexing::Echo(void){/*{{{*/
    230293
    231294        _printf_("DofIndexing:\n");
     
    236299        _printf_("   active: " << active << "\n");
    237300        _printf_("   freeze: " << freeze << "\n");
    238 
    239         _printf_("   set membership: f,s sets \n");
    240         for(i=0;i<gsize;i++){
    241                 _printf_("      dof " << i << ": " <<(f_set[i]?"true":"false")<< " " <<(s_set[i]?"true":"false") << "\n");
    242         }
    243 
    244         _printf_("   svalues (" << this->ssize << "): |");
    245         for(i=0;i<this->gsize;i++){
    246                 if(this->s_set[i])_printf_(" " << svalues[i] << " |");
    247         }
    248         _printf_("\n");
    249 
    250         if(doftype){
    251                 _printf_("   doftype: |");
    252                 for(i=0;i<gsize;i++){
    253                         _printf_(" " << doftype[i] << " |");
    254                 }
    255                 _printf_("\n");
    256         }
    257         else _printf_("   doftype: NULL\n");
    258 
    259         _printf_("   g_doflist (" << this->gsize << "): |");
    260         for(i=0;i<this->gsize;i++){
    261                 _printf_(" " << gdoflist[i] << " |");
    262         }
    263         _printf_("\n");
    264 
    265         _printf_("   f_doflist (" << this->fsize << "): |");
    266         for(i=0;i<this->fsize;i++){
    267                 _printf_(" " << fdoflist[i] << " |");
    268         }
    269         _printf_("\n");
    270 
    271         _printf_("   s_doflist (" << this->ssize << "): |");
    272         for(i=0;i<this->ssize;i++){
    273                 _printf_(" " << sdoflist[i] << " |");
    274         }
    275         _printf_("\n");
    276 }               
    277 /*}}}*/
    278 void DofIndexing::Deactivate(void){/*{{{*/
    279         this->active = false;
    280 
    281         /*Constrain to 0. at this point*/
    282         for(int i=0;i<this->gsize;i++){
    283                 this->f_set[i]    = false;
    284                 this->s_set[i]    = true;
    285                 this->svalues[i]  = 0.;
    286         }
    287         return;
    288 }
    289 /*}}}*/
    290 void DofIndexing::Activate(void){/*{{{*/
    291 
    292         this->active = true;
    293 
    294         /*Constrain to 0. at this point*/
    295         for(int i=0;i<this->gsize;i++){
    296                 this->f_set[i]    = true;
    297                 this->s_set[i]    = false;
    298                 this->svalues[i]  = 0.;
    299         }
    300         return;
    301301}
    302302/*}}}*/
  • issm/trunk-jpl/src/c/classes/DofIndexing.h

    r20462 r20810  
    4545                /*}}}*/
    4646                /*Object like functionality: {{{*/
     47                void  copy(const DofIndexing& in);
     48                void  DeepEcho(void);
    4749                void  Echo(void);
    48                 void  DeepEcho(void);
    49                 void  copy(const DofIndexing& in);
    5050                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    5151                /*}}}*/
    5252                /*DofIndexing management: {{{*/
    53                 DofIndexing* Spawn(int* indices, int numindices);
    5453                void Activate(void);
    5554                void Deactivate(void);
     55                DofIndexing* Spawn(int* indices, int numindices);
    5656                /*}}}*/
    5757
  • issm/trunk-jpl/src/c/classes/Elements/Element.cpp

    r20723 r20810  
    4343        this->inputs->AddInput(input_in);
    4444}/*}}}*/
     45void       Element::ComputeLambdaS(){/*{{{*/
     46
     47        /*Intermediaries*/
     48        IssmDouble vx,vy,vz,vmag;
     49        IssmDouble dvx[3],dvy[3],dvz[3],dvmag[3];
     50        IssmDouble epso,epsprime;
     51        int         dim;
     52        IssmDouble *xyz_list = NULL;
     53
     54        /*Retrieve all inputs we will be needing: */
     55        this->GetVerticesCoordinates(&xyz_list);
     56        parameters->FindParam(&dim,DomainDimensionEnum);
     57        Input* vx_input=this->GetInput(VxEnum); _assert_(vx_input);
     58        Input* vy_input=this->GetInput(VyEnum); _assert_(vy_input);
     59        Input* vz_input=NULL;
     60        if(dim==3){vz_input=this->GetInput(VzEnum); _assert_(vz_input);}
     61
     62        /*Allocate arrays*/
     63        int numvertices = this->GetNumberOfVertices();
     64        IssmDouble* lambdas = xNew<IssmDouble>(numvertices);
     65        IssmDouble* vorticityx = xNew<IssmDouble>(numvertices);
     66        IssmDouble* vorticityy = xNew<IssmDouble>(numvertices);
     67        IssmDouble* vorticityz = xNew<IssmDouble>(numvertices);
     68        IssmDouble* omega_corrx = xNew<IssmDouble>(numvertices);
     69        IssmDouble* omega_corry = xNew<IssmDouble>(numvertices);
     70        IssmDouble* omega_corrz = xNew<IssmDouble>(numvertices);
     71
     72        /* Start looping on the number of vertices: */
     73        Gauss* gauss=this->NewGauss();
     74        for (int iv=0;iv<numvertices;iv++){
     75                gauss->GaussVertex(iv);
     76
     77                /*Get velocity derivatives in all directions*/
     78                _assert_(dim>1);
     79                _assert_(vx_input);
     80                vx_input->GetInputValue(&vx,gauss);
     81                vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     82                _assert_(vy_input);
     83                vy_input->GetInputValue(&vy,gauss);
     84                vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
     85                if(dim==3){
     86                        _assert_(vz_input);
     87                        vz_input->GetInputValue(&vz,gauss);
     88                        vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
     89                }
     90                else{
     91                        vz = 0.;
     92                        dvz[0] = 0.; dvz[1] = 0.; dvz[2] = 0.;
     93                }
     94                /*Calculate velocity magnitude and its derivative*/
     95                vmag = sqrt(vx*vx+vy*vy+vz*vz);
     96                if(vmag<1e-12){
     97                        vmag=1e-12;
     98                        dvmag[0]=0;
     99                        dvmag[1]=0;
     100                        dvmag[2]=0;
     101                }
     102                else{
     103                        dvmag[0]=1./(2*sqrt(vmag))*(2*vx*dvx[0]+2*vy*dvy[0]+2*vz*dvz[0]);
     104                        dvmag[1]=1./(2*sqrt(vmag))*(2*vx*dvx[1]+2*vy*dvy[1]+2*vz*dvz[1]);
     105                        dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]);
     106                }
     107                EstarStrainrateQuantities(&epso,&epsprime,vx,vy,vz,vmag,&dvx[0],&dvy[0],&dvz[0],&dvmag[0]);
     108                lambdas[iv]=EstarLambdaS(epso,epsprime);
     109                vorticityx[iv]=dvz[1]-dvy[2];
     110                vorticityy[iv]=dvx[2]-dvz[0];
     111                vorticityz[iv]=dvy[0]-dvx[1];
     112                omega_corrx[iv] = -vorticityx[iv] + 2*(dvmag[1]*vz - dvmag[2]*vy)/vmag;
     113                omega_corry[iv] = -vorticityy[iv] + 2*(dvmag[2]*vx - dvmag[0]*vz)/vmag;
     114                omega_corrz[iv] = -vorticityz[iv] + 2*(dvmag[0]*vy - dvmag[1]*vx)/vmag;
     115        }
     116
     117        /*Add Stress tensor components into inputs*/
     118        this->AddInput(LambdaSEnum,lambdas,P1Enum);
     119        this->AddInput(Outputdefinition21Enum,vorticityx,P1Enum);
     120        this->AddInput(Outputdefinition22Enum,vorticityy,P1Enum);
     121        this->AddInput(Outputdefinition23Enum,vorticityz,P1Enum);
     122        this->AddInput(Outputdefinition31Enum,omega_corrx,P1Enum);
     123        this->AddInput(Outputdefinition32Enum,omega_corry,P1Enum);
     124        this->AddInput(Outputdefinition33Enum,omega_corrz,P1Enum);
     125       
     126        /*Clean up and return*/
     127        delete gauss;
     128        xDelete<IssmDouble>(xyz_list);
     129        xDelete<IssmDouble>(lambdas);
     130
     131}
     132/*}}}*/
    45133void       Element::ComputeNewDamage(){/*{{{*/
    46134
     
    218306        xDelete<IssmDouble>(eps_yz);
    219307        xDelete<IssmDouble>(eps_ef);
    220 
    221 }
    222 /*}}}*/
    223 void       Element::ComputeLambdaS(){/*{{{*/
    224 
    225         /*Intermediaries*/
    226         IssmDouble vx,vy,vz,vmag;
    227         IssmDouble dvx[3],dvy[3],dvz[3],dvmag[3];
    228         IssmDouble epso,epsprime;
    229         int         dim;
    230         IssmDouble *xyz_list = NULL;
    231 
    232         /*Retrieve all inputs we will be needing: */
    233         this->GetVerticesCoordinates(&xyz_list);
    234         parameters->FindParam(&dim,DomainDimensionEnum);
    235         Input* vx_input=this->GetInput(VxEnum); _assert_(vx_input);
    236         Input* vy_input=this->GetInput(VyEnum); _assert_(vy_input);
    237         Input* vz_input=NULL;
    238         if(dim==3){vz_input=this->GetInput(VzEnum); _assert_(vz_input);}
    239 
    240         /*Allocate arrays*/
    241         int numvertices = this->GetNumberOfVertices();
    242         IssmDouble* lambdas = xNew<IssmDouble>(numvertices);
    243         IssmDouble* vorticityx = xNew<IssmDouble>(numvertices);
    244         IssmDouble* vorticityy = xNew<IssmDouble>(numvertices);
    245         IssmDouble* vorticityz = xNew<IssmDouble>(numvertices);
    246         IssmDouble* omega_corrx = xNew<IssmDouble>(numvertices);
    247         IssmDouble* omega_corry = xNew<IssmDouble>(numvertices);
    248         IssmDouble* omega_corrz = xNew<IssmDouble>(numvertices);
    249 
    250         /* Start looping on the number of vertices: */
    251         Gauss* gauss=this->NewGauss();
    252         for (int iv=0;iv<numvertices;iv++){
    253                 gauss->GaussVertex(iv);
    254 
    255                 /*Get velocity derivatives in all directions*/
    256                 _assert_(dim>1);
    257                 _assert_(vx_input);
    258                 vx_input->GetInputValue(&vx,gauss);
    259                 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    260                 _assert_(vy_input);
    261                 vy_input->GetInputValue(&vy,gauss);
    262                 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    263                 if(dim==3){
    264                         _assert_(vz_input);
    265                         vz_input->GetInputValue(&vz,gauss);
    266                         vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
    267                 }
    268                 else{
    269                         vz = 0.;
    270                         dvz[0] = 0.; dvz[1] = 0.; dvz[2] = 0.;
    271                 }
    272                 /*Calculate velocity magnitude and its derivative*/
    273                 vmag = sqrt(vx*vx+vy*vy+vz*vz);
    274                 if(vmag<1e-12){
    275                         vmag=1e-12;
    276                         dvmag[0]=0;
    277                         dvmag[1]=0;
    278                         dvmag[2]=0;
    279                 }
    280                 else{
    281                         dvmag[0]=1./(2*sqrt(vmag))*(2*vx*dvx[0]+2*vy*dvy[0]+2*vz*dvz[0]);
    282                         dvmag[1]=1./(2*sqrt(vmag))*(2*vx*dvx[1]+2*vy*dvy[1]+2*vz*dvz[1]);
    283                         dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]);
    284                 }
    285                 EstarStrainrateQuantities(&epso,&epsprime,vx,vy,vz,vmag,&dvx[0],&dvy[0],&dvz[0],&dvmag[0]);
    286                 lambdas[iv]=EstarLambdaS(epso,epsprime);
    287                 vorticityx[iv]=dvz[1]-dvy[2];
    288                 vorticityy[iv]=dvx[2]-dvz[0];
    289                 vorticityz[iv]=dvy[0]-dvx[1];
    290                 omega_corrx[iv] = -vorticityx[iv] + 2*(dvmag[1]*vz - dvmag[2]*vy)/vmag;
    291                 omega_corry[iv] = -vorticityy[iv] + 2*(dvmag[2]*vx - dvmag[0]*vz)/vmag;
    292                 omega_corrz[iv] = -vorticityz[iv] + 2*(dvmag[0]*vy - dvmag[1]*vx)/vmag;
    293         }
    294 
    295         /*Add Stress tensor components into inputs*/
    296         this->AddInput(LambdaSEnum,lambdas,P1Enum);
    297         this->AddInput(Outputdefinition21Enum,vorticityx,P1Enum);
    298         this->AddInput(Outputdefinition22Enum,vorticityy,P1Enum);
    299         this->AddInput(Outputdefinition23Enum,vorticityz,P1Enum);
    300         this->AddInput(Outputdefinition31Enum,omega_corrx,P1Enum);
    301         this->AddInput(Outputdefinition32Enum,omega_corry,P1Enum);
    302         this->AddInput(Outputdefinition33Enum,omega_corrz,P1Enum);
    303        
    304         /*Clean up and return*/
    305         delete gauss;
    306         xDelete<IssmDouble>(xyz_list);
    307         xDelete<IssmDouble>(lambdas);
    308308
    309309}
     
    426426        delete this->material;
    427427}/*}}}*/
    428 IssmDouble Element::Divergence(void){/*{{{*/
    429         /*Compute element divergence*/
    430 
    431         /*Intermediaries*/
    432         int        dim;
    433         IssmDouble Jdet;
    434         IssmDouble divergence=0.;
    435         IssmDouble dvx[3],dvy[3],dvz[3];
    436         IssmDouble *xyz_list = NULL;
    437 
    438         /*Get inputs and parameters*/
    439         this->FindParam(&dim,DomainDimensionEnum);
    440         Input* vx_input = this->GetInput(VxEnum); _assert_(vx_input);
    441         Input* vy_input = this->GetInput(VyEnum); _assert_(vy_input);
    442         Input* vz_input = NULL;
    443         if(dim==3){
    444                 vz_input = this->GetInput(VzEnum); _assert_(vz_input);
    445         }
    446         this->GetVerticesCoordinates(&xyz_list);
    447 
    448         Gauss* gauss=this->NewGauss(5);
    449         for(int ig=gauss->begin();ig<gauss->end();ig++){
    450                 gauss->GaussPoint(ig);
    451                 this->JacobianDeterminant(&Jdet,xyz_list,gauss);
    452 
    453                 /*Get strain rate assuming that epsilon has been allocated*/
    454                 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    455                 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    456                 if(dim==2){
    457                         divergence += (dvx[0]+dvy[1])*gauss->weight*Jdet;
    458                 }
    459                 else{
    460                         vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
    461                         divergence += (dvx[0]+dvy[1]+dvz[2])*gauss->weight*Jdet;
    462                 }
    463 
    464         }
    465 
    466         /*Clean up and return*/
    467         xDelete<IssmDouble>(xyz_list);
    468         delete gauss;
    469         return divergence;
    470 }/*}}}*/
    471 void       Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
    472 
    473         /*Intermediaries*/
    474         IssmDouble dmudB;
    475         IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
    476         IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
    477         IssmDouble eps_eff;
    478         IssmDouble eps0=1.e-27;
    479 
    480         if(dim==3){
    481                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
    482                 this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);
    483                 eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[3]*epsilon3d[3] +  epsilon3d[4]*epsilon3d[4] + epsilon3d[5]*epsilon3d[5] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
    484         }
    485         else{
    486                 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
    487                 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    488                 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);
    489         }
    490         /*Get viscosity*/
    491         material->GetViscosity_B(&dmudB,eps_eff);
    492 
    493         /*Assign output pointer*/
    494         *pdmudB=dmudB;
    495 
    496 }
    497 /*}}}*/
    498 void       Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    499 
    500         /*Intermediaries*/
    501         IssmDouble dmudB;
    502         IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
    503         IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy];    */
    504         IssmDouble eps_eff;
    505         IssmDouble eps0=1.e-27;
    506 
    507         if(dim==3){
    508                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
    509                 this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
    510                 eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[2]*epsilon3d[2] + epsilon3d[3]*epsilon3d[3] +  epsilon3d[4]*epsilon3d[4] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
    511         }
    512         else{
    513                 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
    514                 this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    515                 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0);
    516         }
    517         /*Get viscosity*/
    518         material->GetViscosity_B(&dmudB,eps_eff);
    519 
    520         /*Assign output pointer*/
    521         *pdmudB=dmudB;
    522 
    523 }
    524 /*}}}*/
    525 void       Element::dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    526 
    527         /*Intermediaries*/
    528         IssmDouble dmudB;
    529         IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
    530         IssmDouble epsilon1d;   /* epsilon=[exx];    */
    531         IssmDouble eps_eff;
    532 
    533          if(dim==2){
    534                  /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
    535                  this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    536                  eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
    537          }
    538          else{
    539                  /* eps_eff^2 = 1/2 exx^2*/
    540                  this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
    541                  eps_eff = sqrt(epsilon1d*epsilon1d/2.);
    542          }
    543 
    544         /*Get viscosity*/
    545         material->GetViscosity_B(&dmudB,eps_eff);
    546 
    547         /*Assign output pointer*/
    548         *pdmudB=dmudB;
    549 
    550 }
    551 /*}}}*/
    552 void       Element::dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    553 
    554         /*Intermediaries*/
    555         IssmDouble dmudB;
    556         IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
    557         IssmDouble epsilon1d;   /* epsilon=[exx];    */
    558         IssmDouble eps_eff;
    559 
    560         if(dim==2){
    561                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
    562                 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    563                 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
    564         }
    565         else{
    566                 /* eps_eff^2 = 1/2 exx^2*/
    567                 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
    568                 eps_eff = sqrt(epsilon1d*epsilon1d/2.);
    569         }
    570 
    571         /*Get viscosity*/
    572         material->GetViscosity_D(&dmudB,eps_eff);
    573 
    574         /*Assign output pointer*/
    575         *pdmudB=dmudB;
    576 
    577 }
    578 /*}}}*/
    579428void       Element::Delta18oParameterization(void){/*{{{*/
    580429
     
    681530}
    682531/*}}}*/
    683 void       Element::MungsmtpParameterization(void){/*{{{*/
    684         /*Are we on the base? If not, return*/
    685         if(!IsOnBase()) return;
    686 
    687         int        numvertices = this->GetNumberOfVertices();
    688 
    689         int        i;
    690         IssmDouble* monthlytemperatures=xNew<IssmDouble>(12*numvertices);
    691         IssmDouble* monthlyprec=xNew<IssmDouble>(12*numvertices);
    692         IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(12*numvertices);
    693         IssmDouble* TemperaturesLgm=xNew<IssmDouble>(12*numvertices);
    694         IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(12*numvertices);
    695         IssmDouble* PrecipitationsLgm=xNew<IssmDouble>(12*numvertices);
    696         IssmDouble* tmp=xNew<IssmDouble>(numvertices);
    697         IssmDouble TdiffTime,PfacTime;
    698         IssmDouble time,yts,time_yr;
    699         this->parameters->FindParam(&time,TimeEnum);
    700         this->parameters->FindParam(&yts,ConstantsYtsEnum);
    701         time_yr=floor(time/yts)*yts;
    702 
    703         /*Recover present day temperature and precipitation*/
    704         Input*     input=this->inputs->GetInput(SmbTemperaturesPresentdayEnum);    _assert_(input);
    705         Input*     input2=this->inputs->GetInput(SmbTemperaturesLgmEnum);          _assert_(input2);
    706         Input*     input3=this->inputs->GetInput(SmbPrecipitationsPresentdayEnum); _assert_(input3);
    707         Input*     input4=this->inputs->GetInput(SmbPrecipitationsLgmEnum);        _assert_(input4);
    708         /*loop over vertices: */
    709         Gauss* gauss=this->NewGauss();
    710         for(int month=0;month<12;month++) {
    711                 for(int iv=0;iv<numvertices;iv++) {
    712                         gauss->GaussVertex(iv);
    713                         input->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month/12.*yts);
    714                         input2->GetInputValue(&TemperaturesLgm[iv*12+month],gauss,month/12.*yts);
    715                         input3->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month/12.*yts);
    716                         input4->GetInputValue(&PrecipitationsLgm[iv*12+month],gauss,month/12.*yts);
    717 
    718                         PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;
    719                         PrecipitationsLgm[iv*12+month]=PrecipitationsLgm[iv*12+month]*yts;
    720                 }
    721         }
    722 
    723         /*Recover interpolation parameters at time t*/
    724         this->parameters->FindParam(&TdiffTime,SmbTdiffEnum,time);
    725         this->parameters->FindParam(&PfacTime,SmbPfacEnum,time);
    726 
    727         /*Compute the temperature and precipitation*/
    728         for(int iv=0;iv<numvertices;iv++){
    729                 ComputeMungsmTemperaturePrecipitation(TdiffTime,PfacTime,
    730                                         &PrecipitationsLgm[iv*12],&PrecipitationsPresentday[iv*12],
    731                                         &TemperaturesLgm[iv*12], &TemperaturesPresentday[iv*12],
    732                                         &monthlytemperatures[iv*12], &monthlyprec[iv*12]);
    733         }
    734 
    735         /*Update inputs*/
    736         TransientInput* NewTemperatureInput = new TransientInput(SmbMonthlytemperaturesEnum);
    737         TransientInput* NewPrecipitationInput = new TransientInput(SmbPrecipitationEnum);
    738         for (int imonth=0;imonth<12;imonth++) {
    739                 for(i=0;i<numvertices;i++) tmp[i]=monthlytemperatures[i*12+imonth];
    740                 switch(this->ObjectEnum()){
    741                         case TriaEnum:  NewTemperatureInput->AddTimeInput(new TriaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
    742                         case PentaEnum: NewTemperatureInput->AddTimeInput(new PentaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
    743                         case TetraEnum: NewTemperatureInput->AddTimeInput(new TetraInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
    744                         default: _error_("Not implemented yet");
    745                 }
    746                 for(i=0;i<numvertices;i++) tmp[i]=monthlyprec[i*12+imonth]/yts;
    747                 switch(this->ObjectEnum()){
    748                         case TriaEnum:  NewPrecipitationInput->AddTimeInput(new TriaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
    749                         case PentaEnum: NewPrecipitationInput->AddTimeInput(new PentaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
    750                         case TetraEnum: NewPrecipitationInput->AddTimeInput(new TetraInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
    751                         default: _error_("Not implemented yet");
    752                 }
    753         }
    754         NewTemperatureInput->Configure(this->parameters);
    755         NewPrecipitationInput->Configure(this->parameters);
    756 
    757         this->inputs->AddInput(NewTemperatureInput);
    758         this->inputs->AddInput(NewPrecipitationInput);
    759 
    760         switch(this->ObjectEnum()){
    761                 case TriaEnum: break;
    762                 case PentaEnum:
    763                 case TetraEnum:
    764                                                         this->InputExtrude(SmbMonthlytemperaturesEnum,-1);
    765                                                         this->InputExtrude(SmbPrecipitationEnum,-1);
    766                                                         break;
    767                 default: _error_("Not implemented yet");
    768         }
    769 
    770         /*clean-up*/
    771         delete gauss;
    772         xDelete<IssmDouble>(monthlytemperatures);
    773         xDelete<IssmDouble>(monthlyprec);
    774         xDelete<IssmDouble>(TemperaturesPresentday);
    775         xDelete<IssmDouble>(TemperaturesLgm);
    776         xDelete<IssmDouble>(PrecipitationsPresentday);
    777         xDelete<IssmDouble>(PrecipitationsLgm);
    778         xDelete<IssmDouble>(tmp);
    779 
    780 }
    781 /*}}}*/
    782532void       Element::Delta18opdParameterization(void){/*{{{*/
    783533        /*Are we on the base? If not, return*/
     
    870620        xDelete<IssmDouble>(tmp);
    871621       
     622}
     623/*}}}*/
     624IssmDouble Element::Divergence(void){/*{{{*/
     625        /*Compute element divergence*/
     626
     627        /*Intermediaries*/
     628        int        dim;
     629        IssmDouble Jdet;
     630        IssmDouble divergence=0.;
     631        IssmDouble dvx[3],dvy[3],dvz[3];
     632        IssmDouble *xyz_list = NULL;
     633
     634        /*Get inputs and parameters*/
     635        this->FindParam(&dim,DomainDimensionEnum);
     636        Input* vx_input = this->GetInput(VxEnum); _assert_(vx_input);
     637        Input* vy_input = this->GetInput(VyEnum); _assert_(vy_input);
     638        Input* vz_input = NULL;
     639        if(dim==3){
     640                vz_input = this->GetInput(VzEnum); _assert_(vz_input);
     641        }
     642        this->GetVerticesCoordinates(&xyz_list);
     643
     644        Gauss* gauss=this->NewGauss(5);
     645        for(int ig=gauss->begin();ig<gauss->end();ig++){
     646                gauss->GaussPoint(ig);
     647                this->JacobianDeterminant(&Jdet,xyz_list,gauss);
     648
     649                /*Get strain rate assuming that epsilon has been allocated*/
     650                vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     651                vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
     652                if(dim==2){
     653                        divergence += (dvx[0]+dvy[1])*gauss->weight*Jdet;
     654                }
     655                else{
     656                        vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
     657                        divergence += (dvx[0]+dvy[1]+dvz[2])*gauss->weight*Jdet;
     658                }
     659
     660        }
     661
     662        /*Clean up and return*/
     663        xDelete<IssmDouble>(xyz_list);
     664        delete gauss;
     665        return divergence;
     666}/*}}}*/
     667void       Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
     668
     669        /*Intermediaries*/
     670        IssmDouble dmudB;
     671        IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
     672        IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
     673        IssmDouble eps_eff;
     674        IssmDouble eps0=1.e-27;
     675
     676        if(dim==3){
     677                /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
     678                this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);
     679                eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[3]*epsilon3d[3] +  epsilon3d[4]*epsilon3d[4] + epsilon3d[5]*epsilon3d[5] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
     680        }
     681        else{
     682                /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
     683                this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     684                eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);
     685        }
     686        /*Get viscosity*/
     687        material->GetViscosity_B(&dmudB,eps_eff);
     688
     689        /*Assign output pointer*/
     690        *pdmudB=dmudB;
     691
     692}
     693/*}}}*/
     694void       Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     695
     696        /*Intermediaries*/
     697        IssmDouble dmudB;
     698        IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
     699        IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy];    */
     700        IssmDouble eps_eff;
     701        IssmDouble eps0=1.e-27;
     702
     703        if(dim==3){
     704                /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
     705                this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
     706                eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[2]*epsilon3d[2] + epsilon3d[3]*epsilon3d[3] +  epsilon3d[4]*epsilon3d[4] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);
     707        }
     708        else{
     709                /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
     710                this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     711                eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0);
     712        }
     713        /*Get viscosity*/
     714        material->GetViscosity_B(&dmudB,eps_eff);
     715
     716        /*Assign output pointer*/
     717        *pdmudB=dmudB;
     718
     719}
     720/*}}}*/
     721void       Element::dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     722
     723        /*Intermediaries*/
     724        IssmDouble dmudB;
     725        IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
     726        IssmDouble epsilon1d;   /* epsilon=[exx];    */
     727        IssmDouble eps_eff;
     728
     729         if(dim==2){
     730                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
     731                 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     732                 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
     733         }
     734         else{
     735                 /* eps_eff^2 = 1/2 exx^2*/
     736                 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
     737                 eps_eff = sqrt(epsilon1d*epsilon1d/2.);
     738         }
     739
     740        /*Get viscosity*/
     741        material->GetViscosity_B(&dmudB,eps_eff);
     742
     743        /*Assign output pointer*/
     744        *pdmudB=dmudB;
     745
     746}
     747/*}}}*/
     748void       Element::dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     749
     750        /*Intermediaries*/
     751        IssmDouble dmudB;
     752        IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
     753        IssmDouble epsilon1d;   /* epsilon=[exx];    */
     754        IssmDouble eps_eff;
     755
     756        if(dim==2){
     757                /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/
     758                this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     759                eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);
     760        }
     761        else{
     762                /* eps_eff^2 = 1/2 exx^2*/
     763                this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);
     764                eps_eff = sqrt(epsilon1d*epsilon1d/2.);
     765        }
     766
     767        /*Get viscosity*/
     768        material->GetViscosity_D(&dmudB,eps_eff);
     769
     770        /*Assign output pointer*/
     771        *pdmudB=dmudB;
     772
    872773}
    873774/*}}}*/
     
    15541455bool       Element::IsIceInElement(){/*{{{*/
    15551456        return (this->inputs->Min(MaskIceLevelsetEnum)<0.);
    1556 }
    1557 /*}}}*/
    1558 bool       Element::IsWaterInElement(){/*{{{*/
    1559         return (this->inputs->Max(MaskOceanLevelsetEnum)>0.);
    1560 }
    1561 /*}}}*/
    1562 bool       Element::IsLandInElement(){/*{{{*/
    1563         return (this->inputs->Max(MaskLandLevelsetEnum)>0.);
    15641457}
    15651458/*}}}*/
     
    16501543}
    16511544/*}}}*/
     1545bool       Element::IsLandInElement(){/*{{{*/
     1546        return (this->inputs->Max(MaskLandLevelsetEnum)>0.);
     1547}
     1548/*}}}*/
     1549bool       Element::IsWaterInElement(){/*{{{*/
     1550        return (this->inputs->Max(MaskOceanLevelsetEnum)>0.);
     1551}
     1552/*}}}*/
    16521553void       Element::LinearFloatingiceMeltingRate(){/*{{{*/
    16531554
     
    18601761
    18611762}/*}}}*/
     1763void       Element::MungsmtpParameterization(void){/*{{{*/
     1764        /*Are we on the base? If not, return*/
     1765        if(!IsOnBase()) return;
     1766
     1767        int        numvertices = this->GetNumberOfVertices();
     1768
     1769        int        i;
     1770        IssmDouble* monthlytemperatures=xNew<IssmDouble>(12*numvertices);
     1771        IssmDouble* monthlyprec=xNew<IssmDouble>(12*numvertices);
     1772        IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(12*numvertices);
     1773        IssmDouble* TemperaturesLgm=xNew<IssmDouble>(12*numvertices);
     1774        IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(12*numvertices);
     1775        IssmDouble* PrecipitationsLgm=xNew<IssmDouble>(12*numvertices);
     1776        IssmDouble* tmp=xNew<IssmDouble>(numvertices);
     1777        IssmDouble TdiffTime,PfacTime;
     1778        IssmDouble time,yts,time_yr;
     1779        this->parameters->FindParam(&time,TimeEnum);
     1780        this->parameters->FindParam(&yts,ConstantsYtsEnum);
     1781        time_yr=floor(time/yts)*yts;
     1782
     1783        /*Recover present day temperature and precipitation*/
     1784        Input*     input=this->inputs->GetInput(SmbTemperaturesPresentdayEnum);    _assert_(input);
     1785        Input*     input2=this->inputs->GetInput(SmbTemperaturesLgmEnum);          _assert_(input2);
     1786        Input*     input3=this->inputs->GetInput(SmbPrecipitationsPresentdayEnum); _assert_(input3);
     1787        Input*     input4=this->inputs->GetInput(SmbPrecipitationsLgmEnum);        _assert_(input4);
     1788        /*loop over vertices: */
     1789        Gauss* gauss=this->NewGauss();
     1790        for(int month=0;month<12;month++) {
     1791                for(int iv=0;iv<numvertices;iv++) {
     1792                        gauss->GaussVertex(iv);
     1793                        input->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month/12.*yts);
     1794                        input2->GetInputValue(&TemperaturesLgm[iv*12+month],gauss,month/12.*yts);
     1795                        input3->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month/12.*yts);
     1796                        input4->GetInputValue(&PrecipitationsLgm[iv*12+month],gauss,month/12.*yts);
     1797
     1798                        PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;
     1799                        PrecipitationsLgm[iv*12+month]=PrecipitationsLgm[iv*12+month]*yts;
     1800                }
     1801        }
     1802
     1803        /*Recover interpolation parameters at time t*/
     1804        this->parameters->FindParam(&TdiffTime,SmbTdiffEnum,time);
     1805        this->parameters->FindParam(&PfacTime,SmbPfacEnum,time);
     1806
     1807        /*Compute the temperature and precipitation*/
     1808        for(int iv=0;iv<numvertices;iv++){
     1809                ComputeMungsmTemperaturePrecipitation(TdiffTime,PfacTime,
     1810                                        &PrecipitationsLgm[iv*12],&PrecipitationsPresentday[iv*12],
     1811                                        &TemperaturesLgm[iv*12], &TemperaturesPresentday[iv*12],
     1812                                        &monthlytemperatures[iv*12], &monthlyprec[iv*12]);
     1813        }
     1814
     1815        /*Update inputs*/
     1816        TransientInput* NewTemperatureInput = new TransientInput(SmbMonthlytemperaturesEnum);
     1817        TransientInput* NewPrecipitationInput = new TransientInput(SmbPrecipitationEnum);
     1818        for (int imonth=0;imonth<12;imonth++) {
     1819                for(i=0;i<numvertices;i++) tmp[i]=monthlytemperatures[i*12+imonth];
     1820                switch(this->ObjectEnum()){
     1821                        case TriaEnum:  NewTemperatureInput->AddTimeInput(new TriaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
     1822                        case PentaEnum: NewTemperatureInput->AddTimeInput(new PentaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
     1823                        case TetraEnum: NewTemperatureInput->AddTimeInput(new TetraInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
     1824                        default: _error_("Not implemented yet");
     1825                }
     1826                for(i=0;i<numvertices;i++) tmp[i]=monthlyprec[i*12+imonth]/yts;
     1827                switch(this->ObjectEnum()){
     1828                        case TriaEnum:  NewPrecipitationInput->AddTimeInput(new TriaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
     1829                        case PentaEnum: NewPrecipitationInput->AddTimeInput(new PentaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
     1830                        case TetraEnum: NewPrecipitationInput->AddTimeInput(new TetraInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;
     1831                        default: _error_("Not implemented yet");
     1832                }
     1833        }
     1834        NewTemperatureInput->Configure(this->parameters);
     1835        NewPrecipitationInput->Configure(this->parameters);
     1836
     1837        this->inputs->AddInput(NewTemperatureInput);
     1838        this->inputs->AddInput(NewPrecipitationInput);
     1839
     1840        switch(this->ObjectEnum()){
     1841                case TriaEnum: break;
     1842                case PentaEnum:
     1843                case TetraEnum:
     1844                                                        this->InputExtrude(SmbMonthlytemperaturesEnum,-1);
     1845                                                        this->InputExtrude(SmbPrecipitationEnum,-1);
     1846                                                        break;
     1847                default: _error_("Not implemented yet");
     1848        }
     1849
     1850        /*clean-up*/
     1851        delete gauss;
     1852        xDelete<IssmDouble>(monthlytemperatures);
     1853        xDelete<IssmDouble>(monthlyprec);
     1854        xDelete<IssmDouble>(TemperaturesPresentday);
     1855        xDelete<IssmDouble>(TemperaturesLgm);
     1856        xDelete<IssmDouble>(PrecipitationsPresentday);
     1857        xDelete<IssmDouble>(PrecipitationsLgm);
     1858        xDelete<IssmDouble>(tmp);
     1859
     1860}
     1861/*}}}*/
    18621862ElementMatrix* Element::NewElementMatrix(int approximation_enum){/*{{{*/
    18631863        return new ElementMatrix(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
     
    20692069                        switch(calvinglaw){
    20702070                                case DefaultCalvingEnum:
    2071                                 case CalvingMinthicknessEnum:
    20722071                                        //do nothing
    20732072                                        break;
  • issm/trunk-jpl/src/c/classes/Elements/Element.h

    r20723 r20810  
    6363                void               ComputeStrainRate();
    6464                void               CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes,int numnodes,int* cs_array);
    65                 void               Echo();
    6665                void               DeepEcho();
    6766                void               DeleteInput(int input_enum);
    6867                void               DeleteMaterials(void);
    6968                void               Delta18oParameterization(void);
    70                 void               MungsmtpParameterization(void);
    7169                void               Delta18opdParameterization(void);
    7270                IssmDouble         Divergence(void);
     
    7573                void               dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
    7674                void               dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input);
     75                void               Echo();
    7776                IssmDouble         EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure);
    7877                IssmDouble         EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure);
     
    120119                bool               IsFloating();
    121120                bool               IsIceInElement();
     121                bool                 IsInput(int name);
     122                bool               IsLandInElement();
    122123                bool               IsWaterInElement();
    123                 bool               IsLandInElement();
    124                 bool                 IsInput(int name);
    125124                void               LinearFloatingiceMeltingRate();
    126125                void               MantlePlumeGeothermalFlux();
     
    128127                void               MigrateGroundingLine(IssmDouble* sheet_ungrounding);
    129128                void               MismipFloatingiceMeltingRate();
     129                void               MungsmtpParameterization(void);
    130130                ElementMatrix*     NewElementMatrix(int approximation_enum=NoneApproximationEnum);
    131131                ElementMatrix*     NewElementMatrixCoupling(int number_nodes,int approximation_enum=NoneApproximationEnum);
     
    174174                virtual void       AddInput(int input_enum, IssmDouble* values, int interpolation_enum)=0;
    175175                virtual void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part)=0;
     176                virtual void       CalvingRateDev(void){_error_("not implemented yet");};
    176177                virtual void        CalvingRateLevermann(void)=0;
    177                 virtual void       CalvingRateDev(void){_error_("not implemented yet");};
    178                 virtual void       WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};
    179                 virtual void       ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};
    180178                virtual IssmDouble CharacteristicLength(void)=0;
    181179                virtual void       ComputeBasalStress(Vector<IssmDouble>* sigma_b)=0;
     
    266264                virtual void       ResetFSBasalBoundaryCondition()=0;
    267265                virtual void       ResetHooks()=0;
     266                virtual void       ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};
    268267                virtual void       SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0;
    269268                virtual void       SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters)=0;
     
    291290                virtual void       VerticalSegmentIndices(int** pindices,int* pnumseg)=0;
    292291                virtual void       ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input)=0;
     292                virtual void       WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};
    293293                virtual void       ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0;
    294294
     
    297297                #endif
    298298                #ifdef _HAVE_SEALEVELRISE_
     299                virtual IssmDouble    GetArea3D(void)=0;
     300                virtual IssmDouble    OceanAverage(IssmDouble* Sg)=0;
     301                virtual IssmDouble    OceanArea(void)=0;
    299302                virtual void          SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0;
    300303                virtual void          SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0;
    301                 virtual IssmDouble    OceanAverage(IssmDouble* Sg)=0;
    302                 virtual IssmDouble    OceanArea(void)=0;
    303                 virtual IssmDouble    GetArea3D(void)=0;
    304304                #endif
    305305
  • issm/trunk-jpl/src/c/classes/Elements/Elements.cpp

    r18521 r20810  
    4848}
    4949/*}}}*/
    50 void Elements::SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/
     50void Elements::InputDuplicate(int input_enum,int output_enum){/*{{{*/
    5151
    52         vector<Object*>::iterator object;
    53         Element* element=NULL;
    54 
    55         for ( object=objects.begin() ; object < objects.end(); object++ ){
    56 
    57                 element=xDynamicCast<Element*>((*object));
    58                 element->SetCurrentConfiguration(elements,loads,nodes,materials,parameters);
    59 
     52        for(int i=0;i<this->Size();i++){
     53                Element* element=xDynamicCast<Element*>(this->GetObjectByOffset(i));
     54                element->InputDuplicate(input_enum,output_enum);
    6055        }
    61 
    62 }
    63 /*}}}*/
    64 void Elements::ResetHooks(){/*{{{*/
    65 
    66         vector<Object*>::iterator object;
    67         Element* element=NULL;
    68 
    69         for ( object=objects.begin() ; object < objects.end(); object++ ){
    70 
    71                 element=xDynamicCast<Element*>((*object));
    72                 element->ResetHooks();
    73 
    74         }
    75 
    7656}
    7757/*}}}*/
     
    10888}
    10989/*}}}*/
    110 void Elements::InputDuplicate(int input_enum,int output_enum){/*{{{*/
     90void Elements::ResetHooks(){/*{{{*/
    11191
    112         for(int i=0;i<this->Size();i++){
    113                 Element* element=xDynamicCast<Element*>(this->GetObjectByOffset(i));
    114                 element->InputDuplicate(input_enum,output_enum);
     92        vector<Object*>::iterator object;
     93        Element* element=NULL;
     94
     95        for ( object=objects.begin() ; object < objects.end(); object++ ){
     96
     97                element=xDynamicCast<Element*>((*object));
     98                element->ResetHooks();
     99
    115100        }
     101
    116102}
    117103/*}}}*/
     104void Elements::SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/
     105
     106        vector<Object*>::iterator object;
     107        Element* element=NULL;
     108
     109        for ( object=objects.begin() ; object < objects.end(); object++ ){
     110
     111                element=xDynamicCast<Element*>((*object));
     112                element->SetCurrentConfiguration(elements,loads,nodes,materials,parameters);
     113
     114        }
     115
     116}
     117/*}}}*/
  • issm/trunk-jpl/src/c/classes/Elements/Elements.h

    r18237 r20810  
    2525                /*numerics*/
    2626                void   Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters);
     27                void   InputDuplicate(int input_enum,int output_enum);
    2728                int    MaxNumNodes(void);
     29                int    NumberOfElements(void);
    2830                void   SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters);
    2931                void   ResetHooks();
    30                 int    NumberOfElements(void);
    31                 void   InputDuplicate(int input_enum,int output_enum);
    3232
    3333};
  • issm/trunk-jpl/src/c/classes/Elements/Penta.cpp

    r20690 r20810  
    33863386
    33873387#ifdef _HAVE_DAKOTA_
     3388void       Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/
     3389
     3390        int             i,t,row;
     3391        IssmDouble      time;
     3392        TransientInput *transientinput = NULL;
     3393        IssmDouble      values[6];
     3394
     3395        /*Check that name is an element input*/
     3396        if (!IsInput(name)) return;
     3397
     3398        switch(type){
     3399
     3400                case VertexEnum:
     3401                        /*Create transient input: */
     3402                        for(t=0;t<ncols;t++){ //ncols is the number of times
     3403
     3404                                /*create input values: */
     3405                                for(i=0;i<6;i++){
     3406                                        row=this->vertices[i]->Sid();
     3407                                        values[i]=matrix[ncols*row+t];
     3408                                }
     3409
     3410                                /*time:*/
     3411                                time=matrix[(nrows-1)*ncols+t];
     3412
     3413                                if(t==0) transientinput=new TransientInput(name);
     3414                                transientinput->AddTimeInput(new PentaInput(name,values,P1Enum),time);
     3415                                transientinput->Configure(parameters);
     3416                        }
     3417                        this->inputs->AddInput(transientinput);
     3418                        break;
     3419
     3420                default:
     3421                        _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
     3422        }
     3423
     3424}
     3425/*}}}*/
    33883426void       Penta::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){/*{{{*/
    33893427
     
    34863524}
    34873525/*}}}*/
    3488 void       Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/
    3489 
    3490         int             i,t,row;
    3491         IssmDouble      time;
    3492         TransientInput *transientinput = NULL;
    3493         IssmDouble      values[6];
    3494 
    3495         /*Check that name is an element input*/
    3496         if (!IsInput(name)) return;
    3497 
    3498         switch(type){
    3499 
    3500                 case VertexEnum:
    3501                         /*Create transient input: */
    3502                         for(t=0;t<ncols;t++){ //ncols is the number of times
    3503 
    3504                                 /*create input values: */
    3505                                 for(i=0;i<6;i++){
    3506                                         row=this->vertices[i]->Sid();
    3507                                         values[i]=matrix[ncols*row+t];
    3508                                 }
    3509 
    3510                                 /*time:*/
    3511                                 time=matrix[(nrows-1)*ncols+t];
    3512 
    3513                                 if(t==0) transientinput=new TransientInput(name);
    3514                                 transientinput->AddTimeInput(new PentaInput(name,values,P1Enum),time);
    3515                                 transientinput->Configure(parameters);
    3516                         }
    3517                         this->inputs->AddInput(transientinput);
    3518                         break;
    3519 
    3520                 default:
    3521                         _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");
    3522         }
    3523 
    3524 }
    3525 /*}}}*/
    35263526#endif
  • issm/trunk-jpl/src/c/classes/Elements/Penta.h

    r20461 r20810  
    4141                /*Object virtual functions definitions: {{{*/
    4242                Object *copy();
     43                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    4344                int     ObjectEnum();
    44                 void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    4545                /*}}}*/
    4646                /*Penta routines:{{{*/
     
    4848                void           AddInput(int input_enum, IssmDouble* values, int interpolation_enum);
    4949                void           AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part);
     50                void           CalvingRateLevermann();
    5051                IssmDouble     CharacteristicLength(void){_error_("not implemented yet");};
    51                 void           CalvingRateLevermann();
    5252                void           ComputeBasalStress(Vector<IssmDouble>* sigma_b);
    5353                void           ComputeDeviatoricStressTensor();
     
    6363                IssmDouble     FloatingArea(void);
    6464                void           FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating);
     65                IssmDouble     GetArea3D(void){_error_("not implemented yet!");};
    6566                void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints);
    6667                Element*       GetBasalElement(void);
     
    172173                void           ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
    173174                void           ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
    174                 IssmDouble     GetArea3D(void){_error_("not implemented yet!");};
    175175
    176176                #ifdef _HAVE_DAKOTA_
     177                void           InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type);
    177178                void           InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type);
    178                 void           InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type);
    179179                #endif
    180180
     
    183183                #endif
    184184                #ifdef _HAVE_SEALEVELRISE_
     185                IssmDouble    OceanArea(void){_error_("not implemented yet!");};
     186                IssmDouble    OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");};
    185187                void    SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");};
    186188                void    SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");};
    187                 IssmDouble    OceanArea(void){_error_("not implemented yet!");};
    188                 IssmDouble    OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");};
    189189                #endif
    190190
  • issm/trunk-jpl/src/c/classes/Elements/PentaRef.cpp

    r20515 r20810  
    190190        IssmDouble y1,y2,y3,y4,y5,y6;
    191191        IssmDouble z1,z2,z3,z4,z5,z6;
     192        IssmDouble j_const_reciprocal; // SQRT3/12.0
    192193
    193194        /*Cast gauss to GaussPenta*/
     
    224225        z6=xyz_list[3*5+2];
    225226
     227        /* DEBUG
     228         * REMOVE BEFORE SUBMITTING
     229         * ----------
     230         *  CHANGE SQRT3/12 TO MULTIPLY BY RECIPROCAL
     231         */
     232        j_const_reciprocal=SQRT3/12;
     233
    226234        J[NDOF3*0+0] = 0.25*(x1-x2-x4+x5)*zi+0.25*(-x1+x2-x4+x5);
    227         J[NDOF3*1+0] = SQRT3/12.0*(x1+x2-2*x3-x4-x5+2*x6)*zi+SQRT3/12.0*(-x1-x2+2*x3-x4-x5+2*x6);
    228         J[NDOF3*2+0] = SQRT3/12.0*(x1+x2-2*x3-x4-x5+2*x6)*eta+1/4*(x1-x2-x4+x5)*xi +0.25*(-x1+x5-x2+x4);
     235        J[NDOF3*1+0] = j_const_reciprocal*(x1+x2-2*x3-x4-x5+2*x6)*zi+j_const_reciprocal*(-x1-x2+2*x3-x4-x5+2*x6);
     236        J[NDOF3*2+0] = j_const_reciprocal*(x1+x2-2*x3-x4-x5+2*x6)*eta+0.25*(x1-x2-x4+x5)*xi +0.25*(-x1+x5-x2+x4);
    229237
    230238        J[NDOF3*0+1] = 0.25*(y1-y2-y4+y5)*zi+0.25*(-y1+y2-y4+y5);
    231         J[NDOF3*1+1] = SQRT3/12.0*(y1+y2-2*y3-y4-y5+2*y6)*zi+SQRT3/12.0*(-y1-y2+2*y3-y4-y5+2*y6);
    232         J[NDOF3*2+1] = SQRT3/12.0*(y1+y2-2*y3-y4-y5+2*y6)*eta+0.25*(y1-y2-y4+y5)*xi+0.25*(y4-y1+y5-y2);
     239        J[NDOF3*1+1] = j_const_reciprocal*(y1+y2-2*y3-y4-y5+2*y6)*zi+j_const_reciprocal*(-y1-y2+2*y3-y4-y5+2*y6);
     240        J[NDOF3*2+1] = j_const_reciprocal*(y1+y2-2*y3-y4-y5+2*y6)*eta+0.25*(y1-y2-y4+y5)*xi+0.25*(y4-y1+y5-y2);
    233241
    234242        J[NDOF3*0+2] = 0.25*(z1-z2-z4+z5)*zi+0.25*(-z1+z2-z4+z5);
    235         J[NDOF3*1+2] = SQRT3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*zi+SQRT3/12.0*(-z1-z2+2*z3-z4-z5+2*z6);
    236         J[NDOF3*2+2] = SQRT3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*eta+0.25*(z1-z2-z4+z5)*xi+0.25*(-z1+z5-z2+z4);
     243        J[NDOF3*1+2] = j_const_reciprocal*(z1+z2-2*z3-z4-z5+2*z6)*zi+j_const_reciprocal*(-z1-z2+2*z3-z4-z5+2*z6);
     244        J[NDOF3*2+2] = j_const_reciprocal*(z1+z2-2*z3-z4-z5+2*z6)*eta+0.25*(z1-z2-z4+z5)*xi+0.25*(-z1+z5-z2+z4);
    237245}
    238246/*}}}*/
  • issm/trunk-jpl/src/c/classes/Elements/PentaRef.h

    r19254 r20810  
    2828                void GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
    2929                void GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss);
     30                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    3031                int  NumberofNodes(int finiteelement);
    3132                int  PressureInterpolation(int fe_stokes);
     
    3334                int  TensorInterpolation(int fe_stokes);
    3435                int  VelocityInterpolation(int fe_stokes);
    35                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    3636};
    3737#endif
  • issm/trunk-jpl/src/c/classes/Elements/Seg.h

    r20461 r20810  
    3636                /*}}}*/
    3737                /*Object virtual functions definitions:{{{ */
    38                 int     ObjectEnum();
    3938                Object *copy();
    4039                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
     40                int     ObjectEnum();
    4141                /*}}}*/
    4242                /*Element virtual functions definitions: {{{*/
  • issm/trunk-jpl/src/c/classes/Elements/SegRef.h

    r19254 r20810  
    2424                void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss,int finiteelement);
    2525                void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss,int finiteelement);
     26                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    2627                int  NumberofNodes(int finiteelement);
    27                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    2828};
    2929#endif
  • issm/trunk-jpl/src/c/classes/Elements/Tetra.h

    r20461 r20810  
    3636                /*}}}*/
    3737                /*Object virtual functions definitions:{{{ */
    38                 int     ObjectEnum();
    3938                Object *copy();
    4039                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
     40                int     ObjectEnum();
    4141                /*}}}*/
    4242                /*Element virtual functions definitions: {{{*/
     
    6262                IssmDouble  FloatingArea(void){_error_("not implemented yet");};
    6363                void        FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){_error_("not implemented yet");};
     64                IssmDouble     GetArea3D(void){_error_("not implemented yet!");};
    6465                Element*    GetBasalElement(void){_error_("not implemented yet");};
    6566                int         GetElementType(void);
     
    169170                void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
    170171                void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
    171                 IssmDouble     GetArea3D(void){_error_("not implemented yet!");};
    172172
    173173#ifdef _HAVE_GIA_
  • issm/trunk-jpl/src/c/classes/Elements/TetraRef.h

    r19254 r20810  
    2525                void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement);
    2626                void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement);
     27                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    2728                int  NumberofNodes(int finiteelement);
    2829                int  PressureInterpolation(int fe_stokes);
    2930                int  TensorInterpolation(int fe_stokes);
    3031                int  VelocityInterpolation(int fe_stokes);
    31                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    3232};
    3333#endif
  • issm/trunk-jpl/src/c/classes/Elements/Tria.cpp

    r20758 r20810  
    208208}
    209209/*}}}*/
    210 void       Tria::CalvingRateLevermann(){/*{{{*/
    211 
    212         IssmDouble  xyz_list[NUMVERTICES][3];
    213         GaussTria* gauss=NULL;
    214         IssmDouble  vx,vy,vel;
    215         IssmDouble  strainparallel;
    216         IssmDouble  propcoeff;
    217         IssmDouble  strainperpendicular;
    218         IssmDouble  calvingratex[NUMVERTICES];
    219         IssmDouble  calvingratey[NUMVERTICES];
    220         IssmDouble  calvingrate[NUMVERTICES];
    221 
    222 
    223         /* Get node coordinates and dof list: */
    224         ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    225 
    226         /*Retrieve all inputs and parameters we will need*/
    227         Input* vx_input=inputs->GetInput(VxEnum);                                                                                                                                               _assert_(vx_input);
    228         Input* vy_input=inputs->GetInput(VyEnum);                                                                                                                                               _assert_(vy_input);
    229         Input* strainparallel_input=inputs->GetInput(StrainRateparallelEnum);                                                           _assert_(strainparallel_input);
    230         Input* strainperpendicular_input=inputs->GetInput(StrainRateperpendicularEnum);                                 _assert_(strainperpendicular_input);
    231         Input* levermanncoeff_input=inputs->GetInput(CalvinglevermannCoeffEnum);                     _assert_(levermanncoeff_input);
    232 
    233         /* Start looping on the number of vertices: */
    234         gauss=new GaussTria();
    235         for (int iv=0;iv<NUMVERTICES;iv++){
    236                 gauss->GaussVertex(iv);
    237 
    238                 /* Get the value we need*/
    239                 vx_input->GetInputValue(&vx,gauss);
    240                 vy_input->GetInputValue(&vy,gauss);
    241                 vel=vx*vx+vy*vy;
    242                 strainparallel_input->GetInputValue(&strainparallel,gauss);
    243                 strainperpendicular_input->GetInputValue(&strainperpendicular,gauss);
    244                 levermanncoeff_input->GetInputValue(&propcoeff,gauss);
    245 
    246                 /*Calving rate proportionnal to the positive product of the strain rate along the ice flow direction and the strain rate perpendicular to the ice flow */
    247                 calvingrate[iv]=propcoeff*strainparallel*strainperpendicular;
    248                 if(calvingrate[iv]<0){
    249                         calvingrate[iv]=0;
    250                 }
    251                 calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14);
    252                 calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14);
    253         }
    254 
    255         /*Add input*/
    256         this->inputs->AddInput(new TriaInput(CalvingratexEnum,&calvingratex[0],P1Enum));
    257         this->inputs->AddInput(new TriaInput(CalvingrateyEnum,&calvingratey[0],P1Enum));
    258         this->inputs->AddInput(new TriaInput(CalvingCalvingrateEnum,&calvingrate[0],P1Enum));
    259 
    260         /*Clean up and return*/
    261         delete gauss;
    262 
    263 }
    264 /*}}}*/
    265210void       Tria::CalvingRateDev(){/*{{{*/
    266211
     
    338283}
    339284/*}}}*/
    340 void       Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/
    341 
    342         if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return;
    343 
    344         IssmDouble* xyz_list_zero = NULL;
     285void       Tria::CalvingRateLevermann(){/*{{{*/
     286
    345287        IssmDouble  xyz_list[NUMVERTICES][3];
    346         ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
    347         this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum);
    348         if(xyz_list_zero){
    349                 IssmDouble x[2];
    350                 IssmDouble y[2];
    351                 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0];
    352                 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1];
    353                 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
    354         }
    355         xDelete<IssmDouble>(xyz_list_zero);
    356 
    357 //      IssmDouble ls[NUMVERTICES];
    358 //      IssmDouble  xyz_list[NUMVERTICES][3];
    359 //
    360 //      if(IsIceInElement()){
    361 //
    362 //              /*Retrieve all inputs and parameters*/
    363 //              GetInputListOnVertices(&ls[0],levelset_enum);
    364 //
    365 //              /*If the level set is awlays <0, there is no ice front here*/
    366 //              bool iszerols= false;
    367 //              if(IsIceInElement()){
    368 //                      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.)){
    369 //                              iszerols = true;
    370 //                      }
    371 //              }
    372 //
    373 //              if(iszerols){
    374 //                      /*OK we have one segment!*/
    375 //                      ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    376 //                      int count = 0;
    377 //                      IssmDouble x[2];
    378 //                      IssmDouble y[2];
    379 //
    380 //                      for(int i=0;i<NUMVERTICES,i++){
    381 //                              int index1 = i;
    382 //                              int index1 = (i+1)%3;
    383 //                              if(ls[index1]<=0 && ls[index2]>=0){
    384 //
    385 //                              }
    386 //
    387 //                      }
    388 //                      Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false);
    389 //              }
    390 //
    391 //      }
    392 //
    393 //      _error_("STOP");
    394 }
    395 /*}}}*/
    396 void       Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/
    397 
    398         /*Intermediaries*/
    399         IssmDouble d,xn,yn;
    400 
    401         /*Get current levelset and vertex coordinates*/
    402         IssmDouble ls[NUMVERTICES];
    403         IssmDouble  xyz_list[NUMVERTICES][3];
     288        GaussTria* gauss=NULL;
     289        IssmDouble  vx,vy,vel;
     290        IssmDouble  strainparallel;
     291        IssmDouble  propcoeff;
     292        IssmDouble  strainperpendicular;
     293        IssmDouble  calvingratex[NUMVERTICES];
     294        IssmDouble  calvingratey[NUMVERTICES];
     295        IssmDouble  calvingrate[NUMVERTICES];
     296
     297
     298        /* Get node coordinates and dof list: */
    404299        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
    405         GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
    406         InputDuplicate(MaskIceLevelsetEnum,PressureEnum);
    407 
    408         /*Get distance from list of segments and reset ls*/
    409         for(int j=0;j<NUMVERTICES;j++){
    410                 IssmDouble dmin = 1.e+50;
    411                 for(int i=0;i<numsegments;i++){
    412                         IssmDouble x = xyz_list[j][0];
    413                         IssmDouble y = xyz_list[j][1];
    414                         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]);
    415 
    416                         /*Segment has a length of 0*/
    417                         if(l2==0.){
    418                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    419                                 if(d<dmin) dmin = d;
    420                                 continue;
    421                         }
    422 
    423                         /*Consider the line extending the segment, parameterized as v + t (w - v).
    424                          *We find projection of point p onto the line.
    425                          *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
    426                         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;
    427                         if(t < 0.0){
    428                                 // Beyond the 'v' end of the segment
    429                                 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
    430                         }
    431                         else if (t > 1.0){
    432                                 // Beyond the 'w' end of the segment
    433                                 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
    434                         }
    435                         else{
    436                                 // Projection falls on the segment
    437                                 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
    438                                 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
    439                                 d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
    440                         }
    441 
    442                         if(d<dmin) dmin = d;
    443                 }
    444 
    445                 /*Update signed distance*/
    446                 dmin = sqrt(dmin);
    447                 if(dmin>10000) dmin=10000;
    448                 if(ls[j]>0){
    449                         ls[j] = dmin;
    450                 }
    451                 else{
    452                         ls[j] = - dmin;
    453                 }
    454         }
    455 
    456         /*Update Levelset*/
    457         this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));
     300
     301        /*Retrieve all inputs and parameters we will need*/
     302        Input* vx_input=inputs->GetInput(VxEnum);                                                                                                                                               _assert_(vx_input);
     303        Input* vy_input=inputs->GetInput(VyEnum);                                                                                                                                               _assert_(vy_input);
     304        Input* strainparallel_input=inputs->GetInput(StrainRateparallelEnum);                                                           _assert_(strainparallel_input);
     305        Input* strainperpendicular_input=inputs->GetInput(StrainRateperpendicularEnum);                                 _assert_(strainperpendicular_input);
     306        Input* levermanncoeff_input=inputs->GetInput(CalvinglevermannCoeffEnum);                     _assert_(levermanncoeff_input);
     307
     308        /* Start looping on the number of vertices: */
     309        gauss=new GaussTria();
     310        for (int iv=0;iv<NUMVERTICES;iv++){
     311                gauss->GaussVertex(iv);
     312
     313                /* Get the value we need*/
     314                vx_input->GetInputValue(&vx,gauss);
     315                vy_input->GetInputValue(&vy,gauss);
     316                vel=vx*vx+vy*vy;
     317                strainparallel_input->GetInputValue(&strainparallel,gauss);
     318                strainperpendicular_input->GetInputValue(&strainperpendicular,gauss);
     319                levermanncoeff_input->GetInputValue(&propcoeff,gauss);
     320
     321                /*Calving rate proportionnal to the positive product of the strain rate along the ice flow direction and the strain rate perpendicular to the ice flow */
     322                calvingrate[iv]=propcoeff*strainparallel*strainperpendicular;
     323                if(calvingrate[iv]<0){
     324                        calvingrate[iv]=0;
     325                }
     326                calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14);
     327                calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14);
     328        }
     329
     330        /*Add input*/
     331        this->inputs->AddInput(new TriaInput(CalvingratexEnum,&calvingratex[0],P1Enum));
     332        this->inputs->AddInput(new TriaInput(CalvingrateyEnum,&calvingratey[0],P1Enum));
     333        this->inputs->AddInput(new TriaInput(CalvingCalvingrateEnum,&calvingrate[0],P1Enum));
     334
     335        /*Clean up and return*/
     336        delete gauss;
     337
    458338}
    459339/*}}}*/
     
    27442624}
    27452625/*}}}*/
     2626void       Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/
     2627
     2628        /*Intermediaries*/
     2629        IssmDouble d,xn,yn;
     2630
     2631        /*Get current levelset and vertex coordinates*/
     2632        IssmDouble ls[NUMVERTICES];
     2633        IssmDouble  xyz_list[NUMVERTICES][3];
     2634        ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     2635        GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum);
     2636        InputDuplicate(MaskIceLevelsetEnum,PressureEnum);
     2637
     2638        /*Get distance from list of segments and reset ls*/
     2639        for(int j=0;j<NUMVERTICES;j++){
     2640                IssmDouble dmin = 1.e+50;
     2641                for(int i=0;i<numsegments;i++){
     2642                        IssmDouble x = xyz_list[j][0];
     2643                        IssmDouble y = xyz_list[j][1];
     2644                        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]);
     2645
     2646                        /*Segment has a length of 0*/
     2647                        if(l2==0.){
     2648                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     2649                                if(d<dmin) dmin = d;
     2650                                continue;
     2651                        }
     2652
     2653                        /*Consider the line extending the segment, parameterized as v + t (w - v).
     2654                         *We find projection of point p onto the line.
     2655                         *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
     2656                        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;
     2657                        if(t < 0.0){
     2658                                // Beyond the 'v' end of the segment
     2659                                d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]);
     2660                        }
     2661                        else if (t > 1.0){
     2662                                // Beyond the 'w' end of the segment
     2663                                d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]);
     2664                        }
     2665                        else{
     2666                                // Projection falls on the segment
     2667                                xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]);
     2668                                yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]);
     2669                                d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
     2670                        }
     2671
     2672                        if(d<dmin) dmin = d;
     2673                }
     2674
     2675                /*Update signed distance*/
     2676                dmin = sqrt(dmin);
     2677                if(dmin>10000) dmin=10000;
     2678                if(ls[j]>0){
     2679                        ls[j] = dmin;
     2680                }
     2681                else{
     2682                        ls[j] = - dmin;
     2683                }
     2684        }
     2685
     2686        /*Update Levelset*/
     2687        this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum));
     2688}
     2689/*}}}*/
    27462690void       Tria::SetClone(int* minranks){/*{{{*/
    27472691
     
    33613305}
    33623306/*}}}*/
     3307void       Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/
     3308
     3309        if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return;
     3310
     3311        IssmDouble* xyz_list_zero = NULL;
     3312        IssmDouble  xyz_list[NUMVERTICES][3];
     3313        ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES);
     3314        this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum);
     3315        if(xyz_list_zero){
     3316                IssmDouble x[2];
     3317                IssmDouble y[2];
     3318                x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0];
     3319                y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1];
     3320                segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false));
     3321        }
     3322        xDelete<IssmDouble>(xyz_list_zero);
     3323
     3324//      IssmDouble ls[NUMVERTICES];
     3325//      IssmDouble  xyz_list[NUMVERTICES][3];
     3326//
     3327//      if(IsIceInElement()){
     3328//
     3329//              /*Retrieve all inputs and parameters*/
     3330//              GetInputListOnVertices(&ls[0],levelset_enum);
     3331//
     3332//              /*If the level set is awlays <0, there is no ice front here*/
     3333//              bool iszerols= false;
     3334//              if(IsIceInElement()){
     3335//                      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.)){
     3336//                              iszerols = true;
     3337//                      }
     3338//              }
     3339//
     3340//              if(iszerols){
     3341//                      /*OK we have one segment!*/
     3342//                      ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
     3343//                      int count = 0;
     3344//                      IssmDouble x[2];
     3345//                      IssmDouble y[2];
     3346//
     3347//                      for(int i=0;i<NUMVERTICES,i++){
     3348//                              int index1 = i;
     3349//                              int index1 = (i+1)%3;
     3350//                              if(ls[index1]<=0 && ls[index2]>=0){
     3351//
     3352//                              }
     3353//
     3354//                      }
     3355//                      Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false);
     3356//              }
     3357//
     3358//      }
     3359//
     3360//      _error_("STOP");
     3361}
     3362/*}}}*/
    33633363void       Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
    33643364        /* Return coordinates where levelset intersects element edges.
     
    35413541
    35423542#ifdef _HAVE_SEALEVELRISE_
     3543IssmDouble    Tria::OceanArea(void){ /*{{{*/
     3544
     3545        if(IsWaterInElement()) return GetArea3D();
     3546        else return 0;
     3547
     3548}
     3549/*}}}*/
     3550IssmDouble Tria::OceanAverage(IssmDouble* Sg){ /*{{{*/
     3551
     3552        if(IsWaterInElement()){
     3553               
     3554                IssmDouble area;
     3555
     3556                /*Compute area of element:*/
     3557                area=GetArea3D();
     3558
     3559                /*Average Sg over vertices:*/
     3560                IssmDouble Sg_avg=0; for(int i=0;i<NUMVERTICES;i++) Sg_avg+=Sg[this->vertices[i]->Sid()]/NUMVERTICES;
     3561
     3562                /*return: */
     3563                return area*Sg_avg;
     3564        }
     3565        else return 0;
     3566
     3567}
     3568/*}}}*/
    35433569void    Tria::SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){ /*{{{*/
    35443570
     
    38273853
    38283854        return;
    3829 }
    3830 /*}}}*/
    3831 IssmDouble Tria::OceanAverage(IssmDouble* Sg){ /*{{{*/
    3832 
    3833         if(IsWaterInElement()){
    3834                
    3835                 IssmDouble area;
    3836 
    3837                 /*Compute area of element:*/
    3838                 area=GetArea3D();
    3839 
    3840                 /*Average Sg over vertices:*/
    3841                 IssmDouble Sg_avg=0; for(int i=0;i<NUMVERTICES;i++) Sg_avg+=Sg[this->vertices[i]->Sid()]/NUMVERTICES;
    3842 
    3843                 /*return: */
    3844                 return area*Sg_avg;
    3845         }
    3846         else return 0;
    3847 
    3848 }
    3849 /*}}}*/
    3850 IssmDouble    Tria::OceanArea(void){ /*{{{*/
    3851 
    3852         if(IsWaterInElement()) return GetArea3D();
    3853         else return 0;
    3854 
    38553855}
    38563856/*}}}*/
  • issm/trunk-jpl/src/c/classes/Elements/Tria.h

    r20723 r20810  
    3838                /*}}}*/
    3939                /*Object virtual functions definitions:{{{ */
    40                 int     ObjectEnum();
    4140                Object *copy();
    4241                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
     42                int     ObjectEnum();
    4343                /*}}}*/
    4444                /*Update virtual functions resolution: {{{*/
     
    5252                /*Element virtual functions definitions: {{{*/
    5353                void        AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part);
     54                void                    CalvingRateDev();
    5455                void                    CalvingRateLevermann();
    55                 void                    CalvingRateDev();
    56                 void                    WriteLevelsetSegment(DataSet* segments);
    57                 void        ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);
    5856                IssmDouble  CharacteristicLength(void);
    5957                void        ComputeBasalStress(Vector<IssmDouble>* sigma_b);
     
    119117                void        ResetFSBasalBoundaryCondition(void);
    120118                void        ResetHooks();
     119                void        ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);
    121120                void        SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index);
    122121                void        SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters);
     
    139138                int         VertexConnectivity(int vertexindex);
    140139                void        VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
     140                void                    WriteLevelsetSegment(DataSet* segments);
    141141                void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
    142142
     
    145145                #endif
    146146                #ifdef _HAVE_SEALEVELRISE_
     147                IssmDouble OceanArea(void);
     148                IssmDouble OceanAverage(IssmDouble* Sg);
    147149                void    SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea);
    148150                void    SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea);
    149                 IssmDouble OceanAverage(IssmDouble* Sg);
    150                 IssmDouble OceanArea(void);
    151151                #endif
    152152                /*}}}*/
     
    158158                IssmDouble         GetAreaIce(void);
    159159                void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints);
    160                 void            GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level);
    161160                int            GetElementType(void);
    162161                void           GetInputValue(IssmDouble* pvalue,Node* node,int enumtype);
     162                void            GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level);
    163163                void           GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype);
    164164                Node*          GetNode(int node_number);
  • issm/trunk-jpl/src/c/classes/Elements/TriaRef.cpp

    r20515 r20810  
    212212        }
    213213
     214}
     215/*}}}*/
     216void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/
     217        /*Compute B  matrix. B=[phi1 phi2 -phi3 -phi4]
     218         *
     219         * and phi1=phi3 phi2=phi4
     220         *
     221         * We assume B has been allocated already, of size: 1x4
     222         */
     223
     224        /*Fetch number of nodes for this finite element*/
     225        int numnodes = this->NumberofNodes(finiteelement);
     226
     227        /*Get nodal functions*/
     228        IssmDouble* basis=xNew<IssmDouble>(numnodes);
     229        GetNodalFunctions(basis,gauss,finiteelement);
     230
     231        /*Build B for this segment*/
     232        B[0] = +basis[index1];
     233        B[1] = +basis[index2];
     234        B[2] = -basis[index1];
     235        B[3] = -basis[index2];
     236
     237        /*Clean-up*/
     238        xDelete<IssmDouble>(basis);
     239}
     240/*}}}*/
     241void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/
     242        /*Compute Bprime  matrix. Bprime=[phi1 phi2 phi3 phi4]
     243         *
     244         * and phi1=phi3 phi2=phi4
     245         *
     246         * We assume Bprime has been allocated already, of size: 1x4
     247         */
     248
     249        /*Fetch number of nodes for this finite element*/
     250        int numnodes = this->NumberofNodes(finiteelement);
     251
     252        /*Get nodal functions*/
     253        IssmDouble* basis=xNew<IssmDouble>(numnodes);
     254        GetNodalFunctions(basis,gauss,finiteelement);
     255
     256        /*Build B'*/
     257        Bprime[0] = basis[index1];
     258        Bprime[1] = basis[index2];
     259        Bprime[2] = basis[index1];
     260        Bprime[3] = basis[index2];
     261
     262        /*Clean-up*/
     263        xDelete<IssmDouble>(basis);
     264}
     265/*}}}*/
     266void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
     267        /*The Jacobian determinant is constant over the element, discard the gaussian points.
     268         * J is assumed to have been allocated*/
     269
     270        IssmDouble x1 = xyz_list[3*0+0];
     271        IssmDouble y1 = xyz_list[3*0+1];
     272        IssmDouble x2 = xyz_list[3*1+0];
     273        IssmDouble y2 = xyz_list[3*1+1];
     274
     275        *Jdet = .5*sqrt(pow(x2-x1,2) + pow(y2-y1,2));
     276        if(*Jdet<0) _error_("negative jacobian determinant!");
     277
     278}
     279/*}}}*/
     280void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2,int finiteelement){/*{{{*/
     281        /*This routine returns the values of the nodal functions  at the gaussian point.*/
     282
     283        _assert_(index1>=0 && index1<3);
     284        _assert_(index2>=0 && index2<3);
     285
     286        /*Fetch number of nodes for this finite element*/
     287        int numnodes = this->NumberofNodes(finiteelement);
     288
     289        /*Get nodal functions*/
     290        IssmDouble* triabasis=xNew<IssmDouble>(numnodes);
     291        GetNodalFunctions(triabasis,gauss,finiteelement);
     292
     293        switch(finiteelement){
     294                case P1Enum: case P1DGEnum:
     295                        basis[0]=triabasis[index1];
     296                        basis[1]=triabasis[index2];
     297                        xDelete<IssmDouble>(triabasis);
     298                        return;
     299                case P1bubbleEnum: case P1bubblecondensedEnum:
     300                        basis[0]=triabasis[index1];
     301                        basis[1]=triabasis[index2];
     302                        xDelete<IssmDouble>(triabasis);
     303                        return;
     304                case P2Enum:
     305                        _assert_(index2<index1);
     306                        basis[0]=triabasis[index1];
     307                        basis[1]=triabasis[index2];
     308                        basis[2]=triabasis[3+index2-1];
     309                        xDelete<IssmDouble>(triabasis);
     310                        return;
     311                default:
     312                        _error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
     313        }
     314
     315        /*Clean up*/
     316        xDelete<IssmDouble>(triabasis);
    214317}
    215318/*}}}*/
     
    302405        }
    303406
    304 }
    305 /*}}}*/
    306 void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/
    307         /*Compute B  matrix. B=[phi1 phi2 -phi3 -phi4]
    308          *
    309          * and phi1=phi3 phi2=phi4
    310          *
    311          * We assume B has been allocated already, of size: 1x4
    312          */
    313 
    314         /*Fetch number of nodes for this finite element*/
    315         int numnodes = this->NumberofNodes(finiteelement);
    316 
    317         /*Get nodal functions*/
    318         IssmDouble* basis=xNew<IssmDouble>(numnodes);
    319         GetNodalFunctions(basis,gauss,finiteelement);
    320 
    321         /*Build B for this segment*/
    322         B[0] = +basis[index1];
    323         B[1] = +basis[index2];
    324         B[2] = -basis[index1];
    325         B[3] = -basis[index2];
    326 
    327         /*Clean-up*/
    328         xDelete<IssmDouble>(basis);
    329 }
    330 /*}}}*/
    331 void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/
    332         /*Compute Bprime  matrix. Bprime=[phi1 phi2 phi3 phi4]
    333          *
    334          * and phi1=phi3 phi2=phi4
    335          *
    336          * We assume Bprime has been allocated already, of size: 1x4
    337          */
    338 
    339         /*Fetch number of nodes for this finite element*/
    340         int numnodes = this->NumberofNodes(finiteelement);
    341 
    342         /*Get nodal functions*/
    343         IssmDouble* basis=xNew<IssmDouble>(numnodes);
    344         GetNodalFunctions(basis,gauss,finiteelement);
    345 
    346         /*Build B'*/
    347         Bprime[0] = basis[index1];
    348         Bprime[1] = basis[index2];
    349         Bprime[2] = basis[index1];
    350         Bprime[3] = basis[index2];
    351 
    352         /*Clean-up*/
    353         xDelete<IssmDouble>(basis);
    354 }
    355 /*}}}*/
    356 void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
    357         /*The Jacobian determinant is constant over the element, discard the gaussian points.
    358          * J is assumed to have been allocated*/
    359 
    360         IssmDouble x1 = xyz_list[3*0+0];
    361         IssmDouble y1 = xyz_list[3*0+1];
    362         IssmDouble x2 = xyz_list[3*1+0];
    363         IssmDouble y2 = xyz_list[3*1+1];
    364 
    365         *Jdet = .5*sqrt(pow(x2-x1,2) + pow(y2-y1,2));
    366         if(*Jdet<0) _error_("negative jacobian determinant!");
    367 
    368 }
    369 /*}}}*/
    370 void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2,int finiteelement){/*{{{*/
    371         /*This routine returns the values of the nodal functions  at the gaussian point.*/
    372 
    373         _assert_(index1>=0 && index1<3);
    374         _assert_(index2>=0 && index2<3);
    375 
    376         /*Fetch number of nodes for this finite element*/
    377         int numnodes = this->NumberofNodes(finiteelement);
    378 
    379         /*Get nodal functions*/
    380         IssmDouble* triabasis=xNew<IssmDouble>(numnodes);
    381         GetNodalFunctions(triabasis,gauss,finiteelement);
    382 
    383         switch(finiteelement){
    384                 case P1Enum: case P1DGEnum:
    385                         basis[0]=triabasis[index1];
    386                         basis[1]=triabasis[index2];
    387                         xDelete<IssmDouble>(triabasis);
    388                         return;
    389                 case P1bubbleEnum: case P1bubblecondensedEnum:
    390                         basis[0]=triabasis[index1];
    391                         basis[1]=triabasis[index2];
    392                         xDelete<IssmDouble>(triabasis);
    393                         return;
    394                 case P2Enum:
    395                         _assert_(index2<index1);
    396                         basis[0]=triabasis[index1];
    397                         basis[1]=triabasis[index2];
    398                         basis[2]=triabasis[3+index2-1];
    399                         xDelete<IssmDouble>(triabasis);
    400                         return;
    401                 default:
    402                         _error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
    403         }
    404 
    405         /*Clean up*/
    406         xDelete<IssmDouble>(triabasis);
    407407}
    408408/*}}}*/
  • issm/trunk-jpl/src/c/classes/Elements/TriaRef.h

    r19216 r20810  
    2828                void GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss);
    2929                void GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss, int index1,int index2,int finiteelement);
     30                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    3031                void NodeOnEdgeIndices(int* pnumindices,int** pindices,int index,int finiteelement);
    3132                int  NumberofNodes(int finiteelement);
     
    3334                int  TensorInterpolation(int fe_stokes);
    3435                int  VelocityInterpolation(int fe_stokes);
    35                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};
    3636
    3737};
  • issm/trunk-jpl/src/c/classes/ExternalResults/ExternalResult.h

    r18886 r20810  
    2424
    2525                virtual         ~ExternalResult(){};
    26                 virtual void   WriteData(FILE* fid,bool io_gather)=0;
     26                virtual int    GetResultEnum(void)=0;
    2727                virtual char*  GetResultName(void)=0;
    2828                virtual int    GetStep(void)=0;
    2929                virtual double GetValue(void)=0;
    30                 virtual int    GetResultEnum(void)=0;
     30                virtual void   WriteData(FILE* fid,bool io_gather)=0;
    3131};
    3232#endif
  • issm/trunk-jpl/src/c/classes/ExternalResults/GenericExternalResult.h

    r19813 r20810  
    132132
    133133                /*Object virtual functions definitions:*/
     134                Object* copy(void) { /*{{{*/
     135                        return new GenericExternalResult<ResultType>(this->id,this->result_name,this->value,this->step,this->time);
     136                } /*}}}*/
    134137                void Echo(void){ /*{{{*/
    135138                        this->DeepEcho();
     
    146149                        _error_("template ObjectEnum not implemented for this ResultType\n");
    147150                } /*}}}*/
    148                 Object* copy(void) { /*{{{*/
    149                         return new GenericExternalResult<ResultType>(this->id,this->result_name,this->value,this->step,this->time);
    150                 } /*}}}*/
    151151                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/
    152152                        _error_("not implemented yet!");
  • issm/trunk-jpl/src/c/classes/ExternalResults/Results.cpp

    r18886 r20810  
    3131
    3232/*Object management*/
    33 void Results::Write(Parameters* parameters){/*{{{*/
    34 
    35         FILE       *fid  = NULL;
    36         bool        io_gather;
    37 
    38         /*Recover file descriptor: */
    39         parameters->FindParam(&fid,OutputFilePointerEnum);
    40         parameters->FindParam(&io_gather,SettingsIoGatherEnum);
    41 
    42         for(int i=0;i<this->Size();i++){
    43                 ExternalResult* result=xDynamicCast<ExternalResult*>(this->GetObjectByOffset(i));
    44                 result->WriteData(fid,io_gather);
    45         }
    46 
    47 }
    48 /*}}}*/
    4933int Results::AddResult(ExternalResult* in_result){/*{{{*/
    5034
     
    10690}
    10791/*}}}*/
     92void Results::Write(Parameters* parameters){/*{{{*/
     93
     94        FILE       *fid  = NULL;
     95        bool        io_gather;
     96
     97        /*Recover file descriptor: */
     98        parameters->FindParam(&fid,OutputFilePointerEnum);
     99        parameters->FindParam(&io_gather,SettingsIoGatherEnum);
     100
     101        for(int i=0;i<this->Size();i++){
     102                ExternalResult* result=xDynamicCast<ExternalResult*>(this->GetObjectByOffset(i));
     103                result->WriteData(fid,io_gather);
     104        }
     105
     106}
     107/*}}}*/
  • issm/trunk-jpl/src/c/classes/ExternalResults/Results.h

    r18886 r20810  
    2222                /*Mehthos*/
    2323                int AddResult(ExternalResult* result);
     24                int DeleteResult(int result_enum,int result_step);
    2425                ExternalResult* FindResult(int result_enum);
    25                 int DeleteResult(int result_enum,int result_step);
    2626                void Write(Parameters* parameters);
    2727};
  • issm/trunk-jpl/src/c/classes/FemModel.cpp

    r20723 r20810  
    143143
    144144/*Object management*/
    145 void FemModel::Echo(void){/*{{{*/
    146 
    147         _printf_("FemModel echo: \n");
    148         _printf_("   number of fem models: " << nummodels << "\n");
    149         _printf_("   analysis_type_list: \n");
    150         for(int i=0;i<nummodels;i++)_printf_("     " << i << ": " << EnumToStringx(analysis_type_list[i]) << "\n");
    151         _printf_("   current analysis_type: \n");
    152         _printf_("     " << analysis_counter << ": " << EnumToStringx(analysis_type_list[analysis_counter]) << "\n");
    153 
    154 }
    155 /*}}}*/
    156 void FemModel::InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* toolkitsfilename, char* lockfilename, char* restartfilename, const int in_solution_type,bool trace,IssmPDouble* X){/*{{{*/
    157 
    158         /*intermediary*/
    159         int         i;
    160         int         analysis_type;
    161         FILE       *IOMODEL = NULL;
    162         FILE       *toolkitsoptionsfid = NULL;
    163         FILE       *output_fid = NULL;
    164         int         my_rank;
    165 
    166         /*recover my_rank:*/
    167         my_rank=IssmComm::GetRank();
    168 
    169         /*Initialize internal data: */
    170         this->solution_type    = in_solution_type;
    171         this->analysis_counter = nummodels-1;   //point to last analysis_type carried out.
    172         this->results          = new Results(); //not initialized by CreateDataSets
    173         /*Open input file on cpu 0 and create IoModel */
    174         if(my_rank==0) IOMODEL = pfopen0(inputfilename ,"rb");
    175         IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);
    176 
    177         /*Figure out what analyses are activated for this solution*/
    178         SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type);
    179 
    180         /*Open toolkits file: */
    181         toolkitsoptionsfid=pfopen(toolkitsfilename,"r");
    182 
    183         /*create datasets for all analyses*/
    184         ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,rootpath,this->solution_type,this->nummodels,this->analysis_type_list);
    185 
    186 
    187         /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
    188         for(i=0;i<nummodels;i++){
    189 
    190                 if(VerboseMProcessor()) _printf0_("   Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n");
    191                 analysis_type=analysis_type_list[i];
    192                 this->SetCurrentConfiguration(analysis_type);
    193 
    194                 if(VerboseMProcessor()) _printf0_("      configuring element and loads\n");
    195                 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters);
    196 
    197                 if(i==0){
    198                         if(VerboseMProcessor()) _printf0_("      creating vertex PIDs\n");
    199                         VerticesDofx(vertices,parameters);
    200 
    201                         if(VerboseMProcessor()) _printf0_("      detecting active vertices\n");
    202                         GetMaskOfIceVerticesLSMx(this);
    203                 }
    204 
    205                 if(VerboseMProcessor()) _printf0_("      resolving node constraints\n");
    206                 SpcNodesx(nodes,constraints,parameters,analysis_type);
    207 
    208                 if(VerboseMProcessor()) _printf0_("      creating nodal degrees of freedom\n");
    209                 NodesDofx(nodes,parameters,analysis_type);
    210         }
    211 
    212         /*Close input file and toolkits file descriptors: */
    213         if(my_rank==0) pfclose(IOMODEL,inputfilename);
    214         pfclose(toolkitsoptionsfid,toolkitsfilename);
    215 
    216         /*Open output file once for all and add output file descriptor to parameters*/
    217         output_fid=pfopen(outputfilename,"wb");
    218         this->parameters->SetParam(output_fid,OutputFilePointerEnum);
     145void FemModel::CheckPoint(void){/*{{{*/
     146
     147        FILE* restartfid=NULL;
     148        char* restartfilename = NULL;
     149        int   femmodel_size;
     150        char* femmodel_buffer=NULL;
     151        char* femmodel_buffer_ini=NULL;
     152
     153        /*First, recover the name of the restart file: */
     154        parameters->FindParam(&restartfilename,RestartFileNameEnum);
    219155       
    220         /*Now save all of these file names into parameters, you never know when you might need them: */
    221         this->parameters->AddObject(new StringParam(ToolkitsFileNameEnum,toolkitsfilename));
    222         this->parameters->AddObject(new StringParam(RootPathEnum,rootpath));
    223         this->parameters->AddObject(new StringParam(InputFileNameEnum,inputfilename));
    224         this->parameters->AddObject(new StringParam(OutputFileNameEnum,outputfilename));
    225         this->parameters->AddObject(new StringParam(LockFileNameEnum,lockfilename));
    226         this->parameters->AddObject(new StringParam(RestartFileNameEnum,restartfilename));
    227 
    228         /*Clean up*/
    229         delete iomodel;
    230 }/*}}}*/
     156        /*Open file for writing: */
     157        restartfid=pfopen(restartfilename,"wb");
     158
     159        /*Initialize: */
     160        femmodel_size=0;
     161
     162        /*Create buffer to hold marshalled femmodel: */
     163        this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE);
     164        femmodel_buffer=xNew<char>(femmodel_size);
     165        /*Keep track of initial position of femmodel_buffer: */
     166        femmodel_buffer_ini=femmodel_buffer;
     167       
     168        /*Marshall:*/
     169        this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD);
     170
     171        /*Reset position of buffer: */
     172        femmodel_buffer=femmodel_buffer_ini;
     173
     174        /*write buffer: */
     175        fwrite(femmodel_buffer,femmodel_size,sizeof(char),restartfid);
     176
     177        /*Done, close file :*/
     178        pfclose(restartfid,restartfilename);
     179
     180        /*Free ressources: */
     181        xDelete<char>(femmodel_buffer);
     182        xDelete<char>(restartfilename);
     183
     184}
     185/*}}}*/
    231186void FemModel::CleanUp(void){/*{{{*/
    232187
     
    275230}
    276231/*}}}*/
     232FemModel* FemModel::copy(void){/*{{{*/
     233
     234        FemModel* output=NULL;
     235        int       i;
     236        int       analysis_type;
     237
     238        output=new FemModel(*this); //Use default copy constructor.
     239
     240        output->nummodels = this->nummodels;
     241        output->solution_type = this->solution_type;
     242        output->analysis_counter = this->analysis_counter;
     243
     244        /*Now, deep copy arrays: */
     245        output->analysis_type_list=xNew<int>(nummodels);
     246        xMemCpy<int>(output->analysis_type_list,this->analysis_type_list,this->nummodels);
     247
     248        output->profiler=static_cast<Profiler*>(this->profiler->copy());
     249
     250        output->loads=static_cast<Loads*>(this->loads->Copy());
     251        output->materials=static_cast<Materials*>(this->materials->Copy());
     252        output->parameters=static_cast<Parameters*>(this->parameters->Copy());
     253        output->constraints=static_cast<Constraints*>(this->constraints->Copy());
     254        output->results=static_cast<Results*>(this->results->Copy());
     255
     256        output->nodes=static_cast<Nodes*>(this->nodes->Copy());
     257        output->vertices=static_cast<Vertices*>(this->vertices->Copy());
     258        output->elements=static_cast<Elements*>(this->elements->Copy());
     259
     260        /*reset hooks for elements, loads and nodes: */
     261        output->elements->ResetHooks();
     262        output->loads->ResetHooks();
     263        output->materials->ResetHooks();
     264
     265        /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
     266        for(i=0;i<nummodels;i++){
     267                analysis_type=output->analysis_type_list[i];
     268                output->SetCurrentConfiguration(analysis_type);
     269                if(i==0) VerticesDofx(output->vertices,output->parameters); //only call once, we only have one set of vertices
     270                SpcNodesx(output->nodes,output->constraints,output->parameters,analysis_type);
     271                NodesDofx(output->nodes,output->parameters,analysis_type);
     272                ConfigureObjectsx(output->elements,output->loads,output->nodes,output->vertices,output->materials,output->parameters);
     273        }
     274
     275        /*Reset current configuration: */
     276        analysis_type=output->analysis_type_list[analysis_counter];
     277        output->SetCurrentConfiguration(analysis_type);
     278
     279        return output;
     280}
     281/*}}}*/
     282void FemModel::Echo(void){/*{{{*/
     283
     284        _printf_("FemModel echo: \n");
     285        _printf_("   number of fem models: " << nummodels << "\n");
     286        _printf_("   analysis_type_list: \n");
     287        for(int i=0;i<nummodels;i++)_printf_("     " << i << ": " << EnumToStringx(analysis_type_list[i]) << "\n");
     288        _printf_("   current analysis_type: \n");
     289        _printf_("     " << analysis_counter << ": " << EnumToStringx(analysis_type_list[analysis_counter]) << "\n");
     290
     291}
     292/*}}}*/
     293void FemModel::InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* toolkitsfilename, char* lockfilename, char* restartfilename, const int in_solution_type,bool trace,IssmPDouble* X){/*{{{*/
     294
     295        /*intermediary*/
     296        int         i;
     297        int         analysis_type;
     298        FILE       *IOMODEL = NULL;
     299        FILE       *toolkitsoptionsfid = NULL;
     300        FILE       *output_fid = NULL;
     301        int         my_rank;
     302
     303        /*recover my_rank:*/
     304        my_rank=IssmComm::GetRank();
     305
     306        /*Initialize internal data: */
     307        this->solution_type    = in_solution_type;
     308        this->analysis_counter = nummodels-1;   //point to last analysis_type carried out.
     309        this->results          = new Results(); //not initialized by CreateDataSets
     310        /*Open input file on cpu 0 and create IoModel */
     311        if(my_rank==0) IOMODEL = pfopen0(inputfilename ,"rb");
     312        IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);
     313
     314        /*Figure out what analyses are activated for this solution*/
     315        SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type);
     316
     317        /*Open toolkits file: */
     318        toolkitsoptionsfid=pfopen(toolkitsfilename,"r");
     319
     320        /*create datasets for all analyses*/
     321        ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,rootpath,this->solution_type,this->nummodels,this->analysis_type_list);
     322
     323
     324        /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
     325        for(i=0;i<nummodels;i++){
     326
     327                if(VerboseMProcessor()) _printf0_("   Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n");
     328                analysis_type=analysis_type_list[i];
     329                this->SetCurrentConfiguration(analysis_type);
     330
     331                if(VerboseMProcessor()) _printf0_("      configuring element and loads\n");
     332                ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters);
     333
     334                if(i==0){
     335                        if(VerboseMProcessor()) _printf0_("      creating vertex PIDs\n");
     336                        VerticesDofx(vertices,parameters);
     337
     338                        if(VerboseMProcessor()) _printf0_("      detecting active vertices\n");
     339                        GetMaskOfIceVerticesLSMx(this);
     340                }
     341
     342                if(VerboseMProcessor()) _printf0_("      resolving node constraints\n");
     343                SpcNodesx(nodes,constraints,parameters,analysis_type);
     344
     345                if(VerboseMProcessor()) _printf0_("      creating nodal degrees of freedom\n");
     346                NodesDofx(nodes,parameters,analysis_type);
     347        }
     348
     349        /*Close input file and toolkits file descriptors: */
     350        if(my_rank==0) pfclose(IOMODEL,inputfilename);
     351        pfclose(toolkitsoptionsfid,toolkitsfilename);
     352
     353        /*Open output file once for all and add output file descriptor to parameters*/
     354        output_fid=pfopen(outputfilename,"wb");
     355        this->parameters->SetParam(output_fid,OutputFilePointerEnum);
     356       
     357        /*Now save all of these file names into parameters, you never know when you might need them: */
     358        this->parameters->AddObject(new StringParam(ToolkitsFileNameEnum,toolkitsfilename));
     359        this->parameters->AddObject(new StringParam(RootPathEnum,rootpath));
     360        this->parameters->AddObject(new StringParam(InputFileNameEnum,inputfilename));
     361        this->parameters->AddObject(new StringParam(OutputFileNameEnum,outputfilename));
     362        this->parameters->AddObject(new StringParam(LockFileNameEnum,lockfilename));
     363        this->parameters->AddObject(new StringParam(RestartFileNameEnum,restartfilename));
     364
     365        /*Clean up*/
     366        delete iomodel;
     367}/*}}}*/
     368void FemModel::Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
     369
     370        int       i;
     371        int       analysis_type;
     372
     373        if(marshall_direction==MARSHALLING_BACKWARD){
     374                delete this->profiler;
     375                delete this->loads;
     376                delete this->materials;
     377                delete this->parameters;
     378                delete this->constraints;
     379                delete this->results;
     380                delete this->nodes;
     381                delete this->vertices;
     382                delete this->elements;
     383                xDelete<int>(this->analysis_type_list);
     384
     385                this->profiler    = new Profiler();
     386                this->loads       = new Loads();
     387                this->materials   = new Materials();
     388                this->parameters  = new Parameters();
     389                this->constraints = new Constraints();
     390                this->results     = new Results();
     391                this->nodes       = new Nodes();
     392                this->vertices    = new Vertices();
     393                this->elements    = new Elements();
     394        }
     395
     396        MARSHALLING_ENUM(FemModelEnum);
     397
     398        MARSHALLING(solution_type);
     399        MARSHALLING(analysis_counter);
     400        MARSHALLING(nummodels);
     401        MARSHALLING_DYNAMIC(analysis_type_list,int,nummodels);
     402
     403        this->profiler->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     404        this->loads->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     405        this->materials->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     406        this->parameters->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     407        this->constraints->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     408        this->results->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     409        this->nodes->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     410        this->vertices->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     411        this->elements->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
     412
     413        if(marshall_direction==MARSHALLING_BACKWARD){
     414                //reset hooks for elements, loads and nodes:
     415                this->elements->ResetHooks();
     416                this->loads->ResetHooks();
     417                this->materials->ResetHooks();
     418
     419                //do the post-processing of the datasets to get an FemModel that can actually run analyses:
     420                for(i=0;i<nummodels;i++){
     421                        analysis_type=this->analysis_type_list[i];
     422                        SetCurrentConfiguration(analysis_type);
     423                        if(i==0) VerticesDofx(this->vertices,this->parameters); //only call once, we only have one set of vertices
     424                        SpcNodesx(this->nodes,this->constraints,this->parameters,analysis_type);
     425                        NodesDofx(this->nodes,this->parameters,analysis_type);
     426                        ConfigureObjectsx(this->elements,this->loads,this->nodes,this->vertices,this->materials,this->parameters);
     427                }
     428
     429                //Reset current configuration:
     430                analysis_type=this->analysis_type_list[analysis_counter];
     431                SetCurrentConfiguration(analysis_type);
     432        }
     433
     434}
     435/*}}}*/
     436void FemModel::Restart(){ /*{{{*/
     437
     438        FILE* restartfid=NULL;
     439        FILE* output_fid=NULL;
     440        char* restartfilename = NULL;
     441        int   femmodel_size=0;
     442        int   fread_return=0;
     443        char* femmodel_buffer=NULL;
     444        char* femmodel_buffer_ini=NULL;
     445
     446        /*First, recover the name of the restart file: */
     447        parameters->FindParam(&restartfilename,RestartFileNameEnum);
     448
     449        /*Now, figure out whether this file actually exists!: */
     450        restartfid=pfopen(restartfilename,"r",false);
     451
     452        if(restartfid==NULL){
     453                xDelete<char>(restartfilename);
     454                return; //could not find the file, so no restart possible.
     455        }
     456
     457        /*Figure out size of buffer to be read: */
     458        fseek(restartfid, 0L, SEEK_END);
     459        femmodel_size = ftell(restartfid);
     460        fseek(restartfid, 0L, SEEK_SET);
     461
     462        /*Allocate buffer: */
     463        femmodel_buffer=xNew<char>(femmodel_size);
     464
     465        /*Read buffer from file: */
     466        fread_return=fread(femmodel_buffer,femmodel_size,sizeof(char),restartfid); if(fread_return!=1)_error_("error reading the buffer from marshalled file!");
     467        femmodel_buffer_ini=femmodel_buffer; //keep track of the initial position, so as to free later.
     468
     469        this->parameters->FindParam(&output_fid,OutputFilePointerEnum);
     470
     471        /*Create new FemModel by demarshalling the buffer: */
     472        this->Marshall(&femmodel_buffer,NULL,MARSHALLING_BACKWARD);
     473
     474        this->parameters->SetParam(output_fid,OutputFilePointerEnum);
     475
     476        /*Reset position of buffer: */
     477        femmodel_buffer=femmodel_buffer_ini;
     478
     479        /*Done, close file :*/
     480        pfclose(restartfid,restartfilename);
     481
     482        /*Free ressources: */
     483        xDelete<char>(restartfilename);
     484        xDelete<char>(femmodel_buffer);
     485       
     486}
     487/*}}}*/
    277488void FemModel::SetCurrentConfiguration(int configuration_type,int analysis_type){/*{{{*/
    278489
     
    311522void FemModel::SetCurrentConfiguration(int configuration_type){/*{{{*/
    312523        this->SetCurrentConfiguration(configuration_type,configuration_type);
    313 }
    314 /*}}}*/
    315 void FemModel::Solve(void){/*{{{*/
    316 
    317         /*profiling: */
    318         bool profiling = false;
    319         IssmDouble solution_time;
    320         IssmDouble solution_flops;
    321         IssmDouble solution_memory;
    322 
    323         /*solution: */
    324         int solution_type;
    325         void (*solutioncore)(FemModel*)=NULL; //core solution function pointer
    326 
    327         _printf0_("call computational core:\n");
    328 
    329         /*Retrieve solution_type from parameters: */
    330         parameters->FindParam(&solution_type,SolutionTypeEnum);
    331 
    332         /*Figure out which solution core we are going to run with the current solution type: */
    333         WrapperCorePointerFromSolutionEnum(&solutioncore,this->parameters,solution_type);
    334 
    335         /*run solution core: */
    336         profiler->Tag(STARTCORE);   
    337         solutioncore(this);
    338         profiler->Tag(FINISHCORE);
    339 
    340         /*run AD core if needed: */
    341         profiler->Tag(STARTADCORE);
    342         ad_core(this);     
    343         profiler->Tag(FINISHADCORE);
    344 
    345         /*some profiling results for the core: */
    346         parameters->FindParam(&profiling,DebugProfilingEnum);
    347         if(profiling){
    348 
    349                 solution_time=profiler->DeltaTime(STARTCORE,FINISHCORE);
    350                 solution_flops=profiler->DeltaFlops(STARTCORE,FINISHCORE);
    351                 solution_memory=profiler->Memory(FINISHCORE);
    352 
    353                 _printf0_("Core solution elapsed time    : " << solution_time   << " Seconds\n");
    354                 _printf0_("Core solution number of flops : " << solution_flops  << " Flops\n");
    355                 _printf0_("Core solution memory used     : " << solution_memory << " Bytes\n");
    356 
    357                 /*Add to results: */
    358                 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingSolutionTimeEnum, solution_time, 0, 0));
    359                 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentMemEnum, solution_memory, 0, 0));
    360                 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentFlopsEnum, solution_flops, 0, 0));
    361 
    362                 #ifdef _HAVE_ADOLC_
    363                 solution_time=profiler->DeltaTime(STARTADCORE,FINISHADCORE);
    364                 solution_flops=profiler->DeltaFlops(STARTADCORE,FINISHADCORE);
    365                 solution_memory=profiler->Memory(FINISHADCORE);
    366 
    367                 _printf0_("AD Solution elapsed time    : " << solution_time   << " Seconds\n");
    368                 _printf0_("AD Solution number of flops : " << solution_flops  << " Flops\n");
    369                 _printf0_("AD Solution memory used     : " << solution_memory << " Bytes\n");
    370 
    371                 #endif
    372 
    373                         }
    374 }
    375 /*}}}*/
    376 FemModel* FemModel::copy(void){/*{{{*/
    377 
    378         FemModel* output=NULL;
    379         int       i;
    380         int       analysis_type;
    381 
    382         output=new FemModel(*this); //Use default copy constructor.
    383 
    384         output->nummodels = this->nummodels;
    385         output->solution_type = this->solution_type;
    386         output->analysis_counter = this->analysis_counter;
    387 
    388         /*Now, deep copy arrays: */
    389         output->analysis_type_list=xNew<int>(nummodels);
    390         xMemCpy<int>(output->analysis_type_list,this->analysis_type_list,this->nummodels);
    391 
    392         output->profiler=static_cast<Profiler*>(this->profiler->copy());
    393 
    394         output->loads=static_cast<Loads*>(this->loads->Copy());
    395         output->materials=static_cast<Materials*>(this->materials->Copy());
    396         output->parameters=static_cast<Parameters*>(this->parameters->Copy());
    397         output->constraints=static_cast<Constraints*>(this->constraints->Copy());
    398         output->results=static_cast<Results*>(this->results->Copy());
    399 
    400         output->nodes=static_cast<Nodes*>(this->nodes->Copy());
    401         output->vertices=static_cast<Vertices*>(this->vertices->Copy());
    402         output->elements=static_cast<Elements*>(this->elements->Copy());
    403 
    404         /*reset hooks for elements, loads and nodes: */
    405         output->elements->ResetHooks();
    406         output->loads->ResetHooks();
    407         output->materials->ResetHooks();
    408 
    409         /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
    410         for(i=0;i<nummodels;i++){
    411                 analysis_type=output->analysis_type_list[i];
    412                 output->SetCurrentConfiguration(analysis_type);
    413                 if(i==0) VerticesDofx(output->vertices,output->parameters); //only call once, we only have one set of vertices
    414                 SpcNodesx(output->nodes,output->constraints,output->parameters,analysis_type);
    415                 NodesDofx(output->nodes,output->parameters,analysis_type);
    416                 ConfigureObjectsx(output->elements,output->loads,output->nodes,output->vertices,output->materials,output->parameters);
    417         }
    418 
    419         /*Reset current configuration: */
    420         analysis_type=output->analysis_type_list[analysis_counter];
    421         output->SetCurrentConfiguration(analysis_type);
    422 
    423         return output;
    424524}
    425525/*}}}*/
     
    634734        else              xDelete<int>(analyses);
    635735}/*}}}*/
    636 void FemModel::CheckPoint(void){/*{{{*/
    637 
    638         FILE* restartfid=NULL;
    639         char* restartfilename = NULL;
    640         int   femmodel_size;
    641         char* femmodel_buffer=NULL;
    642         char* femmodel_buffer_ini=NULL;
    643 
    644         /*First, recover the name of the restart file: */
    645         parameters->FindParam(&restartfilename,RestartFileNameEnum);
    646        
    647         /*Open file for writing: */
    648         restartfid=pfopen(restartfilename,"wb");
    649 
    650         /*Initialize: */
    651         femmodel_size=0;
    652 
    653         /*Create buffer to hold marshalled femmodel: */
    654         this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE);
    655         femmodel_buffer=xNew<char>(femmodel_size);
    656         /*Keep track of initial position of femmodel_buffer: */
    657         femmodel_buffer_ini=femmodel_buffer;
    658        
    659         /*Marshall:*/
    660         this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD);
    661 
    662         /*Reset position of buffer: */
    663         femmodel_buffer=femmodel_buffer_ini;
    664 
    665         /*write buffer: */
    666         fwrite(femmodel_buffer,femmodel_size,sizeof(char),restartfid);
    667 
    668         /*Done, close file :*/
    669         pfclose(restartfid,restartfilename);
    670 
    671         /*Free ressources: */
    672         xDelete<char>(femmodel_buffer);
    673         xDelete<char>(restartfilename);
    674 
    675 }
    676 /*}}}*/
    677 void FemModel::Restart(){ /*{{{*/
    678 
    679         FILE* restartfid=NULL;
    680         FILE* output_fid=NULL;
    681         char* restartfilename = NULL;
    682         int   femmodel_size=0;
    683         int   fread_return=0;
    684         char* femmodel_buffer=NULL;
    685         char* femmodel_buffer_ini=NULL;
    686 
    687         /*First, recover the name of the restart file: */
    688         parameters->FindParam(&restartfilename,RestartFileNameEnum);
    689 
    690         /*Now, figure out whether this file actually exists!: */
    691         restartfid=pfopen(restartfilename,"r",false);
    692 
    693         if(restartfid==NULL){
    694                 xDelete<char>(restartfilename);
    695                 return; //could not find the file, so no restart possible.
    696         }
    697 
    698         /*Figure out size of buffer to be read: */
    699         fseek(restartfid, 0L, SEEK_END);
    700         femmodel_size = ftell(restartfid);
    701         fseek(restartfid, 0L, SEEK_SET);
    702 
    703         /*Allocate buffer: */
    704         femmodel_buffer=xNew<char>(femmodel_size);
    705 
    706         /*Read buffer from file: */
    707         fread_return=fread(femmodel_buffer,femmodel_size,sizeof(char),restartfid); if(fread_return!=1)_error_("error reading the buffer from marshalled file!");
    708         femmodel_buffer_ini=femmodel_buffer; //keep track of the initial position, so as to free later.
    709 
    710         this->parameters->FindParam(&output_fid,OutputFilePointerEnum);
    711 
    712         /*Create new FemModel by demarshalling the buffer: */
    713         this->Marshall(&femmodel_buffer,NULL,MARSHALLING_BACKWARD);
    714 
    715         this->parameters->SetParam(output_fid,OutputFilePointerEnum);
    716 
    717         /*Reset position of buffer: */
    718         femmodel_buffer=femmodel_buffer_ini;
    719 
    720         /*Done, close file :*/
    721         pfclose(restartfid,restartfilename);
    722 
    723         /*Free ressources: */
    724         xDelete<char>(restartfilename);
    725         xDelete<char>(femmodel_buffer);
    726        
    727 }
    728 /*}}}*/
    729 void FemModel::Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
    730 
    731         int       i;
    732         int       analysis_type;
    733 
    734         if(marshall_direction==MARSHALLING_BACKWARD){
    735                 delete this->profiler;
    736                 delete this->loads;
    737                 delete this->materials;
    738                 delete this->parameters;
    739                 delete this->constraints;
    740                 delete this->results;
    741                 delete this->nodes;
    742                 delete this->vertices;
    743                 delete this->elements;
    744                 xDelete<int>(this->analysis_type_list);
    745 
    746                 this->profiler    = new Profiler();
    747                 this->loads       = new Loads();
    748                 this->materials   = new Materials();
    749                 this->parameters  = new Parameters();
    750                 this->constraints = new Constraints();
    751                 this->results     = new Results();
    752                 this->nodes       = new Nodes();
    753                 this->vertices    = new Vertices();
    754                 this->elements    = new Elements();
    755         }
    756 
    757         MARSHALLING_ENUM(FemModelEnum);
    758 
    759         MARSHALLING(solution_type);
    760         MARSHALLING(analysis_counter);
    761         MARSHALLING(nummodels);
    762         MARSHALLING_DYNAMIC(analysis_type_list,int,nummodels);
    763 
    764         this->profiler->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    765         this->loads->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    766         this->materials->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    767         this->parameters->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    768         this->constraints->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    769         this->results->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    770         this->nodes->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    771         this->vertices->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    772         this->elements->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
    773 
    774         if(marshall_direction==MARSHALLING_BACKWARD){
    775                 //reset hooks for elements, loads and nodes:
    776                 this->elements->ResetHooks();
    777                 this->loads->ResetHooks();
    778                 this->materials->ResetHooks();
    779 
    780                 //do the post-processing of the datasets to get an FemModel that can actually run analyses:
    781                 for(i=0;i<nummodels;i++){
    782                         analysis_type=this->analysis_type_list[i];
    783                         SetCurrentConfiguration(analysis_type);
    784                         if(i==0) VerticesDofx(this->vertices,this->parameters); //only call once, we only have one set of vertices
    785                         SpcNodesx(this->nodes,this->constraints,this->parameters,analysis_type);
    786                         NodesDofx(this->nodes,this->parameters,analysis_type);
    787                         ConfigureObjectsx(this->elements,this->loads,this->nodes,this->vertices,this->materials,this->parameters);
     736void FemModel::Solve(void){/*{{{*/
     737
     738        /*profiling: */
     739        bool profiling = false;
     740        IssmDouble solution_time;
     741        IssmDouble solution_flops;
     742        IssmDouble solution_memory;
     743
     744        /*solution: */
     745        int solution_type;
     746        void (*solutioncore)(FemModel*)=NULL; //core solution function pointer
     747
     748        _printf0_("call computational core:\n");
     749
     750        /*Retrieve solution_type from parameters: */
     751        parameters->FindParam(&solution_type,SolutionTypeEnum);
     752
     753        /*Figure out which solution core we are going to run with the current solution type: */
     754        WrapperCorePointerFromSolutionEnum(&solutioncore,this->parameters,solution_type);
     755
     756        /*run solution core: */
     757        profiler->Tag(STARTCORE);   
     758        solutioncore(this);
     759        profiler->Tag(FINISHCORE);
     760
     761        /*run AD core if needed: */
     762        profiler->Tag(STARTADCORE);
     763        ad_core(this);     
     764        profiler->Tag(FINISHADCORE);
     765
     766        /*some profiling results for the core: */
     767        parameters->FindParam(&profiling,DebugProfilingEnum);
     768        if(profiling){
     769
     770                solution_time=profiler->DeltaTime(STARTCORE,FINISHCORE);
     771                solution_flops=profiler->DeltaFlops(STARTCORE,FINISHCORE);
     772                solution_memory=profiler->Memory(FINISHCORE);
     773
     774                _printf0_("Core solution elapsed time    : " << solution_time   << " Seconds\n");
     775                _printf0_("Core solution number of flops : " << solution_flops  << " Flops\n");
     776                _printf0_("Core solution memory used     : " << solution_memory << " Bytes\n");
     777
     778                /*Add to results: */
     779                results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingSolutionTimeEnum, solution_time, 0, 0));
     780                results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentMemEnum, solution_memory, 0, 0));
     781                results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentFlopsEnum, solution_flops, 0, 0));
     782
     783                #ifdef _HAVE_ADOLC_
     784                solution_time=profiler->DeltaTime(STARTADCORE,FINISHADCORE);
     785                solution_flops=profiler->DeltaFlops(STARTADCORE,FINISHADCORE);
     786                solution_memory=profiler->Memory(FINISHADCORE);
     787
     788                _printf0_("AD Solution elapsed time    : " << solution_time   << " Seconds\n");
     789                _printf0_("AD Solution number of flops : " << solution_flops  << " Flops\n");
     790                _printf0_("AD Solution memory used     : " << solution_memory << " Bytes\n");
     791
     792                #endif
     793
     794                        }
     795}
     796/*}}}*/
     797
     798/*Modules:*/
     799void FemModel::BalancethicknessMisfitx(IssmDouble* presponse){/*{{{*/
     800
     801        /*output: */
     802        IssmDouble J=0.;
     803        IssmDouble J_sum;
     804
     805        IssmDouble  weight,vx,vy,H,dvx[2],dvy[2],dH[2];
     806        IssmDouble  temp,Jdet,dhdt,groundedice_melting,surface_mass_balance;
     807        IssmDouble* xyz_list = NULL;
     808        IssmDouble  dp[3];
     809
     810        /*Compute Misfit: */
     811        for(int i=0;i<elements->Size();i++){
     812                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     813
     814                /*If on water, return 0: */
     815                if(!element->IsIceInElement()) continue;
     816
     817                /* Get node coordinates*/
     818                element->GetVerticesCoordinates(&xyz_list);
     819                Input* weights_input                   = element->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     820                Input* thickness_input                 = element->GetInput(ThicknessEnum); _assert_(thickness_input);
     821                Input* vx_input                        = element->GetInput(VxEnum);                                  _assert_(vx_input);
     822                Input* vy_input                        = element->GetInput(VyEnum);                                  _assert_(vy_input);
     823                Input* surface_mass_balance_input      = element->GetInput(SmbMassBalanceEnum);          _assert_(surface_mass_balance_input);
     824                Input* groundedice_melting_input       = element->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(groundedice_melting_input);
     825                Input* dhdt_input                      = element->GetInput(BalancethicknessThickeningRateEnum);      _assert_(dhdt_input);
     826
     827                /* Start  looping on the number of gaussian points: */
     828                Gauss* gauss=element->NewGauss(2);
     829                for(int ig=gauss->begin();ig<gauss->end();ig++){
     830
     831                        gauss->GaussPoint(ig);
     832
     833                        /* Get Jacobian determinant: */
     834                        element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     835
     836                        /*Get all parameters at gaussian point*/
     837                        weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum);
     838                        thickness_input->GetInputValue(&H, gauss);
     839                        thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss);
     840                        surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss);
     841                        groundedice_melting_input->GetInputValue(&groundedice_melting,gauss);
     842                        dhdt_input->GetInputValue(&dhdt,gauss);
     843                        vx_input->GetInputValue(&vx,gauss);
     844                        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     845                        vy_input->GetInputValue(&vy,gauss);
     846                        vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
     847
     848                        /*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/
     849                        temp  = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-groundedice_melting-dhdt);
     850                        J    +=weight*1/2*temp*temp*Jdet*gauss->weight;
    788851                }
    789852
    790                 //Reset current configuration:
    791                 analysis_type=this->analysis_type_list[analysis_counter];
    792                 SetCurrentConfiguration(analysis_type);
    793         }
    794 
    795 }
    796 /*}}}*/
    797 
    798 /*Modules:*/
    799 int  FemModel::UpdateVertexPositionsx(void){ /*{{{*/
    800 
    801         IssmDouble         *surface = NULL;
    802         IssmDouble         *bed     = NULL;
    803                        
    804         if(VerboseSolution()) _printf0_("   updating vertices positions\n");
    805 
    806         /*get vertex vectors for bed and thickness: */
    807         GetVectorFromInputsx(&surface  ,this, SurfaceEnum,VertexPIdEnum);
    808         GetVectorFromInputsx(&bed      ,this, BaseEnum,   VertexPIdEnum);
    809 
    810         /*Allocate vector*/
    811         Vector<IssmDouble> *vx=new Vector<IssmDouble>(vertices->NumberOfVertices());
    812         Vector<IssmDouble> *vy=new Vector<IssmDouble>(vertices->NumberOfVertices());
    813         Vector<IssmDouble> *vz=new Vector<IssmDouble>(vertices->NumberOfVertices());
    814 
    815         /*Update verices new geometry: */
    816         for(int i=0;i<vertices->Size();i++){
    817                 Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i);
    818                 vertex->UpdatePosition(vx,vy,vz,parameters,surface,bed);
    819         }
    820 
    821         /*Assemble mesh velocity*/
    822         vx->Assemble();
    823         vy->Assemble();
    824         vz->Assemble();
    825 
    826         /*Update element inputs*/
    827         InputUpdateFromVectorx(this,vx,VxMeshEnum,VertexPIdEnum);
    828         InputUpdateFromVectorx(this,vy,VyMeshEnum,VertexPIdEnum);
    829         InputUpdateFromVectorx(this,vz,VzMeshEnum,VertexPIdEnum);
    830 
    831         /*Free ressources:*/
    832         delete vx;
    833         delete vy;
    834         delete vz;
    835         xDelete<IssmDouble>(bed);
    836         xDelete<IssmDouble>(surface);
    837         return 1;
    838 }
    839 /*}}}*/
    840 void FemModel::UpdateConstraintsx(void){ /*{{{*/
    841 
    842         IssmDouble time;
    843         int        analysis_type;
    844 
    845         /*retrieve parameters: */
    846         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    847         parameters->FindParam(&time,TimeEnum);
    848 
    849         /*start module: */
    850         if(VerboseModule()) _printf0_("   Updating constraints and active domain of analysis " << EnumToStringx(analysis_type)  << " for time: " << time << "\n");
    851 
    852         Analysis* analysis= EnumToAnalysis(analysis_type);
    853         analysis->UpdateConstraints(this);
    854         delete analysis;
    855        
    856         /*Second, constraints might be time dependent: */
    857         SpcNodesx(nodes,constraints,parameters,analysis_type);
    858 
    859         /*Now, update degrees of freedoms: */
    860         NodesDofx(nodes,parameters,analysis_type);
    861 
    862 }
    863 /*}}}*/
     853                /*clean up and Return: */
     854                xDelete<IssmDouble>(xyz_list);
     855                delete gauss;
     856        }
     857
     858        /*Sum all J from all cpus of the cluster:*/
     859        ISSM_MPI_Reduce (&J,&J_sum,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     860        ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     861        J=J_sum;
     862
     863        /*Assign output pointers: */
     864        *presponse=J;
     865
     866}/*}}}*/
     867void FemModel::CalvingRateDevx(){/*{{{*/
     868
     869        for(int i=0;i<elements->Size();i++){
     870                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     871                element->CalvingRateDev();
     872        }
     873}
     874/*}}}*/
     875void FemModel::CalvingRateLevermannx(){/*{{{*/
     876
     877        for(int i=0;i<elements->Size();i++){
     878                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     879                element->CalvingRateLevermann();
     880        }
     881}
     882/*}}}*/
     883void FemModel::CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn){/*{{{*/
     884
     885        /*Intermediary*/
     886        int      num_responses;
     887        int     *responses      = NULL;
     888        Results *cost_functions = NULL;
     889
     890        /*Recover parameters*/
     891        parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
     892        parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
     893
     894        /*Get the value of all cost functions*/
     895        this->RequestedOutputsx(&cost_functions,responses,num_responses);
     896
     897        /*Get and add all contributions one by one*/
     898        IssmDouble  J=0;
     899        IssmDouble* Jlist = xNew<IssmDouble>(num_responses);
     900        for(int i=0;i<num_responses;i++){
     901                ExternalResult* result=(ExternalResult*)cost_functions->GetObjectByOffset(i);
     902                Jlist[i] = reCast<IssmDouble>(result->GetValue());
     903                J       += Jlist[i];
     904        }
     905        _assert_(cost_functions->Size()==num_responses);
     906
     907        /*Assign output pointers: */
     908        delete cost_functions;
     909        xDelete<int>(responses);
     910        if(pJ)     *pJ     = J;
     911        if(pJlist) *pJlist = Jlist;
     912        else        xDelete<IssmDouble>(Jlist);
     913        if(pn)     *pn     = num_responses;
     914}
     915/*}}}*/
     916void FemModel::DeviatoricStressx(){/*{{{*/
     917
     918        for(int i=0;i<elements->Size();i++){
     919                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     920                element->ComputeDeviatoricStressTensor();
     921        }
     922}
     923/*}}}*/
     924void FemModel::Divergencex(IssmDouble* pdiv){/*{{{*/
     925
     926        IssmDouble local_divergence=0;
     927        IssmDouble total_divergence;
     928
     929        for(int i=0;i<this->elements->Size();i++){
     930                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     931                local_divergence+=element->Divergence();
     932        }
     933        ISSM_MPI_Reduce(&local_divergence,&total_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     934        ISSM_MPI_Bcast(&total_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     935
     936        /*Assign output pointers: */
     937        *pdiv=total_divergence;
     938
     939}/*}}}*/
    864940void FemModel::ElementOperationx(void (Element::*function)(void)){ /*{{{*/
    865941
     
    869945        }
    870946
     947}
     948/*}}}*/
     949void FemModel::ElementResponsex(IssmDouble* presponse,int response_enum){/*{{{*/
     950
     951        int found=0;
     952        int sumfound=0;
     953        int cpu_found=-1;
     954        int index;
     955        IssmDouble response;
     956        Element* element=NULL;
     957
     958        /*retrieve element we are interested in: */
     959        this->parameters->FindParam(&index,IndexEnum);
     960        int my_rank=IssmComm::GetRank();
     961
     962        /*now, go through our elements, and retrieve the one with this id: index: */
     963        for(int i=0;i<this->elements->Size();i++){
     964                element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     965                if (element->Id()==index){
     966                        found=1;
     967                        cpu_found=my_rank;
     968                        break;
     969                }
     970        }
     971
     972        /*Broadcast whether we found the element: */
     973        ISSM_MPI_Allreduce ( &found,&sumfound,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm());
     974        if(!sumfound)_error_("could not find material with id" << index << " to compute ElementResponse");
     975
     976        /*Ok, we found the element, compute responseocity: */
     977        if(my_rank==cpu_found){
     978                element->ElementResponse(&response,response_enum);
     979        }
     980
     981        /*Broadcast and plug into response: */
     982        ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
     983        ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm());
     984
     985        /*Assign output pointers: */
     986        *presponse=response;
     987
     988}/*}}}*/
     989void FemModel::FloatingAreax(IssmDouble* pV){/*{{{*/
     990
     991        IssmDouble local_floating_area= 0;
     992        IssmDouble total_floating_area;
     993
     994        for(int i=0;i<this->elements->Size();i++){
     995                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     996                local_floating_area+=element->FloatingArea();
     997        }
     998        ISSM_MPI_Reduce(&local_floating_area,&total_floating_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     999        ISSM_MPI_Bcast(&total_floating_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1000
     1001        /*Assign output pointers: */
     1002        *pV=total_floating_area;
     1003
     1004}/*}}}*/
     1005void FemModel::GetInputLocalMinMaxOnNodesx(IssmDouble** pmin,IssmDouble** pmax,IssmDouble* ug){/*{{{*/
     1006
     1007        /*Get vector sizes for current configuration*/
     1008        int configuration_type;
     1009        this->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
     1010        int numnodes = this->nodes->NumberOfNodes(configuration_type);
     1011
     1012        /*Initialize output vectors*/
     1013        IssmDouble* uLmin_local = xNew<IssmDouble>(numnodes);
     1014        IssmDouble* uLmax_local = xNew<IssmDouble>(numnodes);
     1015        IssmDouble* uLmin = xNew<IssmDouble>(numnodes);
     1016        IssmDouble* uLmax = xNew<IssmDouble>(numnodes);
     1017        for(int i=0;i<numnodes;i++){
     1018                uLmin_local[i] = +1.e+50;
     1019                uLmax_local[i] = -1.e+50;
     1020        }
     1021
     1022        for(int i=0;i<this->elements->Size();i++){
     1023                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1024                element->GetInputLocalMinMaxOnNodes(uLmin_local,uLmax_local,ug);
     1025        }
     1026
     1027        /*Synchronize all CPUs*/
     1028        ISSM_MPI_Allreduce((void*)uLmin_local,(void*)uLmin,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,IssmComm::GetComm());
     1029        ISSM_MPI_Allreduce((void*)uLmax_local,(void*)uLmax,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,IssmComm::GetComm());
     1030        xDelete<IssmDouble>(uLmin_local);
     1031        xDelete<IssmDouble>(uLmax_local);
     1032
     1033        /*Assign output pointers: */
     1034        *pmin=uLmin;
     1035        *pmax=uLmax;
     1036
     1037}/*}}}*/
     1038void FemModel::GroundedAreax(IssmDouble* pV){/*{{{*/
     1039
     1040        IssmDouble local_grounded_area= 0;
     1041        IssmDouble total_grounded_area;
     1042
     1043        for(int i=0;i<this->elements->Size();i++){
     1044                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1045                local_grounded_area+=element->GroundedArea();
     1046        }
     1047        ISSM_MPI_Reduce(&local_grounded_area,&total_grounded_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     1048        ISSM_MPI_Bcast(&total_grounded_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1049
     1050        /*Assign output pointers: */
     1051        *pV=total_grounded_area;
     1052
     1053}/*}}}*/
     1054void FemModel::IceMassx(IssmDouble* pM){/*{{{*/
     1055
     1056        IssmDouble local_ice_mass = 0;
     1057        IssmDouble total_ice_mass;
     1058
     1059        for(int i=0;i<this->elements->Size();i++){
     1060                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1061                local_ice_mass+=element->IceMass();
     1062        }
     1063        ISSM_MPI_Reduce(&local_ice_mass,&total_ice_mass,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     1064        ISSM_MPI_Bcast(&total_ice_mass,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1065
     1066        /*Assign output pointers: */
     1067        *pM=total_ice_mass;
     1068
     1069}/*}}}*/
     1070void FemModel::IceVolumeAboveFloatationx(IssmDouble* pV){/*{{{*/
     1071
     1072        IssmDouble local_ice_volume_af = 0;
     1073        IssmDouble total_ice_volume_af;
     1074
     1075        for(int i=0;i<this->elements->Size();i++){
     1076                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1077                local_ice_volume_af+=element->IceVolumeAboveFloatation();
     1078        }
     1079        ISSM_MPI_Reduce(&local_ice_volume_af,&total_ice_volume_af,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     1080        ISSM_MPI_Bcast(&total_ice_volume_af,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1081
     1082        /*Assign output pointers: */
     1083        *pV=total_ice_volume_af;
     1084
     1085}/*}}}*/
     1086void FemModel::IceVolumex(IssmDouble* pV){/*{{{*/
     1087
     1088        IssmDouble local_ice_volume = 0;
     1089        IssmDouble total_ice_volume;
     1090
     1091        for(int i=0;i<this->elements->Size();i++){
     1092                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1093                local_ice_volume+=element->IceVolume();
     1094        }
     1095        ISSM_MPI_Reduce(&local_ice_volume,&total_ice_volume,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     1096        ISSM_MPI_Bcast(&total_ice_volume,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1097
     1098        /*Assign output pointers: */
     1099        *pV=total_ice_volume;
     1100
     1101}/*}}}*/
     1102void FemModel::MassFluxx(IssmDouble* pmass_flux){/*{{{*/
     1103
     1104        int          i,j;
     1105        Element     *element       = NULL;
     1106        int          element_id;
     1107        bool         ispresent     = false;
     1108        IssmDouble   mass_flux     = 0;
     1109        IssmDouble   all_mass_flux = 0;
     1110        int          counter;
     1111        IssmDouble **array         = NULL;
     1112        int          M;
     1113        int         *mdims_array   = NULL;
     1114        int         *ndims_array   = NULL;
     1115        IssmDouble  *segments      = NULL;
     1116        int          num_segments;
     1117
     1118        /*First, figure out which segment to compute our mass flux on. Start with retrieving qmu_mass_flux_segments: */
     1119        this->parameters->FindParam(&ispresent,MassFluxSegmentsPresentEnum);
     1120        if(!ispresent)_error_("no mass flux segments available!");
     1121        this->parameters->FindParam(&array,&M,&mdims_array,&ndims_array,MassFluxSegmentsEnum);
     1122
     1123        /*Retrieve index of segments being used for MassFlux computation: */
     1124        parameters->FindParam(&counter,IndexEnum);
     1125
     1126        /*retrieve segments from array: */
     1127        segments     = array[counter-1]; //matlab to "C" indexing
     1128        num_segments = mdims_array[counter-1];
     1129
     1130        /*Go through segments, and then elements, and figure out which elements belong to a segment.
     1131         * When we find one, use the element to compute the mass flux on the segment: */
     1132        for(i=0;i<num_segments;i++){
     1133                element_id=reCast<int,IssmDouble>(*(segments+5*i+4));
     1134                for(j=0;j<elements->Size();j++){
     1135                        element=(Element*)this->elements->GetObjectByOffset(j);
     1136                        if (element->Id()==element_id){
     1137                                /*We found the element which owns this segment, use it to compute the mass flux: */
     1138                                mass_flux+=element->MassFlux(segments+5*i+0);
     1139                                break;
     1140                        }
     1141                }
     1142        }
     1143
     1144        ISSM_MPI_Allreduce ( (void*)&mass_flux,(void*)&all_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
     1145        mass_flux=all_mass_flux;
     1146
     1147        /*Free ressources:*/
     1148        for(i=0;i<M;i++){
     1149                IssmDouble* matrix=array[i];
     1150                xDelete<IssmDouble>(matrix);
     1151        }
     1152        xDelete<int>(mdims_array);
     1153        xDelete<int>(ndims_array);
     1154        xDelete<IssmDouble*>(array);
     1155
     1156        /*Assign output pointers: */
     1157        *pmass_flux=mass_flux;
     1158
     1159}/*}}}*/
     1160void FemModel::MaxAbsVxx(IssmDouble* pmaxabsvx){/*{{{*/
     1161
     1162        int i;
     1163        IssmDouble maxabsvx;
     1164        IssmDouble node_maxabsvx;
     1165        IssmDouble element_maxabsvx;
     1166
     1167        /*Go through elements, and request velocity: */
     1168        maxabsvx=-INFINITY;
     1169        for(i=0;i<this->elements->Size();i++){
     1170                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1171                element_maxabsvx=element->inputs->MaxAbs(VxEnum);
     1172                if(element_maxabsvx>maxabsvx) maxabsvx=element_maxabsvx;
     1173        }
     1174
     1175        /*Figure out maximum across the cluster: */
     1176        ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1177        ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1178        maxabsvx=node_maxabsvx;
     1179
     1180        /*Assign output pointers:*/
     1181        *pmaxabsvx=maxabsvx;
     1182
     1183}/*}}}*/
     1184void FemModel::MaxAbsVyx(IssmDouble* pmaxabsvy){/*{{{*/
     1185
     1186        int i;
     1187        IssmDouble maxabsvy;
     1188        IssmDouble node_maxabsvy;
     1189        IssmDouble element_maxabsvy;
     1190
     1191        /*Go through elements, and request velocity: */
     1192        maxabsvy=-INFINITY;
     1193        for(i=0;i<this->elements->Size();i++){
     1194                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1195                element_maxabsvy=element->inputs->MaxAbs(VyEnum);
     1196                if(element_maxabsvy>maxabsvy) maxabsvy=element_maxabsvy;
     1197        }
     1198
     1199        /*Figure out maximum across the cluster: */
     1200        ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1201        ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1202        maxabsvy=node_maxabsvy;
     1203
     1204        /*Assign output pointers:*/
     1205        *pmaxabsvy=maxabsvy;
     1206
     1207}/*}}}*/
     1208void FemModel::MaxAbsVzx(IssmDouble* pmaxabsvz){/*{{{*/
     1209
     1210        int i;
     1211        IssmDouble maxabsvz;
     1212        IssmDouble node_maxabsvz;
     1213        IssmDouble element_maxabsvz;
     1214
     1215        /*Go through elements, and request velocity: */
     1216        maxabsvz=-INFINITY;
     1217        for(i=0;i<this->elements->Size();i++){
     1218                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1219                element_maxabsvz=element->inputs->MaxAbs(VzEnum);
     1220                if(element_maxabsvz>maxabsvz) maxabsvz=element_maxabsvz;
     1221        }
     1222
     1223        /*Figure out maximum across the cluster: */
     1224        ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1225        ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1226        maxabsvz=node_maxabsvz;
     1227
     1228        /*Assign output pointers:*/
     1229        *pmaxabsvz=maxabsvz;
     1230
     1231}/*}}}*/
     1232void FemModel::MaxDivergencex(IssmDouble* pdiv){/*{{{*/
     1233
     1234        IssmDouble local_divergence;
     1235        IssmDouble node_max_divergence;
     1236        IssmDouble max_divergence = -INFINITY;
     1237
     1238        for(int i=0;i<this->elements->Size();i++){
     1239                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1240                local_divergence=element->Divergence();
     1241                if(fabs(local_divergence)>max_divergence) max_divergence=fabs(local_divergence);
     1242        }
     1243        ISSM_MPI_Reduce(&max_divergence,&node_max_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1244        ISSM_MPI_Bcast(&node_max_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1245        max_divergence=node_max_divergence;
     1246
     1247        /*Assign output pointers: */
     1248        *pdiv=max_divergence;
     1249
     1250}/*}}}*/
     1251void FemModel::MaxVelx(IssmDouble* pmaxvel){/*{{{*/
     1252
     1253        int i;
     1254        IssmDouble maxvel;
     1255        IssmDouble node_maxvel;
     1256        IssmDouble element_maxvel;
     1257
     1258        /*Go through elements, and request velocity: */
     1259        maxvel=-INFINITY;
     1260        for(i=0;i<this->elements->Size();i++){
     1261                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1262                element_maxvel = element->inputs->Max(VelEnum);
     1263                if(element_maxvel>maxvel) maxvel=element_maxvel;
     1264        }
     1265
     1266        /*Figure out maximum across the cluster: */
     1267        ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1268        ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1269        maxvel=node_maxvel;
     1270
     1271        /*Assign output pointers:*/
     1272        *pmaxvel=maxvel;
     1273
     1274}/*}}}*/
     1275void FemModel::MaxVxx(IssmDouble* pmaxvx){/*{{{*/
     1276
     1277        int i;
     1278        IssmDouble maxvx;
     1279        IssmDouble node_maxvx;
     1280        IssmDouble element_maxvx;
     1281
     1282        /*Go through elements, and request velocity: */
     1283        maxvx=-INFINITY;
     1284        for(i=0;i<this->elements->Size();i++){
     1285                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1286                element_maxvx = element->inputs->Max(VxEnum);
     1287                if(element_maxvx>maxvx) maxvx=element_maxvx;
     1288        }
     1289
     1290        /*Figure out maximum across the cluster: */
     1291        ISSM_MPI_Reduce(&maxvx,&node_maxvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1292        ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1293        maxvx=node_maxvx;
     1294
     1295        /*Assign output pointers:*/
     1296        *pmaxvx=maxvx;
     1297
     1298}/*}}}*/
     1299void FemModel::MaxVyx(IssmDouble* pmaxvy){/*{{{*/
     1300
     1301        int i;
     1302        IssmDouble maxvy;
     1303        IssmDouble node_maxvy;
     1304        IssmDouble element_maxvy;
     1305
     1306        /*Go through elements, and request velocity: */
     1307        maxvy=-INFINITY;
     1308        for(i=0;i<this->elements->Size();i++){
     1309                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1310                element_maxvy = element->inputs->Max(VyEnum);
     1311                if(element_maxvy>maxvy) maxvy=element_maxvy;
     1312        }
     1313
     1314        /*Figure out maximum across the cluster: */
     1315        ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1316        ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1317        maxvy=node_maxvy;
     1318
     1319        /*Assign output pointers:*/
     1320        *pmaxvy=maxvy;
     1321
     1322}/*}}}*/
     1323void FemModel::MaxVzx(IssmDouble* pmaxvz){/*{{{*/
     1324
     1325        int i;
     1326        IssmDouble maxvz;
     1327        IssmDouble node_maxvz;
     1328        IssmDouble element_maxvz;
     1329
     1330        /*Go through elements, and request velocity: */
     1331        maxvz=-INFINITY;
     1332        for(i=0;i<this->elements->Size();i++){
     1333                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1334                element_maxvz = element->inputs->Max(VzEnum);
     1335                if(element_maxvz>maxvz) maxvz=element_maxvz;
     1336        }
     1337
     1338        /*Figure out maximum across the cluster: */
     1339        ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1340        ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1341        maxvz=node_maxvz;
     1342
     1343        /*Assign output pointers:*/
     1344        *pmaxvz=maxvz;
     1345
     1346}/*}}}*/
     1347void FemModel::MinVelx(IssmDouble* pminvel){/*{{{*/
     1348
     1349        int i;
     1350        IssmDouble minvel;
     1351        IssmDouble node_minvel;
     1352        IssmDouble element_minvel;
     1353
     1354        /*Go through elements, and request velocity: */
     1355        minvel=INFINITY;
     1356        for(i=0;i<this->elements->Size();i++){
     1357                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1358                element_minvel = element->inputs->Min(VelEnum);
     1359                if(element_minvel<minvel) minvel=element_minvel;
     1360        }
     1361
     1362        /*Figure out minimum across the cluster: */
     1363        ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1364        ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1365        minvel=node_minvel;
     1366
     1367        /*Assign output pointers:*/
     1368        *pminvel=minvel;
     1369
     1370}/*}}}*/
     1371void FemModel::MinVxx(IssmDouble* pminvx){/*{{{*/
     1372
     1373        int i;
     1374        IssmDouble minvx;
     1375        IssmDouble node_minvx;
     1376        IssmDouble element_minvx;
     1377
     1378        /*Go through elements, and request velocity: */
     1379        minvx=INFINITY;
     1380        for(i=0;i<this->elements->Size();i++){
     1381                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1382                element_minvx = element->inputs->Min(VxEnum);
     1383                if(element_minvx<minvx) minvx=element_minvx;
     1384        }
     1385
     1386        /*Figure out minimum across the cluster: */
     1387        ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1388        ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1389        minvx=node_minvx;
     1390
     1391        /*Assign output pointers:*/
     1392        *pminvx=minvx;
     1393
     1394}/*}}}*/
     1395void FemModel::MinVyx(IssmDouble* pminvy){/*{{{*/
     1396
     1397        int i;
     1398        IssmDouble minvy;
     1399        IssmDouble node_minvy;
     1400        IssmDouble element_minvy;
     1401
     1402        /*Go through elements, and request velocity: */
     1403        minvy=INFINITY;
     1404        for(i=0;i<this->elements->Size();i++){
     1405                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1406                element_minvy = element->inputs->Min(VyEnum);
     1407                if(element_minvy<minvy) minvy=element_minvy;
     1408        }
     1409
     1410        /*Figure out minimum across the cluster: */
     1411        ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1412        ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1413        minvy=node_minvy;
     1414
     1415        /*Assign output pointers:*/
     1416        *pminvy=minvy;
     1417
     1418}/*}}}*/
     1419void FemModel::MinVzx(IssmDouble* pminvz){/*{{{*/
     1420
     1421        int i;
     1422        IssmDouble minvz;
     1423        IssmDouble node_minvz;
     1424        IssmDouble element_minvz;
     1425
     1426        /*Go through elements, and request velocity: */
     1427        minvz=INFINITY;
     1428        for(i=0;i<this->elements->Size();i++){
     1429                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     1430                element_minvz = element->inputs->Min(VzEnum);
     1431                if(element_minvz<minvz) minvz=element_minvz;
     1432        }
     1433
     1434        /*Figure out minimum across the cluster: */
     1435        ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
     1436        ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
     1437        minvz=node_minvz;
     1438
     1439        /*Assign output pointers:*/
     1440        *pminvz=minvz;
     1441
     1442}/*}}}*/
     1443void FemModel::OutputControlsx(Results **presults){/*{{{*/
     1444
     1445        /*parameters: */
     1446        int         num_controls,step;
     1447        IssmDouble  time;
     1448        int        *control_type = NULL;
     1449
     1450        /*recover results*/
     1451        Results* results = *presults;
     1452        if(!results) results = new Results();
     1453
     1454        /*Get list of Controls*/
     1455        this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
     1456        this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
     1457        this->parameters->FindParam(&step,StepEnum);
     1458        this->parameters->FindParam(&time,TimeEnum);
     1459
     1460        for(int i=0;i<num_controls;i++){
     1461
     1462                int control_enum = control_type[i];
     1463                int gradient_enum;
     1464
     1465                switch(i){
     1466                        case 0: gradient_enum = Gradient1Enum; break;
     1467                        case 1: gradient_enum = Gradient2Enum; break;
     1468                        case 2: gradient_enum = Gradient3Enum; break;
     1469                        default: _error_("more than 3 controls not implemented yet");
     1470                }
     1471
     1472                /*Allocate vector*/
     1473                Vector<IssmPDouble> *vector_control  = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
     1474                Vector<IssmPDouble> *vector_gradient = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
     1475
     1476                /*Fill in vector*/
     1477                for(int j=0;j<elements->Size();j++){
     1478                        Element* element=(Element*)elements->GetObjectByOffset(j);
     1479                        element->ControlToVectors(vector_control,vector_gradient,control_enum);
     1480                }
     1481                vector_control->Assemble();
     1482                vector_gradient->Assemble();
     1483
     1484                results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,control_enum,vector_control ,step,time));
     1485                results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,gradient_enum,vector_gradient,step,time));
     1486        }
     1487
     1488        /*Clean up and return*/
     1489        xDelete<int>(control_type);
     1490}
     1491/*}}}*/
     1492void FemModel::RequestedDependentsx(void){/*{{{*/
     1493
     1494        bool        isautodiff      = false;
     1495        IssmDouble  output_value;
     1496
     1497        int         num_dependents;
     1498        IssmPDouble *dependents;
     1499        DataSet*    dependent_objects=NULL;
     1500        int my_rank=IssmComm::GetRank();
     1501
     1502        /*AD mode on?: */
     1503        parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum);
     1504
     1505        if(isautodiff){
     1506                #ifdef _HAVE_ADOLC_
     1507                parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
     1508                parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
     1509                if(num_dependents){
     1510                        dependents=xNew<IssmPDouble>(num_dependents);
     1511
     1512                        /*Go through our dependent variables, and compute the response:*/
     1513                        for(int i=0;i<dependent_objects->Size();i++){
     1514                                DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
     1515                                dep->Responsex(&output_value,this);
     1516                                if (my_rank==0) {
     1517                                        output_value>>=dependents[i];
     1518                                }
     1519                        }
     1520                }
     1521                delete dependent_objects;
     1522                if(num_dependents)xDelete<IssmPDouble>(dependents);
     1523                #else
     1524                _error_("Should not be requesting dependents when an AD library is not available!");
     1525                #endif
     1526        }
     1527}
     1528/*}}}*/
     1529void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs, bool save_results){/*{{{*/
     1530
     1531        /*Intermediaries*/
     1532        bool        isvec,results_on_nodes;
     1533        int         step,output_enum;
     1534        IssmDouble  time;
     1535        IssmDouble  double_result;
     1536        const char *output_string = NULL;
     1537
     1538        /*recover results*/
     1539        Results* results = *presults;
     1540        if(!results) results = new Results();
     1541
     1542        /*Get time and step*/
     1543        parameters->FindParam(&step,StepEnum);
     1544        parameters->FindParam(&time,TimeEnum);
     1545        parameters->FindParam(&results_on_nodes,SettingsResultsOnNodesEnum);
     1546
     1547        /*Go through all requested output*/
     1548        for(int i=0;i<numoutputs;i++){
     1549
     1550                output_string = requested_outputs[i];
     1551                output_enum   = StringToEnumx(output_string,false);
     1552                isvec         = false;
     1553
     1554                /*If string is not an enum, it is defined in output definitions*/
     1555                if(output_enum<0){
     1556                        double_result = OutputDefinitionsResponsex(this,output_string);
     1557                        if(save_results){
     1558                                results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
     1559                                continue;
     1560                        }
     1561                }
     1562                else{
     1563                        /*last chance for the output definition, if the enum is one of Outputdefinition[1-10]Enum:*/
     1564                        if(output_enum>=Outputdefinition1Enum && output_enum <=Outputdefinition10Enum){
     1565                                double_result = OutputDefinitionsResponsex(this,output_enum);
     1566                                if(save_results){
     1567                                        results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
     1568                                        continue;
     1569                                }
     1570                        }
     1571                        else{
     1572                                switch(output_enum){
     1573
     1574                                        /*Scalar output*/
     1575                                        case DivergenceEnum:               this->Divergencex(&double_result);               break;
     1576                                        case MaxDivergenceEnum:            this->MaxDivergencex(&double_result);            break;
     1577                                        case IceMassEnum:                  this->IceMassx(&double_result);                  break;
     1578                                        case IceVolumeEnum:                this->IceVolumex(&double_result);                break;
     1579                                        case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(&double_result); break;
     1580                                        case GroundedAreaEnum:             this->GroundedAreax(&double_result);             break;
     1581                                        case FloatingAreaEnum:             this->FloatingAreax(&double_result);             break;
     1582                                        case MinVelEnum:                   this->MinVelx(&double_result);                   break;
     1583                                        case MaxVelEnum:                   this->MaxVelx(&double_result);                   break;
     1584                                        case MinVxEnum:                    this->MinVxx(&double_result);                    break;
     1585                                        case MaxVxEnum:                    this->MaxVxx(&double_result);                    break;
     1586                                        case MaxAbsVxEnum:                 this->MaxAbsVxx(&double_result);                 break;
     1587                                        case MinVyEnum:                    this->MinVyx(&double_result);                    break;
     1588                                        case MaxVyEnum:                    this->MaxVyx(&double_result);                    break;
     1589                                        case MaxAbsVyEnum:                 this->MaxAbsVyx(&double_result);                 break;
     1590                                        case MinVzEnum:                    this->MinVzx(&double_result);                    break;
     1591                                        case MaxVzEnum:                    this->MaxVzx(&double_result);                    break;
     1592                                        case MaxAbsVzEnum:                 this->MaxAbsVzx(&double_result);                 break;
     1593                                        case MassFluxEnum:                 this->MassFluxx(&double_result);                 break;
     1594                                        case TotalFloatingBmbEnum:         this->TotalFloatingBmbx(&double_result);         break;
     1595                                        case TotalGroundedBmbEnum:         this->TotalGroundedBmbx(&double_result);         break;
     1596                                        case TotalSmbEnum:                 this->TotalSmbx(&double_result);                 break;
     1597
     1598                           /*Scalar control output*/
     1599                                case SurfaceAbsVelMisfitEnum:       SurfaceAbsVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
     1600                                case SurfaceRelVelMisfitEnum:       SurfaceRelVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
     1601                                case SurfaceLogVelMisfitEnum:       SurfaceLogVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
     1602                                case SurfaceLogVxVyMisfitEnum:      SurfaceLogVxVyMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);       break;
     1603                                case SurfaceAverageVelMisfitEnum:   SurfaceAverageVelMisfitx(&double_result,this);                                                  break;
     1604                                case ThicknessAbsMisfitEnum:        ThicknessAbsMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);         break;
     1605                                case ThicknessAbsGradientEnum:      this->ThicknessAbsGradientx(&double_result);                                                    break;
     1606                                case ThicknessAlongGradientEnum:    ThicknessAlongGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);     break;
     1607                                case ThicknessAcrossGradientEnum:   ThicknessAcrossGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);    break;
     1608                                case ThicknessPositiveEnum:         this->ThicknessPositivex(&double_result);                                                       break;
     1609                                case RheologyBbarAbsGradientEnum:   RheologyBbarAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);    break;
     1610                                case RheologyBAbsGradientEnum:      RheologyBAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);       break;
     1611                                case DragCoefficientAbsGradientEnum:DragCoefficientAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break;
     1612                                case BalancethicknessMisfitEnum:    BalancethicknessMisfitx(&double_result);                                                        break;
     1613                                case SurfaceAbsMisfitEnum:          SurfaceAbsMisfitx(&double_result); break;
     1614
     1615                                   /*Vector */
     1616                                        default:
     1617
     1618                                                /*Vector layout*/
     1619                                                int interpolation,nodesperelement,size,nlines,ncols,array_size;
     1620                                                int rank_interpolation=-1,rank_nodesperelement=-1,rank_arraysize=-1,max_rank_arraysize=0;
     1621                                                bool isarray=false;
     1622
     1623                                                /*Get interpolation (and compute input if necessary)*/
     1624                                                for(int j=0;j<elements->Size();j++){
     1625                                                        Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
     1626                                                        element->ResultInterpolation(&rank_interpolation,&rank_nodesperelement,&rank_arraysize,output_enum);
     1627                                                        if (rank_arraysize>max_rank_arraysize)max_rank_arraysize=rank_arraysize;
     1628                                                }
     1629                                                rank_arraysize=max_rank_arraysize;
     1630
     1631                                                /*Broadcast for cpus that do not have any elements*/
     1632                                                ISSM_MPI_Reduce(&rank_interpolation,&interpolation,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     1633                                                ISSM_MPI_Reduce(&rank_nodesperelement,&nodesperelement,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     1634                                                ISSM_MPI_Reduce(&rank_arraysize,&array_size,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
     1635                                                ISSM_MPI_Bcast(&interpolation,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     1636                                                ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     1637                                                ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     1638                                               
     1639                                                if(results_on_nodes){
     1640
     1641                                                        /*Allocate matrices*/
     1642                                                        int         nbe       = this->elements->NumberOfElements();
     1643                                                        IssmDouble* values    = xNewZeroInit<IssmDouble>(nbe*nodesperelement);
     1644                                                        IssmDouble* allvalues = xNew<IssmDouble>(nbe*nodesperelement);
     1645
     1646                                                        /*Fill-in matrix*/
     1647                                                        for(int j=0;j<elements->Size();j++){
     1648                                                                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
     1649                                                                element->ResultToPatch(values,nodesperelement,output_enum);
     1650                                                        }
     1651
     1652                                                        /*Gather from all cpus*/
     1653                                                        ISSM_MPI_Allreduce((void*)values,(void*)allvalues,nbe*nodesperelement,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
     1654                                                        xDelete<IssmDouble>(values);
     1655
     1656                                                        if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nbe,nodesperelement,step,time));
     1657                                                        xDelete<IssmDouble>(allvalues);
     1658
     1659                                                }
     1660                                                else{
     1661
     1662                                                        /*Allocate vector depending on interpolation*/
     1663                                                        switch(interpolation){
     1664                                                                case P0Enum: isarray = false; size = this->elements->NumberOfElements(); break;
     1665                                                                case P1Enum: isarray = false; size = this->vertices->NumberOfVertices(); break;
     1666                                                                case P0ArrayEnum: isarray = true; nlines = this->elements->NumberOfElements(); ncols= array_size; break;
     1667                                                                default:     _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet");
     1668
     1669                                                        }
     1670                                                        if (!isarray){
     1671                                                                Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size);
     1672
     1673                                                                /*Fill in vector*/
     1674                                                                for(int j=0;j<elements->Size();j++){
     1675                                                                        Element* element=(Element*)elements->GetObjectByOffset(j);
     1676                                                                        element->ResultToVector(vector_result,output_enum);
     1677                                                                }
     1678                                                                vector_result->Assemble();
     1679
     1680                                                                if(save_results)results->AddResult(new GenericExternalResult<Vector<IssmDouble>*>(results->Size()+1,output_enum,vector_result,step,time));
     1681                                                        }
     1682                                                        else{
     1683                                                                IssmDouble* values    = xNewZeroInit<IssmDouble>(nlines*ncols);
     1684                                                                IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols);
     1685                                                               
     1686                                                                /*Fill-in matrix*/
     1687                                                                for(int j=0;j<elements->Size();j++){
     1688                                                                        Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
     1689                                                                        element->ResultToMatrix(values,ncols, output_enum);
     1690                                                                }
     1691                                                                /*Gather from all cpus*/
     1692                                                                ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
     1693                                                                xDelete<IssmDouble>(values);
     1694                                                               
     1695                                                                if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time));
     1696                                                                xDelete<IssmDouble>(allvalues);
     1697                                                        }
     1698                                                }
     1699                                                isvec = true;
     1700                                                break;
     1701                                }
     1702                        }
     1703
     1704                }
     1705
     1706                /*Add result to Results*/
     1707                if(!isvec && save_results){
     1708                        results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
     1709                }
     1710        }
     1711
     1712        /*Assign pointer and clean up*/
     1713        *presults = results;
     1714}
     1715/*}}}*/
     1716void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results){/*{{{*/
     1717
     1718        /*Convert list of enums to list of string*/
     1719        char** enumlist = xNew<char*>(numoutputs);
     1720        for(int i=0;i<numoutputs;i++){
     1721                EnumToStringx(&enumlist[i],requested_outputs[i]);
     1722        }
     1723
     1724        /*Call main module*/
     1725        this->RequestedOutputsx(presults,enumlist,numoutputs,save_results);
     1726
     1727        /*clean up and return*/
     1728        for(int i=0;i<numoutputs;i++) xDelete<char>(enumlist[i]);
     1729        xDelete<char*>(enumlist);
     1730        return;
    8711731}
    8721732/*}}}*/
     
    9751835}
    9761836/*}}}*/
    977 void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs, bool save_results){/*{{{*/
    978 
    979         /*Intermediaries*/
    980         bool        isvec,results_on_nodes;
    981         int         step,output_enum;
    982         IssmDouble  time;
    983         IssmDouble  double_result;
    984         const char *output_string = NULL;
    985 
    986         /*recover results*/
    987         Results* results = *presults;
    988         if(!results) results = new Results();
    989 
    990         /*Get time and step*/
    991         parameters->FindParam(&step,StepEnum);
    992         parameters->FindParam(&time,TimeEnum);
    993         parameters->FindParam(&results_on_nodes,SettingsResultsOnNodesEnum);
    994 
    995         /*Go through all requested output*/
    996         for(int i=0;i<numoutputs;i++){
    997 
    998                 output_string = requested_outputs[i];
    999                 output_enum   = StringToEnumx(output_string,false);
    1000                 isvec         = false;
    1001 
    1002                 /*If string is not an enum, it is defined in output definitions*/
    1003                 if(output_enum<0){
    1004                         double_result = OutputDefinitionsResponsex(this,output_string);
    1005                         if(save_results){
    1006                                 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
    1007                                 continue;
    1008                         }
    1009                 }
    1010                 else{
    1011                         /*last chance for the output definition, if the enum is one of Outputdefinition[1-10]Enum:*/
    1012                         if(output_enum>=Outputdefinition1Enum && output_enum <=Outputdefinition10Enum){
    1013                                 double_result = OutputDefinitionsResponsex(this,output_enum);
    1014                                 if(save_results){
    1015                                         results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
    1016                                         continue;
    1017                                 }
    1018                         }
    1019                         else{
    1020                                 switch(output_enum){
    1021 
    1022                                         /*Scalar output*/
    1023                                         case DivergenceEnum:               this->Divergencex(&double_result);               break;
    1024                                         case MaxDivergenceEnum:            this->MaxDivergencex(&double_result);            break;
    1025                                         case IceMassEnum:                  this->IceMassx(&double_result);                  break;
    1026                                         case IceVolumeEnum:                this->IceVolumex(&double_result);                break;
    1027                                         case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(&double_result); break;
    1028                                         case GroundedAreaEnum:             this->GroundedAreax(&double_result);             break;
    1029                                         case FloatingAreaEnum:             this->FloatingAreax(&double_result);             break;
    1030                                         case MinVelEnum:                   this->MinVelx(&double_result);                   break;
    1031                                         case MaxVelEnum:                   this->MaxVelx(&double_result);                   break;
    1032                                         case MinVxEnum:                    this->MinVxx(&double_result);                    break;
    1033                                         case MaxVxEnum:                    this->MaxVxx(&double_result);                    break;
    1034                                         case MaxAbsVxEnum:                 this->MaxAbsVxx(&double_result);                 break;
    1035                                         case MinVyEnum:                    this->MinVyx(&double_result);                    break;
    1036                                         case MaxVyEnum:                    this->MaxVyx(&double_result);                    break;
    1037                                         case MaxAbsVyEnum:                 this->MaxAbsVyx(&double_result);                 break;
    1038                                         case MinVzEnum:                    this->MinVzx(&double_result);                    break;
    1039                                         case MaxVzEnum:                    this->MaxVzx(&double_result);                    break;
    1040                                         case MaxAbsVzEnum:                 this->MaxAbsVzx(&double_result);                 break;
    1041                                         case MassFluxEnum:                 this->MassFluxx(&double_result);                 break;
    1042                                         case TotalFloatingBmbEnum:         this->TotalFloatingBmbx(&double_result);         break;
    1043                                         case TotalGroundedBmbEnum:         this->TotalGroundedBmbx(&double_result);         break;
    1044                                         case TotalSmbEnum:                 this->TotalSmbx(&double_result);                 break;
    1045 
    1046                            /*Scalar control output*/
    1047                                 case SurfaceAbsVelMisfitEnum:       SurfaceAbsVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
    1048                                 case SurfaceRelVelMisfitEnum:       SurfaceRelVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
    1049                                 case SurfaceLogVelMisfitEnum:       SurfaceLogVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);        break;
    1050                                 case SurfaceLogVxVyMisfitEnum:      SurfaceLogVxVyMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);       break;
    1051                                 case SurfaceAverageVelMisfitEnum:   SurfaceAverageVelMisfitx(&double_result,this);                                                  break;
    1052                                 case ThicknessAbsMisfitEnum:        ThicknessAbsMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters);         break;
    1053                                 case ThicknessAbsGradientEnum:      this->ThicknessAbsGradientx(&double_result);                                                    break;
    1054                                 case ThicknessAlongGradientEnum:    ThicknessAlongGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);     break;
    1055                                 case ThicknessAcrossGradientEnum:   ThicknessAcrossGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);    break;
    1056                                 case ThicknessPositiveEnum:         this->ThicknessPositivex(&double_result);                                                       break;
    1057                                 case RheologyBbarAbsGradientEnum:   RheologyBbarAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);    break;
    1058                                 case RheologyBAbsGradientEnum:      RheologyBAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters);       break;
    1059                                 case DragCoefficientAbsGradientEnum:DragCoefficientAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break;
    1060                                 case BalancethicknessMisfitEnum:    BalancethicknessMisfitx(&double_result);                                                        break;
    1061                                 case SurfaceAbsMisfitEnum:          SurfaceAbsMisfitx(&double_result); break;
    1062 
    1063                                    /*Vector */
    1064                                         default:
    1065 
    1066                                                 /*Vector layout*/
    1067                                                 int interpolation,nodesperelement,size,nlines,ncols,array_size;
    1068                                                 int rank_interpolation=-1,rank_nodesperelement=-1,rank_arraysize=-1,max_rank_arraysize=0;
    1069                                                 bool isarray=false;
    1070 
    1071                                                 /*Get interpolation (and compute input if necessary)*/
    1072                                                 for(int j=0;j<elements->Size();j++){
    1073                                                         Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
    1074                                                         element->ResultInterpolation(&rank_interpolation,&rank_nodesperelement,&rank_arraysize,output_enum);
    1075                                                         if (rank_arraysize>max_rank_arraysize)max_rank_arraysize=rank_arraysize;
    1076                                                 }
    1077                                                 rank_arraysize=max_rank_arraysize;
    1078 
    1079                                                 /*Broadcast for cpus that do not have any elements*/
    1080                                                 ISSM_MPI_Reduce(&rank_interpolation,&interpolation,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    1081                                                 ISSM_MPI_Reduce(&rank_nodesperelement,&nodesperelement,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    1082                                                 ISSM_MPI_Reduce(&rank_arraysize,&array_size,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
    1083                                                 ISSM_MPI_Bcast(&interpolation,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    1084                                                 ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    1085                                                 ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    1086                                                
    1087                                                 if(results_on_nodes){
    1088 
    1089                                                         /*Allocate matrices*/
    1090                                                         int         nbe       = this->elements->NumberOfElements();
    1091                                                         IssmDouble* values    = xNewZeroInit<IssmDouble>(nbe*nodesperelement);
    1092                                                         IssmDouble* allvalues = xNew<IssmDouble>(nbe*nodesperelement);
    1093 
    1094                                                         /*Fill-in matrix*/
    1095                                                         for(int j=0;j<elements->Size();j++){
    1096                                                                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
    1097                                                                 element->ResultToPatch(values,nodesperelement,output_enum);
    1098                                                         }
    1099 
    1100                                                         /*Gather from all cpus*/
    1101                                                         ISSM_MPI_Allreduce((void*)values,(void*)allvalues,nbe*nodesperelement,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
    1102                                                         xDelete<IssmDouble>(values);
    1103 
    1104                                                         if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nbe,nodesperelement,step,time));
    1105                                                         xDelete<IssmDouble>(allvalues);
    1106 
    1107                                                 }
    1108                                                 else{
    1109 
    1110                                                         /*Allocate vector depending on interpolation*/
    1111                                                         switch(interpolation){
    1112                                                                 case P0Enum: isarray = false; size = this->elements->NumberOfElements(); break;
    1113                                                                 case P1Enum: isarray = false; size = this->vertices->NumberOfVertices(); break;
    1114                                                                 case P0ArrayEnum: isarray = true; nlines = this->elements->NumberOfElements(); ncols= array_size; break;
    1115                                                                 default:     _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet");
    1116 
    1117                                                         }
    1118                                                         if (!isarray){
    1119                                                                 Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size);
    1120 
    1121                                                                 /*Fill in vector*/
    1122                                                                 for(int j=0;j<elements->Size();j++){
    1123                                                                         Element* element=(Element*)elements->GetObjectByOffset(j);
    1124                                                                         element->ResultToVector(vector_result,output_enum);
    1125                                                                 }
    1126                                                                 vector_result->Assemble();
    1127 
    1128                                                                 if(save_results)results->AddResult(new GenericExternalResult<Vector<IssmDouble>*>(results->Size()+1,output_enum,vector_result,step,time));
    1129                                                         }
    1130                                                         else{
    1131                                                                 IssmDouble* values    = xNewZeroInit<IssmDouble>(nlines*ncols);
    1132                                                                 IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols);
    1133                                                                
    1134                                                                 /*Fill-in matrix*/
    1135                                                                 for(int j=0;j<elements->Size();j++){
    1136                                                                         Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
    1137                                                                         element->ResultToMatrix(values,ncols, output_enum);
    1138                                                                 }
    1139                                                                 /*Gather from all cpus*/
    1140                                                                 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
    1141                                                                 xDelete<IssmDouble>(values);
    1142                                                                
    1143                                                                 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time));
    1144                                                                 xDelete<IssmDouble>(allvalues);
    1145                                                         }
    1146                                                 }
    1147                                                 isvec = true;
    1148                                                 break;
    1149                                 }
    1150                         }
    1151 
    1152                 }
    1153 
    1154                 /*Add result to Results*/
    1155                 if(!isvec && save_results){
    1156                         results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
    1157                 }
    1158         }
    1159 
    1160         /*Assign pointer and clean up*/
    1161         *presults = results;
    1162 }
    1163 /*}}}*/
    1164 void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results){/*{{{*/
    1165 
    1166         /*Convert list of enums to list of string*/
    1167         char** enumlist = xNew<char*>(numoutputs);
    1168         for(int i=0;i<numoutputs;i++){
    1169                 EnumToStringx(&enumlist[i],requested_outputs[i]);
    1170         }
    1171 
    1172         /*Call main module*/
    1173         this->RequestedOutputsx(presults,enumlist,numoutputs,save_results);
    1174 
    1175         /*clean up and return*/
    1176         for(int i=0;i<numoutputs;i++) xDelete<char>(enumlist[i]);
    1177         xDelete<char*>(enumlist);
    1178         return;
    1179 }
    1180 /*}}}*/
    1181 void FemModel::RequestedDependentsx(void){/*{{{*/
    1182 
    1183         bool        isautodiff      = false;
    1184         IssmDouble  output_value;
    1185 
    1186         int         num_dependents;
    1187         IssmPDouble *dependents;
    1188         DataSet*    dependent_objects=NULL;
    1189         int my_rank=IssmComm::GetRank();
    1190 
    1191         /*AD mode on?: */
    1192         parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum);
    1193 
    1194         if(isautodiff){
    1195                 #ifdef _HAVE_ADOLC_
    1196                 parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum);
    1197                 parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
    1198                 if(num_dependents){
    1199                         dependents=xNew<IssmPDouble>(num_dependents);
    1200 
    1201                         /*Go through our dependent variables, and compute the response:*/
    1202                         for(int i=0;i<dependent_objects->Size();i++){
    1203                                 DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
    1204                                 dep->Responsex(&output_value,this);
    1205                                 if (my_rank==0) {
    1206                                         output_value>>=dependents[i];
    1207                                 }
    1208                         }
    1209                 }
    1210                 delete dependent_objects;
    1211                 if(num_dependents)xDelete<IssmPDouble>(dependents);
    1212                 #else
    1213                 _error_("Should not be requesting dependents when an AD library is not available!");
    1214                 #endif
    1215         }
    1216 }
    1217 /*}}}*/
    1218 void FemModel::TimeAdaptx(IssmDouble* pdt){/*{{{*/
    1219 
    1220         int      i;
    1221 
    1222         /*output: */
    1223         IssmDouble   dt;
    1224 
    1225         /*intermediary: */
    1226         Element *element     = NULL;
    1227         IssmDouble   min_dt      = 0;
    1228         IssmDouble   node_min_dt = 0;
    1229 
    1230         /*Go through elements, and figure out the minimum of the time steps for each element (using CFL criterion): */
    1231         element=(Element*)elements->GetObjectByOffset(0); min_dt=element->TimeAdapt();
    1232 
    1233         for (i=1;i<elements->Size();i++){
    1234                 element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1235                 dt=element->TimeAdapt();
    1236                 if(dt<min_dt)min_dt=dt;
    1237         }
    1238 
    1239         /*Figure out minimum across the cluster: */
    1240         ISSM_MPI_Reduce (&min_dt,&node_min_dt,1,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm() );
    1241         ISSM_MPI_Bcast(&node_min_dt,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1242         min_dt=node_min_dt;
    1243 
    1244         /*Assign output pointers:*/
    1245         *pdt=min_dt;
    1246 }
    1247 /*}}}*/
    1248 void FemModel::UpdateConstraintsExtrudeFromBasex(void){ /*{{{*/
     1837void FemModel::StrainRateparallelx(){/*{{{*/
    12491838
    12501839        for(int i=0;i<elements->Size();i++){
    1251                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1252                 element->UpdateConstraintsExtrudeFromBase();
    1253         }
    1254 
    1255 }
    1256 /*}}}*/
    1257 void FemModel::UpdateConstraintsExtrudeFromTopx(void){ /*{{{*/
     1840                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     1841                element->StrainRateparallel();
     1842        }
     1843}
     1844/*}}}*/
     1845void FemModel::StrainRateperpendicularx(){/*{{{*/
    12581846
    12591847        for(int i=0;i<elements->Size();i++){
    1260                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1261                 element->UpdateConstraintsExtrudeFromTop();
    1262         }
    1263 
    1264 }
    1265 /*}}}*/
    1266 void FemModel::MassFluxx(IssmDouble* pmass_flux){/*{{{*/
    1267 
    1268         int          i,j;
    1269         Element     *element       = NULL;
    1270         int          element_id;
    1271         bool         ispresent     = false;
    1272         IssmDouble   mass_flux     = 0;
    1273         IssmDouble   all_mass_flux = 0;
    1274         int          counter;
    1275         IssmDouble **array         = NULL;
    1276         int          M;
    1277         int         *mdims_array   = NULL;
    1278         int         *ndims_array   = NULL;
    1279         IssmDouble  *segments      = NULL;
    1280         int          num_segments;
    1281 
    1282         /*First, figure out which segment to compute our mass flux on. Start with retrieving qmu_mass_flux_segments: */
    1283         this->parameters->FindParam(&ispresent,MassFluxSegmentsPresentEnum);
    1284         if(!ispresent)_error_("no mass flux segments available!");
    1285         this->parameters->FindParam(&array,&M,&mdims_array,&ndims_array,MassFluxSegmentsEnum);
    1286 
    1287         /*Retrieve index of segments being used for MassFlux computation: */
    1288         parameters->FindParam(&counter,IndexEnum);
    1289 
    1290         /*retrieve segments from array: */
    1291         segments     = array[counter-1]; //matlab to "C" indexing
    1292         num_segments = mdims_array[counter-1];
    1293 
    1294         /*Go through segments, and then elements, and figure out which elements belong to a segment.
    1295          * When we find one, use the element to compute the mass flux on the segment: */
    1296         for(i=0;i<num_segments;i++){
    1297                 element_id=reCast<int,IssmDouble>(*(segments+5*i+4));
    1298                 for(j=0;j<elements->Size();j++){
    1299                         element=(Element*)this->elements->GetObjectByOffset(j);
    1300                         if (element->Id()==element_id){
    1301                                 /*We found the element which owns this segment, use it to compute the mass flux: */
    1302                                 mass_flux+=element->MassFlux(segments+5*i+0);
    1303                                 break;
    1304                         }
    1305                 }
    1306         }
    1307 
    1308         ISSM_MPI_Allreduce ( (void*)&mass_flux,(void*)&all_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
    1309         mass_flux=all_mass_flux;
    1310 
    1311         /*Free ressources:*/
    1312         for(i=0;i<M;i++){
    1313                 IssmDouble* matrix=array[i];
    1314                 xDelete<IssmDouble>(matrix);
    1315         }
    1316         xDelete<int>(mdims_array);
    1317         xDelete<int>(ndims_array);
    1318         xDelete<IssmDouble*>(array);
    1319 
    1320         /*Assign output pointers: */
    1321         *pmass_flux=mass_flux;
    1322 
    1323 }/*}}}*/
    1324 void FemModel::MaxAbsVxx(IssmDouble* pmaxabsvx){/*{{{*/
    1325 
    1326         int i;
    1327         IssmDouble maxabsvx;
    1328         IssmDouble node_maxabsvx;
    1329         IssmDouble element_maxabsvx;
    1330 
    1331         /*Go through elements, and request velocity: */
    1332         maxabsvx=-INFINITY;
    1333         for(i=0;i<this->elements->Size();i++){
    1334                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1335                 element_maxabsvx=element->inputs->MaxAbs(VxEnum);
    1336                 if(element_maxabsvx>maxabsvx) maxabsvx=element_maxabsvx;
    1337         }
    1338 
    1339         /*Figure out maximum across the cluster: */
    1340         ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1341         ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1342         maxabsvx=node_maxabsvx;
    1343 
    1344         /*Assign output pointers:*/
    1345         *pmaxabsvx=maxabsvx;
    1346 
    1347 }/*}}}*/
    1348 void FemModel::MaxAbsVyx(IssmDouble* pmaxabsvy){/*{{{*/
    1349 
    1350         int i;
    1351         IssmDouble maxabsvy;
    1352         IssmDouble node_maxabsvy;
    1353         IssmDouble element_maxabsvy;
    1354 
    1355         /*Go through elements, and request velocity: */
    1356         maxabsvy=-INFINITY;
    1357         for(i=0;i<this->elements->Size();i++){
    1358                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1359                 element_maxabsvy=element->inputs->MaxAbs(VyEnum);
    1360                 if(element_maxabsvy>maxabsvy) maxabsvy=element_maxabsvy;
    1361         }
    1362 
    1363         /*Figure out maximum across the cluster: */
    1364         ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1365         ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1366         maxabsvy=node_maxabsvy;
    1367 
    1368         /*Assign output pointers:*/
    1369         *pmaxabsvy=maxabsvy;
    1370 
    1371 }/*}}}*/
    1372 void FemModel::MaxAbsVzx(IssmDouble* pmaxabsvz){/*{{{*/
    1373 
    1374         int i;
    1375         IssmDouble maxabsvz;
    1376         IssmDouble node_maxabsvz;
    1377         IssmDouble element_maxabsvz;
    1378 
    1379         /*Go through elements, and request velocity: */
    1380         maxabsvz=-INFINITY;
    1381         for(i=0;i<this->elements->Size();i++){
    1382                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1383                 element_maxabsvz=element->inputs->MaxAbs(VzEnum);
    1384                 if(element_maxabsvz>maxabsvz) maxabsvz=element_maxabsvz;
    1385         }
    1386 
    1387         /*Figure out maximum across the cluster: */
    1388         ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1389         ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1390         maxabsvz=node_maxabsvz;
    1391 
    1392         /*Assign output pointers:*/
    1393         *pmaxabsvz=maxabsvz;
    1394 
    1395 }/*}}}*/
    1396 void FemModel::MaxVelx(IssmDouble* pmaxvel){/*{{{*/
    1397 
    1398         int i;
    1399         IssmDouble maxvel;
    1400         IssmDouble node_maxvel;
    1401         IssmDouble element_maxvel;
    1402 
    1403         /*Go through elements, and request velocity: */
    1404         maxvel=-INFINITY;
    1405         for(i=0;i<this->elements->Size();i++){
    1406                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1407                 element_maxvel = element->inputs->Max(VelEnum);
    1408                 if(element_maxvel>maxvel) maxvel=element_maxvel;
    1409         }
    1410 
    1411         /*Figure out maximum across the cluster: */
    1412         ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1413         ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1414         maxvel=node_maxvel;
    1415 
    1416         /*Assign output pointers:*/
    1417         *pmaxvel=maxvel;
    1418 
    1419 }/*}}}*/
    1420 void FemModel::MaxVxx(IssmDouble* pmaxvx){/*{{{*/
    1421 
    1422         int i;
    1423         IssmDouble maxvx;
    1424         IssmDouble node_maxvx;
    1425         IssmDouble element_maxvx;
    1426 
    1427         /*Go through elements, and request velocity: */
    1428         maxvx=-INFINITY;
    1429         for(i=0;i<this->elements->Size();i++){
    1430                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1431                 element_maxvx = element->inputs->Max(VxEnum);
    1432                 if(element_maxvx>maxvx) maxvx=element_maxvx;
    1433         }
    1434 
    1435         /*Figure out maximum across the cluster: */
    1436         ISSM_MPI_Reduce(&maxvx,&node_maxvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1437         ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1438         maxvx=node_maxvx;
    1439 
    1440         /*Assign output pointers:*/
    1441         *pmaxvx=maxvx;
    1442 
    1443 }/*}}}*/
    1444 void FemModel::MaxVyx(IssmDouble* pmaxvy){/*{{{*/
    1445 
    1446         int i;
    1447         IssmDouble maxvy;
    1448         IssmDouble node_maxvy;
    1449         IssmDouble element_maxvy;
    1450 
    1451         /*Go through elements, and request velocity: */
    1452         maxvy=-INFINITY;
    1453         for(i=0;i<this->elements->Size();i++){
    1454                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1455                 element_maxvy = element->inputs->Max(VyEnum);
    1456                 if(element_maxvy>maxvy) maxvy=element_maxvy;
    1457         }
    1458 
    1459         /*Figure out maximum across the cluster: */
    1460         ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1461         ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1462         maxvy=node_maxvy;
    1463 
    1464         /*Assign output pointers:*/
    1465         *pmaxvy=maxvy;
    1466 
    1467 }/*}}}*/
    1468 void FemModel::MaxVzx(IssmDouble* pmaxvz){/*{{{*/
    1469 
    1470         int i;
    1471         IssmDouble maxvz;
    1472         IssmDouble node_maxvz;
    1473         IssmDouble element_maxvz;
    1474 
    1475         /*Go through elements, and request velocity: */
    1476         maxvz=-INFINITY;
    1477         for(i=0;i<this->elements->Size();i++){
    1478                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1479                 element_maxvz = element->inputs->Max(VzEnum);
    1480                 if(element_maxvz>maxvz) maxvz=element_maxvz;
    1481         }
    1482 
    1483         /*Figure out maximum across the cluster: */
    1484         ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1485         ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1486         maxvz=node_maxvz;
    1487 
    1488         /*Assign output pointers:*/
    1489         *pmaxvz=maxvz;
    1490 
    1491 }/*}}}*/
    1492 void FemModel::MinVelx(IssmDouble* pminvel){/*{{{*/
    1493 
    1494         int i;
    1495         IssmDouble minvel;
    1496         IssmDouble node_minvel;
    1497         IssmDouble element_minvel;
    1498 
    1499         /*Go through elements, and request velocity: */
    1500         minvel=INFINITY;
    1501         for(i=0;i<this->elements->Size();i++){
    1502                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1503                 element_minvel = element->inputs->Min(VelEnum);
    1504                 if(element_minvel<minvel) minvel=element_minvel;
    1505         }
    1506 
    1507         /*Figure out minimum across the cluster: */
    1508         ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1509         ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1510         minvel=node_minvel;
    1511 
    1512         /*Assign output pointers:*/
    1513         *pminvel=minvel;
    1514 
    1515 }/*}}}*/
    1516 void FemModel::MinVxx(IssmDouble* pminvx){/*{{{*/
    1517 
    1518         int i;
    1519         IssmDouble minvx;
    1520         IssmDouble node_minvx;
    1521         IssmDouble element_minvx;
    1522 
    1523         /*Go through elements, and request velocity: */
    1524         minvx=INFINITY;
    1525         for(i=0;i<this->elements->Size();i++){
    1526                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1527                 element_minvx = element->inputs->Min(VxEnum);
    1528                 if(element_minvx<minvx) minvx=element_minvx;
    1529         }
    1530 
    1531         /*Figure out minimum across the cluster: */
    1532         ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1533         ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1534         minvx=node_minvx;
    1535 
    1536         /*Assign output pointers:*/
    1537         *pminvx=minvx;
    1538 
    1539 }/*}}}*/
    1540 void FemModel::MinVyx(IssmDouble* pminvy){/*{{{*/
    1541 
    1542         int i;
    1543         IssmDouble minvy;
    1544         IssmDouble node_minvy;
    1545         IssmDouble element_minvy;
    1546 
    1547         /*Go through elements, and request velocity: */
    1548         minvy=INFINITY;
    1549         for(i=0;i<this->elements->Size();i++){
    1550                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1551                 element_minvy = element->inputs->Min(VyEnum);
    1552                 if(element_minvy<minvy) minvy=element_minvy;
    1553         }
    1554 
    1555         /*Figure out minimum across the cluster: */
    1556         ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1557         ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1558         minvy=node_minvy;
    1559 
    1560         /*Assign output pointers:*/
    1561         *pminvy=minvy;
    1562 
    1563 }/*}}}*/
    1564 void FemModel::MinVzx(IssmDouble* pminvz){/*{{{*/
    1565 
    1566         int i;
    1567         IssmDouble minvz;
    1568         IssmDouble node_minvz;
    1569         IssmDouble element_minvz;
    1570 
    1571         /*Go through elements, and request velocity: */
    1572         minvz=INFINITY;
    1573         for(i=0;i<this->elements->Size();i++){
    1574                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1575                 element_minvz = element->inputs->Min(VzEnum);
    1576                 if(element_minvz<minvz) minvz=element_minvz;
    1577         }
    1578 
    1579         /*Figure out minimum across the cluster: */
    1580         ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1581         ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());   
    1582         minvz=node_minvz;
    1583 
    1584         /*Assign output pointers:*/
    1585         *pminvz=minvz;
    1586 
    1587 }/*}}}*/
    1588 void FemModel::TotalFloatingBmbx(IssmDouble* pFbmb){/*{{{*/
    1589 
    1590         IssmDouble local_fbmb = 0;
    1591         IssmDouble total_fbmb;
    1592 
    1593         for(int i=0;i<this->elements->Size();i++){
    1594                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1595                 local_fbmb+=element->TotalFloatingBmb();
    1596         }
    1597         ISSM_MPI_Reduce(&local_fbmb,&total_fbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1598         ISSM_MPI_Bcast(&total_fbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1599 
    1600         /*Assign output pointers: */
    1601         *pFbmb=total_fbmb;
    1602 
    1603 }/*}}}*/
    1604 void FemModel::TotalGroundedBmbx(IssmDouble* pGbmb){/*{{{*/
    1605 
    1606         IssmDouble local_gbmb = 0;
    1607         IssmDouble total_gbmb;
    1608 
    1609         for(int i=0;i<this->elements->Size();i++){
    1610                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1611                 local_gbmb+=element->TotalGroundedBmb();
    1612         }
    1613         ISSM_MPI_Reduce(&local_gbmb,&total_gbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1614         ISSM_MPI_Bcast(&total_gbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1615 
    1616         /*Assign output pointers: */
    1617         *pGbmb=total_gbmb;
    1618 
    1619 }/*}}}*/
    1620 void FemModel::TotalSmbx(IssmDouble* pSmb){/*{{{*/
    1621 
    1622         IssmDouble local_smb = 0;
    1623         IssmDouble total_smb;
    1624 
    1625         for(int i=0;i<this->elements->Size();i++){
    1626                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1627                 local_smb+=element->TotalSmb();
    1628         }
    1629         ISSM_MPI_Reduce(&local_smb,&total_smb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1630         ISSM_MPI_Bcast(&total_smb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1631 
    1632         /*Assign output pointers: */
    1633         *pSmb=total_smb;
    1634 
    1635 }/*}}}*/
    1636 void FemModel::Divergencex(IssmDouble* pdiv){/*{{{*/
    1637 
    1638         IssmDouble local_divergence=0;
    1639         IssmDouble total_divergence;
    1640 
    1641         for(int i=0;i<this->elements->Size();i++){
    1642                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1643                 local_divergence+=element->Divergence();
    1644         }
    1645         ISSM_MPI_Reduce(&local_divergence,&total_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1646         ISSM_MPI_Bcast(&total_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1647 
    1648         /*Assign output pointers: */
    1649         *pdiv=total_divergence;
    1650 
    1651 }/*}}}*/
    1652 void FemModel::MaxDivergencex(IssmDouble* pdiv){/*{{{*/
    1653 
    1654         IssmDouble local_divergence;
    1655         IssmDouble node_max_divergence;
    1656         IssmDouble max_divergence = -INFINITY;
    1657 
    1658         for(int i=0;i<this->elements->Size();i++){
    1659                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1660                 local_divergence=element->Divergence();
    1661                 if(fabs(local_divergence)>max_divergence) max_divergence=fabs(local_divergence);
    1662         }
    1663         ISSM_MPI_Reduce(&max_divergence,&node_max_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
    1664         ISSM_MPI_Bcast(&node_max_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1665         max_divergence=node_max_divergence;
    1666 
    1667         /*Assign output pointers: */
    1668         *pdiv=max_divergence;
    1669 
    1670 }/*}}}*/
    1671 void FemModel::FloatingAreax(IssmDouble* pV){/*{{{*/
    1672 
    1673         IssmDouble local_floating_area= 0;
    1674         IssmDouble total_floating_area;
    1675 
    1676         for(int i=0;i<this->elements->Size();i++){
    1677                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1678                 local_floating_area+=element->FloatingArea();
    1679         }
    1680         ISSM_MPI_Reduce(&local_floating_area,&total_floating_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1681         ISSM_MPI_Bcast(&total_floating_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1682 
    1683         /*Assign output pointers: */
    1684         *pV=total_floating_area;
    1685 
    1686 }/*}}}*/
    1687 void FemModel::GetInputLocalMinMaxOnNodesx(IssmDouble** pmin,IssmDouble** pmax,IssmDouble* ug){/*{{{*/
    1688 
    1689         /*Get vector sizes for current configuration*/
    1690         int configuration_type;
    1691         this->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
    1692         int numnodes = this->nodes->NumberOfNodes(configuration_type);
    1693 
    1694         /*Initialize output vectors*/
    1695         IssmDouble* uLmin_local = xNew<IssmDouble>(numnodes);
    1696         IssmDouble* uLmax_local = xNew<IssmDouble>(numnodes);
    1697         IssmDouble* uLmin = xNew<IssmDouble>(numnodes);
    1698         IssmDouble* uLmax = xNew<IssmDouble>(numnodes);
    1699         for(int i=0;i<numnodes;i++){
    1700                 uLmin_local[i] = +1.e+50;
    1701                 uLmax_local[i] = -1.e+50;
    1702         }
    1703 
    1704         for(int i=0;i<this->elements->Size();i++){
    1705                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1706                 element->GetInputLocalMinMaxOnNodes(uLmin_local,uLmax_local,ug);
    1707         }
    1708 
    1709         /*Synchronize all CPUs*/
    1710         ISSM_MPI_Allreduce((void*)uLmin_local,(void*)uLmin,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,IssmComm::GetComm());
    1711         ISSM_MPI_Allreduce((void*)uLmax_local,(void*)uLmax,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,IssmComm::GetComm());
    1712         xDelete<IssmDouble>(uLmin_local);
    1713         xDelete<IssmDouble>(uLmax_local);
    1714 
    1715         /*Assign output pointers: */
    1716         *pmin=uLmin;
    1717         *pmax=uLmax;
    1718 
    1719 }/*}}}*/
    1720 void FemModel::GroundedAreax(IssmDouble* pV){/*{{{*/
    1721 
    1722         IssmDouble local_grounded_area= 0;
    1723         IssmDouble total_grounded_area;
    1724 
    1725         for(int i=0;i<this->elements->Size();i++){
    1726                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1727                 local_grounded_area+=element->GroundedArea();
    1728         }
    1729         ISSM_MPI_Reduce(&local_grounded_area,&total_grounded_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1730         ISSM_MPI_Bcast(&total_grounded_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1731 
    1732         /*Assign output pointers: */
    1733         *pV=total_grounded_area;
    1734 
    1735 }/*}}}*/
    1736 void FemModel::IceMassx(IssmDouble* pM){/*{{{*/
    1737 
    1738         IssmDouble local_ice_mass = 0;
    1739         IssmDouble total_ice_mass;
    1740 
    1741         for(int i=0;i<this->elements->Size();i++){
    1742                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1743                 local_ice_mass+=element->IceMass();
    1744         }
    1745         ISSM_MPI_Reduce(&local_ice_mass,&total_ice_mass,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1746         ISSM_MPI_Bcast(&total_ice_mass,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1747 
    1748         /*Assign output pointers: */
    1749         *pM=total_ice_mass;
    1750 
    1751 }/*}}}*/
    1752 void FemModel::IceVolumex(IssmDouble* pV){/*{{{*/
    1753 
    1754         IssmDouble local_ice_volume = 0;
    1755         IssmDouble total_ice_volume;
    1756 
    1757         for(int i=0;i<this->elements->Size();i++){
    1758                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1759                 local_ice_volume+=element->IceVolume();
    1760         }
    1761         ISSM_MPI_Reduce(&local_ice_volume,&total_ice_volume,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1762         ISSM_MPI_Bcast(&total_ice_volume,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1763 
    1764         /*Assign output pointers: */
    1765         *pV=total_ice_volume;
    1766 
    1767 }/*}}}*/
    1768 void FemModel::IceVolumeAboveFloatationx(IssmDouble* pV){/*{{{*/
    1769 
    1770         IssmDouble local_ice_volume_af = 0;
    1771         IssmDouble total_ice_volume_af;
    1772 
    1773         for(int i=0;i<this->elements->Size();i++){
    1774                 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1775                 local_ice_volume_af+=element->IceVolumeAboveFloatation();
    1776         }
    1777         ISSM_MPI_Reduce(&local_ice_volume_af,&total_ice_volume_af,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1778         ISSM_MPI_Bcast(&total_ice_volume_af,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1779 
    1780         /*Assign output pointers: */
    1781         *pV=total_ice_volume_af;
    1782 
    1783 }/*}}}*/
    1784 void FemModel::ElementResponsex(IssmDouble* presponse,int response_enum){/*{{{*/
    1785 
    1786         int found=0;
    1787         int sumfound=0;
    1788         int cpu_found=-1;
    1789         int index;
    1790         IssmDouble response;
    1791         Element* element=NULL;
    1792 
    1793         /*retrieve element we are interested in: */
    1794         this->parameters->FindParam(&index,IndexEnum);
    1795         int my_rank=IssmComm::GetRank();
    1796 
    1797         /*now, go through our elements, and retrieve the one with this id: index: */
    1798         for(int i=0;i<this->elements->Size();i++){
    1799                 element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
    1800                 if (element->Id()==index){
    1801                         found=1;
    1802                         cpu_found=my_rank;
    1803                         break;
    1804                 }
    1805         }
    1806 
    1807         /*Broadcast whether we found the element: */
    1808         ISSM_MPI_Allreduce ( &found,&sumfound,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm());
    1809         if(!sumfound)_error_("could not find material with id" << index << " to compute ElementResponse");
    1810 
    1811         /*Ok, we found the element, compute responseocity: */
    1812         if(my_rank==cpu_found){
    1813                 element->ElementResponse(&response,response_enum);
    1814         }
    1815 
    1816         /*Broadcast and plug into response: */
    1817         ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
    1818         ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm());
    1819 
    1820         /*Assign output pointers: */
    1821         *presponse=response;
    1822 
    1823 }/*}}}*/
    1824 void FemModel::BalancethicknessMisfitx(IssmDouble* presponse){/*{{{*/
    1825 
    1826         /*output: */
    1827         IssmDouble J=0.;
    1828         IssmDouble J_sum;
    1829 
    1830         IssmDouble  weight,vx,vy,H,dvx[2],dvy[2],dH[2];
    1831         IssmDouble  temp,Jdet,dhdt,groundedice_melting,surface_mass_balance;
    1832         IssmDouble* xyz_list = NULL;
    1833         IssmDouble  dp[3];
    1834 
    1835         /*Compute Misfit: */
     1848                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     1849                element->StrainRateperpendicular();
     1850        }
     1851}
     1852/*}}}*/
     1853void FemModel::StressIntensityFactorx(){/*{{{*/
     1854
     1855        /*Update input for basal element only*/
    18361856        for(int i=0;i<elements->Size();i++){
    1837                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1838 
    1839                 /*If on water, return 0: */
    1840                 if(!element->IsIceInElement()) continue;
    1841 
    1842                 /* Get node coordinates*/
    1843                 element->GetVerticesCoordinates(&xyz_list);
    1844                 Input* weights_input                   = element->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    1845                 Input* thickness_input                 = element->GetInput(ThicknessEnum); _assert_(thickness_input);
    1846                 Input* vx_input                        = element->GetInput(VxEnum);                                  _assert_(vx_input);
    1847                 Input* vy_input                        = element->GetInput(VyEnum);                                  _assert_(vy_input);
    1848                 Input* surface_mass_balance_input      = element->GetInput(SmbMassBalanceEnum);          _assert_(surface_mass_balance_input);
    1849                 Input* groundedice_melting_input       = element->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(groundedice_melting_input);
    1850                 Input* dhdt_input                      = element->GetInput(BalancethicknessThickeningRateEnum);      _assert_(dhdt_input);
    1851 
    1852                 /* Start  looping on the number of gaussian points: */
    1853                 Gauss* gauss=element->NewGauss(2);
    1854                 for(int ig=gauss->begin();ig<gauss->end();ig++){
    1855 
    1856                         gauss->GaussPoint(ig);
    1857 
    1858                         /* Get Jacobian determinant: */
    1859                         element->JacobianDeterminant(&Jdet,xyz_list,gauss);
    1860 
    1861                         /*Get all parameters at gaussian point*/
    1862                         weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum);
    1863                         thickness_input->GetInputValue(&H, gauss);
    1864                         thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss);
    1865                         surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss);
    1866                         groundedice_melting_input->GetInputValue(&groundedice_melting,gauss);
    1867                         dhdt_input->GetInputValue(&dhdt,gauss);
    1868                         vx_input->GetInputValue(&vx,gauss);
    1869                         vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    1870                         vy_input->GetInputValue(&vy,gauss);
    1871                         vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    1872 
    1873                         /*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/
    1874                         temp  = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-groundedice_melting-dhdt);
    1875                         J    +=weight*1/2*temp*temp*Jdet*gauss->weight;
    1876                 }
    1877 
    1878                 /*clean up and Return: */
    1879                 xDelete<IssmDouble>(xyz_list);
    1880                 delete gauss;
    1881         }
    1882 
    1883         /*Sum all J from all cpus of the cluster:*/
    1884         ISSM_MPI_Reduce (&J,&J_sum,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
    1885         ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    1886         J=J_sum;
    1887 
    1888         /*Assign output pointers: */
    1889         *presponse=J;
    1890 
    1891 }/*}}}*/
     1857                Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
     1858                element->StressIntensityFactor();
     1859        }
     1860}
     1861        /*}}}*/
    18921862void FemModel::SurfaceAbsMisfitx(IssmDouble* presponse){/*{{{*/
    18931863
     
    20592029}
    20602030/*}}}*/
    2061 void FemModel::CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn){/*{{{*/
    2062 
    2063         /*Intermediary*/
    2064         int      num_responses;
    2065         int     *responses      = NULL;
    2066         Results *cost_functions = NULL;
    2067 
    2068         /*Recover parameters*/
    2069         parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
    2070         parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum);
    2071 
    2072         /*Get the value of all cost functions*/
    2073         this->RequestedOutputsx(&cost_functions,responses,num_responses);
    2074 
    2075         /*Get and add all contributions one by one*/
    2076         IssmDouble  J=0;
    2077         IssmDouble* Jlist = xNew<IssmDouble>(num_responses);
    2078         for(int i=0;i<num_responses;i++){
    2079                 ExternalResult* result=(ExternalResult*)cost_functions->GetObjectByOffset(i);
    2080                 Jlist[i] = reCast<IssmDouble>(result->GetValue());
    2081                 J       += Jlist[i];
    2082         }
    2083         _assert_(cost_functions->Size()==num_responses);
     2031void FemModel::TimeAdaptx(IssmDouble* pdt){/*{{{*/
     2032
     2033        int      i;
     2034
     2035        /*output: */
     2036        IssmDouble   dt;
     2037
     2038        /*intermediary: */
     2039        Element *element     = NULL;
     2040        IssmDouble   min_dt      = 0;
     2041        IssmDouble   node_min_dt = 0;
     2042
     2043        /*Go through elements, and figure out the minimum of the time steps for each element (using CFL criterion): */
     2044        element=(Element*)elements->GetObjectByOffset(0); min_dt=element->TimeAdapt();
     2045
     2046        for (i=1;i<elements->Size();i++){
     2047                element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     2048                dt=element->TimeAdapt();
     2049                if(dt<min_dt)min_dt=dt;
     2050        }
     2051
     2052        /*Figure out minimum across the cluster: */
     2053        ISSM_MPI_Reduce (&min_dt,&node_min_dt,1,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm() );
     2054        ISSM_MPI_Bcast(&node_min_dt,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     2055        min_dt=node_min_dt;
     2056
     2057        /*Assign output pointers:*/
     2058        *pdt=min_dt;
     2059}
     2060/*}}}*/
     2061void FemModel::TotalFloatingBmbx(IssmDouble* pFbmb){/*{{{*/
     2062
     2063        IssmDouble local_fbmb = 0;
     2064        IssmDouble total_fbmb;
     2065
     2066        for(int i=0;i<this->elements->Size();i++){
     2067                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     2068                local_fbmb+=element->TotalFloatingBmb();
     2069        }
     2070        ISSM_MPI_Reduce(&local_fbmb,&total_fbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     2071        ISSM_MPI_Bcast(&total_fbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    20842072
    20852073        /*Assign output pointers: */
    2086         delete cost_functions;
    2087         xDelete<int>(responses);
    2088         if(pJ)     *pJ     = J;
    2089         if(pJlist) *pJlist = Jlist;
    2090         else        xDelete<IssmDouble>(Jlist);
    2091         if(pn)     *pn     = num_responses;
    2092 }
    2093 /*}}}*/
    2094 void FemModel::OutputControlsx(Results **presults){/*{{{*/
    2095 
    2096         /*parameters: */
    2097         int         num_controls,step;
    2098         IssmDouble  time;
    2099         int        *control_type = NULL;
    2100 
    2101         /*recover results*/
    2102         Results* results = *presults;
    2103         if(!results) results = new Results();
    2104 
    2105         /*Get list of Controls*/
    2106         this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
    2107         this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
    2108         this->parameters->FindParam(&step,StepEnum);
    2109         this->parameters->FindParam(&time,TimeEnum);
    2110 
    2111         for(int i=0;i<num_controls;i++){
    2112 
    2113                 int control_enum = control_type[i];
    2114                 int gradient_enum;
    2115 
    2116                 switch(i){
    2117                         case 0: gradient_enum = Gradient1Enum; break;
    2118                         case 1: gradient_enum = Gradient2Enum; break;
    2119                         case 2: gradient_enum = Gradient3Enum; break;
    2120                         default: _error_("more than 3 controls not implemented yet");
    2121                 }
    2122 
    2123                 /*Allocate vector*/
    2124                 Vector<IssmPDouble> *vector_control  = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
    2125                 Vector<IssmPDouble> *vector_gradient = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
    2126 
    2127                 /*Fill in vector*/
    2128                 for(int j=0;j<elements->Size();j++){
    2129                         Element* element=(Element*)elements->GetObjectByOffset(j);
    2130                         element->ControlToVectors(vector_control,vector_gradient,control_enum);
    2131                 }
    2132                 vector_control->Assemble();
    2133                 vector_gradient->Assemble();
    2134 
    2135                 results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,control_enum,vector_control ,step,time));
    2136                 results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,gradient_enum,vector_gradient,step,time));
    2137         }
    2138 
    2139         /*Clean up and return*/
    2140         xDelete<int>(control_type);
    2141 }
    2142 /*}}}*/
    2143 void FemModel::StressIntensityFactorx(){/*{{{*/
    2144 
    2145         /*Update input for basal element only*/
     2074        *pFbmb=total_fbmb;
     2075
     2076}/*}}}*/
     2077void FemModel::TotalGroundedBmbx(IssmDouble* pGbmb){/*{{{*/
     2078
     2079        IssmDouble local_gbmb = 0;
     2080        IssmDouble total_gbmb;
     2081
     2082        for(int i=0;i<this->elements->Size();i++){
     2083                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     2084                local_gbmb+=element->TotalGroundedBmb();
     2085        }
     2086        ISSM_MPI_Reduce(&local_gbmb,&total_gbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     2087        ISSM_MPI_Bcast(&total_gbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     2088
     2089        /*Assign output pointers: */
     2090        *pGbmb=total_gbmb;
     2091
     2092}/*}}}*/
     2093void FemModel::TotalSmbx(IssmDouble* pSmb){/*{{{*/
     2094
     2095        IssmDouble local_smb = 0;
     2096        IssmDouble total_smb;
     2097
     2098        for(int i=0;i<this->elements->Size();i++){
     2099                Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
     2100                local_smb+=element->TotalSmb();
     2101        }
     2102        ISSM_MPI_Reduce(&local_smb,&total_smb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
     2103        ISSM_MPI_Bcast(&total_smb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     2104
     2105        /*Assign output pointers: */
     2106        *pSmb=total_smb;
     2107
     2108}/*}}}*/
     2109void FemModel::UpdateConstraintsExtrudeFromBasex(void){ /*{{{*/
     2110
    21462111        for(int i=0;i<elements->Size();i++){
    2147                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2148                 element->StressIntensityFactor();
    2149         }
    2150 }
    2151         /*}}}*/
    2152 void FemModel::CalvingRateLevermannx(){/*{{{*/
     2112                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     2113                element->UpdateConstraintsExtrudeFromBase();
     2114        }
     2115
     2116}
     2117/*}}}*/
     2118void FemModel::UpdateConstraintsExtrudeFromTopx(void){ /*{{{*/
    21532119
    21542120        for(int i=0;i<elements->Size();i++){
    2155                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2156                 element->CalvingRateLevermann();
    2157         }
    2158 }
    2159 /*}}}*/
    2160 void FemModel::CalvingRateDevx(){/*{{{*/
    2161 
    2162         for(int i=0;i<elements->Size();i++){
    2163                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2164                 element->CalvingRateDev();
    2165         }
    2166 }
    2167 /*}}}*/
    2168 void FemModel::StrainRateparallelx(){/*{{{*/
    2169 
    2170         for(int i=0;i<elements->Size();i++){
    2171                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2172                 element->StrainRateparallel();
    2173         }
    2174 }
    2175 /*}}}*/
    2176 void FemModel::StrainRateperpendicularx(){/*{{{*/
    2177 
    2178         for(int i=0;i<elements->Size();i++){
    2179                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2180                 element->StrainRateperpendicular();
    2181         }
    2182 }
    2183 /*}}}*/
    2184 void FemModel::DeviatoricStressx(){/*{{{*/
    2185 
    2186         for(int i=0;i<elements->Size();i++){
    2187                 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
    2188                 element->ComputeDeviatoricStressTensor();
    2189         }
     2121                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     2122                element->UpdateConstraintsExtrudeFromTop();
     2123        }
     2124
     2125}
     2126/*}}}*/
     2127void FemModel::UpdateConstraintsx(void){ /*{{{*/
     2128
     2129        IssmDouble time;
     2130        int        analysis_type;
     2131
     2132        /*retrieve parameters: */
     2133        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     2134        parameters->FindParam(&time,TimeEnum);
     2135
     2136        /*start module: */
     2137        if(VerboseModule()) _printf0_("   Updating constraints and active domain of analysis " << EnumToStringx(analysis_type)  << " for time: " << time << "\n");
     2138
     2139        Analysis* analysis= EnumToAnalysis(analysis_type);
     2140        analysis->UpdateConstraints(this);
     2141        delete analysis;
     2142       
     2143        /*Second, constraints might be time dependent: */
     2144        SpcNodesx(nodes,constraints,parameters,analysis_type);
     2145
     2146        /*Now, update degrees of freedoms: */
     2147        NodesDofx(nodes,parameters,analysis_type);
     2148
     2149}
     2150/*}}}*/
     2151int  FemModel::UpdateVertexPositionsx(void){ /*{{{*/
     2152
     2153        IssmDouble         *surface = NULL;
     2154        IssmDouble         *bed     = NULL;
     2155                       
     2156        if(VerboseSolution()) _printf0_("   updating vertices positions\n");
     2157
     2158        /*get vertex vectors for bed and thickness: */
     2159        GetVectorFromInputsx(&surface  ,this, SurfaceEnum,VertexPIdEnum);
     2160        GetVectorFromInputsx(&bed      ,this, BaseEnum,   VertexPIdEnum);
     2161
     2162        /*Allocate vector*/
     2163        Vector<IssmDouble> *vx=new Vector<IssmDouble>(vertices->NumberOfVertices());
     2164        Vector<IssmDouble> *vy=new Vector<IssmDouble>(vertices->NumberOfVertices());
     2165        Vector<IssmDouble> *vz=new Vector<IssmDouble>(vertices->NumberOfVertices());
     2166
     2167        /*Update verices new geometry: */
     2168        for(int i=0;i<vertices->Size();i++){
     2169                Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i);
     2170                vertex->UpdatePosition(vx,vy,vz,parameters,surface,bed);
     2171        }
     2172
     2173        /*Assemble mesh velocity*/
     2174        vx->Assemble();
     2175        vy->Assemble();
     2176        vz->Assemble();
     2177
     2178        /*Update element inputs*/
     2179        InputUpdateFromVectorx(this,vx,VxMeshEnum,VertexPIdEnum);
     2180        InputUpdateFromVectorx(this,vy,VyMeshEnum,VertexPIdEnum);
     2181        InputUpdateFromVectorx(this,vz,VzMeshEnum,VertexPIdEnum);
     2182
     2183        /*Free ressources:*/
     2184        delete vx;
     2185        delete vy;
     2186        delete vz;
     2187        xDelete<IssmDouble>(bed);
     2188        xDelete<IssmDouble>(surface);
     2189        return 1;
    21902190}
    21912191/*}}}*/
     
    26082608}
    26092609/*}}}*/
    2610 void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
    2611 
    2612         /*intermediary*/
    2613         int         i;
    2614         int         analysis_type;
    2615         FILE       *IOMODEL = NULL;
    2616         FILE       *toolkitsoptionsfid = NULL;
    2617         FILE       *output_fid = NULL;
    2618         int         my_rank;
    2619         size_t      outputsize;
    2620         char       *outputbuffer;
    2621         const char* rootpath=""; //needed for Dakota runs only, which we won't do here.
    2622 
    2623         /*recover my_rank:*/
    2624         my_rank=IssmComm::GetRank();
    2625 
    2626         /*Initialize internal data: */
    2627         this->solution_type    = in_solution_type;
    2628         this->analysis_counter = nummodels-1;   //point to last analysis_type carried out.
    2629         this->results          = new Results(); //not initialized by CreateDataSets
    2630        
    2631         /*Open input file on cpu 0 and create IoModel */
    2632         if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb");
    2633         IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);
    2634 
    2635         /*Figure out what analyses are activated for this solution*/
    2636         SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type);
    2637 
    2638         /*Open toolkits file: */
    2639         toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r");
    2640 
    2641         /*create datasets for all analyses*/
    2642         ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,(char*)rootpath,this->solution_type,this->nummodels,this->analysis_type_list);
    2643 
    2644         /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
    2645         for(i=0;i<nummodels;i++){
    2646 
    2647                 if(VerboseMProcessor()) _printf0_("   Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n");
    2648                 analysis_type=analysis_type_list[i];
    2649                 this->SetCurrentConfiguration(analysis_type);
    2650 
    2651                 if(i==0){
    2652                         if(VerboseMProcessor()) _printf0_("      creating vertex PIDs\n");
    2653                         VerticesDofx(vertices,parameters); //only call once, we only have one set of vertices
    2654                 }
    2655 
    2656                 if(VerboseMProcessor()) _printf0_("      resolving node constraints\n");
    2657                 SpcNodesx(nodes,constraints,parameters,analysis_type);
    2658 
    2659                 if(VerboseMProcessor()) _printf0_("      creating nodal degrees of freedom\n");
    2660                 NodesDofx(nodes,parameters,analysis_type);
    2661 
    2662                 if(VerboseMProcessor()) _printf0_("      configuring element and loads\n");
    2663                 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters);
    2664         }
    2665 
    2666         /*Close input file and toolkits file descriptors: */
    2667         if(my_rank==0) fclose(IOMODEL);
    2668         fclose(toolkitsoptionsfid);
    2669 
    2670         /*Open output file once for all and add output file descriptor to parameters*/
    2671         output_fid=open_memstream(&outputbuffer,&outputsize);
    2672         if(output_fid==NULL)_error_("could not initialize output stream");
    2673         this->parameters->SetParam(output_fid,OutputFilePointerEnum);
    2674         this->parameters->AddObject(new GenericParam<char**>(&outputbuffer,OutputBufferPointerEnum));
    2675         this->parameters->AddObject(new GenericParam<size_t*>(&outputsize,OutputBufferSizePointerEnum));
    2676 
    2677         /*Clean up*/
    2678         delete iomodel;
    2679 }/*}}}*/
    26802610void FemModel::CleanUpJs(char** poutput, size_t* psize){/*{{{*/
    26812611
     
    27172647}
    27182648/*}}}*/
     2649void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
     2650
     2651        /*intermediary*/
     2652        int         i;
     2653        int         analysis_type;
     2654        FILE       *IOMODEL = NULL;
     2655        FILE       *toolkitsoptionsfid = NULL;
     2656        FILE       *output_fid = NULL;
     2657        int         my_rank;
     2658        size_t      outputsize;
     2659        char       *outputbuffer;
     2660        const char* rootpath=""; //needed for Dakota runs only, which we won't do here.
     2661
     2662        /*recover my_rank:*/
     2663        my_rank=IssmComm::GetRank();
     2664
     2665        /*Initialize internal data: */
     2666        this->solution_type    = in_solution_type;
     2667        this->analysis_counter = nummodels-1;   //point to last analysis_type carried out.
     2668        this->results          = new Results(); //not initialized by CreateDataSets
     2669       
     2670        /*Open input file on cpu 0 and create IoModel */
     2671        if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb");
     2672        IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);
     2673
     2674        /*Figure out what analyses are activated for this solution*/
     2675        SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type);
     2676
     2677        /*Open toolkits file: */
     2678        toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r");
     2679
     2680        /*create datasets for all analyses*/
     2681        ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,(char*)rootpath,this->solution_type,this->nummodels,this->analysis_type_list);
     2682
     2683        /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
     2684        for(i=0;i<nummodels;i++){
     2685
     2686                if(VerboseMProcessor()) _printf0_("   Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n");
     2687                analysis_type=analysis_type_list[i];
     2688                this->SetCurrentConfiguration(analysis_type);
     2689
     2690                if(i==0){
     2691                        if(VerboseMProcessor()) _printf0_("      creating vertex PIDs\n");
     2692                        VerticesDofx(vertices,parameters); //only call once, we only have one set of vertices
     2693                }
     2694
     2695                if(VerboseMProcessor()) _printf0_("      resolving node constraints\n");
     2696                SpcNodesx(nodes,constraints,parameters,analysis_type);
     2697
     2698                if(VerboseMProcessor()) _printf0_("      creating nodal degrees of freedom\n");
     2699                NodesDofx(nodes,parameters,analysis_type);
     2700
     2701                if(VerboseMProcessor()) _printf0_("      configuring element and loads\n");
     2702                ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters);
     2703        }
     2704
     2705        /*Close input file and toolkits file descriptors: */
     2706        if(my_rank==0) fclose(IOMODEL);
     2707        fclose(toolkitsoptionsfid);
     2708
     2709        /*Open output file once for all and add output file descriptor to parameters*/
     2710        output_fid=open_memstream(&outputbuffer,&outputsize);
     2711        if(output_fid==NULL)_error_("could not initialize output stream");
     2712        this->parameters->SetParam(output_fid,OutputFilePointerEnum);
     2713        this->parameters->AddObject(new GenericParam<char**>(&outputbuffer,OutputBufferPointerEnum));
     2714        this->parameters->AddObject(new GenericParam<size_t*>(&outputsize,OutputBufferSizePointerEnum));
     2715
     2716        /*Clean up*/
     2717        delete iomodel;
     2718}/*}}}*/
    27192719#endif
  • issm/trunk-jpl/src/c/classes/FemModel.h

    r20723 r20810  
    2828        public:
    2929
     30                int          analysis_counter;     //counter into analysis_type_list
     31                int         *analysis_type_list;   //list of analyses this femmodel is going to carry out
    3032                int          nummodels;
    3133                int          solution_type;
    32                 int         *analysis_type_list;   //list of analyses this femmodel is going to carry out
    33                 int          analysis_counter;     //counter into analysis_type_list
    3434
    3535                Profiler*    profiler;             //keep time, cpu and mem statistics while we are running.
    3636
     37                Constraints *constraints;          //one set of constraints. each constraint knows which analysis_type it handles
    3738                Elements    *elements;             //elements (one set for all analyses)
    38                 Nodes       *nodes;                //one set of nodes
    39                 Vertices    *vertices;             //one set of vertices
    40                 Constraints *constraints;          //one set of constraints. each constraint knows which analysis_type it handles
    4139                Loads       *loads;                //one set of constraints. each constraint knows which analysis_type it handles
    4240                Materials   *materials;            //one set of materials, for each element
     41                Nodes       *nodes;                //one set of nodes
    4342                Parameters  *parameters;           //one set of parameters, independent of the analysis_type
    4443                Results     *results;              //results that cannot be fit into the elements
     44                Vertices    *vertices;             //one set of vertices
    4545
    4646                /*constructors, destructors: */
     
    5050
    5151                /*Methods:*/
     52                void CheckPoint(void);
     53                void CleanUp(void);
     54                FemModel* copy();
    5255                void Echo();
    53                 FemModel* copy();
    5456                void InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* petscfilename, char* lockfilename, char* restartfilename, const int solution_type,bool trace,IssmPDouble* X=NULL);
    55                 void SolutionAnalysesList(int** panalyses,int* pnumanalyses,IoModel* iomodel,int solutiontype);
    56                 void CleanUp(void);
    57                 void Solve(void);
     57                void Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction);
     58                void Restart(void);
    5859                void SetCurrentConfiguration(int configuration_type);
    5960                void SetCurrentConfiguration(int configuration_type,int analysis_type);
    60                 void CheckPoint(void);
    61                 void Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction);
    62                 void Restart(void);
     61                void SolutionAnalysesList(int** panalyses,int* pnumanalyses,IoModel* iomodel,int solutiontype);
     62                void Solve(void);
    6363
    6464                /*Modules*/
     65                void BalancethicknessMisfitx(IssmDouble* pV);
     66                void CalvingRateDevx();
     67                void CalvingRateLevermannx();
     68                void DeviatoricStressx();
     69                void Divergencex(IssmDouble* pdiv);
    6570                void ElementOperationx(void (Element::*function)(void));
     71                void ElementResponsex(IssmDouble* presponse,int response_enum);
     72                void FloatingAreax(IssmDouble* pV);
    6673                void GetInputLocalMinMaxOnNodesx(IssmDouble** pmin,IssmDouble** pmax,IssmDouble* ug);
     74                void GroundedAreax(IssmDouble* pV);
     75                void IceMassx(IssmDouble* pV);
     76                void IceVolumex(IssmDouble* pV);
     77                void IceVolumeAboveFloatationx(IssmDouble* pV);
    6778                void MassFluxx(IssmDouble* presponse);
    6879                void MaxAbsVxx(IssmDouble* presponse);
    6980                void MaxAbsVyx(IssmDouble* presponse);
    7081                void MaxAbsVzx(IssmDouble* presponse);
     82                void MaxDivergencex(IssmDouble* pdiv);
    7183                void MaxVelx(IssmDouble* presponse);
    7284                void MaxVxx(IssmDouble* presponse);
     
    7789                void MinVyx(IssmDouble* presponse);
    7890                void MinVzx(IssmDouble* presponse);
     91                void ResetLevelset();
     92                void StrainRateparallelx();
     93                void StrainRateperpendicularx();
     94                void StressIntensityFactorx();
    7995                void TotalFloatingBmbx(IssmDouble* pFbmb);
    8096                void TotalGroundedBmbx(IssmDouble* pGbmb);
    8197                void TotalSmbx(IssmDouble* pSmb);
    82                 void Divergencex(IssmDouble* pdiv);
    83                 void MaxDivergencex(IssmDouble* pdiv);
    84                 void FloatingAreax(IssmDouble* pV);
    85                 void GroundedAreax(IssmDouble* pV);
    86                 void IceMassx(IssmDouble* pV);
    87                 void IceVolumex(IssmDouble* pV);
    88                 void IceVolumeAboveFloatationx(IssmDouble* pV);
    89                 void ElementResponsex(IssmDouble* presponse,int response_enum);
    90                 void BalancethicknessMisfitx(IssmDouble* pV);
    91                 void StressIntensityFactorx();
    92                 void StrainRateparallelx();
    93                 void StrainRateperpendicularx();
    94                 void DeviatoricStressx();
    95                 void CalvingRateLevermannx();
    96                 void CalvingRateDevx();
    97                 void ResetLevelset();
    9898                #ifdef  _HAVE_DAKOTA_
    9999                void DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses);
    100100                #endif
     101                void CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn);
     102                void OutputControlsx(Results **presults);
     103                void RequestedDependentsx(void);
    101104                void RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs,bool save_results=true);
    102105                void RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results=true);
    103                 void RequestedDependentsx(void);
    104106                void Responsex(IssmDouble* presponse,int response_descriptor_enum);
    105107                void Responsex(IssmDouble* presponse,const char* response_descriptor);
    106                 void OutputControlsx(Results **presults);
    107                 void CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn);
     108                void SurfaceAbsMisfitx( IssmDouble* pJ);
    108109                void ThicknessAbsGradientx( IssmDouble* pJ);
    109110                void ThicknessPositivex(IssmDouble* pJ);
    110                 void SurfaceAbsMisfitx( IssmDouble* pJ);
    111111                #ifdef _HAVE_GIA_
    112112                void Deflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y);
     
    117117                IssmDouble SealevelriseOceanAverage(Vector<IssmDouble>* Sg);
    118118                #endif
     119                void HydrologyEPLupdateDomainx(IssmDouble* pEplcount);
    119120                void TimeAdaptx(IssmDouble* pdt);
     121                void UpdateConstraintsExtrudeFromBasex();
     122                void UpdateConstraintsExtrudeFromTopx();
     123                void UpdateConstraintsL2ProjectionEPLx(IssmDouble* pL2count);
    120124                void UpdateConstraintsx(void);
    121125                int  UpdateVertexPositionsx(void);
    122                 void UpdateConstraintsExtrudeFromBasex();
    123                 void UpdateConstraintsExtrudeFromTopx();
    124                 void HydrologyEPLupdateDomainx(IssmDouble* pEplcount);
    125                 void UpdateConstraintsL2ProjectionEPLx(IssmDouble* pL2count);
    126126
    127127                #ifdef _HAVE_JAVASCRIPT_
    128128                FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace=false);
     129                void CleanUpJs(char** poutput, size_t* psize);
    129130                void InitFromBuffers(char* buffer, int buffersize, char* toolkits, int solution_type,bool trace,IssmPDouble* X=NULL);
    130                 void CleanUpJs(char** poutput, size_t* psize);
    131131                #endif
    132132};
  • issm/trunk-jpl/src/c/classes/GiaDeflectionCoreArgs.h

    r15141 r20810  
    99
    1010        /*inputs: */
     11        IssmDouble currenttime;
     12        IssmDouble* hes; //loading history (in ice thickness)
     13        int numtimes; //loading history length
    1114        IssmDouble ri; //radial distance from center of disk to vertex  i
    1215        IssmDouble re; //radius of disk
    13         IssmDouble* hes; //loading history (in ice thickness)
    1416        IssmDouble* times; //loading history times
    15         int numtimes; //loading history length
    16         IssmDouble currenttime;
    1717
    1818        /*gia material parameters: */
     19        IssmDouble lithosphere_density;
    1920        IssmDouble lithosphere_shear_modulus;
    20         IssmDouble lithosphere_density;
     21        IssmDouble lithosphere_thickness;
     22        IssmDouble mantle_density;
    2123        IssmDouble mantle_shear_modulus;
    2224        IssmDouble mantle_viscosity;
    23         IssmDouble mantle_density;
    24         IssmDouble lithosphere_thickness;
    2525
    2626        /*gia solution parameters: */
  • issm/trunk-jpl/src/c/classes/Hook.cpp

    r19254 r20810  
    5959
    6060/*Some of the Object functionality: */
    61 void Hook::Echo(void){/*{{{*/
    62         _assert_(this);
    63         int i;
    64         if (num){
    65                 _printf_("   Hook: \n");
    66                 _printf_("      num=" << this->num << "\n");
    67                 _printf_("      ids: ");
    68                 for(i=0;i<this->num;i++) _printf_(this->ids[i] << " ");
    69                 _printf_("\n");
    70                 _printf_("      offsets: ");
    71                 for (i=0;i<this->num;i++) _printf_(this->offsets[i] << " ");
    72                 _printf_("\n");
    73         }
    74         else{
    75                 _printf_("   Hook: num=0 \n");
    76         }
     61Object* Hook::copy(void){/*{{{*/
     62
     63        /*output: */
     64        Hook* output=NULL;
     65
     66        /*initalize output: */
     67        output=new Hook(this->ids,this->num);
     68
     69        for(int i=0;i<output->num;i++){
     70                output->objects[i] = this->objects[i];
     71                output->offsets[i] = this->offsets[i];
     72        }
     73
     74        return (Object*)output;
    7775}
    7876/*}}}*/
     
    104102}
    105103/*}}}*/
    106 Object* Hook::copy(void){/*{{{*/
    107 
    108         /*output: */
    109         Hook* output=NULL;
    110 
    111         /*initalize output: */
    112         output=new Hook(this->ids,this->num);
    113 
    114         for(int i=0;i<output->num;i++){
    115                 output->objects[i] = this->objects[i];
    116                 output->offsets[i] = this->offsets[i];
    117         }
    118 
    119         return (Object*)output;
     104void Hook::Echo(void){/*{{{*/
     105        _assert_(this);
     106        int i;
     107        if (num){
     108                _printf_("   Hook: \n");
     109                _printf_("      num=" << this->num << "\n");
     110                _printf_("      ids: ");
     111                for(i=0;i<this->num;i++) _printf_(this->ids[i] << " ");
     112                _printf_("\n");
     113                _printf_("      offsets: ");
     114                for (i=0;i<this->num;i++) _printf_(this->offsets[i] << " ");
     115                _printf_("\n");
     116        }
     117        else{
     118                _printf_("   Hook: num=0 \n");
     119        }
    120120}
    121121/*}}}*/
     
    143143
    144144/*Hook management: */
    145 void Hook::reset(){/*{{{*/
    146 
    147         /*intermediary: */
    148         Object* object=NULL;
    149         int i;
    150 
    151         for(i=0;i<this->num;i++){
    152                         this->objects[i]=NULL; //reset this node.
    153         }
    154 }
    155 /*}}}*/
    156145void Hook::configure(DataSet* dataset){/*{{{*/
    157146
     
    196185}
    197186/*}}}*/
     187Object** Hook::deliverp(void){/*{{{*/
     188        return objects;
     189}
     190/*}}}*/
    198191Object* Hook::delivers(void){/*{{{*/
    199192
     
    208201
    209202/*}}}*/
    210 Object** Hook::deliverp(void){/*{{{*/
    211         return objects;
     203int Hook::GetNum(void){/*{{{*/
     204        return this->num;
    212205}
    213206/*}}}*/
     
    216209}
    217210/*}}}*/
    218 int Hook::GetNum(void){/*{{{*/
    219         return this->num;
     211void Hook::reset(){/*{{{*/
     212
     213        /*intermediary: */
     214        Object* object=NULL;
     215        int i;
     216
     217        for(i=0;i<this->num;i++){
     218                        this->objects[i]=NULL; //reset this node.
     219        }
    220220}
    221221/*}}}*/
  • issm/trunk-jpl/src/c/classes/Hook.h

    r19215 r20810  
    1818        private:
    1919
     20                int     *ids;       //list of object ids, to go look for them in datasets.
    2021                int      num;       //number of objects being hooked onto
    2122                Object **objects;   //list of object pointers
    22                 int     *ids;       //list of object ids, to go look for them in datasets.
    2323                int     *offsets;   //list of object offsets into datasets, to speed up lookup.
    2424
     
    3131                /*}}}*/
    3232                /*Object like functionality:{{{*/
     33                Object*    copy(void);
     34                void       DeepEcho(void);
    3335                void       Echo(void);
    34                 void       DeepEcho(void);
    35                 Object*    copy(void);
    3636                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3737                /*}}}*/
    3838                /*Hook management: {{{*/
     39                void       configure(DataSet* dataset);
     40                Object**   deliverp(void); //deliver all objects
    3941                Object*    delivers(void); //single object deliver
    40                 Object**   deliverp(void); //deliver all objects
    41                 void       configure(DataSet* dataset);
     42                int        GetNum(void);
     43                int*       Ids(void);
    4244                void       reset(void);
    4345                Hook*      Spawn(int* indices, int numindices);
    44                 int*       Ids(void);
    45                 int        GetNum(void);
    4646                /*}}}*/
    4747};
  • issm/trunk-jpl/src/c/classes/Inputs/BoolInput.cpp

    r19254 r20810  
    2929
    3030/*Object virtual functions definitions:*/
    31 void BoolInput::Echo(void){/*{{{*/
    32         this->DeepEcho();
     31Object* BoolInput::copy() {/*{{{*/
     32
     33        return new BoolInput(this->enum_type,this->value);
     34
    3335}
    3436/*}}}*/
     
    3840}
    3941/*}}}*/
    40 int  BoolInput::Id(void){ return -1; }/*{{{*/
    41 /*}}}*/
    42 int  BoolInput::ObjectEnum(void){/*{{{*/
    43 
    44         return BoolInputEnum;
    45 
     42void BoolInput::Echo(void){/*{{{*/
     43        this->DeepEcho();
    4644}
    4745/*}}}*/
    48 Object* BoolInput::copy() {/*{{{*/
    49 
    50         return new BoolInput(this->enum_type,this->value);
    51 
    52 }
     46int  BoolInput::Id(void){ return -1; }/*{{{*/
    5347/*}}}*/
    5448void BoolInput::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
     
    6155}
    6256/*}}}*/
     57int  BoolInput::ObjectEnum(void){/*{{{*/
     58
     59        return BoolInputEnum;
     60
     61}
     62/*}}}*/
    6363
    6464/*BoolInput management*/
     
    6666
    6767        return this->enum_type;
     68
     69}
     70/*}}}*/
     71Input* BoolInput::SpawnSegInput(int index1,int index2){/*{{{*/
     72
     73                /*output*/
     74                BoolInput* outinput=new BoolInput();
     75
     76                /*only copy current value*/
     77                outinput->enum_type=this->enum_type;
     78                outinput->value=this->value;
     79
     80                /*Assign output*/
     81                return outinput;
    6882
    6983}
     
    8397}
    8498/*}}}*/
    85 Input* BoolInput::SpawnSegInput(int index1,int index2){/*{{{*/
    86 
    87                 /*output*/
    88                 BoolInput* outinput=new BoolInput();
    89 
    90                 /*only copy current value*/
    91                 outinput->enum_type=this->enum_type;
    92                 outinput->value=this->value;
    93 
    94                 /*Assign output*/
    95                 return outinput;
    96 
    97 }
    98 /*}}}*/
    9999
    100100/*Object functions*/
    101 void BoolInput::GetInputValue(bool* pvalue){/*{{{*/
    102         *pvalue=value;
    103 }
    104 /*}}}*/
    105 void BoolInput::GetInputValue(int* pvalue){_error_("not supported yet!");}/*{{{*/
    106 /*}}}*/
    107 void BoolInput::GetInputValue(IssmDouble* pvalue){_error_("not supported yet!");}/*{{{*/
    108 /*}}}*/
    109 void BoolInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not supported yet!");}/*{{{*/
    110 /*}}}*/
    111 void BoolInput::ChangeEnum(int newenumtype){/*{{{*/
    112         this->enum_type=newenumtype;
    113 }
    114 /*}}}*/
    115 void BoolInput::SquareMin(IssmDouble* psquaremin,Parameters* parameters){/*{{{*/
    116         /*square of a bool is the bool itself: */
    117         *psquaremin=value;
    118 }
    119 /*}}}*/
    120 void BoolInput::Scale(IssmDouble scale_factor){/*{{{*/
    121         /*a bool cannot be scaled: */
    122 }
    123 /*}}}*/
    124101void BoolInput::AXPY(Input* xinput,IssmDouble scalar){/*{{{*/
    125102
     
    142119}
    143120/*}}}*/
     121void BoolInput::ChangeEnum(int newenumtype){/*{{{*/
     122        this->enum_type=newenumtype;
     123}
     124/*}}}*/
     125void BoolInput::Configure(Parameters* parameters){/*{{{*/
     126        /*do nothing: */
     127}
     128/*}}}*/
    144129void BoolInput::Extrude(int start){/*{{{*/
    145130
     
    147132        return;
    148133}
     134/*}}}*/
     135void BoolInput::GetInputValue(bool* pvalue){/*{{{*/
     136        *pvalue=value;
     137}
     138/*}}}*/
     139void BoolInput::GetInputValue(int* pvalue){_error_("not supported yet!");}/*{{{*/
     140/*}}}*/
     141void BoolInput::GetInputValue(IssmDouble* pvalue){_error_("not supported yet!");}/*{{{*/
     142/*}}}*/
     143void BoolInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not supported yet!");}/*{{{*/
    149144/*}}}*/
    150145void BoolInput::GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist){/*{{{*/
     
    154149}
    155150/*}}}*/
    156 void BoolInput::Configure(Parameters* parameters){/*{{{*/
    157         /*do nothing: */
     151void BoolInput::Scale(IssmDouble scale_factor){/*{{{*/
     152        /*a bool cannot be scaled: */
    158153}
    159154/*}}}*/
     155void BoolInput::SquareMin(IssmDouble* psquaremin,Parameters* parameters){/*{{{*/
     156        /*square of a bool is the bool itself: */
     157        *psquaremin=value;
     158}
     159/*}}}*/
  • issm/trunk-jpl/src/c/classes/Inputs/BoolInput.h

    r19725 r20810  
    2222                /*}}}*/
    2323                /*Object virtual functions definitions:{{{ */
     24                Object *copy();
     25                void    DeepEcho();
    2426                void    Echo();
    25                 void    DeepEcho();
    2627                int     Id();
     28                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    2729                int     ObjectEnum();
    28                 Object *copy();
    29                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    3030                /*}}}*/
    3131                /*BoolInput management: {{{*/
     32                void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
     33                void Configure(Parameters* parameters);
     34                int  GetResultArraySize(void){return 1;};
     35                int  GetResultInterpolation(void){return P0Enum;};
     36                int  GetResultNumberOfNodes(void){return 1;};
    3237                int   InstanceEnum();
    33                 Input* SpawnTriaInput(int index1,int index2,int index3);
    34                 Input* SpawnSegInput(int index1,int index2);
    3538                Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");};
    3639                Input* PointwiseMin(Input* inputB){_error_("not implemented yet");};
    3740                Input* PointwiseMax(Input* inputB){_error_("not implemented yet");};
    38                 int  GetResultInterpolation(void){return P0Enum;};
    39                 int  GetResultNumberOfNodes(void){return 1;};
    40                 int  GetResultArraySize(void){return 1;};
     41                Input* SpawnSegInput(int index1,int index2);
     42                Input* SpawnTriaInput(int index1,int index2,int index3);
    4143                void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");};
    42                 void Configure(Parameters* parameters);
    43                 void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};
    4444                /*}}}*/
    4545                /*numerics: {{{*/
     46                void AXPY(Input* xinput,IssmDouble scalar);
     47                void ChangeEnum(int newenumtype);
     48                void Constrain(IssmDouble cm_min, IssmDouble cm_max){_error_("Constrain not implemented for booleans");};
     49                void ConstrainMin(IssmDouble minimum){_error_("not implemented yet");};
     50                void Extrude(int start);
     51                void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
     52                void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");};
     53                void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){_error_("not implemented yet");};
     54                void GetInputDerivativeAverageValue(IssmDouble* derivativevalues, IssmDouble* xyz_list){_error_("not implemented yet");};
     55                void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
    4656                void GetInputValue(bool* pvalue);
    4757                void GetInputValue(int* pvalue);
     
    5060                void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");};
    5161                void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");};
    52                 void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){_error_("not implemented yet");};
    53                 void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");};
    54                 void GetInputDerivativeAverageValue(IssmDouble* derivativevalues, IssmDouble* xyz_list){_error_("not implemented yet");};
    55                 void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");};
    56                 void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");};
    57                 void ChangeEnum(int newenumtype);
    58                 void SquareMin(IssmDouble* psquaremin, Parameters* parameters);
    59                 void ConstrainMin(IssmDouble minimum){_error_("not implemented yet");};
     62                void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist);
    6063                IssmDouble InfinityNorm(void){_error_("InfinityNorm not implemented for booleans");};
    6164                IssmDouble Max(void){_error_("Max not implemented for booleans");};
     
    6568                void Set(IssmDouble setvalue){_error_("Set not implemented yet");};
    6669                void Scale(IssmDouble scale_factor);
    67                 void AXPY(Input* xinput,IssmDouble scalar);
    68                 void Constrain(IssmDouble cm_min, IssmDouble cm_max){_error_("Constrain not implemented for booleans");};
    69                 void Extrude(int start);
     70                void SquareMin(IssmDouble* psquaremin, Parameters* parameters);
    7071                void VerticallyIntegrate(Input* thickness_input){_error_("not supported yet");};
    71                 void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist);
    7272                /*}}}*/
    7373
  • issm/trunk-jpl/src/c/classes/IoModel.cpp

    r20690 r20810  
    377377}
    378378/*}}}*/
    379 void  IoModel::FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* constant_name){/*{{{*/
    380 
    381         /*recover my_rank:*/
    382         int my_rank=IssmComm::GetRank();
    383 
    384         /*recover Xcount if X is not NULL:*/
    385         int Xcount = 0;
    386         if(X) Xcount=*pXcount;
    387 
    388         #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
    389 
    390         /*output: */
    391         IssmPDouble  pscalar;
    392         IssmDouble   scalar; //same as pscalar, except it's an ADOLC independent variable
    393         int          code;
    394 
    395         /*Set file pointer to beginning of the data: */
    396         fid=this->SetFilePointerToData(&code,NULL,constant_name);
    397         if(code!=3) _error_("expecting a IssmDouble for \"" << constant_name<<"\"");
    398 
    399         /*We have to read a scalar from disk. First read the dimensions of the scalar, then the scalar: */
    400         if(my_rank==0){
    401                 if(fread(&pscalar,sizeof(IssmPDouble),1,fid)!=1)_error_("could not read scalar ");
    402 
    403                 /*Now, before we even broadcast this to other nodes, declare the scalar  as an independent variable!. If we
    404                  *have been supplied an X vector, use it instead of what we just read: */
    405                 if(X){
    406                         scalar<<=X[Xcount];
    407                 }
    408                 else{
    409                         scalar<<=pscalar;
    410                 }
    411         }
    412 
    413         ISSM_MPI_Bcast(&scalar,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    414         this->AddConstantIndependent(new IoConstant(scalar,constant_name));
    415 
    416         /*increment offset into X vector, now that we have read 1 value:*/
    417         Xcount++; *pXcount=Xcount;
    418         #endif
    419 }
    420 /*}}}*/
    421 void  IoModel::FetchIndependentData(int* pXcount,IssmPDouble* X,const char* data_name){/*{{{*/
    422 
    423         /*recover my_rank:*/
    424         int my_rank=IssmComm::GetRank();
    425 
    426         /*recover Xcount if X is not NULL:*/
    427         int Xcount = 0;
    428         if(X) Xcount=*pXcount;
    429 
    430         #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
    431 
    432         /*Intermediaries*/
    433         int M,N;
    434         IssmPDouble* buffer=NULL; //a buffer to read the data from disk
    435         IssmDouble* matrix=NULL; //our independent variable
    436         int code,layout;
    437 
    438         /*Set file pointer to beginning of the data: */
    439         fid=this->SetFilePointerToData(&code,&layout,data_name);
    440         if((code!=5) && (code!=6) && (code!=7))_error_("expecting a IssmDouble, integer or boolean matrix for \"" << data_name<<"\"");
    441 
    442         /*We have to read a matrix from disk. First read the dimensions of the matrix, then the whole matrix: */
    443         /*numberofelements: */
    444         if(my_rank==0){ 
    445                 if(fread(&M,sizeof(int),1,fid)!=1) _error_("could not read number of rows for matrix ");
    446         }
    447         ISSM_MPI_Bcast(&M,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    448 
    449         if(my_rank==0){ 
    450                 if(fread(&N,sizeof(int),1,fid)!=1) _error_("could not read number of columns for matrix ");
    451         }
    452         ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    453 
    454         /*Now allocate matrix: */
    455         if(M*N){
    456                 buffer=xNew<IssmPDouble>(M*N);
    457                 matrix=xNew<IssmDouble>(M*N);
    458 
    459                 /*Read matrix on node 0, then broadcast: */
    460                 if(my_rank==0){ 
    461                         if(fread(buffer,M*N*sizeof(IssmPDouble),1,fid)!=1) _error_("could not read matrix ");
    462 
    463                         /*Now, before we even broadcast this to other nodes, declare the whole matrix as a independent variable!
    464                           If we have been supplied an X vector, use it instead of what we just read: */
    465                         if(X){
    466                                 for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i];  /*<<= ADOLC overloaded operator to declare independent*/
    467                         }
    468                         else{
    469                                 for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i];
    470                         }
    471                 }
    472                 ISSM_MPI_Bcast(matrix,M*N,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
    473 
    474                 xDelete<IssmPDouble>(buffer);
    475         }
    476         else _error_("cannot declare the independent variable \"" << data_name <<  "\" if it's empty!");
    477 
    478         /*Add to data as independent*/
    479         this->AddDataIndependent(new IoData(matrix,code,layout,M,N,data_name));
    480 
    481         /*increment offset into X vector, now that we have read M*N values:*/
    482         Xcount+=M*N; *pXcount=Xcount;
    483         #endif
    484 }
    485 /*}}}*/
    486 void  IoModel::FindConstant(bool* pvalue,const char* constant_name){/*{{{*/
    487 
    488         /*Intermediary*/
    489         vector<IoConstant*>::iterator iter;
    490 
    491         for(iter=constants.begin();iter<constants.end();iter++){
    492                 IoConstant* ioconstant=*iter;
    493 
    494                 if(strcmp(ioconstant->name,constant_name)==0){
    495                         ioconstant->constant->GetParameterValue(pvalue);
    496                         return;
    497                 }
    498         }
    499 
    500         for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++) (*iter)->constant->Echo();
    501         _error_("Could not find constant \""<<constant_name<<"\"");
    502 }
    503 /*}}}*/
    504 void  IoModel::FindConstant(int* pvalue,const char* constant_name){/*{{{*/
    505 
    506         /*Intermediary*/
    507         vector<IoConstant*>::iterator iter;
    508 
    509         for(iter=constants.begin();iter<constants.end();iter++){
    510                 IoConstant* ioconstant=*iter;
    511 
    512                 if(strcmp(ioconstant->name,constant_name)==0){
    513                         ioconstant->constant->GetParameterValue(pvalue);
    514                         return;
    515                 }
    516         }
    517 
    518         _error_("Could not find constant \""<<constant_name <<"\"");
    519 }
    520 /*}}}*/
    521 void  IoModel::FindConstant(IssmDouble* pvalue,const char* constant_name){/*{{{*/
    522 
    523         /*Intermediary*/
    524         vector<IoConstant*>::iterator iter;
    525 
    526         for(iter=constants.begin();iter<constants.end();iter++){
    527                 IoConstant* ioconstant=*iter;
    528 
    529                 if(strcmp(ioconstant->name,constant_name)==0){
    530                         ioconstant->constant->GetParameterValue(pvalue);
    531                         return;
    532                 }
    533         }
    534 
    535         _error_("Could not find constant \""<<constant_name <<"\"");
    536 }
    537 /*}}}*/
    538 void  IoModel::FindConstant(char** pvalue,const char* constant_name){/*{{{*/
    539 
    540         /*Intermediary*/
    541         vector<IoConstant*>::iterator iter;
    542 
    543         for(iter=constants.begin();iter<constants.end();iter++){
    544                 IoConstant* ioconstant=*iter;
    545 
    546                 if(strcmp(ioconstant->name,constant_name)==0){
    547                         ioconstant->constant->GetParameterValue(pvalue);
    548                         return;
    549                 }
    550         }
    551 
    552         _error_("Could not find constant \""<<constant_name <<"\"");
    553 }
    554 /*}}}*/
    555 void  IoModel::FindConstant(char*** pvalue,int* psize,const char* constant_name){/*{{{*/
    556 
    557         /*Intermediary*/
    558         vector<IoConstant*>::iterator iter;
    559 
    560         for(iter=constants.begin();iter<constants.end();iter++){
    561                 IoConstant* ioconstant=*iter;
    562 
    563                 if(strcmp(ioconstant->name,constant_name)==0){
    564                         ioconstant->constant->GetParameterValue(pvalue,psize);
    565                         return;
    566                 }
    567         }
    568 
    569         _error_("Could not find constant \""<<constant_name <<"\"");
    570 }
    571 /*}}}*/
    572 int   IoModel::NumIndependents(void){/*{{{*/
    573 
    574         /*Initialize output*/
    575         int num_independents = 0;
    576 
    577         /*Process constants*/
    578         for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){
    579                 if((*iter)->isindependent){
    580                         num_independents+= 1;
    581                 }
    582         }
    583 
    584         /*Process data*/
    585         for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){
    586                 if((*iter)->isindependent){
    587                         num_independents+= (*iter)->M*(*iter)->N;
    588                 }
    589         }
    590 
    591         /*return*/
    592         return num_independents;
    593 }
    594 /*}}}*/
    595 void  IoModel::FillIndependents(IssmDouble* xp){/*{{{*/
    596 
    597         _assert_(xp);
    598 
    599         /*Initialize local num ind*/
    600         int local_num_ind = 0;
    601 
    602         /*Process constants*/
    603         for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){
    604                 if((*iter)->isindependent){
    605                         (*iter)->constant->GetParameterValue(&xp[local_num_ind]);
    606                         local_num_ind += 1;
    607                 }
    608         }
    609 
    610         /*Process data*/
    611         for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){
    612                 if((*iter)->isindependent){
    613                         for(int i=0;i<(*iter)->M*(*iter)->N;i++){
    614                                 xp[local_num_ind+i] = (*iter)->data[i];
    615                         }
    616                         local_num_ind += (*iter)->M*(*iter)->N;
    617                 }
    618         }
    619 
    620         _assert_(local_num_ind == this->NumIndependents());
    621 }
    622 /*}}}*/
    623379Param* IoModel::CopyConstantObject(const char* constant_name,int param_enum){/*{{{*/
    624380
     
    651407
    652408        return NULL;
    653 }
    654 /*}}}*/
    655 void  IoModel::StartTrace(bool trace){/*{{{*/
    656 
    657         bool autodiff = false;
    658         bool iscontrol = false;
    659         bool keep=false;
    660         IssmDouble gcTriggerRatio;
    661         IssmDouble gcTriggerMaxSize;
    662         IssmDouble obufsize;
    663         IssmDouble lbufsize;
    664         IssmDouble cbufsize;
    665         IssmDouble tbufsize;
    666 
    667         int my_rank=IssmComm::GetRank();
    668 
    669         this->FetchData(&autodiff,"md.autodiff.isautodiff");
    670         this->FetchData(&iscontrol,"md.inversion.iscontrol");
    671 
    672         if(trace || (autodiff && !iscontrol)){
    673                 #ifdef _HAVE_ADOLC_
    674                 /*Retrieve parameters: */
    675                 this->FetchData(&keep,"md.autodiff.keep");
    676                 int keepTaylors=keep?1:0;
    677                 this->FetchData(&gcTriggerRatio,"md.autodiff.gcTriggerRatio");
    678                 this->FetchData(&gcTriggerMaxSize,"md.autodiff.gcTriggerMaxSize");
    679                 this->FetchData(&obufsize,"md.autodiff.obufsize");
    680                 this->FetchData(&lbufsize,"md.autodiff.lbufsize");
    681                 this->FetchData(&cbufsize,"md.autodiff.cbufsize");
    682                 this->FetchData(&tbufsize,"md.autodiff.tbufsize");
    683 
    684                 /*Set garbage collection parameters: */
    685                 setStoreManagerControl(reCast<IssmPDouble>(gcTriggerRatio),reCast<size_t>(gcTriggerMaxSize));
    686 
    687                 /*Start trace: */
    688                 int skipFileDeletion=1;
    689                 trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion);
    690                 #endif
    691         }
    692 
    693409}
    694410/*}}}*/
     
    15191235}
    15201236/*}}}*/
     1237void  IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value){/*{{{*/
     1238
     1239        /*First, look whether it is not already loaded in this->data*/
     1240        vector<IoData*>::iterator iter;
     1241        for(iter=data.begin();iter<data.end();iter++){
     1242                IoData* iodata=*iter;
     1243                if(strcmp(iodata->name,vector_name)==0){
     1244                        _assert_(iodata->code==7);
     1245                        for(int i=0;i<elements->Size();i++){
     1246                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1247                                element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements.
     1248                        }
     1249                        return;
     1250                }
     1251        }
     1252
     1253        /*intermediary: */
     1254        int         code,vector_layout;
     1255        IssmDouble *doublearray = NULL;
     1256        int         M,N;
     1257
     1258        /*First of, find the record for the name, and get code  of data type: */
     1259        this->SetFilePointerToData(&code, &vector_layout,vector_name);
     1260
     1261        /*Defaulting only supported for double arrays*/
     1262        if(code!=7) _error_(vector_name<<" is not a double array");
     1263
     1264        this->FetchData(&doublearray,&M,&N,vector_name);
     1265
     1266        for(int i=0;i<elements->Size();i++){
     1267                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1268                if(!doublearray) element->AddInput(input_enum,&default_value,P0Enum);
     1269                else             element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
     1270        }
     1271
     1272        /*Free ressources*/
     1273        xDelete<IssmDouble>(doublearray);
     1274}
     1275/*}}}*/
     1276void  IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum){/*{{{*/
     1277
     1278        /*First, look whether it is not already loaded in this->data*/
     1279        vector<IoData*>::iterator iter;
     1280        for(iter=data.begin();iter<data.end();iter++){
     1281                IoData* iodata=*iter;
     1282                if(strcmp(iodata->name,vector_name)==0){
     1283                        for(int i=0;i<elements->Size();i++){
     1284                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1285                                element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements.
     1286                        }
     1287                        return;
     1288                }
     1289        }
     1290
     1291        /*intermediary: */
     1292        int     i;
     1293        int     code,vector_layout;
     1294
     1295        /*variables being fetched: */
     1296        bool        boolean;
     1297        int         integer;
     1298        IssmDouble  scalar;
     1299        char       *string           = NULL;
     1300        IssmDouble *doublearray = NULL;
     1301        int         M,N;
     1302
     1303        /*First of, find the record for the name, and get code  of data type: */
     1304        this->SetFilePointerToData(&code, &vector_layout,vector_name);
     1305
     1306        switch(code){
     1307                case 1: //boolean constant
     1308                        this->FetchData(&boolean,vector_name);
     1309                        for(i=0;i<elements->Size();i++){
     1310                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1311                                element->InputUpdateFromConstant(boolean,input_enum);
     1312                        }
     1313                        break;
     1314                case 2: //integer constant
     1315                        this->FetchData(&integer,vector_name);
     1316                        for(i=0;i<elements->Size();i++){
     1317                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1318                                element->InputUpdateFromConstant(integer,input_enum);
     1319                        }
     1320                        break;
     1321                case 3: //IssmDouble constant
     1322                        this->FetchData(&scalar,vector_name);
     1323                        for(i=0;i<elements->Size();i++){
     1324                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1325                                element->InputUpdateFromConstant(scalar,input_enum);
     1326                        }
     1327                        break;
     1328                case 5: //boolean vector
     1329                        this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode
     1330                        if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file");
     1331                        for(i=0;i<elements->Size();i++){
     1332                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1333                                element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
     1334                        }
     1335                        break;
     1336                case 6: //int vector
     1337                        this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode
     1338                        if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file");
     1339                        for(i=0;i<elements->Size();i++){
     1340                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1341                                element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
     1342                        }
     1343                        break;
     1344                case 7: //IssmDouble vector
     1345                        this->FetchData(&doublearray,&M,&N,vector_name);
     1346                        if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file");
     1347                        for(i=0;i<elements->Size();i++){
     1348                                Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
     1349                                element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
     1350                        }
     1351                        break;
     1352                default:
     1353                        _error_("data code " << code << " not supported yet (detected while processing \""<<vector_name<<"\")");
     1354                        break;
     1355        }
     1356        /*Free ressources*/
     1357        xDelete<IssmDouble>(doublearray);
     1358        xDelete<char>(string);
     1359}
     1360/*}}}*/
     1361void  IoModel::FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* constant_name){/*{{{*/
     1362
     1363        /*recover my_rank:*/
     1364        int my_rank=IssmComm::GetRank();
     1365
     1366        /*recover Xcount if X is not NULL:*/
     1367        int Xcount = 0;
     1368        if(X) Xcount=*pXcount;
     1369
     1370        #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
     1371
     1372        /*output: */
     1373        IssmPDouble  pscalar;
     1374        IssmDouble   scalar; //same as pscalar, except it's an ADOLC independent variable
     1375        int          code;
     1376
     1377        /*Set file pointer to beginning of the data: */
     1378        fid=this->SetFilePointerToData(&code,NULL,constant_name);
     1379        if(code!=3) _error_("expecting a IssmDouble for \"" << constant_name<<"\"");
     1380
     1381        /*We have to read a scalar from disk. First read the dimensions of the scalar, then the scalar: */
     1382        if(my_rank==0){
     1383                if(fread(&pscalar,sizeof(IssmPDouble),1,fid)!=1)_error_("could not read scalar ");
     1384
     1385                /*Now, before we even broadcast this to other nodes, declare the scalar  as an independent variable!. If we
     1386                 *have been supplied an X vector, use it instead of what we just read: */
     1387                if(X){
     1388                        scalar<<=X[Xcount];
     1389                }
     1390                else{
     1391                        scalar<<=pscalar;
     1392                }
     1393        }
     1394
     1395        ISSM_MPI_Bcast(&scalar,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1396        this->AddConstantIndependent(new IoConstant(scalar,constant_name));
     1397
     1398        /*increment offset into X vector, now that we have read 1 value:*/
     1399        Xcount++; *pXcount=Xcount;
     1400        #endif
     1401}
     1402/*}}}*/
     1403void  IoModel::FetchIndependentData(int* pXcount,IssmPDouble* X,const char* data_name){/*{{{*/
     1404
     1405        /*recover my_rank:*/
     1406        int my_rank=IssmComm::GetRank();
     1407
     1408        /*recover Xcount if X is not NULL:*/
     1409        int Xcount = 0;
     1410        if(X) Xcount=*pXcount;
     1411
     1412        #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:
     1413
     1414        /*Intermediaries*/
     1415        int M,N;
     1416        IssmPDouble* buffer=NULL; //a buffer to read the data from disk
     1417        IssmDouble* matrix=NULL; //our independent variable
     1418        int code,layout;
     1419
     1420        /*Set file pointer to beginning of the data: */
     1421        fid=this->SetFilePointerToData(&code,&layout,data_name);
     1422        if((code!=5) && (code!=6) && (code!=7))_error_("expecting a IssmDouble, integer or boolean matrix for \"" << data_name<<"\"");
     1423
     1424        /*We have to read a matrix from disk. First read the dimensions of the matrix, then the whole matrix: */
     1425        /*numberofelements: */
     1426        if(my_rank==0){ 
     1427                if(fread(&M,sizeof(int),1,fid)!=1) _error_("could not read number of rows for matrix ");
     1428        }
     1429        ISSM_MPI_Bcast(&M,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     1430
     1431        if(my_rank==0){ 
     1432                if(fread(&N,sizeof(int),1,fid)!=1) _error_("could not read number of columns for matrix ");
     1433        }
     1434        ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     1435
     1436        /*Now allocate matrix: */
     1437        if(M*N){
     1438                buffer=xNew<IssmPDouble>(M*N);
     1439                matrix=xNew<IssmDouble>(M*N);
     1440
     1441                /*Read matrix on node 0, then broadcast: */
     1442                if(my_rank==0){ 
     1443                        if(fread(buffer,M*N*sizeof(IssmPDouble),1,fid)!=1) _error_("could not read matrix ");
     1444
     1445                        /*Now, before we even broadcast this to other nodes, declare the whole matrix as a independent variable!
     1446                          If we have been supplied an X vector, use it instead of what we just read: */
     1447                        if(X){
     1448                                for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i];  /*<<= ADOLC overloaded operator to declare independent*/
     1449                        }
     1450                        else{
     1451                                for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i];
     1452                        }
     1453                }
     1454                ISSM_MPI_Bcast(matrix,M*N,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
     1455
     1456                xDelete<IssmPDouble>(buffer);
     1457        }
     1458        else _error_("cannot declare the independent variable \"" << data_name <<  "\" if it's empty!");
     1459
     1460        /*Add to data as independent*/
     1461        this->AddDataIndependent(new IoData(matrix,code,layout,M,N,data_name));
     1462
     1463        /*increment offset into X vector, now that we have read M*N values:*/
     1464        Xcount+=M*N; *pXcount=Xcount;
     1465        #endif
     1466}
     1467/*}}}*/
    15211468void  IoModel::FetchMultipleData(char*** pstrings,int* pnumstrings,const char* data_name){/*{{{*/
    15221469
     
    18971844}
    18981845/*}}}*/
    1899 void  IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value){/*{{{*/
    1900 
    1901         /*First, look whether it is not already loaded in this->data*/
    1902         vector<IoData*>::iterator iter;
    1903         for(iter=data.begin();iter<data.end();iter++){
    1904                 IoData* iodata=*iter;
    1905                 if(strcmp(iodata->name,vector_name)==0){
    1906                         _assert_(iodata->code==7);
    1907                         for(int i=0;i<elements->Size();i++){
    1908                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1909                                 element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements.
    1910                         }
     1846void  IoModel::FillIndependents(IssmDouble* xp){/*{{{*/
     1847
     1848        _assert_(xp);
     1849
     1850        /*Initialize local num ind*/
     1851        int local_num_ind = 0;
     1852
     1853        /*Process constants*/
     1854        for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){
     1855                if((*iter)->isindependent){
     1856                        (*iter)->constant->GetParameterValue(&xp[local_num_ind]);
     1857                        local_num_ind += 1;
     1858                }
     1859        }
     1860
     1861        /*Process data*/
     1862        for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){
     1863                if((*iter)->isindependent){
     1864                        for(int i=0;i<(*iter)->M*(*iter)->N;i++){
     1865                                xp[local_num_ind+i] = (*iter)->data[i];
     1866                        }
     1867                        local_num_ind += (*iter)->M*(*iter)->N;
     1868                }
     1869        }
     1870
     1871        _assert_(local_num_ind == this->NumIndependents());
     1872}
     1873/*}}}*/
     1874void  IoModel::FindConstant(bool* pvalue,const char* constant_name){/*{{{*/
     1875
     1876        /*Intermediary*/
     1877        vector<IoConstant*>::iterator iter;
     1878
     1879        for(iter=constants.begin();iter<constants.end();iter++){
     1880                IoConstant* ioconstant=*iter;
     1881
     1882                if(strcmp(ioconstant->name,constant_name)==0){
     1883                        ioconstant->constant->GetParameterValue(pvalue);
    19111884                        return;
    19121885                }
    19131886        }
    19141887
    1915         /*intermediary: */
    1916         int         code,vector_layout;
    1917         IssmDouble *doublearray = NULL;
    1918         int         M,N;
    1919 
    1920         /*First of, find the record for the name, and get code  of data type: */
    1921         this->SetFilePointerToData(&code, &vector_layout,vector_name);
    1922 
    1923         /*Defaulting only supported for double arrays*/
    1924         if(code!=7) _error_(vector_name<<" is not a double array");
    1925 
    1926         this->FetchData(&doublearray,&M,&N,vector_name);
    1927 
    1928         for(int i=0;i<elements->Size();i++){
    1929                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1930                 if(!doublearray) element->AddInput(input_enum,&default_value,P0Enum);
    1931                 else             element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
    1932         }
    1933 
    1934         /*Free ressources*/
    1935         xDelete<IssmDouble>(doublearray);
    1936 }
    1937 /*}}}*/
    1938 void  IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum){/*{{{*/
    1939 
    1940         /*First, look whether it is not already loaded in this->data*/
    1941         vector<IoData*>::iterator iter;
    1942         for(iter=data.begin();iter<data.end();iter++){
    1943                 IoData* iodata=*iter;
    1944                 if(strcmp(iodata->name,vector_name)==0){
    1945                         for(int i=0;i<elements->Size();i++){
    1946                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1947                                 element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements.
    1948                         }
     1888        for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++) (*iter)->constant->Echo();
     1889        _error_("Could not find constant \""<<constant_name<<"\"");
     1890}
     1891/*}}}*/
     1892void  IoModel::FindConstant(int* pvalue,const char* constant_name){/*{{{*/
     1893
     1894        /*Intermediary*/
     1895        vector<IoConstant*>::iterator iter;
     1896
     1897        for(iter=constants.begin();iter<constants.end();iter++){
     1898                IoConstant* ioconstant=*iter;
     1899
     1900                if(strcmp(ioconstant->name,constant_name)==0){
     1901                        ioconstant->constant->GetParameterValue(pvalue);
    19491902                        return;
    19501903                }
    19511904        }
    19521905
    1953         /*intermediary: */
    1954         int     i;
    1955         int     code,vector_layout;
    1956 
    1957         /*variables being fetched: */
    1958         bool        boolean;
    1959         int         integer;
    1960         IssmDouble  scalar;
    1961         char       *string           = NULL;
    1962         IssmDouble *doublearray = NULL;
    1963         int         M,N;
    1964 
    1965         /*First of, find the record for the name, and get code  of data type: */
    1966         this->SetFilePointerToData(&code, &vector_layout,vector_name);
    1967 
    1968         switch(code){
    1969                 case 1: //boolean constant
    1970                         this->FetchData(&boolean,vector_name);
    1971                         for(i=0;i<elements->Size();i++){
    1972                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1973                                 element->InputUpdateFromConstant(boolean,input_enum);
    1974                         }
    1975                         break;
    1976                 case 2: //integer constant
    1977                         this->FetchData(&integer,vector_name);
    1978                         for(i=0;i<elements->Size();i++){
    1979                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1980                                 element->InputUpdateFromConstant(integer,input_enum);
    1981                         }
    1982                         break;
    1983                 case 3: //IssmDouble constant
    1984                         this->FetchData(&scalar,vector_name);
    1985                         for(i=0;i<elements->Size();i++){
    1986                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1987                                 element->InputUpdateFromConstant(scalar,input_enum);
    1988                         }
    1989                         break;
    1990                 case 5: //boolean vector
    1991                         this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode
    1992                         if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file");
    1993                         for(i=0;i<elements->Size();i++){
    1994                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    1995                                 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
    1996                         }
    1997                         break;
    1998                 case 6: //int vector
    1999                         this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode
    2000                         if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file");
    2001                         for(i=0;i<elements->Size();i++){
    2002                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2003                                 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
    2004                         }
    2005                         break;
    2006                 case 7: //IssmDouble vector
    2007                         this->FetchData(&doublearray,&M,&N,vector_name);
    2008                         if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file");
    2009                         for(i=0;i<elements->Size();i++){
    2010                                 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
    2011                                 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements.
    2012                         }
    2013                         break;
    2014                 default:
    2015                         _error_("data code " << code << " not supported yet (detected while processing \""<<vector_name<<"\")");
    2016                         break;
    2017         }
    2018         /*Free ressources*/
    2019         xDelete<IssmDouble>(doublearray);
    2020         xDelete<char>(string);
     1906        _error_("Could not find constant \""<<constant_name <<"\"");
     1907}
     1908/*}}}*/
     1909void  IoModel::FindConstant(IssmDouble* pvalue,const char* constant_name){/*{{{*/
     1910
     1911        /*Intermediary*/
     1912        vector<IoConstant*>::iterator iter;
     1913
     1914        for(iter=constants.begin();iter<constants.end();iter++){
     1915                IoConstant* ioconstant=*iter;
     1916
     1917                if(strcmp(ioconstant->name,constant_name)==0){
     1918                        ioconstant->constant->GetParameterValue(pvalue);
     1919                        return;
     1920                }
     1921        }
     1922
     1923        _error_("Could not find constant \""<<constant_name <<"\"");
     1924}
     1925/*}}}*/
     1926void  IoModel::FindConstant(char** pvalue,const char* constant_name){/*{{{*/
     1927
     1928        /*Intermediary*/
     1929        vector<IoConstant*>::iterator iter;
     1930
     1931        for(iter=constants.begin();iter<constants.end();iter++){
     1932                IoConstant* ioconstant=*iter;
     1933
     1934                if(strcmp(ioconstant->name,constant_name)==0){
     1935                        ioconstant->constant->GetParameterValue(pvalue);
     1936                        return;
     1937                }
     1938        }
     1939
     1940        _error_("Could not find constant \""<<constant_name <<"\"");
     1941}
     1942/*}}}*/
     1943void  IoModel::FindConstant(char*** pvalue,int* psize,const char* constant_name){/*{{{*/
     1944
     1945        /*Intermediary*/
     1946        vector<IoConstant*>::iterator iter;
     1947
     1948        for(iter=constants.begin();iter<constants.end();iter++){
     1949                IoConstant* ioconstant=*iter;
     1950
     1951                if(strcmp(ioconstant->name,constant_name)==0){
     1952                        ioconstant->constant->GetParameterValue(pvalue,psize);
     1953                        return;
     1954                }
     1955        }
     1956
     1957        _error_("Could not find constant \""<<constant_name <<"\"");
    20211958}
    20221959/*}}}*/
     
    20571994}
    20581995/*}}}*/
    2059 FILE* IoModel::SetFilePointerToData(int* pcode,int* pvector_type,const char* data_name){/*{{{*/
    2060 
    2061         int my_rank;
    2062 
    2063         int found  = 0;
    2064         const char* mddot = "md.";
    2065         char* record_name = NULL;
    2066         int   record_name_size;
    2067         int record_length;
    2068         int record_code;       //1 to 7 number
    2069         int vector_type   = 0; //nodal or elementary
    2070 
    2071         /*recover my_rank:*/
    2072         my_rank=IssmComm::GetRank();
    2073         _assert_(strncmp(data_name,mddot,3)==0);
    2074 
    2075         /*Go find in the binary file, the position of the data we want to fetch: */
    2076         if(my_rank==0){
    2077 
    2078                 /*First set FILE* position to the beginning of the file: */
    2079                 fseek(fid,0,SEEK_SET);
    2080 
    2081                 /*Now march through file looking for the correct data identifier: */
    2082                 for(;;){
    2083                         /*Read size of first string name: */
    2084                         if(fread(&record_name_size,sizeof(int),1,fid)==0){
    2085                                 /*we have reached the end of the file. break: */
    2086                                 xDelete<char>(record_name);
    2087                                 break;
    2088                         }
    2089                         if(record_name_size<3 || record_name_size>80){
    2090                                 _error_("error while looking in binary file. Found a string of size "<<record_name_size);
    2091                         }
    2092 
    2093                         /*Allocate string of correct size: */
    2094                         record_name=xNew<char>(record_name_size+1);
    2095                         record_name[record_name_size]='\0';
    2096 
    2097                         /*Read record_name: */
    2098                         if(fread(record_name,record_name_size*sizeof(char),1,fid)==0){
    2099                                 /*we have reached the end of the file. break: */
    2100                                 found=0;
    2101                                 xDelete<char>(record_name);
    2102                                 break;
    2103                         }
    2104                         if(strncmp(record_name,mddot,3)!=0){
    2105                                 _error_("error while reading binary file: record does not start with \"md.\": "<<record_name);
    2106                         }
    2107 
    2108                         /*Is this the record sought for? : */
    2109                         if(strcmp(record_name,data_name)==0){
    2110                                 /*Ok, we have found the correct string. Pass the record length, and read data type code: */
    2111                                 fseek(fid,sizeof(int),SEEK_CUR);
    2112                                 if(fread(&record_code,sizeof(int),1,fid)!=1) _error_("Could not read record_code");
    2113 
    2114                                 /*if record_code points to a vector, get its type (nodal or elementary): */
    2115                                 if(5<=record_code && record_code<=7){
    2116                                         if(fread(&vector_type,sizeof(int),1,fid)!=1) _error_("Could not read vector_type");
    2117                                 }
    2118                                 found=1;
    2119                                 xDelete<char>(record_name);
    2120                                 break;
    2121                         }
    2122                         else{
    2123                                 /*This is not the correct string, read the record length, and use it to skip this record: */
    2124                                 if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length");
    2125                                 /*skip: */
    2126                                 fseek(fid,record_length,SEEK_CUR);
    2127                                 xDelete<char>(record_name);
    2128                         }
    2129                 }
    2130         }
    2131         ISSM_MPI_Bcast(&found,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2132         if(!found)_error_("could not find data with name \"" << data_name << "\" in binary file");
    2133 
    2134         /*Broadcast code and vector type: */
    2135         ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2136         ISSM_MPI_Bcast(&vector_type,1,ISSM_MPI_INT,0,IssmComm::GetComm());
    2137 
    2138         /*Assign output pointers:*/
    2139         *pcode=record_code;
    2140         if(pvector_type)*pvector_type=vector_type;
    2141 
    2142         return fid;
     1996int   IoModel::NumIndependents(void){/*{{{*/
     1997
     1998        /*Initialize output*/
     1999        int num_independents = 0;
     2000
     2001        /*Process constants*/
     2002        for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){
     2003                if((*iter)->isindependent){
     2004                        num_independents+= 1;
     2005                }
     2006        }
     2007
     2008        /*Process data*/
     2009        for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){
     2010                if((*iter)->isindependent){
     2011                        num_independents+= (*iter)->M*(*iter)->N;
     2012                }
     2013        }
     2014
     2015        /*return*/
     2016        return num_independents;
    21432017}
    21442018/*}}}*/
     
    22842158}
    22852159/*}}}*/
     2160FILE* IoModel::SetFilePointerToData(int* pcode,int* pvector_type,const char* data_name){/*{{{*/
     2161
     2162        int my_rank;
     2163
     2164        int found  = 0;
     2165        const char* mddot = "md.";
     2166        char* record_name = NULL;
     2167        int   record_name_size;
     2168        int record_length;
     2169        int record_code;       //1 to 7 number
     2170        int vector_type   = 0; //nodal or elementary
     2171
     2172        /*recover my_rank:*/
     2173        my_rank=IssmComm::GetRank();
     2174        _assert_(strncmp(data_name,mddot,3)==0);
     2175
     2176        /*Go find in the binary file, the position of the data we want to fetch: */
     2177        if(my_rank==0){
     2178
     2179                /*First set FILE* position to the beginning of the file: */
     2180                fseek(fid,0,SEEK_SET);
     2181
     2182                /*Now march through file looking for the correct data identifier: */
     2183                for(;;){
     2184                        /*Read size of first string name: */
     2185                        if(fread(&record_name_size,sizeof(int),1,fid)==0){
     2186                                /*we have reached the end of the file. break: */
     2187                                xDelete<char>(record_name);
     2188                                break;
     2189                        }
     2190                        if(record_name_size<3 || record_name_size>80){
     2191                                _error_("error while looking in binary file. Found a string of size "<<record_name_size);
     2192                        }
     2193
     2194                        /*Allocate string of correct size: */
     2195                        record_name=xNew<char>(record_name_size+1);
     2196                        record_name[record_name_size]='\0';
     2197
     2198                        /*Read record_name: */
     2199                        if(fread(record_name,record_name_size*sizeof(char),1,fid)==0){
     2200                                /*we have reached the end of the file. break: */
     2201                                found=0;
     2202                                xDelete<char>(record_name);
     2203                                break;
     2204                        }
     2205                        if(strncmp(record_name,mddot,3)!=0){
     2206                                _error_("error while reading binary file: record does not start with \"md.\": "<<record_name);
     2207                        }
     2208
     2209                        /*Is this the record sought for? : */
     2210                        if(strcmp(record_name,data_name)==0){
     2211                                /*Ok, we have found the correct string. Pass the record length, and read data type code: */
     2212                                fseek(fid,sizeof(int),SEEK_CUR);
     2213                                if(fread(&record_code,sizeof(int),1,fid)!=1) _error_("Could not read record_code");
     2214
     2215                                /*if record_code points to a vector, get its type (nodal or elementary): */
     2216                                if(5<=record_code && record_code<=7){
     2217                                        if(fread(&vector_type,sizeof(int),1,fid)!=1) _error_("Could not read vector_type");
     2218                                }
     2219                                found=1;
     2220                                xDelete<char>(record_name);
     2221                                break;
     2222                        }
     2223                        else{
     2224                                /*This is not the correct string, read the record length, and use it to skip this record: */
     2225                                if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length");
     2226                                /*skip: */
     2227                                fseek(fid,record_length,SEEK_CUR);
     2228                                xDelete<char>(record_name);
     2229                        }
     2230                }
     2231        }
     2232        ISSM_MPI_Bcast(&found,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     2233        if(!found)_error_("could not find data with name \"" << data_name << "\" in binary file");
     2234
     2235        /*Broadcast code and vector type: */
     2236        ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     2237        ISSM_MPI_Bcast(&vector_type,1,ISSM_MPI_INT,0,IssmComm::GetComm());
     2238
     2239        /*Assign output pointers:*/
     2240        *pcode=record_code;
     2241        if(pvector_type)*pvector_type=vector_type;
     2242
     2243        return fid;
     2244}
     2245/*}}}*/
     2246void  IoModel::StartTrace(bool trace){/*{{{*/
     2247
     2248        bool autodiff = false;
     2249        bool iscontrol = false;
     2250        bool keep=false;
     2251        IssmDouble gcTriggerRatio;
     2252        IssmDouble gcTriggerMaxSize;
     2253        IssmDouble obufsize;
     2254        IssmDouble lbufsize;
     2255        IssmDouble cbufsize;
     2256        IssmDouble tbufsize;
     2257
     2258        int my_rank=IssmComm::GetRank();
     2259
     2260        this->FetchData(&autodiff,"md.autodiff.isautodiff");
     2261        this->FetchData(&iscontrol,"md.inversion.iscontrol");
     2262
     2263        if(trace || (autodiff && !iscontrol)){
     2264                #ifdef _HAVE_ADOLC_
     2265                /*Retrieve parameters: */
     2266                this->FetchData(&keep,"md.autodiff.keep");
     2267                int keepTaylors=keep?1:0;
     2268                this->FetchData(&gcTriggerRatio,"md.autodiff.gcTriggerRatio");
     2269                this->FetchData(&gcTriggerMaxSize,"md.autodiff.gcTriggerMaxSize");
     2270                this->FetchData(&obufsize,"md.autodiff.obufsize");
     2271                this->FetchData(&lbufsize,"md.autodiff.lbufsize");
     2272                this->FetchData(&cbufsize,"md.autodiff.cbufsize");
     2273                this->FetchData(&tbufsize,"md.autodiff.tbufsize");
     2274
     2275                /*Set garbage collection parameters: */
     2276                setStoreManagerControl(reCast<IssmPDouble>(gcTriggerRatio),reCast<size_t>(gcTriggerMaxSize));
     2277
     2278                /*Start trace: */
     2279                int skipFileDeletion=1;
     2280                trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion);
     2281                #endif
     2282        }
     2283
     2284}
     2285/*}}}*/
  • issm/trunk-jpl/src/c/classes/IoModel.h

    r20690 r20810  
    1818class IoConstant { /*holds single IssmDouble, int, bool and char from input*/
    1919        public:
     20                Param* constant;
    2021                bool   isindependent;
    2122                char*  name;
    22                 Param* constant;
    2323
    2424                ~IoConstant();
     
    3333class IoData { /*holds temporary data (array), memory intensive*/
    3434        public:
     35                int         code;
     36                IssmDouble* data;
    3537                bool        isindependent;
     38                int         layout;
     39                int         M,N;
    3640                char*       name;
    37                 int         M,N;
    38                 int         code;
    39                 int         layout;
    40                 IssmDouble* data;
    4141
    4242                ~IoData();
     
    6767
    6868                /*Mesh properties and connectivity tables*/
     69                int  domaindim;
    6970                int  domaintype;
    70                 int  domaindim;
    71                 int  meshelementtype;
    72                 int  numberofvertices;
    73                 int  numberofelements;
    74                 int  numberoffaces;
    75                 int  numberofedges;
    76                 int  facescols;
    7771                int *elements;
    78                 int *faces;
    7972                int *edges;
    8073                int *elementtoedgeconnectivity;
    8174                int *elementtofaceconnectivity;
     75                int *faces;
     76                int  facescols;
     77                int  meshelementtype;
     78                int *numbernodetoelementconnectivity;
     79                int  numberofedges;
     80                int  numberofelements;
     81                int  numberoffaces;
     82                int  numberofvertices;
    8283                int *singlenodetoelementconnectivity;
    83                 int *numbernodetoelementconnectivity;
    8484
    8585                /*Data to synchronize through low level object drivers: */
     86                int constraintcounter;   //keep track of how many constraints are being created in each analysis
     87                int loadcounter;         //keep track of how many loads are being created in each analysis
    8688                int nodecounter;         //keep track of how many nodes are being created in each analysis
    87                 int loadcounter;         //keep track of how many loads are being created in each analysis
    88                 int constraintcounter;   //keep track of how many constraints are being created in each analysis
    8989
    9090                /*Methods*/
     
    9898                void        AddData(IoData* data_in);
    9999                void        AddDataIndependent(IoData* data_in);
     100                void        FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* name);
     101                void        FetchIndependentData(int* pXcount,IssmPDouble* X,const char* name);
     102                void        FillIndependents(IssmDouble* xp);
    100103                void        FindConstant(bool* pvalue,const char* constant_name);
    101104                void        FindConstant(int* pvalue,const char* constant_name);
     
    103106                void        FindConstant(char **pvalue,const char* constant_name);
    104107                void        FindConstant(char ***pvalue,int* psize,const char* constant_name);
    105                 void        FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* name);
    106                 void        FetchIndependentData(int* pXcount,IssmPDouble* X,const char* name);
    107108                int         NumIndependents();
    108                 void        FillIndependents(IssmDouble* xp);
    109109
    110110                /*Input/Output*/
     
    112112                Param      *CopyConstantObject(const char* constant_name,int param_enum);
    113113                IssmDouble *Data(const char* data_name);
     114                void        DeclareIndependents(bool trace,IssmPDouble* X);
    114115                void        DeleteData(int num,...);
    115116                void        DeleteData(IssmDouble* vector,const char* data_name);
     
    123124                void        FetchData(IssmDouble**  pscalarmatrix,int* pM,int* pN,const char* data_name);
    124125                void        FetchData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,const char* data_name);
     126                void        FetchData(Option **poption,int index);
     127                void        FetchData(int num,...);
     128                void        FetchDataToInput(Elements* elements,const char* vector_name,int input_enum);
     129                void        FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value);
     130                void        FetchIndependent(const char* dependent_name);
    125131                void        FetchMultipleData(char***   pstringarray,int* pnumstrings,const char* data_name);
    126132                void        FetchMultipleData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,const char* data_name);
     
    128134                void        FetchMultipleData(int** pvector, int* pnum_instances,const char* data_name);
    129135                void        FetchMultipleData(IssmDouble** pvector, int* pnum_instances,const char* data_name);
    130                 void        FetchData(Option **poption,int index);
    131                 void        FetchData(int num,...);
    132                 void        FetchDataToInput(Elements* elements,const char* vector_name,int input_enum);
    133                 void        FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value);
    134136                void        LastIndex(int *pindex);
     137                fpos_t*     SetFilePointersToData(int** pcodes,int** pvector_types, int* pnum_instances, const char* data_name);
    135138                FILE*       SetFilePointerToData(int* pcode,int* pvector_type, const char* data_name);
    136                 fpos_t*     SetFilePointersToData(int** pcodes,int** pvector_types, int* pnum_instances, const char* data_name);
    137                 void        DeclareIndependents(bool trace,IssmPDouble* X);
    138139                void        StartTrace(bool trace);
    139                 void        FetchIndependent(const char* dependent_name);
    140140};
    141141
  • issm/trunk-jpl/src/c/classes/Masscon.h

    r19198 r20810  
    5454                /*}}}*/
    5555                /*Object virtual function resolutoin: */
     56                Object* copy() {/*{{{*/
     57                        Masscon* mf = new Masscon(this->name,this->definitionenum,this->levelset,this->M);
     58                        return (Object*) mf;
     59                }
     60                /*}}}*/
     61                void DeepEcho(void){/*{{{*/
     62                        this->Echo();
     63                }
     64                /*}}}*/
    5665                void Echo(void){/*{{{*/
    5766                        _printf_(" Masscon: " << this->name << " " << this->definitionenum << "\n");
     
    6069                }
    6170                /*}}}*/
    62                 void DeepEcho(void){/*{{{*/
    63                         this->Echo();
    64                 }
    65                 /*}}}*/
    6671                int Id(void){/*{{{*/
    6772                        return -1;
    68                 }
    69                 /*}}}*/
    70                 int ObjectEnum(void){/*{{{*/
    71                         return MassconEnum;
    72                 }
    73                 /*}}}*/
    74                 Object* copy() {/*{{{*/
    75                         Masscon* mf = new Masscon(this->name,this->definitionenum,this->levelset,this->M);
    76                         return (Object*) mf;
    7773                }
    7874                /*}}}*/
     
    8177                }
    8278                /*}}}*/
     79                int ObjectEnum(void){/*{{{*/
     80                        return MassconEnum;
     81                }
     82                /*}}}*/
    8383                /*Definition virtual function resolutoin: */
     84                int DefinitionEnum(){/*{{{*/
     85
     86                        return this->definitionenum;
     87                }
     88                /*}}}*/
    8489                char* Name(){/*{{{*/
    8590
     
    8893
    8994                        return name2;
    90                 }
    91                 /*}}}*/
    92                 int DefinitionEnum(){/*{{{*/
    93 
    94                         return this->definitionenum;
    9595                }
    9696                /*}}}*/
  • issm/trunk-jpl/src/c/classes/Massconaxpby.h

    r19198 r20810  
    6363                /*}}}*/
    6464                /*Object virtual function resolutoin: */
     65                Object* copy() {/*{{{*/
     66                        Massconaxpby* mf = new Massconaxpby(this->name,this->definitionenum,this->namex,this->namey, this->alpha, this->beta);
     67                        return (Object*) mf;
     68                }
     69                /*}}}*/
     70                void DeepEcho(void){/*{{{*/
     71                        this->Echo();
     72                }
     73                /*}}}*/
    6574                void Echo(void){/*{{{*/
    6675                        _printf_(" Massconaxpby: " << this->name << " " << this->definitionenum << "\n");
     
    7180                }
    7281                /*}}}*/
    73                 void DeepEcho(void){/*{{{*/
    74                         this->Echo();
    75                 }
    76                 /*}}}*/
    7782                int Id(void){/*{{{*/
    7883                        return -1;
    79                 }
    80                 /*}}}*/
    81                 int ObjectEnum(void){/*{{{*/
    82                         return MassconaxpbyEnum;
    83                 }
    84                 /*}}}*/
    85                 Object* copy() {/*{{{*/
    86                         Massconaxpby* mf = new Massconaxpby(this->name,this->definitionenum,this->namex,this->namey, this->alpha, this->beta);
    87                         return (Object*) mf;
    8884                }
    8985                /*}}}*/
     
    9288                }
    9389                /*}}}*/
     90                int ObjectEnum(void){/*{{{*/
     91                        return MassconaxpbyEnum;
     92                }
     93                /*}}}*/
    9494                /*Definition virtual function resolutoin: */
     95                int DefinitionEnum(){/*{{{*/
     96
     97                        return this->definitionenum;
     98                }
     99                /*}}}*/
    95100                char* Name(){/*{{{*/
    96101
     
    99104
    100105                        return name2;
    101                 }
    102                 /*}}}*/
    103                 int DefinitionEnum(){/*{{{*/
    104 
    105                         return this->definitionenum;
    106106                }
    107107                /*}}}*/
  • issm/trunk-jpl/src/c/classes/Massfluxatgate.h

    r19198 r20810  
    9494
    9595                /*Object virtual function resolutoin: */
     96                Object* copy() {/*{{{*/
     97                        return new Massfluxatgate(this->name,this->definitionenum,this->numsegments,this->x1,this->y1,this->x2,this->y2,this->elements);
     98                }
     99                /*}}}*/
     100                void DeepEcho(void){/*{{{*/
     101                        this->Echo();
     102                }
     103                /*}}}*/
    96104                void Echo(void){/*{{{*/
    97105                        _printf_(" Massfluxatgate: " << name << " " << this->definitionenum << "\n");
     
    105113                }
    106114                /*}}}*/
    107                 void DeepEcho(void){/*{{{*/
    108                         this->Echo();
    109                 }
    110                 /*}}}*/
    111115                int Id(void){/*{{{*/
    112116                        return -1;
     
    117121                }
    118122                /*}}}*/
    119                 Object* copy() {/*{{{*/
    120                         return new Massfluxatgate(this->name,this->definitionenum,this->numsegments,this->x1,this->y1,this->x2,this->y2,this->elements);
    121                 }
    122                 /*}}}*/
    123123                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/
    124124                        _error_("not implemented yet!");
     
    126126                /*}}}*/
    127127                /*Definition virtual function resolutoin: */
     128                int DefinitionEnum(){/*{{{*/
     129
     130                        return this->definitionenum;
     131                }
     132                /*}}}*/
    128133                char* Name(){/*{{{*/
    129134
     
    132137
    133138                        return name2;
    134                 }
    135                 /*}}}*/
    136                 int DefinitionEnum(){/*{{{*/
    137 
    138                         return this->definitionenum;
    139139                }
    140140                /*}}}*/
  • issm/trunk-jpl/src/c/classes/Misfit.h

    r19198 r20810  
    2525
    2626                int         definitionenum;
     27                bool        local;     
     28                int         model_enum;
    2729                char*       name;
    28                 int         model_enum;
    2930                int         observation_enum;
     31                char*       timeinterpolation;
    3032                int         weights_enum;
    31                 char*       timeinterpolation;
    32                 bool        local;     
    3333               
     34                int         lock; // if lock is on, we just return the value stored in "misfit".  this is used so we don't compute misfit past the final_time
    3435                IssmDouble  misfit; //value carried over in time.
    35                 int         lock; // if lock is on, we just return the value stored in "misfit".  this is used so we don't compute misfit past the final_time
    3636               
    3737                /*Misfit constructors, destructors :*/
     
    7676                /*}}}*/
    7777                /*Object virtual function resolutoin: */
     78                Object* copy() {/*{{{*/
     79                        Misfit* mf = new Misfit(this->name,this->definitionenum, this->model_enum,this->observation_enum,this->timeinterpolation,this->local,this->weights_enum);
     80                        mf->misfit=this->misfit;
     81                        mf->lock=this->lock;
     82                        return (Object*) mf;
     83                }
     84                /*}}}*/
     85                void DeepEcho(void){/*{{{*/
     86                        this->Echo();
     87                }
     88                /*}}}*/
    7889                void Echo(void){/*{{{*/
    7990                        _printf_(" Misfit: " << name << " " << this->definitionenum << "\n");
     
    8596                }
    8697                /*}}}*/
    87                 void DeepEcho(void){/*{{{*/
    88                         this->Echo();
    89                 }
    90                 /*}}}*/
    9198                int Id(void){/*{{{*/
    9299                        return -1;
    93                 }
    94                 /*}}}*/
    95                 int ObjectEnum(void){/*{{{*/
    96                         return MisfitEnum;
    97                 }
    98                 /*}}}*/
    99                 Object* copy() {/*{{{*/
    100                         Misfit* mf = new Misfit(this->name,this->definitionenum, this->model_enum,this->observation_enum,this->timeinterpolation,this->local,this->weights_enum);
    101                         mf->misfit=this->misfit;
    102                         mf->lock=this->lock;
    103                         return (Object*) mf;
    104100                }
    105101                /*}}}*/
     
    108104                }
    109105                /*}}}*/
     106                int ObjectEnum(void){/*{{{*/
     107                        return MisfitEnum;
     108                }
     109                /*}}}*/
    110110                /*Definition virtual function resolutoin: */
     111                int DefinitionEnum(){/*{{{*/
     112
     113                        return this->definitionenum;
     114                }
     115                /*}}}*/
    111116                char* Name(){/*{{{*/
    112117
     
    115120
    116121                        return name2;
    117                 }
    118                 /*}}}*/
    119                 int DefinitionEnum(){/*{{{*/
    120 
    121                         return this->definitionenum;
    122122                }
    123123                /*}}}*/
  • issm/trunk-jpl/src/c/classes/Nodalvalue.h

    r20038 r20810  
    2727
    2828                int         definitionenum;
     29                int         model_enum;
    2930                char*       name;
    30                 int         model_enum;
    3131                int         node;
    3232               
     
    5656                /*}}}*/
    5757                /*Object virtual function resolutoin: */
     58                Object* copy() {/*{{{*/
     59                        Nodalvalue* mf = new Nodalvalue(this->name,this->definitionenum, this->model_enum,this->node);
     60                        return (Object*) mf;
     61                }
     62                /*}}}*/
     63                void DeepEcho(void){/*{{{*/
     64                        this->Echo();
     65                }
     66                /*}}}*/
    5867                void Echo(void){/*{{{*/
    5968                        _printf_(" Nodalvalue: " << name << " " << this->definitionenum << "\n");
     
    6271                }
    6372                /*}}}*/
    64                 void DeepEcho(void){/*{{{*/
    65                         this->Echo();
    66                 }
    67                 /*}}}*/
    6873                int Id(void){/*{{{*/
    6974                        return -1;
    70                 }
    71                 /*}}}*/
    72                 int ObjectEnum(void){/*{{{*/
    73                         return NodalvalueEnum;
    74                 }
    75                 /*}}}*/
    76                 Object* copy() {/*{{{*/
    77                         Nodalvalue* mf = new Nodalvalue(this->name,this->definitionenum, this->model_enum,this->node);
    78                         return (Object*) mf;
    7975                }
    8076                /*}}}*/
     
    8379                }
    8480                /*}}}*/
     81                int ObjectEnum(void){/*{{{*/
     82                        return NodalvalueEnum;
     83                }
     84                /*}}}*/
    8585                /*Definition virtual function resolutoin: */
     86                int DefinitionEnum(){/*{{{*/
     87
     88                        return this->definitionenum;
     89                }
     90                /*}}}*/
    8691                char* Name(){/*{{{*/
    8792
     
    9095
    9196                        return name2;
    92                 }
    93                 /*}}}*/
    94                 int DefinitionEnum(){/*{{{*/
    95 
    96                         return this->definitionenum;
    9797                }
    9898                /*}}}*/
  • issm/trunk-jpl/src/c/classes/Node.cpp

    r20690 r20810  
    165165
    166166/*Object virtual functions definitions:*/
     167void Node::DeepEcho(void){/*{{{*/
     168
     169        _printf_("Node:\n");
     170        _printf_("   id: " << id << "\n");
     171        _printf_("   sid: " << sid << "\n");
     172        _printf_("   analysis_enum: " << EnumToStringx(analysis_enum) << "\n");
     173        _printf_("   approximation: " << EnumToStringx(approximation) << "\n");
     174        _printf_("   indexingupdate: " << indexingupdate << "\n");
     175        indexing.DeepEcho();
     176
     177}
     178/*}}}*/
    167179void Node::Echo(void){/*{{{*/
    168180
     
    177189}
    178190/*}}}*/
    179 void Node::DeepEcho(void){/*{{{*/
    180 
    181         _printf_("Node:\n");
    182         _printf_("   id: " << id << "\n");
    183         _printf_("   sid: " << sid << "\n");
    184         _printf_("   analysis_enum: " << EnumToStringx(analysis_enum) << "\n");
    185         _printf_("   approximation: " << EnumToStringx(approximation) << "\n");
    186         _printf_("   indexingupdate: " << indexingupdate << "\n");
    187         indexing.DeepEcho();
    188 
    189 }
    190 /*}}}*/
    191191int  Node::Id(void){ return id; }/*{{{*/
    192192/*}}}*/
     
    199199
    200200/*Node management:*/
     201void Node::GetCoordinateSystem(IssmDouble* coord_system_out){/*{{{*/
     202
     203        /*Copy coord_system*/
     204        for(int k=0;k<3;k++) for(int l=0;l<3;l++) coord_system_out[3*k+l]=this->coord_system[k][l];
     205
     206}
     207/*}}}*/
    201208int  Node::GetDof(int dofindex,int setenum){/*{{{*/
    202209
     
    380387}
    381388/*}}}*/
    382 int  Node::Sid(void){/*{{{*/
    383         return sid;
    384 }
    385 /*}}}*/
    386 int  Node::Lid(void){/*{{{*/
    387         return lid;
    388 }
    389 /*}}}*/
    390 void Node::GetCoordinateSystem(IssmDouble* coord_system_out){/*{{{*/
    391 
    392         /*Copy coord_system*/
    393         for(int k=0;k<3;k++) for(int l=0;l<3;l++) coord_system_out[3*k+l]=this->coord_system[k][l];
    394 
    395 }
    396 /*}}}*/
    397389bool Node::InAnalysis(int in_analysis_enum){/*{{{*/
    398390        if (in_analysis_enum==this->analysis_enum) return true;
     
    400392}
    401393/*}}}*/
     394int  Node::Lid(void){/*{{{*/
     395        return lid;
     396}
     397/*}}}*/
     398int  Node::Sid(void){/*{{{*/
     399        return sid;
     400}
     401/*}}}*/
    402402
    403403/*Node numerics:*/
     404void Node::Activate(void){/*{{{*/
     405
     406        if(!IsActive() && !this->indexing.freeze){
     407                this->indexingupdate = true;
     408                indexing.Activate();
     409        }
     410
     411}
     412/*}}}*/
    404413void Node::ApplyConstraint(int dof,IssmDouble value){/*{{{*/
    405414
     
    408417        DofInSSet(dof);
    409418        this->indexing.svalues[dof]=value;
    410 }
    411 /*}}}*/
    412 bool Node::RequiresDofReindexing(void){/*{{{*/
    413 
    414         return this->indexingupdate;
    415 
    416 }
    417 /*}}}*/
    418 void Node::ReindexingDone(void){/*{{{*/
    419 
    420         this->indexingupdate = false;
    421 
    422 }
    423 /*}}}*/
    424 void Node::RelaxConstraint(int dof){/*{{{*/
    425 
    426         /*Dof should be added to the f-set, and taken out of the s-set:*/
    427         DofInFSet(dof);
    428         this->indexing.svalues[dof]=0.;
    429419}
    430420/*}}}*/
     
    456446}
    457447/*}}}*/
     448void Node::Deactivate(void){/*{{{*/
     449
     450        if(IsActive() && !this->indexing.freeze){
     451                this->indexingupdate = true;
     452                indexing.Deactivate();
     453        }
     454
     455}
     456/*}}}*/
     457void Node::DofInFSet(int dof){/*{{{*/
     458
     459        /*Put dof for this node into the f set (ie, this dof will NOT be constrained
     460         * to a fixed value during computations. */
     461        _assert_(dof<this->indexing.gsize);
     462
     463        if(this->indexing.f_set[dof] == 0){
     464                if(this->indexing.freeze) _error_("Cannot change dof of frozen node");
     465                this->indexingupdate = true;
     466                this->indexing.f_set[dof]=1;
     467                this->indexing.s_set[dof]=0;
     468        }
     469}
     470/*}}}*/
    458471void Node::DofInSSet(int dof){/*{{{*/
    459472
     
    470483}
    471484/*}}}*/
    472 void Node::DofInFSet(int dof){/*{{{*/
    473 
    474         /*Put dof for this node into the f set (ie, this dof will NOT be constrained
    475          * to a fixed value during computations. */
    476         _assert_(dof<this->indexing.gsize);
    477 
    478         if(this->indexing.f_set[dof] == 0){
    479                 if(this->indexing.freeze) _error_("Cannot change dof of frozen node");
    480                 this->indexingupdate = true;
    481                 this->indexing.f_set[dof]=1;
    482                 this->indexing.s_set[dof]=0;
    483         }
    484 }
    485 /*}}}*/
    486485void Node::FreezeDof(int dof){/*{{{*/
    487486
     
    489488        //FIXME: for now we don't want this element to change so we use freeze
    490489        this->indexing.freeze =true;
    491 
    492 }
    493 /*}}}*/
    494 void Node::Deactivate(void){/*{{{*/
    495 
    496         if(IsActive() && !this->indexing.freeze){
    497                 this->indexingupdate = true;
    498                 indexing.Deactivate();
    499         }
    500 
    501 }
    502 /*}}}*/
    503 void Node::HardDeactivate(void){/*{{{*/
    504 
    505         this->indexing.Deactivate();
    506         this->indexing.freeze =true;
    507 
    508 }
    509 /*}}}*/
    510 void Node::Activate(void){/*{{{*/
    511 
    512         if(!IsActive() && !this->indexing.freeze){
    513                 this->indexingupdate = true;
    514                 indexing.Activate();
    515         }
    516 
    517 }
    518 /*}}}*/
    519 bool Node::IsActive(void){/*{{{*/
    520 
    521         return indexing.active;
    522490
    523491}
     
    575543}
    576544/*}}}*/
     545void Node::HardDeactivate(void){/*{{{*/
     546
     547        this->indexing.Deactivate();
     548        this->indexing.freeze =true;
     549
     550}
     551/*}}}*/
     552bool Node::IsActive(void){/*{{{*/
     553
     554        return indexing.active;
     555
     556}
     557/*}}}*/
    577558int  Node::IsClone(){/*{{{*/
    578559
    579560        return indexing.clone;
     561
     562}
     563/*}}}*/
     564void Node::ReindexingDone(void){/*{{{*/
     565
     566        this->indexingupdate = false;
     567
     568}
     569/*}}}*/
     570void Node::RelaxConstraint(int dof){/*{{{*/
     571
     572        /*Dof should be added to the f-set, and taken out of the s-set:*/
     573        DofInFSet(dof);
     574        this->indexing.svalues[dof]=0.;
     575}
     576/*}}}*/
     577bool Node::RequiresDofReindexing(void){/*{{{*/
     578
     579        return this->indexingupdate;
    580580
    581581}
     
    738738        }
    739739        else _error_("set of enum type " << EnumToStringx(setenum) << " not supported yet!");
     740}
     741/*}}}*/
     742void Node::SetClone(int* minranks){/*{{{*/
     743
     744        int my_rank;
     745
     746        /*recover my_rank:*/
     747        my_rank=IssmComm::GetRank();
     748
     749        if (minranks[sid]==my_rank){
     750                indexing.clone=false;
     751        }
     752        else{
     753                /*!there is a cpu with lower rank that has the same node,
     754                therefore, I am a clone*/
     755                indexing.clone=true;   
     756        }
    740757}
    741758/*}}}*/
     
    788805}
    789806/*}}}*/
    790 void Node::SetClone(int* minranks){/*{{{*/
    791 
    792         int my_rank;
    793 
    794         /*recover my_rank:*/
    795         my_rank=IssmComm::GetRank();
    796 
    797         if (minranks[sid]==my_rank){
    798                 indexing.clone=false;
    799         }
    800         else{
    801                 /*!there is a cpu with lower rank that has the same node,
    802                 therefore, I am a clone*/
    803                 indexing.clone=true;   
    804         }
    805 }
    806 /*}}}*/
    807807
    808808/*Methods inherent to Node: */
     809int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation){/*{{{*/
     810
     811        int  i,numdof,count;
     812        int* ndof_list=NULL;
     813        int *doflist = NULL;
     814
     815        if(numnodes){
     816
     817                /*Allocate:*/
     818                ndof_list=xNew<int>(numnodes);
     819
     820                /*First, figure out size of doflist: */
     821                numdof=0;
     822                for(i=0;i<numnodes;i++){
     823                        ndof_list[i]=nodes[i]->GetNumberOfDofs(approximation,setenum);
     824                        numdof+=ndof_list[i];
     825                }
     826
     827                if(numdof){
     828                        /*Allocate: */
     829                        doflist=xNew<int>(numdof);
     830
     831                        /*Populate: */
     832                        count=0;
     833                        for(i=0;i<numnodes;i++){
     834                                nodes[i]->GetDofList(&doflist[count],approximation,setenum);
     835                                count+=ndof_list[i];
     836                        }
     837                }
     838                else doflist=NULL;
     839        }
     840        /*Free ressources:*/
     841        xDelete<int>(ndof_list);
     842
     843        return doflist;
     844}
     845/*}}}*/
    809846int* GetLocalDofList(Node** nodes,int numnodes,int setenum,int approximation){ /*{{{*/
    810847
     
    864901}
    865902/*}}}*/
    866 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation){/*{{{*/
    867 
    868         int  i,numdof,count;
    869         int* ndof_list=NULL;
    870         int *doflist = NULL;
    871 
    872         if(numnodes){
    873 
    874                 /*Allocate:*/
    875                 ndof_list=xNew<int>(numnodes);
    876 
    877                 /*First, figure out size of doflist: */
    878                 numdof=0;
    879                 for(i=0;i<numnodes;i++){
    880                         ndof_list[i]=nodes[i]->GetNumberOfDofs(approximation,setenum);
    881                         numdof+=ndof_list[i];
    882                 }
    883 
    884                 if(numdof){
    885                         /*Allocate: */
    886                         doflist=xNew<int>(numdof);
    887 
    888                         /*Populate: */
    889                         count=0;
    890                         for(i=0;i<numnodes;i++){
    891                                 nodes[i]->GetDofList(&doflist[count],approximation,setenum);
    892                                 count+=ndof_list[i];
    893                         }
    894                 }
    895                 else doflist=NULL;
    896         }
    897         /*Free ressources:*/
    898         xDelete<int>(ndof_list);
    899 
    900         return doflist;
    901 }
    902 /*}}}*/
    903903int GetNumberOfDofs(Node** nodes,int numnodes,int setenum,int approximation){/*{{{*/
    904904
  • issm/trunk-jpl/src/c/classes/Node.h

    r20462 r20810  
    3434                int lid;   // "local"  id (rank of this node in current partition)
    3535
     36                int          analysis_enum;
     37                IssmDouble   coord_system[3][3];
    3638                bool         indexingupdate;
    3739                DofIndexing  indexing;
    38                 int          analysis_enum;
    39                 IssmDouble   coord_system[3][3];
    4040
    4141                /*Node constructors, destructors*/
     
    4545
    4646                /*Object virtual functions definitions:*/
     47                Object *copy();
     48                void    DeepEcho();
    4749                void    Echo();
    48                 void    DeepEcho();
    4950                int     Id();
     51                void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    5052                int     ObjectEnum();
    51                 Object *copy();
    52                 void    Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    5353
    5454                /*Node numerical routines*/
     55                void  Activate(void);
     56                void  ApplyConstraint(int dof,IssmDouble value);
    5557                void  CreateNodalConstraints(Vector<IssmDouble>* ys);
    56                 void  SetCurrentConfiguration(DataSet* nodes,Vertices* vertices);
    57                 int   Sid(void);
    58                 int   Lid(void);
     58                void  Deactivate(void);
     59                void  DistributeDofs(int* pdofcount,int setenum);
     60                void  DofInFSet(int dof);
     61                void  DofInSSet(int dof);
     62                void  FreezeDof(int dof);
     63                int   GetApproximation();
    5964                void  GetCoordinateSystem(IssmDouble* coord_system_out);
    60                 bool  InAnalysis(int analysis_enum);
    61                 int   GetApproximation();
    62                 int   GetNumberOfDofs(int approximation_enum,int setenum);
    63                 int   IsClone();
    64                 void  ApplyConstraint(int dof,IssmDouble value);
    65                 void  RelaxConstraint(int dof);
    66                 void  DofInSSet(int dof);
    67                 void  DofInFSet(int dof);
    6865                int   GetDof(int dofindex,int setenum);
    6966                void  GetDofList(int* poutdoflist,int approximation_enum,int setenum);
    7067                void  GetLocalDofList(int* poutdoflist,int approximation_enum,int setenum);
    71                 void  FreezeDof(int dof);
     68                int   GetNumberOfDofs(int approximation_enum,int setenum);
     69                void  HardDeactivate(void);
     70                bool  InAnalysis(int analysis_enum);
    7271                bool  IsActive(void);
    73                 void  Activate(void);
    74                 void  Deactivate(void);
    75                 void  HardDeactivate(void);
    76                 void  ReindexingDone(void);
    77                 bool  RequiresDofReindexing(void);
     72                int   IsClone();
    7873                int   IsFloating();
    7974                int   IsGrounded();
     75                int   Lid(void);
     76                void  OffsetDofs(int dofcount,int setenum);
     77                void  ReindexingDone(void);
     78                void  RelaxConstraint(int dof);
     79                bool  RequiresDofReindexing(void);
     80                void  SetClone(int* minranks);
     81                void  SetCurrentConfiguration(DataSet* nodes,Vertices* vertices);
     82                void  ShowTrueDofs(int* truerows,int ncols,int setenum);
     83                int   Sid(void);
     84                void  UpdateCloneDofs(int* alltruerows,int ncols,int setenum);
    8085                void  VecMerge(Vector<IssmDouble>* ug, IssmDouble* vector_serial,int setenum);
    8186                void  VecReduce(Vector<IssmDouble>* vector, IssmDouble* ug_serial,int setnum);
    82                 void  DistributeDofs(int* pdofcount,int setenum);
    83                 void  OffsetDofs(int dofcount,int setenum);
    84                 void  ShowTrueDofs(int* truerows,int ncols,int setenum);
    85                 void  UpdateCloneDofs(int* alltruerows,int ncols,int setenum);
    86                 void  SetClone(int* minranks);
    8787};
    8888
    8989/*Methods inherent to Node: */
     90int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation);
    9091int* GetLocalDofList(Node** nodes,int numnodes,int setenum,int approximation);
    91 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation);
    9292int  GetNumberOfDofs(Node** nodes,int numnodes,int setenum,int approximation);
    9393
  • issm/trunk-jpl/src/c/classes/Nodes.cpp

    r19198 r20810  
    164164}
    165165/*}}}*/
    166 int   Nodes::MaxNumDofs(int analysis_type,int setenum){/*{{{*/
    167 
    168         int max=0;
    169         int allmax,numdofs;
    170 
    171         /*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */
    172         for(int i=0;i<this->Size();i++){
    173 
    174                 Node* node=xDynamicCast<Node*>(this->GetObjectByOffset(i));
    175 
    176                 /*Check that this node corresponds to our analysis currently being carried out: */
    177                 if (node->InAnalysis(analysis_type)){
    178 
    179                         numdofs=node->GetNumberOfDofs(NoneApproximationEnum,setenum);
    180                         if(numdofs>max)max=numdofs;
    181                 }
    182         }
    183 
    184         /*Grab max of all cpus: */
    185         ISSM_MPI_Allreduce((void*)&max,(void*)&allmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
    186         max=allmax;
    187 
    188         return max;
    189 }
    190 /*}}}*/
    191166int   Nodes::MaximumId(){/*{{{*/
    192167
     
    219194}
    220195/*}}}*/
     196int   Nodes::MaxNumDofs(int analysis_type,int setenum){/*{{{*/
     197
     198        int max=0;
     199        int allmax,numdofs;
     200
     201        /*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */
     202        for(int i=0;i<this->Size();i++){
     203
     204                Node* node=xDynamicCast<Node*>(this->GetObjectByOffset(i));
     205
     206                /*Check that this node corresponds to our analysis currently being carried out: */
     207                if (node->InAnalysis(analysis_type)){
     208
     209                        numdofs=node->GetNumberOfDofs(NoneApproximationEnum,setenum);
     210                        if(numdofs>max)max=numdofs;
     211                }
     212        }
     213
     214        /*Grab max of all cpus: */
     215        ISSM_MPI_Allreduce((void*)&max,(void*)&allmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
     216        max=allmax;
     217
     218        return max;
     219}
     220/*}}}*/
    221221int   Nodes::NumberOfDofs(int analysis_type,int setenum){/*{{{*/
    222222
  • issm/trunk-jpl/src/c/classes/Nodes.h

    r15861 r20810  
    2727                void  DistributeDofs(int analysis_type,int SETENUM);
    2828                void  FlagClones(int analysis_type);
    29                 bool  RequiresDofReindexing(int analysis_type);
     29                int   MaximumId(void);
    3030                int   MaxNumDofs(int analysis_type,int setenum);
    31                 int   MaximumId(void);
    3231                int   NumberOfDofs(int analysis_type,int setenum);
    3332                int   NumberOfDofsLocal(int analysis_type,int setenum);
     
    3534                int   NumberOfNodes(void);
    3635                void  Ranks(int* ranks,int analysis_type);
     36                bool  RequiresDofReindexing(int analysis_type);
    3737
    3838};
  • issm/trunk-jpl/src/c/classes/Profiler.cpp

    r20637 r20810  
    4141
    4242/*Object virtual functions definitions:*/
     43void Profiler::DeepEcho(void){/*{{{*/
     44
     45        this->Echo();
     46
     47}
     48/*}}}*/
    4349void Profiler::Echo(void){/*{{{*/
    4450
     
    4955}
    5056/*}}}*/
    51 void Profiler::DeepEcho(void){/*{{{*/
    52 
    53         this->Echo();
    54 
    55 }
    56 /*}}}*/
    5757int  Profiler::Id(void){ return -1; }/*{{{*/
    58 /*}}}*/
    59 int  Profiler::ObjectEnum(void){/*{{{*/
    60 
    61         return ProfilerEnum;
    62 
    63 }
    6458/*}}}*/
    6559void Profiler::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
     
    7670
    7771} /*}}}*/
     72int  Profiler::ObjectEnum(void){/*{{{*/
     73
     74        return ProfilerEnum;
     75
     76}
     77/*}}}*/
    7878
    7979/*Profiler routines:*/
     80IssmDouble  Profiler::DeltaFlops(int inittag, int finaltag){/*{{{*/
     81
     82        /*Get initial flops*/
     83        _assert_(inittag>=0);
     84        _assert_(inittag<MAXIMUMSIZE);
     85        if(xIsNan<IssmDouble>(this->flops[inittag])) _error_("Tag not set");
     86        IssmDouble init = this->flops[inittag];
     87
     88        /*Get final flops*/
     89        _assert_(finaltag>=0);
     90        _assert_(finaltag<MAXIMUMSIZE);
     91        if(xIsNan<IssmDouble>(this->flops[finaltag])) _error_("Tag not set");
     92        IssmDouble final = this->flops[finaltag];
     93
     94        return final-init;
     95}
     96/*}}}*/
     97IssmDouble  Profiler::DeltaTime(int inittag, int finaltag){/*{{{*/
     98
     99        /*Get initial time*/
     100        _assert_(inittag>=0);
     101        _assert_(inittag<MAXIMUMSIZE);
     102        if(xIsNan<IssmDouble>(this->time[inittag])) _error_("Tag not set");
     103        IssmDouble init = this->time[inittag];
     104
     105        /*Get final time*/
     106        _assert_(finaltag>=0);
     107        _assert_(finaltag<MAXIMUMSIZE);
     108        if(xIsNan<IssmDouble>(this->time[finaltag])) _error_("Tag not set");
     109        IssmDouble final = this->time[finaltag];
     110
     111        #ifdef _HAVE_MPI_
     112        return final-init;
     113        #else
     114        return (final-init)/CLOCKS_PER_SEC;
     115        #endif
     116}
     117/*}}}*/
     118int Profiler::DeltaTimeModHour(int inittag, int finishtag){/*{{{*/
     119
     120        IssmDouble delta = this->DeltaTime(inittag,finishtag);
     121        return int((reCast<int,IssmDouble>(delta))/3600);
     122
     123}
     124/*}}}*/
     125int Profiler::DeltaTimeModMin(int inittag, int finishtag){/*{{{*/
     126
     127        IssmDouble delta = this->DeltaTime(inittag,finishtag);
     128        return int(int(reCast<int,IssmDouble>(delta))%3600/60);
     129}
     130/*}}}*/
     131int Profiler::DeltaTimeModSec(int inittag, int finishtag){/*{{{*/
     132
     133        IssmDouble delta = this->DeltaTime(inittag,finishtag);
     134        return int(reCast<int,IssmDouble>(delta)%60);
     135}
     136/*}}}*/
     137IssmDouble  Profiler::Memory(int tag){/*{{{*/
     138
     139        /*Get initial flops*/
     140        _assert_(tag>=0);
     141        _assert_(tag<MAXIMUMSIZE);
     142        if(xIsNan<IssmDouble>(this->flops[tag])) _error_("Tag not set");
     143        return this->memory[tag];
     144}
     145/*}}}*/
    80146void  Profiler::Tag(int tagenum,bool dontmpisync){/*{{{*/
    81147
     
    117183}
    118184/*}}}*/
    119 IssmDouble  Profiler::DeltaTime(int inittag, int finaltag){/*{{{*/
    120 
    121         /*Get initial time*/
    122         _assert_(inittag>=0);
    123         _assert_(inittag<MAXIMUMSIZE);
    124         if(xIsNan<IssmDouble>(this->time[inittag])) _error_("Tag not set");
    125         IssmDouble init = this->time[inittag];
    126 
    127         /*Get final time*/
    128         _assert_(finaltag>=0);
    129         _assert_(finaltag<MAXIMUMSIZE);
    130         if(xIsNan<IssmDouble>(this->time[finaltag])) _error_("Tag not set");
    131         IssmDouble final = this->time[finaltag];
    132 
    133         #ifdef _HAVE_MPI_
    134         return final-init;
    135         #else
    136         return (final-init)/CLOCKS_PER_SEC;
    137         #endif
    138 }
    139 /*}}}*/
    140 IssmDouble  Profiler::DeltaFlops(int inittag, int finaltag){/*{{{*/
    141 
    142         /*Get initial flops*/
    143         _assert_(inittag>=0);
    144         _assert_(inittag<MAXIMUMSIZE);
    145         if(xIsNan<IssmDouble>(this->flops[inittag])) _error_("Tag not set");
    146         IssmDouble init = this->flops[inittag];
    147 
    148         /*Get final flops*/
    149         _assert_(finaltag>=0);
    150         _assert_(finaltag<MAXIMUMSIZE);
    151         if(xIsNan<IssmDouble>(this->flops[finaltag])) _error_("Tag not set");
    152         IssmDouble final = this->flops[finaltag];
    153 
    154         return final-init;
    155 }
    156 /*}}}*/
    157 int Profiler::DeltaTimeModHour(int inittag, int finishtag){/*{{{*/
    158 
    159         IssmDouble delta = this->DeltaTime(inittag,finishtag);
    160         return int((reCast<int,IssmDouble>(delta))/3600);
    161 
    162 }
    163 /*}}}*/
    164 int Profiler::DeltaTimeModMin(int inittag, int finishtag){/*{{{*/
    165 
    166         IssmDouble delta = this->DeltaTime(inittag,finishtag);
    167         return int(int(reCast<int,IssmDouble>(delta))%3600/60);
    168 }
    169 /*}}}*/
    170 int Profiler::DeltaTimeModSec(int inittag, int finishtag){/*{{{*/
    171 
    172         IssmDouble delta = this->DeltaTime(inittag,finishtag);
    173         return int(reCast<int,IssmDouble>(delta)%60);
    174 }
    175 /*}}}*/
    176 IssmDouble  Profiler::Memory(int tag){/*{{{*/
    177 
    178         /*Get initial flops*/
    179         _assert_(tag>=0);
    180         _assert_(tag<MAXIMUMSIZE);
    181         if(xIsNan<IssmDouble>(this->flops[tag])) _error_("Tag not set");
    182         return this->memory[tag];
    183 }
    184 /*}}}*/
  • issm/trunk-jpl/src/c/classes/Profiler.h

    r20637 r20810  
    2727
    2828        public:
    29                 IssmDouble time[MAXIMUMSIZE];
    3029                IssmDouble flops[MAXIMUMSIZE];
    3130                IssmDouble memory[MAXIMUMSIZE];
     31                IssmDouble time[MAXIMUMSIZE];
    3232
    3333                /*Profiler constructors, destructors {{{*/
     
    3636                /*}}}*/
    3737                /*Object virtual functions definitions:{{{ */
     38                Object *copy();
     39                void    DeepEcho();
    3840                void    Echo();
    39                 void    DeepEcho();
    4041                int     Id();
     42                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    4143                int     ObjectEnum();
    42                 Object *copy();
    43                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);
    4444                /*}}}*/
    4545                /*Profiler routines {{{*/
    46                 void    Tag(int tagenum,bool dontmpisync=false);
    47                 IssmDouble  Memory(int tag);
     46                IssmDouble  DeltaFlops(int inittag, int finaltag);
    4847                IssmDouble  DeltaTime(int inittag, int finaltag);
    49                 IssmDouble  DeltaFlops(int inittag, int finaltag);
    5048                int     DeltaTimeModHour(int inittag, int finaltag);
    5149                int     DeltaTimeModMin(int inittag, int finaltag);
    5250                int     DeltaTimeModSec(int inittag, int finaltag);
     51                IssmDouble  Memory(int tag);
     52                void    Tag(int tagenum,bool dontmpisync=false);
    5353                /*}}}*/
    5454};
  • issm/trunk-jpl/src/c/classes/RiftStruct.h

    r14222 r20810  
    1010        public:
    1111                int      numrifts;
     12                int    **riftspairs;
     13                double **riftspenaltypairs;
     14                int     *riftsnumpairs;
     15                int     *riftsnumpenaltypairs;
     16                int     *riftsnumsegments;
    1217                int    **riftssegments;
    13                 int     *riftsnumsegments;
    14                 int    **riftspairs;
    15                 int     *riftsnumpairs;
    16                 double **riftspenaltypairs;
    17                 int     *riftsnumpenaltypairs;
    1818                int     *riftstips;
    1919                double **state;
  • issm/trunk-jpl/src/c/classes/Segment.h

    r19198 r20810  
    4646
    4747                /*Object virtual functions definitions:*/
     48                Object* copy() {/*{{{*/
     49                        return new Segment(this->eid,this->x1,this->y1,this->x2,this->y2);
     50                }
     51                /*}}}*/
     52                void DeepEcho(void){/*{{{*/
     53                        this->Echo();
     54                }
     55                /*}}}*/
    4856                void Echo(void){/*{{{*/
    4957
     
    5563                }
    5664                /*}}}*/
    57                 void DeepEcho(void){/*{{{*/
    58                         this->Echo();
    59                 }
     65                int    Id(void){ return eid; }/*{{{*/
    6066                /*}}}*/
    61                 int    Id(void){ return eid; }/*{{{*/
     67                void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/
     68                        _error_("not implemented yet!");
     69                }
    6270                /*}}}*/
    6371                int ObjectEnum(void){/*{{{*/
     
    6775                }
    6876                /*}}}*/
    69                 Object* copy() {/*{{{*/
    70                         return new Segment(this->eid,this->x1,this->y1,this->x2,this->y2);
    71                 }
    72                 /*}}}*/
    73                 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/
    74                         _error_("not implemented yet!");
    75                 }
    76                 /*}}}*/
    7777
    7878};
  • issm/trunk-jpl/src/c/classes/Update.h

    r16783 r20810  
    1414        public:
    1515
    16                 virtual void  InputUpdateFromVector(IssmDouble* vector, int name, int type)=0;
     16                virtual void  InputUpdateFromConstant(IssmDouble constant, int name)=0;
     17                virtual void  InputUpdateFromConstant(int constant, int name)=0;
     18                virtual void  InputUpdateFromConstant(bool constant, int name)=0;
    1719                #ifdef _HAVE_DAKOTA_
    1820                virtual void  InputUpdateFromMatrixDakota(IssmDouble* matrix, int rows, int ncols, int name, int type)=0;
    1921                virtual void  InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type)=0;
    2022                #endif
    21                 virtual void  InputUpdateFromConstant(IssmDouble constant, int name)=0;
    22                 virtual void  InputUpdateFromConstant(int constant, int name)=0;
    23                 virtual void  InputUpdateFromConstant(bool constant, int name)=0;
    2423                virtual void  InputUpdateFromIoModel(int index, IoModel* iomodel)=0;
     24                virtual void  InputUpdateFromVector(IssmDouble* vector, int name, int type)=0;
    2525
    2626};
  • issm/trunk-jpl/src/c/classes/Vertex.cpp

    r20690 r20810  
    6262
    6363/*Object virtual functions definitions:*/
     64Object* Vertex::copy() {/*{{{*/
     65
     66        return new Vertex(*this);
     67
     68}
     69/*}}}*/
     70void Vertex::DeepEcho(void){/*{{{*/
     71        this->Echo();
     72}
     73/*}}}*/
    6474void Vertex::Echo(void){/*{{{*/
    6575
     
    7888}
    7989/*}}}*/
    80 void Vertex::DeepEcho(void){/*{{{*/
    81         this->Echo();
    82 }
    83 /*}}}*/
    8490int Vertex::Id(void){ return id; }/*{{{*/
    85 /*}}}*/
    86 int Vertex::ObjectEnum(void){/*{{{*/
    87 
    88         return VertexEnum;
    89 
    90 }
    91 /*}}}*/
    92 Object* Vertex::copy() {/*{{{*/
    93 
    94         return new Vertex(*this);
    95 
    96 }
    9791/*}}}*/
    9892void Vertex::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
     
    112106}
    113107/*}}}*/
     108int Vertex::ObjectEnum(void){/*{{{*/
     109
     110        return VertexEnum;
     111
     112}
     113/*}}}*/
    114114
    115115/*Vertex management: */
    116116int        Vertex::Connectivity(void){return connectivity;}/*{{{*/
    117117/*}}}*/
     118void       Vertex::DistributePids(int* ppidcount){/*{{{*/
     119
     120        /*retrieve current pid*/
     121        int pidcount=*ppidcount;
     122
     123        /*This vertex is a clone! Don't distribute pids, it will get them from another cpu!*/
     124        if(this->clone) return;
     125
     126        /*This vertex should distribute its pid*/
     127        this->pid=pidcount;
     128        pidcount++;
     129
     130        /*Assign output pointers: */
     131        *ppidcount=pidcount;
     132}
     133/*}}}*/
     134IssmDouble Vertex::GetLatitude(){/*{{{*/
     135        return this->latitute;
     136}
     137/*}}}*/
     138IssmDouble Vertex::GetLongitude(){/*{{{*/
     139        return this->longitude;
     140}
     141/*}}}*/
     142IssmDouble Vertex::GetRadius(){/*{{{*/
     143        return this->R;
     144}
     145/*}}}*/
    118146IssmDouble Vertex::GetX(){/*{{{*/
    119147        return this->x;
     
    128156}
    129157/*}}}*/
    130 IssmDouble Vertex::GetLatitude(){/*{{{*/
    131         return this->latitute;
    132 }
    133 /*}}}*/
    134 IssmDouble Vertex::GetLongitude(){/*{{{*/
    135         return this->longitude;
    136 }
    137 /*}}}*/
    138 IssmDouble Vertex::GetRadius(){/*{{{*/
    139         return this->R;
     158void       Vertex::OffsetPids(int pidcount){/*{{{*/
     159
     160        /*This vertex is a clone, don't offset the pids*/
     161        if(this->clone) return;
     162
     163        /*This vertex should offset his pid, go ahead: */
     164        this->pid+=pidcount;
     165}
     166/*}}}*/
     167int        Vertex::Pid(void){ return pid; }/*{{{*/
     168/*}}}*/
     169void       Vertex::SetClone(int* minranks){/*{{{*/
     170
     171        int my_rank;
     172
     173        /*recover my_rank:*/
     174        my_rank=IssmComm::GetRank();
     175
     176        if (minranks[this->sid]==my_rank){
     177                this->clone=false;
     178        }
     179        else{
     180                /*!there is a cpu with lower rank that has the same vertex,
     181                therefore, I am a clone*/
     182                this->clone=true;
     183        }
     184
     185}
     186/*}}}*/
     187void       Vertex::ShowTruePids(int* truepids){/*{{{*/
     188
     189        /*Are we a clone? : */
     190        if(this->clone)return;
     191
     192        /*Ok, we are not a clone, just plug our pid into truepids: */
     193        truepids[this->sid]=this->pid;
    140194}
    141195/*}}}*/
    142196int        Vertex::Sid(void){ return sid; }/*{{{*/
    143197/*}}}*/
    144 int        Vertex::Pid(void){ return pid; }/*{{{*/
     198void       Vertex::ToXYZ(Matrix<IssmDouble>* matrix){/*{{{*/
     199
     200        IssmDouble xyz[3];
     201        int        indices[3];
     202
     203        if (this->clone==true) return;
     204
     205        xyz[0]=x;
     206        xyz[1]=y;
     207        xyz[2]=z;
     208        indices[0]=0;
     209        indices[1]=1;
     210        indices[2]=2;
     211
     212        matrix->SetValues(1,&sid,3,&indices[0],&xyz[0],INS_VAL);
     213}
     214/*}}}*/
     215void       Vertex::UpdateClonePids(int* alltruepids){/*{{{*/
     216
     217        /*If we are not a clone, don't update, we already have pids: */
     218        if(!this->clone)return;
     219
     220        /*Ok, we are a clone node, but we did not create the pid for this vertex
     221         * Therefore, our pid is garbage right now. Go pick it up in the alltruepids: */
     222        this->pid=alltruepids[this->sid];
     223}
    145224/*}}}*/
    146225void       Vertex::UpdatePosition(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz,Parameters* parameters,IssmDouble* surface,IssmDouble* bed){/*{{{*/
     
    179258}
    180259/*}}}*/
    181 void       Vertex::DistributePids(int* ppidcount){/*{{{*/
    182 
    183         /*retrieve current pid*/
    184         int pidcount=*ppidcount;
    185 
    186         /*This vertex is a clone! Don't distribute pids, it will get them from another cpu!*/
    187         if(this->clone) return;
    188 
    189         /*This vertex should distribute its pid*/
    190         this->pid=pidcount;
    191         pidcount++;
    192 
    193         /*Assign output pointers: */
    194         *ppidcount=pidcount;
    195 }
    196 /*}}}*/
    197 void       Vertex::OffsetPids(int pidcount){/*{{{*/
    198 
    199         /*This vertex is a clone, don't offset the pids*/
    200         if(this->clone) return;
    201 
    202         /*This vertex should offset his pid, go ahead: */
    203         this->pid+=pidcount;
    204 }
    205 /*}}}*/
    206 void       Vertex::ShowTruePids(int* truepids){/*{{{*/
    207 
    208         /*Are we a clone? : */
    209         if(this->clone)return;
    210 
    211         /*Ok, we are not a clone, just plug our pid into truepids: */
    212         truepids[this->sid]=this->pid;
    213 }
    214 /*}}}*/
    215 void       Vertex::UpdateClonePids(int* alltruepids){/*{{{*/
    216 
    217         /*If we are not a clone, don't update, we already have pids: */
    218         if(!this->clone)return;
    219 
    220         /*Ok, we are a clone node, but we did not create the pid for this vertex
    221          * Therefore, our pid is garbage right now. Go pick it up in the alltruepids: */
    222         this->pid=alltruepids[this->sid];
    223 }
    224 /*}}}*/
    225 void       Vertex::SetClone(int* minranks){/*{{{*/
    226 
    227         int my_rank;
    228 
    229         /*recover my_rank:*/
    230         my_rank=IssmComm::GetRank();
    231 
    232         if (minranks[this->sid]==my_rank){
    233                 this->clone=false;
    234         }
    235         else{
    236                 /*!there is a cpu with lower rank that has the same vertex,
    237                 therefore, I am a clone*/
    238                 this->clone=true;
    239         }
    240 
    241 }
    242 /*}}}*/
    243 void       Vertex::ToXYZ(Matrix<IssmDouble>* matrix){/*{{{*/
    244 
    245         IssmDouble xyz[3];
    246         int        indices[3];
    247 
    248         if (this->clone==true) return;
    249 
    250         xyz[0]=x;
    251         xyz[1]=y;
    252         xyz[2]=z;
    253         indices[0]=0;
    254         indices[1]=1;
    255         indices[2]=2;
    256 
    257         matrix->SetValues(1,&sid,3,&indices[0],&xyz[0],INS_VAL);
    258 }
    259 /*}}}*/
    260260void       Vertex::VertexCoordinates(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz, bool spherical){/*{{{*/
    261261
  • issm/trunk-jpl/src/c/classes/Vertex.h

    r19984 r20810  
    4949                /*}}}*/
    5050                /*Vertex management:*/
    51                 int        Pid(void);
    52                 int        Sid(void);
    5351                int        Connectivity(void);
     52                void       DistributePids(int* ppidcount);
     53                IssmDouble GetLatitude(void);
     54                IssmDouble GetLongitude(void);
     55                IssmDouble GetRadius(void);
    5456                IssmDouble GetX(void);
    5557                IssmDouble GetY(void);
    5658                IssmDouble GetZ(void);
    57                 IssmDouble GetLatitude(void);
    58                 IssmDouble GetLongitude(void);
    59                 IssmDouble GetRadius(void);
     59                void       OffsetPids(int pidcount);
     60                int        Pid(void);
     61                void       SetClone(int* minranks);
     62                void       ShowTruePids(int* borderpids);
     63                int        Sid(void);
     64                void       ToXYZ(Matrix<IssmDouble>* matrix);
     65                void       UpdateClonePids(int* allborderpids);
    6066                void       UpdatePosition(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz,Parameters* parameters,IssmDouble* thickness,IssmDouble* bed);
    61                 void       DistributePids(int* ppidcount);
    62                 void       OffsetPids(int pidcount);
    63                 void       ShowTruePids(int* borderpids);
    64                 void       UpdateClonePids(int* allborderpids);
    65                 void       SetClone(int* minranks);
    66                 void       ToXYZ(Matrix<IssmDouble>* matrix);
    6767                void       VertexCoordinates(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz,bool spherical=false);
    6868};
Note: See TracChangeset for help on using the changeset viewer.