Changeset 18920


Ignore:
Timestamp:
12/03/14 20:36:06 (10 years ago)
Author:
seroussi
Message:

CHG: alphabetical order in Element.cpp

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/Elements/Element.cpp

    r18908 r18920  
    306306}
    307307/*}}}*/
    308 void       Element::DeleteMaterials(void){/*{{{*/
    309         delete this->material;
    310 }/*}}}*/
    311308void       Element::DeepEcho(void){/*{{{*/
    312309
     
    343340}
    344341/*}}}*/
    345 void       Element::Echo(void){/*{{{*/
    346         _printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
    347         _printf_("   id : "<<this->id <<"\n");
    348         _printf_("   sid: "<<this->sid<<"\n");
    349         if(vertices){
    350                 int numvertices = this->GetNumberOfVertices();
    351                 for(int i=0;i<numvertices;i++) vertices[i]->Echo();
    352         }
    353         else _printf_("vertices = NULL\n");
    354 
    355         if(nodes){
    356                 int numnodes = this->GetNumberOfNodes();
    357                 for(int i=0;i<numnodes;i++) {
    358                         _printf_("nodes[" << i << "] = " << nodes[i]); 
    359                         nodes[i]->Echo();
    360                 }
    361         }
    362         else _printf_("nodes = NULL\n");
    363 
    364         if (material) material->Echo();
    365         else _printf_("material = NULL\n");
    366 
    367         if (matpar) matpar->Echo();
    368         else _printf_("matpar = NULL\n");
    369 
    370         _printf_("   parameters\n");
    371         if (parameters) parameters->Echo();
    372         else _printf_("parameters = NULL\n");
    373 
    374         _printf_("   inputs\n");
    375         if (inputs) inputs->Echo();
    376         else _printf_("inputs=NULL\n");
    377 }
    378 /*}}}*/
     342void       Element::DeleteInput(int input_enum){/*{{{*/
     343
     344        inputs->DeleteInput(input_enum);
     345
     346}
     347/*}}}*/
     348void       Element::DeleteMaterials(void){/*{{{*/
     349        delete this->material;
     350}/*}}}*/
    379351IssmDouble Element::Divergence(void){/*{{{*/
    380352        /*Compute element divergence*/
     
    419391        return divergence;
    420392}/*}}}*/
     393void       Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
     394
     395        /*Intermediaries*/
     396        IssmDouble dmudB;
     397        IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
     398        IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
     399        IssmDouble eps_eff;
     400        IssmDouble eps0=1.e-27;
     401
     402        if(dim==3){
     403                /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
     404                this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);
     405                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);
     406        }
     407        else{
     408                /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
     409                this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     410                eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);
     411        }
     412        /*Get viscosity*/
     413        material->GetViscosity_B(&dmudB,eps_eff);
     414
     415        /*Assign output pointer*/
     416        *pdmudB=dmudB;
     417
     418}
     419/*}}}*/
     420void       Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     421
     422        /*Intermediaries*/
     423        IssmDouble dmudB;
     424        IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
     425        IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy];    */
     426        IssmDouble eps_eff;
     427        IssmDouble eps0=1.e-27;
     428
     429        if(dim==3){
     430                /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
     431                this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
     432                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);
     433        }
     434        else{
     435                /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
     436                this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     437                eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0);
     438        }
     439        /*Get viscosity*/
     440        material->GetViscosity_B(&dmudB,eps_eff);
     441
     442        /*Assign output pointer*/
     443        *pdmudB=dmudB;
     444
     445}
     446/*}}}*/
    421447void       Element::dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    422448
     
    446472}
    447473/*}}}*/
    448 void       Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    449 
    450         /*Intermediaries*/
    451         IssmDouble dmudB;
    452         IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
    453         IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy];    */
    454         IssmDouble eps_eff;
    455         IssmDouble eps0=1.e-27;
    456 
    457         if(dim==3){
    458                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
    459                 this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
    460                 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);
    461         }
    462         else{
    463                 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
    464                 this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    465                 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0);
    466         }
    467         /*Get viscosity*/
    468         material->GetViscosity_B(&dmudB,eps_eff);
    469 
    470         /*Assign output pointer*/
    471         *pdmudB=dmudB;
    472 
    473 }
    474 /*}}}*/
    475 void       Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
    476 
    477         /*Intermediaries*/
    478         IssmDouble dmudB;
    479         IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz];    */
    480         IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy];    */
    481         IssmDouble eps_eff;
    482         IssmDouble eps0=1.e-27;
    483 
    484         if(dim==3){
    485                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
    486                 this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);
    487                 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);
    488         }
    489         else{
    490                 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/
    491                 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    492                 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);
    493         }
    494         /*Get viscosity*/
    495         material->GetViscosity_B(&dmudB,eps_eff);
    496 
    497         /*Assign output pointer*/
    498         *pdmudB=dmudB;
    499 
    500 }
    501 /*}}}*/
    502474void       Element::dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    503475
     
    527499}
    528500/*}}}*/
    529 void       Element::ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure){/*{{{*/
    530         matpar->ThermalToEnthalpy(penthalpy,temperature,waterfraction,pressure);
     501void       Element::Echo(void){/*{{{*/
     502        _printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
     503        _printf_("   id : "<<this->id <<"\n");
     504        _printf_("   sid: "<<this->sid<<"\n");
     505        if(vertices){
     506                int numvertices = this->GetNumberOfVertices();
     507                for(int i=0;i<numvertices;i++) vertices[i]->Echo();
     508        }
     509        else _printf_("vertices = NULL\n");
     510
     511        if(nodes){
     512                int numnodes = this->GetNumberOfNodes();
     513                for(int i=0;i<numnodes;i++) {
     514                        _printf_("nodes[" << i << "] = " << nodes[i]); 
     515                        nodes[i]->Echo();
     516                }
     517        }
     518        else _printf_("nodes = NULL\n");
     519
     520        if (material) material->Echo();
     521        else _printf_("material = NULL\n");
     522
     523        if (matpar) matpar->Echo();
     524        else _printf_("matpar = NULL\n");
     525
     526        _printf_("   parameters\n");
     527        if (parameters) parameters->Echo();
     528        else _printf_("parameters = NULL\n");
     529
     530        _printf_("   inputs\n");
     531        if (inputs) inputs->Echo();
     532        else _printf_("inputs=NULL\n");
     533}
     534/*}}}*/
     535IssmDouble Element::EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
     536        return matpar->GetEnthalpyDiffusionParameter(enthalpy,pressure);
     537}/*}}}*/
     538IssmDouble Element::EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure){/*{{{*/
     539        return matpar->GetEnthalpyDiffusionParameterVolume(numvertices,enthalpy,pressure);
    531540}/*}}}*/
    532541void       Element::EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
    533542        matpar->EnthalpyToThermal(ptemperature,pwaterfraction,enthalpy,pressure);
    534 }/*}}}*/
    535 IssmDouble Element::EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
    536         return matpar->GetEnthalpyDiffusionParameter(enthalpy,pressure);
    537 }/*}}}*/
    538 IssmDouble Element::EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure){/*{{{*/
    539         return matpar->GetEnthalpyDiffusionParameterVolume(numvertices,enthalpy,pressure);
    540543}/*}}}*/
    541544void       Element::FindParam(bool* pvalue,int paramenum){/*{{{*/
     
    574577}
    575578/*}}}*/
     579void       Element::GetDofListPressure(int** pdoflist,int setenum){/*{{{*/
     580
     581        /*Fetch number of nodes and dof for this finite element*/
     582        int vnumnodes = this->NumberofNodesVelocity();
     583        int pnumnodes = this->NumberofNodesPressure();
     584
     585        /*First, figure out size of doflist and create it: */
     586        int numberofdofs=0;
     587        for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
     588
     589        /*Allocate output*/
     590        int* doflist=xNew<int>(numberofdofs);
     591
     592        /*Populate: */
     593        int count=0;
     594        for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
     595                nodes[i]->GetDofList(doflist+count,FSApproximationEnum,setenum);
     596                count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
     597        }
     598
     599        /*Assign output pointers:*/
     600        *pdoflist=doflist;
     601}
     602/*}}}*/
    576603void       Element::GetDofListVelocity(int** pdoflist,int setenum){/*{{{*/
    577604
     
    597624}
    598625/*}}}*/
    599 void       Element::GetDofListPressure(int** pdoflist,int setenum){/*{{{*/
    600 
    601         /*Fetch number of nodes and dof for this finite element*/
    602         int vnumnodes = this->NumberofNodesVelocity();
    603         int pnumnodes = this->NumberofNodesPressure();
    604 
    605         /*First, figure out size of doflist and create it: */
    606         int numberofdofs=0;
    607         for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
    608 
    609         /*Allocate output*/
    610         int* doflist=xNew<int>(numberofdofs);
    611 
    612         /*Populate: */
    613         int count=0;
    614         for(int i=vnumnodes;i<vnumnodes+pnumnodes;i++){
    615                 nodes[i]->GetDofList(doflist+count,FSApproximationEnum,setenum);
    616                 count+=nodes[i]->GetNumberOfDofs(FSApproximationEnum,setenum);
    617         }
    618 
    619         /*Assign output pointers:*/
    620         *pdoflist=doflist;
    621 }
    622 /*}}}*/
     626Input*     Element::GetInput(int inputenum){/*{{{*/
     627        return inputs->GetInput(inputenum);
     628}/*}}}*/
     629void       Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
     630
     631        _assert_(pvalue);
     632
     633        Input *input    = this->GetInput(enumtype);
     634        int    numnodes = this->GetNumberOfNodes();
     635
     636        /* Start looping on the number of vertices: */
     637        if(input){
     638                Gauss* gauss=this->NewGauss();
     639                for(int iv=0;iv<numnodes;iv++){
     640                        gauss->GaussNode(this->FiniteElement(),iv);
     641                        input->GetInputValue(&pvalue[iv],gauss);
     642                }
     643                delete gauss;
     644        }
     645        else{
     646                for(int iv=0;iv<numnodes;iv++) pvalue[iv]=defaultvalue;
     647        }
     648}
     649/*}}}*/
     650void       Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){/*{{{*/
     651
     652        _assert_(pvalue);
     653
     654        int    numnodes = this->GetNumberOfNodes();
     655        Input *input    = this->GetInput(enumtype);
     656        if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
     657
     658        /* Start looping on the number of vertices: */
     659        Gauss* gauss=this->NewGauss();
     660        for(int iv=0;iv<numnodes;iv++){
     661                gauss->GaussNode(this->FiniteElement(),iv);
     662                input->GetInputValue(&pvalue[iv],gauss);
     663        }
     664        delete gauss;
     665}
     666/*}}}*/
     667void       Element::GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype){/*{{{*/
     668
     669        _assert_(pvalue);
     670
     671        int    numnodes = this->NumberofNodesVelocity();
     672        Input *input    = this->GetInput(enumtype);
     673        if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
     674
     675        /* Start looping on the number of vertices: */
     676        Gauss* gauss=this->NewGauss();
     677        for(int iv=0;iv<numnodes;iv++){
     678                gauss->GaussNode(this->VelocityInterpolation(),iv);
     679                input->GetInputValue(&pvalue[iv],gauss);
     680        }
     681        delete gauss;
     682}
     683/*}}}*/
     684void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){/*{{{*/
     685
     686        /*Recover input*/
     687        Input* input=this->GetInput(enumtype);
     688        if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
     689
     690        /*Fetch number vertices for this element*/
     691        int numvertices = this->GetNumberOfVertices();
     692
     693        /*Checks in debugging mode*/
     694        _assert_(pvalue);
     695
     696        /* Start looping on the number of vertices: */
     697        Gauss*gauss=this->NewGauss();
     698        for(int iv=0;iv<numvertices;iv++){
     699                gauss->GaussVertex(iv);
     700                input->GetInputValue(&pvalue[iv],gauss);
     701        }
     702
     703        /*clean-up*/
     704        delete gauss;
     705}
     706/*}}}*/
     707void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
     708
     709        /*Recover input*/
     710        Input* input=this->GetInput(enumtype);
     711
     712        /*Checks in debugging mode*/
     713        _assert_(pvalue);
     714
     715        /*Fetch number vertices for this element*/
     716        int numvertices = this->GetNumberOfVertices();
     717
     718        /* Start looping on the number of vertices: */
     719        if (input){
     720                Gauss* gauss=this->NewGauss();
     721                for (int iv=0;iv<numvertices;iv++){
     722                        gauss->GaussVertex(iv);
     723                        input->GetInputValue(&pvalue[iv],gauss);
     724                }
     725                delete gauss;
     726        }
     727        else{
     728                for(int iv=0;iv<numvertices;iv++) pvalue[iv]=defaultvalue;
     729        }
     730}
     731/*}}}*/
     732void       Element::GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug){/*{{{*/
     733
     734
     735        /*Get number of nodes for this element*/
     736        int numnodes = this->GetNumberOfNodes();
     737
     738        /*Some checks to avoid segmentation faults*/
     739        _assert_(ug);
     740        _assert_(numnodes>0);
     741        _assert_(nodes);
     742
     743        /*Get element minimum/maximum*/
     744        IssmDouble input_min = ug[nodes[0]->GetDof(0,GsetEnum)];
     745        IssmDouble input_max = input_min;
     746        for(int i=1;i<numnodes;i++){
     747                if(ug[nodes[i]->GetDof(0,GsetEnum)] < input_min) input_min = ug[nodes[i]->GetDof(0,GsetEnum)];
     748                if(ug[nodes[i]->GetDof(0,GsetEnum)] > input_max) input_max = ug[nodes[i]->GetDof(0,GsetEnum)];
     749        }
     750
     751
     752        /*Second loop to reassign min and max with local extrema*/
     753        for(int i=0;i<numnodes;i++){
     754                if(min[nodes[i]->GetDof(0,GsetEnum)]>input_min) min[nodes[i]->GetDof(0,GsetEnum)] = input_min;
     755                if(max[nodes[i]->GetDof(0,GsetEnum)]<input_max) max[nodes[i]->GetDof(0,GsetEnum)] = input_max;
     756        }
     757}
     758/*}}}*/
     759void       Element::GetInputValue(bool* pvalue,int inputenum){/*{{{*/
     760
     761        Input* input=inputs->GetInput(inputenum);
     762        if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
     763        input->GetInputValue(pvalue);
     764
     765}/*}}}*/
     766void       Element::GetInputValue(int* pvalue,int inputenum){/*{{{*/
     767
     768        Input* input=inputs->GetInput(inputenum);
     769        if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
     770        input->GetInputValue(pvalue);
     771
     772}/*}}}*/
     773void       Element::GetInputValue(IssmDouble* pvalue,int inputenum){/*{{{*/
     774
     775        Input* input=inputs->GetInput(inputenum);
     776        if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
     777        input->GetInputValue(pvalue);
     778
     779}/*}}}*/
     780void       Element::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int inputenum){/*{{{*/
     781
     782        Input* input=inputs->GetInput(inputenum);
     783        if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
     784        input->GetInputValue(pvalue,gauss);
     785
     786}/*}}}*/
    623787IssmDouble Element::GetMaterialParameter(int enum_in){/*{{{*/
    624788
     
    635799        }
    636800}/*}}}*/
     801void       Element::GetNodesLidList(int* lidlist){/*{{{*/
     802
     803        _assert_(lidlist);
     804        _assert_(nodes);
     805        int numnodes = this->GetNumberOfNodes();
     806        for(int i=0;i<numnodes;i++){
     807                lidlist[i]=nodes[i]->Lid();
     808        }
     809}
     810/*}}}*/
     811void       Element::GetNodesSidList(int* sidlist){/*{{{*/
     812
     813        _assert_(sidlist);
     814        _assert_(nodes);
     815        int numnodes = this->GetNumberOfNodes();
     816        for(int i=0;i<numnodes;i++){
     817                sidlist[i]=nodes[i]->Sid();
     818        }
     819}
     820/*}}}*/
    637821void       Element::GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity){/*{{{*/
    638822        /*Compute deformational heating from epsilon and viscosity */
     
    672856}
    673857/*}}}*/
    674 Input*     Element::GetInput(int inputenum){/*{{{*/
    675         return inputs->GetInput(inputenum);
    676 }/*}}}*/
    677 void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){/*{{{*/
    678 
    679         /*Recover input*/
    680         Input* input=this->GetInput(enumtype);
    681         if (!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
    682 
    683         /*Fetch number vertices for this element*/
    684         int numvertices = this->GetNumberOfVertices();
    685 
    686         /*Checks in debugging mode*/
    687         _assert_(pvalue);
    688 
    689         /* Start looping on the number of vertices: */
    690         Gauss*gauss=this->NewGauss();
    691         for(int iv=0;iv<numvertices;iv++){
    692                 gauss->GaussVertex(iv);
    693                 input->GetInputValue(&pvalue[iv],gauss);
    694         }
    695 
    696         /*clean-up*/
    697         delete gauss;
    698 }
    699 /*}}}*/
    700 void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
    701 
    702         /*Recover input*/
    703         Input* input=this->GetInput(enumtype);
    704 
    705         /*Checks in debugging mode*/
    706         _assert_(pvalue);
    707 
    708         /*Fetch number vertices for this element*/
    709         int numvertices = this->GetNumberOfVertices();
    710 
    711         /* Start looping on the number of vertices: */
    712         if (input){
    713                 Gauss* gauss=this->NewGauss();
    714                 for (int iv=0;iv<numvertices;iv++){
    715                         gauss->GaussVertex(iv);
    716                         input->GetInputValue(&pvalue[iv],gauss);
    717                 }
    718                 delete gauss;
    719         }
    720         else{
    721                 for(int iv=0;iv<numvertices;iv++) pvalue[iv]=defaultvalue;
    722         }
    723 }
    724 /*}}}*/
    725 void       Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
    726 
    727         _assert_(pvalue);
    728 
    729         Input *input    = this->GetInput(enumtype);
    730         int    numnodes = this->GetNumberOfNodes();
    731 
    732         /* Start looping on the number of vertices: */
    733         if(input){
    734                 Gauss* gauss=this->NewGauss();
    735                 for(int iv=0;iv<numnodes;iv++){
    736                         gauss->GaussNode(this->FiniteElement(),iv);
    737                         input->GetInputValue(&pvalue[iv],gauss);
    738                 }
    739                 delete gauss;
    740         }
    741         else{
    742                 for(int iv=0;iv<numnodes;iv++) pvalue[iv]=defaultvalue;
    743         }
    744 }
    745 /*}}}*/
    746 void       Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){/*{{{*/
    747 
    748         _assert_(pvalue);
    749 
    750         int    numnodes = this->GetNumberOfNodes();
    751         Input *input    = this->GetInput(enumtype);
    752         if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
    753 
    754         /* Start looping on the number of vertices: */
    755         Gauss* gauss=this->NewGauss();
    756         for(int iv=0;iv<numnodes;iv++){
    757                 gauss->GaussNode(this->FiniteElement(),iv);
    758                 input->GetInputValue(&pvalue[iv],gauss);
    759         }
    760         delete gauss;
    761 }
    762 /*}}}*/
    763 void       Element::GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype){/*{{{*/
    764 
    765         _assert_(pvalue);
    766 
    767         int    numnodes = this->NumberofNodesVelocity();
    768         Input *input    = this->GetInput(enumtype);
    769         if(!input) _error_("Input " << EnumToStringx(enumtype) << " not found in element");
    770 
    771         /* Start looping on the number of vertices: */
    772         Gauss* gauss=this->NewGauss();
    773         for(int iv=0;iv<numnodes;iv++){
    774                 gauss->GaussNode(this->VelocityInterpolation(),iv);
    775                 input->GetInputValue(&pvalue[iv],gauss);
    776         }
    777         delete gauss;
    778 }
    779 /*}}}*/
    780 void       Element::GetInputLocalMinMaxOnNodes(IssmDouble* min,IssmDouble* max,IssmDouble* ug){/*{{{*/
    781 
    782 
    783         /*Get number of nodes for this element*/
    784         int numnodes = this->GetNumberOfNodes();
    785 
    786         /*Some checks to avoid segmentation faults*/
    787         _assert_(ug);
    788         _assert_(numnodes>0);
    789         _assert_(nodes);
    790 
    791         /*Get element minimum/maximum*/
    792         IssmDouble input_min = ug[nodes[0]->GetDof(0,GsetEnum)];
    793         IssmDouble input_max = input_min;
    794         for(int i=1;i<numnodes;i++){
    795                 if(ug[nodes[i]->GetDof(0,GsetEnum)] < input_min) input_min = ug[nodes[i]->GetDof(0,GsetEnum)];
    796                 if(ug[nodes[i]->GetDof(0,GsetEnum)] > input_max) input_max = ug[nodes[i]->GetDof(0,GsetEnum)];
    797         }
    798 
    799 
    800         /*Second loop to reassign min and max with local extrema*/
    801         for(int i=0;i<numnodes;i++){
    802                 if(min[nodes[i]->GetDof(0,GsetEnum)]>input_min) min[nodes[i]->GetDof(0,GsetEnum)] = input_min;
    803                 if(max[nodes[i]->GetDof(0,GsetEnum)]<input_max) max[nodes[i]->GetDof(0,GsetEnum)] = input_max;
    804         }
    805 }
    806 /*}}}*/
    807 void       Element::GetInputValue(bool* pvalue,int inputenum){/*{{{*/
    808 
    809         Input* input=inputs->GetInput(inputenum);
    810         if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
    811         input->GetInputValue(pvalue);
    812 
    813 }/*}}}*/
    814 void       Element::GetInputValue(int* pvalue,int inputenum){/*{{{*/
    815 
    816         Input* input=inputs->GetInput(inputenum);
    817         if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
    818         input->GetInputValue(pvalue);
    819 
    820 }/*}}}*/
    821 void       Element::GetInputValue(IssmDouble* pvalue,int inputenum){/*{{{*/
    822 
    823         Input* input=inputs->GetInput(inputenum);
    824         if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
    825         input->GetInputValue(pvalue);
    826 
    827 }/*}}}*/
    828 void       Element::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int inputenum){/*{{{*/
    829 
    830         Input* input=inputs->GetInput(inputenum);
    831         if(!input) _error_("Input " << EnumToStringx(inputenum) << " not found in element");
    832         input->GetInputValue(pvalue,gauss);
    833 
    834 }/*}}}*/
    835 void       Element::GetNodesSidList(int* sidlist){/*{{{*/
    836 
    837         _assert_(sidlist);
    838         _assert_(nodes);
    839         int numnodes = this->GetNumberOfNodes();
    840         for(int i=0;i<numnodes;i++){
    841                 sidlist[i]=nodes[i]->Sid();
    842         }
    843 }
    844 /*}}}*/
    845 void       Element::GetNodesLidList(int* lidlist){/*{{{*/
    846 
    847         _assert_(lidlist);
    848         _assert_(nodes);
    849         int numnodes = this->GetNumberOfNodes();
    850         for(int i=0;i<numnodes;i++){
    851                 lidlist[i]=nodes[i]->Lid();
    852         }
    853 }
    854 /*}}}*/
    855858void       Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){/*{{{*/
    856859
     
    878881}
    879882/*}}}*/
     883void       Element::GetVerticesConnectivityList(int* connectivity){/*{{{*/
     884
     885        int numvertices = this->GetNumberOfVertices();
     886        for(int i=0;i<numvertices;i++) connectivity[i]=this->vertices[i]->Connectivity();
     887}
     888/*}}}*/
    880889void       Element::GetVerticesCoordinates(IssmDouble** pxyz_list){/*{{{*/
    881890
     
    891900        int numvertices = this->GetNumberOfVertices();
    892901        for(int i=0;i<numvertices;i++) sidlist[i]=this->vertices[i]->Sid();
    893 }
    894 /*}}}*/
    895 void       Element::GetVerticesConnectivityList(int* connectivity){/*{{{*/
    896 
    897         int numvertices = this->GetNumberOfVertices();
    898         for(int i=0;i<numvertices;i++) connectivity[i]=this->vertices[i]->Connectivity();
    899902}
    900903/*}}}*/
     
    10551058        /*Call inputs method*/
    10561059        if (IsInput(original_enum)) inputs->DuplicateInput(original_enum,new_enum);
    1057 
    1058 }
    1059 /*}}}*/
    1060 void       Element::DeleteInput(int input_enum){/*{{{*/
    1061 
    1062         inputs->DeleteInput(input_enum);
    10631060
    10641061}
     
    12981295}
    12991296/*}}}*/
     1297ElementMatrix* Element::NewElementMatrix(int approximation_enum){/*{{{*/
     1298        return new ElementMatrix(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
     1299}
     1300/*}}}*/
     1301ElementMatrix* Element::NewElementMatrixCoupling(int number_nodes,int approximation_enum){/*{{{*/
     1302        return new ElementMatrix(nodes,number_nodes,this->parameters,approximation_enum);
     1303}
     1304/*}}}*/
    13001305ElementVector* Element::NewElementVector(int approximation_enum){/*{{{*/
    13011306        return new ElementVector(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
    1302 }
    1303 /*}}}*/
    1304 ElementMatrix* Element::NewElementMatrix(int approximation_enum){/*{{{*/
    1305         return new ElementMatrix(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum);
    1306 }
    1307 /*}}}*/
    1308 ElementMatrix* Element::NewElementMatrixCoupling(int number_nodes,int approximation_enum){/*{{{*/
    1309         return new ElementMatrix(nodes,number_nodes,this->parameters,approximation_enum);
    13101307}
    13111308/*}}}*/
     
    13931390        *pnodesperelement = input->GetResultNumberOfNodes();
    13941391}/*}}}*/
     1392void       Element::ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum){/*{{{*/
     1393
     1394        Input* input=this->inputs->GetInput(output_enum);
     1395        if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
     1396
     1397        input->ResultToPatch(values,nodesperelement,this->Sid());
     1398
     1399} /*}}}*/
    13951400void       Element::ResultToVector(Vector<IssmDouble>* vector,int output_enum){/*{{{*/
    13961401
     
    14401445                                         _error_("interpolation "<<EnumToStringx(input->GetResultInterpolation())<<" not supported yet");
    14411446        }
    1442 } /*}}}*/
    1443 void       Element::ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum){/*{{{*/
    1444 
    1445         Input* input=this->inputs->GetInput(output_enum);
    1446         if(!input) _error_("input "<<EnumToStringx(output_enum)<<" not found in element");
    1447 
    1448         input->ResultToPatch(values,nodesperelement,this->Sid());
    1449 
    14501447} /*}}}*/
    14511448void       Element::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){/*{{{*/
     
    15251522}
    15261523/*}}}*/
    1527 IssmDouble Element::TMeltingPoint(IssmDouble pressure){/*{{{*/
    1528         _assert_(matpar);
    1529         return this->matpar->TMeltingPoint(pressure);
     1524void       Element::StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
     1525        /*Compute the 3d Strain Rate (6 components):
     1526         *
     1527         * epsilon=[exx eyy ezz exy exz eyz]
     1528         */
     1529
     1530        /*Intermediaries*/
     1531        IssmDouble dvx[3];
     1532        IssmDouble dvy[3];
     1533        IssmDouble dvz[3];
     1534
     1535        /*Check that both inputs have been found*/
     1536        if (!vx_input || !vy_input || !vz_input){
     1537                _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << ", vz: " << vz_input << "\n");
     1538        }
     1539
     1540        /*Get strain rate assuming that epsilon has been allocated*/
     1541        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     1542        vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
     1543        vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
     1544        epsilon[0] = dvx[0];
     1545        epsilon[1] = dvy[1];
     1546        epsilon[2] = dvz[2];
     1547        epsilon[3] = 0.5*(dvx[1] + dvy[0]);
     1548        epsilon[4] = 0.5*(dvx[2] + dvz[0]);
     1549        epsilon[5] = 0.5*(dvy[2] + dvz[1]);
     1550
     1551}/*}}}*/
     1552void       Element::StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     1553        /*Compute the 3d Blatter/HOStrain Rate (5 components):
     1554         *
     1555         * epsilon=[exx eyy exy exz eyz]
     1556         *
     1557         * with exz=1/2 du/dz
     1558         *      eyz=1/2 dv/dz
     1559         *
     1560         * the contribution of vz is neglected
     1561         */
     1562
     1563        /*Intermediaries*/
     1564        IssmDouble dvx[3];
     1565        IssmDouble dvy[3];
     1566
     1567        /*Check that both inputs have been found*/
     1568        if (!vx_input || !vy_input){
     1569                _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
     1570        }
     1571
     1572        /*Get strain rate assuming that epsilon has been allocated*/
     1573        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     1574        vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
     1575        epsilon[0] = dvx[0];
     1576        epsilon[1] = dvy[1];
     1577        epsilon[2] = 0.5*(dvx[1] + dvy[0]);
     1578        epsilon[3] = 0.5*dvx[2];
     1579        epsilon[4] = 0.5*dvy[2];
     1580
     1581}/*}}}*/
     1582void       Element::StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     1583        /*Compute the 2d Blatter/HOStrain Rate (2 components):
     1584         *
     1585         * epsilon=[exx exz]
     1586         *
     1587         * with exz=1/2 du/dz
     1588         *
     1589         * the contribution of vz is neglected
     1590         */
     1591
     1592        /*Intermediaries*/
     1593        IssmDouble dvx[3];
     1594
     1595        /*Check that both inputs have been found*/
     1596        if (!vx_input){
     1597                _error_("Input missing. Here are the input pointers we have for vx: " << vx_input <<"\n");
     1598        }
     1599
     1600        /*Get strain rate assuming that epsilon has been allocated*/
     1601        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     1602        epsilon[0] = dvx[0];
     1603        epsilon[1] = 0.5*dvx[1];
     1604
     1605}/*}}}*/
     1606void       Element::StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     1607
     1608        /*Intermediaries*/
     1609        IssmDouble dvx[3];
     1610        IssmDouble dvy[3];
     1611
     1612        /*Check that both inputs have been found*/
     1613        if(!vx_input || !vy_input){
     1614                _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
     1615        }
     1616
     1617        /*Get strain rate assuming that epsilon has been allocated*/
     1618        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     1619        vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
     1620        epsilon[0] = dvx[0];
     1621        epsilon[1] = dvy[1];
     1622        epsilon[2] = 0.5*(dvx[1] + dvy[0]);
     1623
     1624}/*}}}*/
     1625void       Element::StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input){/*{{{*/
     1626
     1627        /*Intermediaries*/
     1628        IssmDouble dvx[3];
     1629
     1630        /*Check that both inputs have been found*/
     1631        if (!vx_input){
     1632                _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << "\n");
     1633        }
     1634
     1635        /*Get strain rate assuming that epsilon has been allocated*/
     1636        vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
     1637        *epsilon = dvx[0];
     1638
    15301639}/*}}}*/
    15311640void       Element::StressMaxPrincipalCreateInput(void){/*{{{*/
     
    16151724}
    16161725/*}}}*/
    1617 void       Element::ViscousHeatingCreateInput(void){/*{{{*/
    1618 
    1619         /*Intermediaries*/
    1620         IssmDouble phi;
    1621         IssmDouble viscosity;
    1622         IssmDouble epsilon[6];
    1623         IssmDouble thickness;
    1624         IssmDouble *xyz_list = NULL;
    1625 
    1626         /*Fetch number vertices and allocate memory*/
    1627         int         numvertices    = this->GetNumberOfVertices();
    1628         IssmDouble* viscousheating = xNew<IssmDouble>(numvertices);
    1629 
    1630         /*Retrieve all inputs and parameters*/
    1631         this->GetVerticesCoordinatesBase(&xyz_list);
    1632         Input* vx_input        = this->GetInput(VxEnum); _assert_(vx_input);
    1633         Input* vy_input        = this->GetInput(VyEnum); _assert_(vy_input);
    1634         Input* vz_input        = this->GetInput(VzEnum); _assert_(vz_input);
    1635         Input* thickness_input = this->GetInput(ThicknessEnum); _assert_(thickness_input);
    1636 
    1637         /*loop over vertices: */
    1638         Gauss* gauss=this->NewGauss();
    1639         for (int iv=0;iv<numvertices;iv++){
    1640                 gauss->GaussVertex(iv);
    1641 
    1642                 thickness_input->GetInputValue(&thickness,gauss);
    1643 
    1644                 this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
    1645                 this->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
    1646                 this->GetPhi(&phi,&epsilon[0],viscosity);
    1647 
    1648                 viscousheating[iv]=phi*thickness;
    1649         }
    1650 
    1651         /*Create PentaVertex input, which will hold the basal friction:*/
    1652         this->AddInput(ViscousHeatingEnum,viscousheating,P1Enum);
    1653 
    1654         /*Clean up and return*/
    1655         xDelete<IssmDouble>(viscousheating);
    1656         delete gauss;
    1657 }
    1658 /*}}}*/
     1726void       Element::ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure){/*{{{*/
     1727        matpar->ThermalToEnthalpy(penthalpy,temperature,waterfraction,pressure);
     1728}/*}}}*/
     1729IssmDouble Element::TMeltingPoint(IssmDouble pressure){/*{{{*/
     1730        _assert_(matpar);
     1731        return this->matpar->TMeltingPoint(pressure);
     1732}/*}}}*/
     1733void       Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
     1734
     1735        /*All nodes have the same Coordinate System*/
     1736        int numnodes  = this->GetNumberOfNodes();
     1737        int* cs_array = xNew<int>(numnodes);
     1738        for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
     1739
     1740        /*Call core*/
     1741        TransformInvStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
     1742
     1743        /*Clean-up*/
     1744        xDelete<int>(cs_array);
     1745}/*}}}*/
     1746void       Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
     1747
     1748        int         i,j;
     1749        int         numdofs   = 0;
     1750        IssmDouble *transform = NULL;
     1751        IssmDouble *values    = NULL;
     1752
     1753        /*Get total number of dofs*/
     1754        for(i=0;i<numnodes;i++){
     1755                switch(cs_array[i]){
     1756                        case PressureEnum: numdofs+=1; break;
     1757                        case XYEnum:       numdofs+=2; break;
     1758                        case XYZEnum:      numdofs+=3; break;
     1759                        default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
     1760                }
     1761        }
     1762
     1763        /*Copy current stiffness matrix*/
     1764        values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
     1765        for(i=0;i<Ke->nrows;i++) for(j=0;j<Ke->ncols;j++) values[i*Ke->ncols+j]=Ke->values[i*Ke->ncols+j];
     1766
     1767        /*Get Coordinate Systems transform matrix*/
     1768        CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
     1769
     1770        /*Transform matrix: R*Ke*R^T */
     1771        TripleMultiply(transform,numdofs,numdofs,0,
     1772                                values,Ke->nrows,Ke->ncols,0,
     1773                                transform,numdofs,numdofs,1,
     1774                                &Ke->values[0],0);
     1775
     1776        /*Free Matrix*/
     1777        xDelete<IssmDouble>(transform);
     1778        xDelete<IssmDouble>(values);
     1779}/*}}}*/
     1780void       Element::TransformLoadVectorCoord(ElementVector* pe,int transformenum){/*{{{*/
     1781
     1782        /*All nodes have the same Coordinate System*/
     1783        int  numnodes = this->GetNumberOfNodes();
     1784        int* cs_array = xNew<int>(numnodes);
     1785        for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
     1786
     1787        /*Call core*/
     1788        this->TransformLoadVectorCoord(pe,this->nodes,numnodes,cs_array);
     1789
     1790        /*Clean-up*/
     1791        xDelete<int>(cs_array);
     1792}/*}}}*/
     1793void       Element::TransformLoadVectorCoord(ElementVector* pe,int* cs_array){/*{{{*/
     1794
     1795        this->TransformLoadVectorCoord(pe,this->nodes,this->GetNumberOfNodes(),cs_array);
     1796
     1797}/*}}}*/
     1798void       Element::TransformLoadVectorCoord(ElementVector* pe,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
     1799
     1800        int         i;
     1801        int         numdofs   = 0;
     1802        IssmDouble *transform = NULL;
     1803        IssmDouble *values    = NULL;
     1804
     1805        /*Get total number of dofs*/
     1806        for(i=0;i<numnodes;i++){
     1807                switch(cs_array[i]){
     1808                        case PressureEnum: numdofs+=1; break;
     1809                        case XYEnum:       numdofs+=2; break;
     1810                        case XYZEnum:      numdofs+=3; break;
     1811                        default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
     1812                }
     1813        }
     1814
     1815        /*Copy current load vector*/
     1816        values=xNew<IssmDouble>(pe->nrows);
     1817        for(i=0;i<pe->nrows;i++) values[i]=pe->values[i];
     1818
     1819        /*Get Coordinate Systems transform matrix*/
     1820        CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
     1821
     1822        /*Transform matrix: R^T*pe */
     1823        MatrixMultiply(transform,numdofs,numdofs,1,
     1824                                values,pe->nrows,1,0,
     1825                                &pe->values[0],0);
     1826
     1827        /*Free Matrices*/
     1828        xDelete<IssmDouble>(transform);
     1829        xDelete<IssmDouble>(values);
     1830}/*}}}*/
     1831void       Element::TransformSolutionCoord(IssmDouble* values,int transformenum){/*{{{*/
     1832
     1833        /*All nodes have the same Coordinate System*/
     1834        int  numnodes = this->GetNumberOfNodes();
     1835        int* cs_array = xNew<int>(numnodes);
     1836        for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
     1837
     1838        /*Call core*/
     1839        this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
     1840
     1841        /*Clean-up*/
     1842        xDelete<int>(cs_array);
     1843}/*}}}*/
     1844void       Element::TransformSolutionCoord(IssmDouble* values,int* transformenum_list){/*{{{*/
     1845        this->TransformSolutionCoord(values,this->nodes,this->GetNumberOfNodes(),transformenum_list);
     1846}/*}}}*/
     1847void       Element::TransformSolutionCoord(IssmDouble* values,int numnodes,int transformenum){/*{{{*/
     1848
     1849        /*All nodes have the same Coordinate System*/
     1850        int* cs_array = xNew<int>(numnodes);
     1851        for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
     1852
     1853        /*Call core*/
     1854        this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
     1855
     1856        /*Clean-up*/
     1857        xDelete<int>(cs_array);
     1858}/*}}}*/
     1859void       Element::TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array){/*{{{*/
     1860        this->TransformSolutionCoord(solution,this->nodes,numnodes,cs_array);
     1861}/*}}}*/
     1862void       Element::TransformSolutionCoord(IssmDouble* values,Node** nodes_list,int numnodes,int transformenum){/*{{{*/
     1863        /*NOT NEEDED*/
     1864        /*All nodes have the same Coordinate System*/
     1865        int* cs_array = xNew<int>(numnodes);
     1866        for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
     1867
     1868        /*Call core*/
     1869        this->TransformSolutionCoord(values,nodes_list,numnodes,cs_array);
     1870
     1871        /*Clean-up*/
     1872        xDelete<int>(cs_array);
     1873}/*}}}*/
     1874void       Element::TransformSolutionCoord(IssmDouble* solution,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
     1875
     1876        int         i;
     1877        int         numdofs   = 0;
     1878        IssmDouble *transform = NULL;
     1879        IssmDouble *values    = NULL;
     1880
     1881        /*Get total number of dofs*/
     1882        for(i=0;i<numnodes;i++){
     1883                switch(cs_array[i]){
     1884                        case PressureEnum: numdofs+=1; break;
     1885                        case XYEnum:       numdofs+=2; break;
     1886                        case XYZEnum:      numdofs+=3; break;
     1887                        default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
     1888                }
     1889        }
     1890
     1891        /*Copy current solution vector*/
     1892        values=xNew<IssmDouble>(numdofs);
     1893        for(i=0;i<numdofs;i++) values[i]=solution[i];
     1894
     1895        /*Get Coordinate Systems transform matrix*/
     1896        CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
     1897
     1898        /*Transform matrix: R*U */
     1899        MatrixMultiply(transform,numdofs,numdofs,0,
     1900                                values,numdofs,1,0,
     1901                                &solution[0],0);
     1902
     1903        /*Free Matrices*/
     1904        xDelete<IssmDouble>(transform);
     1905        xDelete<IssmDouble>(values);
     1906}/*}}}*/
     1907void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
     1908
     1909        /*All nodes have the same Coordinate System*/
     1910        int  numnodes = this->GetNumberOfNodes();
     1911        int* cs_array = xNew<int>(numnodes);
     1912        for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
     1913
     1914        /*Call core*/
     1915        this->TransformStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
     1916
     1917        /*Clean-up*/
     1918        xDelete<int>(cs_array);
     1919}/*}}}*/
     1920void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* transformenum_list){/*{{{*/
     1921        this->TransformStiffnessMatrixCoord(Ke,this->nodes,this->GetNumberOfNodes(),transformenum_list);
     1922}/*}}}*/
     1923void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
     1924
     1925        int         numdofs = 0;
     1926        IssmDouble *transform = NULL;
     1927        IssmDouble *values    = NULL;
     1928
     1929        /*Get total number of dofs*/
     1930        for(int i=0;i<numnodes;i++){
     1931                switch(cs_array[i]){
     1932                        case PressureEnum: numdofs+=1; break;
     1933                        case XYEnum:       numdofs+=2; break;
     1934                        case XYZEnum:      numdofs+=3; break;
     1935                        default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
     1936                }
     1937        }
     1938
     1939        /*Copy current stiffness matrix*/
     1940        values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
     1941        for(int i=0;i<Ke->nrows*Ke->ncols;i++) values[i]=Ke->values[i];
     1942
     1943        /*Get Coordinate Systems transform matrix*/
     1944        CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
     1945
     1946        /*Transform matrix: R^T*Ke*R */
     1947        TripleMultiply(transform,numdofs,numdofs,1,
     1948                                values,Ke->nrows,Ke->ncols,0,
     1949                                transform,numdofs,numdofs,0,
     1950                                &Ke->values[0],0);
     1951
     1952        /*Free Matrix*/
     1953        xDelete<IssmDouble>(transform);
     1954        xDelete<IssmDouble>(values);
     1955}/*}}}*/
    16591956void       Element::ViscosityFS(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
    16601957        /*The effective strain rate is defined in Paterson 3d Ed p 91 eq 9,
     
    16961993}
    16971994/*}}}*/
     1995void       Element::ViscosityFSDerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
     1996        this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
     1997}/*}}}*/
     1998void       Element::ViscosityHO(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
     1999
     2000        /*Intermediaries*/
     2001        IssmDouble viscosity;
     2002        IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exz,eyz];*/
     2003        IssmDouble epsilon2d[2];/* epsilon=[exx,exy];            */
     2004        IssmDouble eps_eff;
     2005
     2006        if(dim==3){
     2007                /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
     2008                this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
     2009                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]);
     2010        }
     2011        else{
     2012                /* eps_eff^2 = 1/2 (exx^2 + 2*exy^2 )*/
     2013                this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
     2014                eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1]);
     2015        }
     2016
     2017        /*Get viscosity*/
     2018        material->GetViscosity(&viscosity,eps_eff);
     2019
     2020        /*Assign output pointer*/
     2021        *pviscosity=viscosity;
     2022}/*}}}*/
     2023void       Element::ViscosityHODerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
     2024        this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
     2025}/*}}}*/
    16982026void       Element::ViscosityL1L2(IssmDouble* pviscosity,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* surface_input){/*{{{*/
    16992027        /*Compute the L1L2 viscosity
     
    17552083        *pviscosity = viscosity;
    17562084}/*}}}*/
    1757 void       Element::ViscosityHO(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    1758 
    1759         /*Intermediaries*/
    1760         IssmDouble viscosity;
    1761         IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exz,eyz];*/
    1762         IssmDouble epsilon2d[2];/* epsilon=[exx,exy];            */
    1763         IssmDouble eps_eff;
    1764 
    1765         if(dim==3){
    1766                 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */
    1767                 this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);
    1768                 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]);
    1769         }
    1770         else{
    1771                 /* eps_eff^2 = 1/2 (exx^2 + 2*exy^2 )*/
    1772                 this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);
    1773                 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1]);
    1774         }
    1775 
    1776         /*Get viscosity*/
    1777         material->GetViscosity(&viscosity,eps_eff);
    1778 
    1779         /*Assign output pointer*/
    1780         *pviscosity=viscosity;
    1781 }/*}}}*/
    17822085void       Element::ViscositySSA(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    17832086
     
    18082111        this->material->GetViscosity2dDerivativeEpsSquare(pmu_prime,epsilon);
    18092112}/*}}}*/
    1810 void       Element::ViscosityHODerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
    1811         this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
    1812 }/*}}}*/
    1813 void       Element::ViscosityFSDerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
    1814         this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
    1815 }/*}}}*/
    1816 void       Element::StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
    1817         /*Compute the 3d Strain Rate (6 components):
    1818          *
    1819          * epsilon=[exx eyy ezz exy exz eyz]
    1820          */
     2113void       Element::ViscousHeatingCreateInput(void){/*{{{*/
    18212114
    18222115        /*Intermediaries*/
    1823         IssmDouble dvx[3];
    1824         IssmDouble dvy[3];
    1825         IssmDouble dvz[3];
    1826 
    1827         /*Check that both inputs have been found*/
    1828         if (!vx_input || !vy_input || !vz_input){
    1829                 _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << ", vz: " << vz_input << "\n");
    1830         }
    1831 
    1832         /*Get strain rate assuming that epsilon has been allocated*/
    1833         vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    1834         vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    1835         vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);
    1836         epsilon[0] = dvx[0];
    1837         epsilon[1] = dvy[1];
    1838         epsilon[2] = dvz[2];
    1839         epsilon[3] = 0.5*(dvx[1] + dvy[0]);
    1840         epsilon[4] = 0.5*(dvx[2] + dvz[0]);
    1841         epsilon[5] = 0.5*(dvy[2] + dvz[1]);
    1842 
    1843 }/*}}}*/
    1844 void       Element::StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    1845         /*Compute the 3d Blatter/HOStrain Rate (5 components):
    1846          *
    1847          * epsilon=[exx eyy exy exz eyz]
    1848          *
    1849          * with exz=1/2 du/dz
    1850          *      eyz=1/2 dv/dz
    1851          *
    1852          * the contribution of vz is neglected
    1853          */
    1854 
    1855         /*Intermediaries*/
    1856         IssmDouble dvx[3];
    1857         IssmDouble dvy[3];
    1858 
    1859         /*Check that both inputs have been found*/
    1860         if (!vx_input || !vy_input){
    1861                 _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
    1862         }
    1863 
    1864         /*Get strain rate assuming that epsilon has been allocated*/
    1865         vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    1866         vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    1867         epsilon[0] = dvx[0];
    1868         epsilon[1] = dvy[1];
    1869         epsilon[2] = 0.5*(dvx[1] + dvy[0]);
    1870         epsilon[3] = 0.5*dvx[2];
    1871         epsilon[4] = 0.5*dvy[2];
    1872 
    1873 }/*}}}*/
    1874 void       Element::StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    1875         /*Compute the 2d Blatter/HOStrain Rate (2 components):
    1876          *
    1877          * epsilon=[exx exz]
    1878          *
    1879          * with exz=1/2 du/dz
    1880          *
    1881          * the contribution of vz is neglected
    1882          */
    1883 
    1884         /*Intermediaries*/
    1885         IssmDouble dvx[3];
    1886 
    1887         /*Check that both inputs have been found*/
    1888         if (!vx_input){
    1889                 _error_("Input missing. Here are the input pointers we have for vx: " << vx_input <<"\n");
    1890         }
    1891 
    1892         /*Get strain rate assuming that epsilon has been allocated*/
    1893         vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    1894         epsilon[0] = dvx[0];
    1895         epsilon[1] = 0.5*dvx[1];
    1896 
    1897 }/*}}}*/
    1898 void       Element::StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
    1899 
    1900         /*Intermediaries*/
    1901         IssmDouble dvx[3];
    1902         IssmDouble dvy[3];
    1903 
    1904         /*Check that both inputs have been found*/
    1905         if(!vx_input || !vy_input){
    1906                 _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << ", vy: " << vy_input << "\n");
    1907         }
    1908 
    1909         /*Get strain rate assuming that epsilon has been allocated*/
    1910         vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    1911         vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
    1912         epsilon[0] = dvx[0];
    1913         epsilon[1] = dvy[1];
    1914         epsilon[2] = 0.5*(dvx[1] + dvy[0]);
    1915 
    1916 }/*}}}*/
    1917 void       Element::StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input){/*{{{*/
    1918 
    1919         /*Intermediaries*/
    1920         IssmDouble dvx[3];
    1921 
    1922         /*Check that both inputs have been found*/
    1923         if (!vx_input){
    1924                 _error_("Input missing. Here are the input pointers we have for vx: " << vx_input << "\n");
    1925         }
    1926 
    1927         /*Get strain rate assuming that epsilon has been allocated*/
    1928         vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
    1929         *epsilon = dvx[0];
    1930 
    1931 }/*}}}*/
    1932 void       Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
    1933 
    1934         /*All nodes have the same Coordinate System*/
    1935         int numnodes  = this->GetNumberOfNodes();
    1936         int* cs_array = xNew<int>(numnodes);
    1937         for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
    1938 
    1939         /*Call core*/
    1940         TransformInvStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
    1941 
    1942         /*Clean-up*/
    1943         xDelete<int>(cs_array);
    1944 }/*}}}*/
    1945 void       Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
    1946 
    1947         int         i,j;
    1948         int         numdofs   = 0;
    1949         IssmDouble *transform = NULL;
    1950         IssmDouble *values    = NULL;
    1951 
    1952         /*Get total number of dofs*/
    1953         for(i=0;i<numnodes;i++){
    1954                 switch(cs_array[i]){
    1955                         case PressureEnum: numdofs+=1; break;
    1956                         case XYEnum:       numdofs+=2; break;
    1957                         case XYZEnum:      numdofs+=3; break;
    1958                         default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
    1959                 }
    1960         }
    1961 
    1962         /*Copy current stiffness matrix*/
    1963         values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
    1964         for(i=0;i<Ke->nrows;i++) for(j=0;j<Ke->ncols;j++) values[i*Ke->ncols+j]=Ke->values[i*Ke->ncols+j];
    1965 
    1966         /*Get Coordinate Systems transform matrix*/
    1967         CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
    1968 
    1969         /*Transform matrix: R*Ke*R^T */
    1970         TripleMultiply(transform,numdofs,numdofs,0,
    1971                                 values,Ke->nrows,Ke->ncols,0,
    1972                                 transform,numdofs,numdofs,1,
    1973                                 &Ke->values[0],0);
    1974 
    1975         /*Free Matrix*/
    1976         xDelete<IssmDouble>(transform);
    1977         xDelete<IssmDouble>(values);
    1978 }/*}}}*/
    1979 void       Element::TransformLoadVectorCoord(ElementVector* pe,int transformenum){/*{{{*/
    1980 
    1981         /*All nodes have the same Coordinate System*/
    1982         int  numnodes = this->GetNumberOfNodes();
    1983         int* cs_array = xNew<int>(numnodes);
    1984         for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
    1985 
    1986         /*Call core*/
    1987         this->TransformLoadVectorCoord(pe,this->nodes,numnodes,cs_array);
    1988 
    1989         /*Clean-up*/
    1990         xDelete<int>(cs_array);
    1991 }/*}}}*/
    1992 void       Element::TransformLoadVectorCoord(ElementVector* pe,int* cs_array){/*{{{*/
    1993 
    1994         this->TransformLoadVectorCoord(pe,this->nodes,this->GetNumberOfNodes(),cs_array);
    1995 
    1996 }/*}}}*/
    1997 void       Element::TransformLoadVectorCoord(ElementVector* pe,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
    1998 
    1999         int         i;
    2000         int         numdofs   = 0;
    2001         IssmDouble *transform = NULL;
    2002         IssmDouble *values    = NULL;
    2003 
    2004         /*Get total number of dofs*/
    2005         for(i=0;i<numnodes;i++){
    2006                 switch(cs_array[i]){
    2007                         case PressureEnum: numdofs+=1; break;
    2008                         case XYEnum:       numdofs+=2; break;
    2009                         case XYZEnum:      numdofs+=3; break;
    2010                         default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
    2011                 }
    2012         }
    2013 
    2014         /*Copy current load vector*/
    2015         values=xNew<IssmDouble>(pe->nrows);
    2016         for(i=0;i<pe->nrows;i++) values[i]=pe->values[i];
    2017 
    2018         /*Get Coordinate Systems transform matrix*/
    2019         CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
    2020 
    2021         /*Transform matrix: R^T*pe */
    2022         MatrixMultiply(transform,numdofs,numdofs,1,
    2023                                 values,pe->nrows,1,0,
    2024                                 &pe->values[0],0);
    2025 
    2026         /*Free Matrices*/
    2027         xDelete<IssmDouble>(transform);
    2028         xDelete<IssmDouble>(values);
    2029 }/*}}}*/
    2030 void       Element::TransformSolutionCoord(IssmDouble* values,int transformenum){/*{{{*/
    2031 
    2032         /*All nodes have the same Coordinate System*/
    2033         int  numnodes = this->GetNumberOfNodes();
    2034         int* cs_array = xNew<int>(numnodes);
    2035         for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
    2036 
    2037         /*Call core*/
    2038         this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
    2039 
    2040         /*Clean-up*/
    2041         xDelete<int>(cs_array);
    2042 }/*}}}*/
    2043 void       Element::TransformSolutionCoord(IssmDouble* values,int* transformenum_list){/*{{{*/
    2044         this->TransformSolutionCoord(values,this->nodes,this->GetNumberOfNodes(),transformenum_list);
    2045 }/*}}}*/
    2046 void       Element::TransformSolutionCoord(IssmDouble* values,int numnodes,int transformenum){/*{{{*/
    2047 
    2048         /*All nodes have the same Coordinate System*/
    2049         int* cs_array = xNew<int>(numnodes);
    2050         for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
    2051 
    2052         /*Call core*/
    2053         this->TransformSolutionCoord(values,this->nodes,numnodes,cs_array);
    2054 
    2055         /*Clean-up*/
    2056         xDelete<int>(cs_array);
    2057 }/*}}}*/
    2058 void       Element::TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array){/*{{{*/
    2059         this->TransformSolutionCoord(solution,this->nodes,numnodes,cs_array);
    2060 }/*}}}*/
    2061 void       Element::TransformSolutionCoord(IssmDouble* values,Node** nodes_list,int numnodes,int transformenum){/*{{{*/
    2062         /*NOT NEEDED*/
    2063         /*All nodes have the same Coordinate System*/
    2064         int* cs_array = xNew<int>(numnodes);
    2065         for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
    2066 
    2067         /*Call core*/
    2068         this->TransformSolutionCoord(values,nodes_list,numnodes,cs_array);
    2069 
    2070         /*Clean-up*/
    2071         xDelete<int>(cs_array);
    2072 }/*}}}*/
    2073 void       Element::TransformSolutionCoord(IssmDouble* solution,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
    2074 
    2075         int         i;
    2076         int         numdofs   = 0;
    2077         IssmDouble *transform = NULL;
    2078         IssmDouble *values    = NULL;
    2079 
    2080         /*Get total number of dofs*/
    2081         for(i=0;i<numnodes;i++){
    2082                 switch(cs_array[i]){
    2083                         case PressureEnum: numdofs+=1; break;
    2084                         case XYEnum:       numdofs+=2; break;
    2085                         case XYZEnum:      numdofs+=3; break;
    2086                         default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
    2087                 }
    2088         }
    2089 
    2090         /*Copy current solution vector*/
    2091         values=xNew<IssmDouble>(numdofs);
    2092         for(i=0;i<numdofs;i++) values[i]=solution[i];
    2093 
    2094         /*Get Coordinate Systems transform matrix*/
    2095         CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
    2096 
    2097         /*Transform matrix: R*U */
    2098         MatrixMultiply(transform,numdofs,numdofs,0,
    2099                                 values,numdofs,1,0,
    2100                                 &solution[0],0);
    2101 
    2102         /*Free Matrices*/
    2103         xDelete<IssmDouble>(transform);
    2104         xDelete<IssmDouble>(values);
    2105 }/*}}}*/
    2106 void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
    2107 
    2108         /*All nodes have the same Coordinate System*/
    2109         int  numnodes = this->GetNumberOfNodes();
    2110         int* cs_array = xNew<int>(numnodes);
    2111         for(int i=0;i<numnodes;i++) cs_array[i]=transformenum;
    2112 
    2113         /*Call core*/
    2114         this->TransformStiffnessMatrixCoord(Ke,this->nodes,numnodes,cs_array);
    2115 
    2116         /*Clean-up*/
    2117         xDelete<int>(cs_array);
    2118 }/*}}}*/
    2119 void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* transformenum_list){/*{{{*/
    2120         this->TransformStiffnessMatrixCoord(Ke,this->nodes,this->GetNumberOfNodes(),transformenum_list);
    2121 }/*}}}*/
    2122 void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
    2123 
    2124         int         numdofs = 0;
    2125         IssmDouble *transform = NULL;
    2126         IssmDouble *values    = NULL;
    2127 
    2128         /*Get total number of dofs*/
    2129         for(int i=0;i<numnodes;i++){
    2130                 switch(cs_array[i]){
    2131                         case PressureEnum: numdofs+=1; break;
    2132                         case XYEnum:       numdofs+=2; break;
    2133                         case XYZEnum:      numdofs+=3; break;
    2134                         default: _error_("Coordinate system " << EnumToStringx(cs_array[i]) << " not supported yet");
    2135                 }
    2136         }
    2137 
    2138         /*Copy current stiffness matrix*/
    2139         values=xNew<IssmDouble>(Ke->nrows*Ke->ncols);
    2140         for(int i=0;i<Ke->nrows*Ke->ncols;i++) values[i]=Ke->values[i];
    2141 
    2142         /*Get Coordinate Systems transform matrix*/
    2143         CoordinateSystemTransform(&transform,nodes_list,numnodes,cs_array);
    2144 
    2145         /*Transform matrix: R^T*Ke*R */
    2146         TripleMultiply(transform,numdofs,numdofs,1,
    2147                                 values,Ke->nrows,Ke->ncols,0,
    2148                                 transform,numdofs,numdofs,0,
    2149                                 &Ke->values[0],0);
    2150 
    2151         /*Free Matrix*/
    2152         xDelete<IssmDouble>(transform);
    2153         xDelete<IssmDouble>(values);
    2154 }/*}}}*/
     2116        IssmDouble phi;
     2117        IssmDouble viscosity;
     2118        IssmDouble epsilon[6];
     2119        IssmDouble thickness;
     2120        IssmDouble *xyz_list = NULL;
     2121
     2122        /*Fetch number vertices and allocate memory*/
     2123        int         numvertices    = this->GetNumberOfVertices();
     2124        IssmDouble* viscousheating = xNew<IssmDouble>(numvertices);
     2125
     2126        /*Retrieve all inputs and parameters*/
     2127        this->GetVerticesCoordinatesBase(&xyz_list);
     2128        Input* vx_input        = this->GetInput(VxEnum); _assert_(vx_input);
     2129        Input* vy_input        = this->GetInput(VyEnum); _assert_(vy_input);
     2130        Input* vz_input        = this->GetInput(VzEnum); _assert_(vz_input);
     2131        Input* thickness_input = this->GetInput(ThicknessEnum); _assert_(thickness_input);
     2132
     2133        /*loop over vertices: */
     2134        Gauss* gauss=this->NewGauss();
     2135        for (int iv=0;iv<numvertices;iv++){
     2136                gauss->GaussVertex(iv);
     2137
     2138                thickness_input->GetInputValue(&thickness,gauss);
     2139
     2140                this->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input);
     2141                this->ViscosityFS(&viscosity,3,xyz_list,gauss,vx_input,vy_input,vz_input);
     2142                this->GetPhi(&phi,&epsilon[0],viscosity);
     2143
     2144                viscousheating[iv]=phi*thickness;
     2145        }
     2146
     2147        /*Create PentaVertex input, which will hold the basal friction:*/
     2148        this->AddInput(ViscousHeatingEnum,viscousheating,P1Enum);
     2149
     2150        /*Clean up and return*/
     2151        xDelete<IssmDouble>(viscousheating);
     2152        delete gauss;
     2153}
     2154/*}}}*/
Note: See TracChangeset for help on using the changeset viewer.