Changeset 4250


Ignore:
Timestamp:
06/26/10 23:10:55 (15 years ago)
Author:
Eric.Larour
Message:

reorganized element routines

Location:
issm/trunk/src/c/objects/Elements
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified issm/trunk/src/c/objects/Elements/Beam.cpp

    r4248 r4250  
    3131}
    3232/*}}}*/
    33 /*FUNCTION void Beam::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type);{{{1*/
    34 void Beam::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type){
    35         ISSMERROR(" not supported yet!");
    36 }
    37 /*}}}*/
    38 
    39 /*Object virtual functions definitions: */
     33
     34/*Object virtual functions definitions:*/
     35/*FUNCTION Beam::copy{{{1*/
     36Object* Beam::copy() {
     37
     38        int i;
     39        Beam* beam=NULL;
     40
     41        beam=new Beam();
     42
     43        /*copy fields: */
     44        beam->id=this->id;
     45        if(this->inputs){
     46                beam->inputs=(Inputs*)this->inputs->Copy();
     47        }
     48        else{
     49                beam->inputs=new Inputs();
     50        }
     51        /*point parameters: */
     52        beam->parameters=this->parameters;
     53
     54        /*pointers: */
     55        beam->nodes=(Node**)xmalloc(2*sizeof(Node*));
     56        for(i=0;i<2;i++)beam->nodes[i]=this->nodes[i];
     57        beam->matice=this->matice;
     58        beam->matpar=this->matpar;
     59
     60        return beam;
     61}
     62/*}}}*/
    4063/*FUNCTION Beam::DeepEcho{{{1*/
    4164void Beam::DeepEcho(void){
     
    5881}
    5982/*}}}*/
    60 /*FUNCTION Beam::Id{{{1*/
    61 int    Beam::Id(void){ return id; }
    62 /*}}}*/
    63 /*FUNCTION Beam::MyRank{{{1*/
    64 int    Beam::MyRank(void){
    65         extern int my_rank;
    66         return my_rank;
    67 }
    68 /*}}}*/
    69 /*FUNCTION Beam::Marshall{{{1*/
    70 void  Beam::Marshall(char** pmarshalled_dataset){
    71         ISSMERROR("not supported yet!");
    72 }
    73 /*}}}*/
    74 /*FUNCTION Beam::MarshallSize{{{1*/
    75 int   Beam::MarshallSize(){
    76         ISSMERROR("not supported yet!");
    77 }
    78 /*}}}*/
    7983/*FUNCTION Beam::Demarshall{{{1*/
    8084void  Beam::Demarshall(char** pmarshalled_dataset){
    8185        ISSMERROR("not supported yet!");
    82 }
    83 /*}}}*/
    84 /*FUNCTION Beam::Enum{{{1*/
    85 int Beam::Enum(void){
    86 
    87         return BeamEnum;
    88 
    89 }
    90 /*}}}*/
    91 /*FUNCTION Beam::copy{{{1*/
    92 Object* Beam::copy() {
    93 
    94         int i;
    95         Beam* beam=NULL;
    96 
    97         beam=new Beam();
    98 
    99         /*copy fields: */
    100         beam->id=this->id;
    101         if(this->inputs){
    102                 beam->inputs=(Inputs*)this->inputs->Copy();
    103         }
    104         else{
    105                 beam->inputs=new Inputs();
    106         }
    107         /*point parameters: */
    108         beam->parameters=this->parameters;
    109 
    110         /*pointers: */
    111         beam->nodes=(Node**)xmalloc(2*sizeof(Node*));
    112         for(i=0;i<2;i++)beam->nodes[i]=this->nodes[i];
    113         beam->matice=this->matice;
    114         beam->matpar=this->matpar;
    115 
    116         return beam;
    117 }
    118 /*}}}*/
    119 
    120 /*Beam management*/
    121 /*FUNCTION Beam::Configure {{{1*/
    122 void  Beam::Configure(Elements* elementsin,Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){
    123 
    124         ISSMERROR(" not supported yet!");
    125 
    12686}
    12787/*}}}*/
     
    146106}
    147107/*}}}*/
    148 /*FUNCTION Beam::IsInput{{{1*/
    149 bool Beam::IsInput(int name){
    150         if (name==SurfaceSlopeXEnum ||
    151                                 name==SurfaceSlopeYEnum){
    152                 return true;
    153         }
    154         else return false;
     108/*FUNCTION Beam::Enum{{{1*/
     109int Beam::Enum(void){
     110
     111        return BeamEnum;
     112
     113}
     114/*}}}*/
     115/*FUNCTION Beam::Id{{{1*/
     116int    Beam::Id(void){ return id; }
     117/*}}}*/
     118/*FUNCTION Beam::Marshall{{{1*/
     119void  Beam::Marshall(char** pmarshalled_dataset){
     120        ISSMERROR("not supported yet!");
     121}
     122/*}}}*/
     123/*FUNCTION Beam::MarshallSize{{{1*/
     124int   Beam::MarshallSize(){
     125        ISSMERROR("not supported yet!");
     126}
     127/*}}}*/
     128/*FUNCTION Beam::MyRank{{{1*/
     129int    Beam::MyRank(void){
     130        extern int my_rank;
     131        return my_rank;
     132}
     133/*}}}*/
     134
     135/*Update virtual functions definitions:*/
     136/*FUNCTION Beam::InputUpdateFromVector(double* vector, int name, int type);{{{1*/
     137void  Beam::InputUpdateFromVector(double* vector, int name, int type){
     138
     139        /*Check that name is an element input*/
     140        if (!IsInput(name)) return;
     141        switch(type){
     142
     143                case VertexEnum:
     144
     145                        /*New PentaVertexInpu*/
     146                        double values[2];
     147
     148                        /*Get values on the 6 vertices*/
     149                        for (int i=0;i<2;i++){
     150                                values[i]=vector[nodes[i]->GetVertexDof()];
     151                        }
     152
     153                        /*update input*/
     154                        this->inputs->AddInput(new BeamVertexInput(name,values));
     155                        return;
     156
     157                default:
     158
     159                        ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type));
     160        }
     161}
     162/*}}}*/
     163/*FUNCTION Beam::InputUpdateFromVector(int* vector, int name, int type);{{{1*/
     164void  Beam::InputUpdateFromVector(int* vector, int name, int type){
     165        ISSMERROR(" not supported yet!");
     166}
     167/*}}}*/
     168/*FUNCTION Beam::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/
     169void  Beam::InputUpdateFromVector(bool* vector, int name, int type){
     170        ISSMERROR(" not supported yet!");
    155171}
    156172/*}}}*/
     
    160176}
    161177/*}}}*/
    162 /*FUNCTION Beam::GetSolutionFromInputs(Vec solution);{{{1*/
    163 void  Beam::GetSolutionFromInputs(Vec solution){
    164         ISSMERROR(" not supported yet!");
    165 }
    166 /*}}}*/
    167 /*FUNCTION Beam::InputToResult(int enum_type,int step,double time){{{1*/
    168 void  Beam::InputToResult(int enum_type,int step,double time){
    169         ISSMERROR(" not supported yet!");
    170 }
    171 /*}}}*/
    172 /*FUNCTION Beam::ProcessResultsUnits(void){{{1*/
    173 void  Beam::ProcessResultsUnits(void){
    174         ISSMERROR(" not supported yet!");
    175 }
    176 /*}}}*/
    177 
    178 /*Object functions*/
     178
     179/*Element virtual functions definitions:*/
    179180/*FUNCTION Beam::ComputeBasalStress{{{1*/
    180181void  Beam::ComputeBasalStress(Vec eps){
     
    232233}
    233234/*}}}*/
     235/*FUNCTION Beam::Configure {{{1*/
     236void  Beam::Configure(Elements* elementsin,Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){
     237
     238        ISSMERROR(" not supported yet!");
     239
     240}
     241/*}}}*/
    234242/*FUNCTION Beam::CostFunction{{{1*/
    235243double Beam::CostFunction(void){
     
    255263}
    256264/*}}}*/
     265/*FUNCTION Beam::CreatePVector{{{1*/
     266void  Beam::CreatePVector(Vec pg){
     267
     268        int analysis_type,sub_analysis_type;
     269
     270        /*retrive parameters: */
     271        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     272        parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
     273       
     274        /*Just branch to the correct load generator, according to the type of analysis we are carrying out: */
     275        if (analysis_type==DiagnosticHutterAnalysisEnum) {
     276                CreatePVectorDiagnosticHutter( pg);
     277        }
     278        else{
     279                ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
     280        }
     281
     282}
     283/*}}}*/
     284/*FUNCTION Beam::Du{{{1*/
     285void  Beam::Du(Vec){
     286        ISSMERROR(" not supported yet!");
     287}
     288/*}}}*/
     289/*FUNCTION Beam::GetBedList{{{1*/
     290void  Beam::GetBedList(double*){
     291        ISSMERROR(" not supported yet!");
     292}
     293/*}}}*/
     294/*FUNCTION Beam::GetMatPar{{{1*/
     295void* Beam::GetMatPar(){
     296
     297        return matpar;
     298}
     299/*}}}*/
     300/*FUNCTION Beam::GetNodes{{{1*/
     301void  Beam::GetNodes(void** vpnodes){
     302        int i;
     303        Node** pnodes=NULL;
     304
     305        /*recover nodes: */
     306        pnodes=(Node**)vpnodes;
     307
     308        for(i=0;i<3;i++){
     309                pnodes[i]=nodes[i];
     310        }
     311}
     312/*}}}*/
     313/*FUNCTION Beam::GetOnBed{{{1*/
     314bool   Beam::GetOnBed(){
     315        ISSMERROR(" not supported yet!");
     316}
     317/*}}}*/
     318/*FUNCTION Beam::GetShelf{{{1*/
     319bool   Beam::GetShelf(){
     320        ISSMERROR(" not supported yet!");
     321}
     322/*}}}*/
     323/*FUNCTION Beam::GetSolutionFromInputs(Vec solution);{{{1*/
     324void  Beam::GetSolutionFromInputs(Vec solution){
     325        ISSMERROR(" not supported yet!");
     326}
     327/*}}}*/
     328/*FUNCTION Beam::GetThicknessList{{{1*/
     329void  Beam::GetThicknessList(double* thickness_list){
     330        ISSMERROR(" not supported yet!");
     331}
     332/*}}}*/
     333/*FUNCTION Beam::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/
     334void  Beam::GetVectorFromInputs(Vec vector,int NameEnum){
     335
     336        int i;
     337        const int numvertices=2;
     338        int doflist1[numvertices];
     339
     340        /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */
     341        for(i=0;i<this->inputs->Size();i++){
     342                Input* input=(Input*)this->inputs->GetObjectByOffset(i);
     343                if(input->EnumType()==NameEnum){
     344                        /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
     345                        this->GetDofList1(&doflist1[0]);
     346                        input->GetVectorFromInputs(vector,&doflist1[0]);
     347                        break;
     348                }
     349        }
     350}
     351/*}}}*/
     352/*FUNCTION Beam::Gradj{{{1*/
     353void  Beam::Gradj(Vec gradient,int control_type){
     354        ISSMERROR(" not supported yet!");
     355}
     356/*}}}*/
     357/*FUNCTION Beam::GradjB{{{1*/
     358void  Beam::GradjB(Vec gradient){
     359        ISSMERROR(" not supported yet!");
     360}
     361/*}}}*/
     362/*FUNCTION Beam::GradjDrag{{{1*/
     363void  Beam::GradjDrag(Vec gradient){
     364        ISSMERROR(" not supported yet!");
     365}
     366/*}}}*/
     367/*FUNCTION Beam::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/
     368void  Beam::InputAXPY(int YEnum, double scalar, int XEnum){
     369
     370        Input* xinput=NULL;
     371        Input* yinput=NULL;
     372
     373        /*Find x and y inputs: */
     374        xinput=(Input*)this->inputs->GetInput(XEnum);
     375        yinput=(Input*)this->inputs->GetInput(YEnum);
     376
     377        /*some checks: */
     378        if(!xinput || !yinput)ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!");
     379        if(xinput->Enum()!=yinput->Enum())ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," and input ",EnumAsString(YEnum)," are not of the same type!");
     380
     381        /*Scale: */
     382        yinput->AXPY(xinput,scalar);
     383}
     384/*}}}*/
     385/*FUNCTION Beam::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/
     386void  Beam::InputControlConstrain(int control_type, double cm_min, double cm_max){
     387
     388        Input* input=NULL;
     389
     390        /*Find input: */
     391        input=(Input*)this->inputs->GetInput(control_type);
     392       
     393        /*Do nothing if we  don't find it: */
     394        if(!input)return;
     395
     396        /*Constrain input using cm_min and cm_max: */
     397        input->Constrain(cm_min,cm_max);
     398
     399}
     400/*}}}*/
     401/*FUNCTION Beam::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/
     402void  Beam::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){
     403
     404        int     i;
     405        Input** new_inputs=NULL;
     406        Input** old_inputs=NULL;
     407        int     converged=1;
     408
     409        new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs
     410        old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs
     411       
     412        for(i=0;i<num_enums/2;i++){
     413                new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]);
     414                old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]);
     415                if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
     416                if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
     417        }
     418
     419        /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/
     420        for(i=0;i<num_criterionenums;i++){
     421                IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]);
     422                if(eps[i]>criterionvalues[i]) converged=0;
     423        }
     424
     425        /*Assign output pointers:*/
     426        *pconverged=converged;
     427
     428}
     429/*}}}*/
     430/*FUNCTION Beam::InputDuplicate(int original_enum,int new_enum){{{1*/
     431void  Beam::InputDuplicate(int original_enum,int new_enum){
     432
     433        Input* original=NULL;
     434        Input* copy=NULL;
     435
     436        /*Make a copy of the original input: */
     437        original=(Input*)this->inputs->GetInput(original_enum);
     438        copy=(Input*)original->copy();
     439
     440        /*Change copy enum to reinitialized_enum: */
     441        copy->ChangeEnum(new_enum);
     442
     443        /*Add copy into inputs, it will wipe off the one already there: */
     444        inputs->AddObject((Input*)copy);
     445}
     446/*}}}*/
     447/*FUNCTION Beam::InputScale(int enum_type,double scale_factor){{{1*/
     448void  Beam::InputScale(int enum_type,double scale_factor){
     449
     450        Input* input=NULL;
     451
     452        /*Make a copy of the original input: */
     453        input=(Input*)this->inputs->GetInput(enum_type);
     454
     455        /*Scale: */
     456        input->Scale(scale_factor);
     457}
     458/*}}}*/
     459/*FUNCTION Beam::InputToResult(int enum_type,int step,double time){{{1*/
     460void  Beam::InputToResult(int enum_type,int step,double time){
     461        ISSMERROR(" not supported yet!");
     462}
     463/*}}}*/
     464/*FUNCTION Beam::MassFlux{{{1*/
     465double Beam::MassFlux( double* segment){
     466        ISSMERROR(" not supported yet!");
     467}
     468/*}}}*/
     469/*FUNCTION Beam::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/
     470void  Beam::MaxAbsVx(double* pmaxabsvx, bool process_units){
     471
     472        int i;
     473        int dim;
     474        const int numgrids=2;
     475        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     476        double  vx_values[numgrids];
     477        double  maxabsvx;
     478
     479        /*retrieve dim parameter: */
     480        parameters->FindParam(&dim,DimEnum);
     481
     482        /*retrive velocity values at nodes */
     483        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     484
     485        /*now, compute maximum:*/
     486        maxabsvx=fabs(vx_values[0]);
     487        for(i=1;i<numgrids;i++){
     488                if (fabs(vx_values[i])>maxabsvx)maxabsvx=fabs(vx_values[i]);
     489        }
     490
     491        /*Assign output pointers:*/
     492        *pmaxabsvx=maxabsvx;
     493}
     494/*}}}*/
     495/*FUNCTION Beam::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/
     496void  Beam::MaxAbsVy(double* pmaxabsvy, bool process_units){
     497
     498        int i;
     499        int dim;
     500        const int numgrids=2;
     501        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     502        double  vy_values[numgrids];
     503        double  maxabsvy;
     504
     505        /*retrieve dim parameter: */
     506        parameters->FindParam(&dim,DimEnum);
     507
     508        /*retrive velocity values at nodes */
     509        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     510
     511        /*now, compute maximum:*/
     512        maxabsvy=fabs(vy_values[0]);
     513        for(i=1;i<numgrids;i++){
     514                if (fabs(vy_values[i])>maxabsvy)maxabsvy=fabs(vy_values[i]);
     515        }
     516
     517        /*Assign output pointers:*/
     518        *pmaxabsvy=maxabsvy;
     519}
     520/*}}}*/
     521/*FUNCTION Beam::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/
     522void  Beam::MaxAbsVz(double* pmaxabsvz, bool process_units){
     523
     524        int i;
     525        int dim;
     526        const int numgrids=2;
     527        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     528        double  vz_values[numgrids];
     529        double  maxabsvz;
     530
     531        /*retrieve dim parameter: */
     532        parameters->FindParam(&dim,DimEnum);
     533
     534        /*retrive velocity values at nodes */
     535        inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     536
     537        /*now, compute maximum:*/
     538        maxabsvz=fabs(vz_values[0]);
     539        for(i=1;i<numgrids;i++){
     540                if (fabs(vz_values[i])>maxabsvz)maxabsvz=fabs(vz_values[i]);
     541        }
     542
     543        /*Assign output pointers:*/
     544        *pmaxabsvz=maxabsvz;
     545}
     546/*}}}*/
     547/*FUNCTION Beam::MaxVel(double* pmaxvel, bool process_units);{{{1*/
     548void  Beam::MaxVel(double* pmaxvel, bool process_units){
     549
     550        int i;
     551        int dim;
     552        const int numgrids=2;
     553        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     554        double  vx_values[numgrids];
     555        double  vy_values[numgrids];
     556        double  vz_values[numgrids];
     557        double  vel_values[numgrids];
     558        double  maxvel;
     559
     560        /*retrieve dim parameter: */
     561        parameters->FindParam(&dim,DimEnum);
     562
     563        /*retrive velocity values at nodes */
     564        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     565        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     566        if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     567
     568        /*now, compute maximum of velocity :*/
     569        if(dim==2){
     570                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
     571        }
     572        else{
     573                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
     574        }
     575
     576        /*now, compute maximum:*/
     577        maxvel=vel_values[0];
     578        for(i=1;i<numgrids;i++){
     579                if (vel_values[i]>maxvel)maxvel=vel_values[i];
     580        }
     581
     582        /*Assign output pointers:*/
     583        *pmaxvel=maxvel;
     584
     585}
     586/*}}}*/
     587/*FUNCTION Beam::MaxVx(double* pmaxvx, bool process_units);{{{1*/
     588void  Beam::MaxVx(double* pmaxvx, bool process_units){
     589
     590        int i;
     591        int dim;
     592        const int numgrids=2;
     593        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     594        double  vx_values[numgrids];
     595        double  maxvx;
     596
     597        /*retrieve dim parameter: */
     598        parameters->FindParam(&dim,DimEnum);
     599
     600        /*retrive velocity values at nodes */
     601        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     602
     603        /*now, compute maximum:*/
     604        maxvx=vx_values[0];
     605        for(i=1;i<numgrids;i++){
     606                if (vx_values[i]>maxvx)maxvx=vx_values[i];
     607        }
     608
     609        /*Assign output pointers:*/
     610        *pmaxvx=maxvx;
     611
     612}
     613/*}}}*/
     614/*FUNCTION Beam::MaxVy(double* pmaxvy, bool process_units);{{{1*/
     615void  Beam::MaxVy(double* pmaxvy, bool process_units){
     616
     617        int i;
     618        int dim;
     619        const int numgrids=2;
     620        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     621        double  vy_values[numgrids];
     622        double  maxvy;
     623
     624        /*retrieve dim parameter: */
     625        parameters->FindParam(&dim,DimEnum);
     626
     627        /*retrive velocity values at nodes */
     628        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     629
     630        /*now, compute maximum:*/
     631        maxvy=vy_values[0];
     632        for(i=1;i<numgrids;i++){
     633                if (vy_values[i]>maxvy)maxvy=vy_values[i];
     634        }
     635
     636        /*Assign output pointers:*/
     637        *pmaxvy=maxvy;
     638
     639}
     640/*}}}*/
     641/*FUNCTION Beam::MaxVz(double* pmaxvz, bool process_units);{{{1*/
     642void  Beam::MaxVz(double* pmaxvz, bool process_units){
     643
     644        int i;
     645        int dim;
     646        const int numgrids=2;
     647        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     648        double  vz_values[numgrids];
     649        double  maxvz;
     650
     651        /*retrieve dim parameter: */
     652        parameters->FindParam(&dim,DimEnum);
     653
     654        /*retrive velocity values at nodes */
     655        inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     656
     657        /*now, compute maximum:*/
     658        maxvz=vz_values[0];
     659        for(i=1;i<numgrids;i++){
     660                if (vz_values[i]>maxvz)maxvz=vz_values[i];
     661        }
     662
     663        /*Assign output pointers:*/
     664        *pmaxvz=maxvz;
     665
     666}
     667/*}}}*/
     668/*FUNCTION Beam::MinVel(double* pminvel, bool process_units);{{{1*/
     669void  Beam::MinVel(double* pminvel, bool process_units){
     670
     671        int i;
     672        int dim;
     673        const int numgrids=2;
     674        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     675        double  vx_values[numgrids];
     676        double  vy_values[numgrids];
     677        double  vz_values[numgrids];
     678        double  vel_values[numgrids];
     679        double  minvel;
     680
     681        /*retrieve dim parameter: */
     682        parameters->FindParam(&dim,DimEnum);
     683
     684        /*retrive velocity values at nodes */
     685        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     686        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     687        if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     688
     689        /*now, compute minimum of velocity :*/
     690        if(dim==2){
     691                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
     692        }
     693        else{
     694                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
     695        }
     696
     697        /*now, compute minimum:*/
     698        minvel=vel_values[0];
     699        for(i=1;i<numgrids;i++){
     700                if (vel_values[i]<minvel)minvel=vel_values[i];
     701        }
     702
     703        /*Assign output pointers:*/
     704        *pminvel=minvel;
     705
     706}
     707/*}}}*/
     708/*FUNCTION Beam::MinVx(double* pminvx, bool process_units);{{{1*/
     709void  Beam::MinVx(double* pminvx, bool process_units){
     710
     711        int i;
     712        int dim;
     713        const int numgrids=2;
     714        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     715        double  vx_values[numgrids];
     716        double  minvx;
     717
     718        /*retrieve dim parameter: */
     719        parameters->FindParam(&dim,DimEnum);
     720
     721        /*retrive velocity values at nodes */
     722        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     723
     724        /*now, compute minimum:*/
     725        minvx=vx_values[0];
     726        for(i=1;i<numgrids;i++){
     727                if (vx_values[i]<minvx)minvx=vx_values[i];
     728        }
     729
     730        /*Assign output pointers:*/
     731        *pminvx=minvx;
     732
     733}
     734/*}}}*/
     735/*FUNCTION Beam::MinVy(double* pminvy, bool process_units);{{{1*/
     736void  Beam::MinVy(double* pminvy, bool process_units){
     737
     738        int i;
     739        int dim;
     740        const int numgrids=2;
     741        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     742        double  vy_values[numgrids];
     743        double  minvy;
     744
     745        /*retrieve dim parameter: */
     746        parameters->FindParam(&dim,DimEnum);
     747
     748        /*retrive velocity values at nodes */
     749        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     750
     751        /*now, compute minimum:*/
     752        minvy=vy_values[0];
     753        for(i=1;i<numgrids;i++){
     754                if (vy_values[i]<minvy)minvy=vy_values[i];
     755        }
     756
     757        /*Assign output pointers:*/
     758        *pminvy=minvy;
     759
     760}
     761/*}}}*/
     762/*FUNCTION Beam::MinVz(double* pminvz, bool process_units);{{{1*/
     763void  Beam::MinVz(double* pminvz, bool process_units){
     764
     765        int i;
     766        int dim;
     767        const int numgrids=2;
     768        double  gaussgrids[numgrids][2]={{0,1},{1,0}};
     769        double  vz_values[numgrids];
     770        double  minvz;
     771
     772        /*retrieve dim parameter: */
     773        parameters->FindParam(&dim,DimEnum);
     774
     775        /*retrive velocity values at nodes */
     776        inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     777
     778        /*now, compute minimum:*/
     779        minvz=vz_values[0];
     780        for(i=1;i<numgrids;i++){
     781                if (vz_values[i]<minvz)minvz=vz_values[i];
     782        }
     783
     784        /*Assign output pointers:*/
     785        *pminvz=minvz;
     786
     787}
     788/*}}}*/
     789/*FUNCTION Beam::Misfit{{{1*/
     790double Beam::Misfit(void){
     791        ISSMERROR(" not supported yet!");
     792}
     793/*}}}*/
     794/*FUNCTION Beam::PatchFill(int* pcount, Patch* patch){{{1*/
     795void  Beam::PatchFill(int* pcount, Patch* patch){
     796
     797        ISSMERROR(" not supported yet!");
     798}
     799/*}}}*/
     800/*FUNCTION Beam::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){{{1*/
     801void  Beam::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){
     802
     803        ISSMERROR(" not supported yet!");
     804       
     805}
     806/*}}}*/
     807/*FUNCTION Beam::ProcessResultsUnits(void){{{1*/
     808void  Beam::ProcessResultsUnits(void){
     809        ISSMERROR(" not supported yet!");
     810}
     811/*}}}*/
     812/*FUNCTION Beam::SurfaceArea{{{1*/
     813double Beam::SurfaceArea(void){
     814        ISSMERROR(" not supported yet!");
     815}
     816/*}}}*/
     817/*FUNCTION Beam::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type);{{{1*/
     818void Beam::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type){
     819        ISSMERROR(" not supported yet!");
     820}
     821/*}}}*/
     822
     823/*Beam specific routines: */
    257824/*FUNCTION Beam::CreateKMatrixDiagnosticHutter{{{1*/
    258825
     
    304871        /*Add Ke_gg to global matrix Kgg: */
    305872        MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
    306 
    307 }
    308 /*}}}*/
    309 /*FUNCTION Beam::CreatePVector{{{1*/
    310 void  Beam::CreatePVector(Vec pg){
    311 
    312         int analysis_type,sub_analysis_type;
    313 
    314         /*retrive parameters: */
    315         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    316         parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
    317        
    318         /*Just branch to the correct load generator, according to the type of analysis we are carrying out: */
    319         if (analysis_type==DiagnosticHutterAnalysisEnum) {
    320                 CreatePVectorDiagnosticHutter( pg);
    321         }
    322         else{
    323                 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
    324         }
    325873
    326874}
     
    4551003}
    4561004/*}}}*/
    457 /*FUNCTION Beam::Du{{{1*/
    458 void  Beam::Du(Vec){
    459         ISSMERROR(" not supported yet!");
    460 }
    461 /*}}}*/
    462 /*FUNCTION Beam::GetBedList{{{1*/
    463 void  Beam::GetBedList(double*){
    464         ISSMERROR(" not supported yet!");
    465 }
    466 /*}}}*/
    4671005/*FUNCTION Beam::GetDofList{{{1*/
    4681006void  Beam::GetDofList(int* doflist,int* pnumberofdofspernode){
     
    5091047}
    5101048/*}}}*/
    511 /*FUNCTION Beam::GetMatPar{{{1*/
    512 void* Beam::GetMatPar(){
    513 
    514         return matpar;
    515 }
    516 /*}}}*/
    5171049/*FUNCTION Beam::GetNodalFunctions{{{1*/
    5181050void Beam::GetNodalFunctions(double* l1l2, double gauss_coord){
     
    5271059}
    5281060/*}}}*/
    529 /*FUNCTION Beam::GetNodes{{{1*/
    530 void  Beam::GetNodes(void** vpnodes){
    531         int i;
    532         Node** pnodes=NULL;
    533 
    534         /*recover nodes: */
    535         pnodes=(Node**)vpnodes;
    536 
    537         for(i=0;i<3;i++){
    538                 pnodes[i]=nodes[i];
    539         }
    540 }
    541 /*}}}*/
    542 /*FUNCTION Beam::GetOnBed{{{1*/
    543 bool   Beam::GetOnBed(){
    544         ISSMERROR(" not supported yet!");
    545 }
    546 /*}}}*/
    5471061/*FUNCTION Beam::GetParameterValue{{{1*/
    5481062void Beam::GetParameterValue(double* pvalue, double* value_list,double gauss_coord){
     
    5551069}
    5561070/*}}}*/
    557 /*FUNCTION Beam::GetShelf{{{1*/
    558 bool   Beam::GetShelf(){
    559         ISSMERROR(" not supported yet!");
    560 }
    561 /*}}}*/
    562 /*FUNCTION Beam::GetThicknessList{{{1*/
    563 void  Beam::GetThicknessList(double* thickness_list){
    564         ISSMERROR(" not supported yet!");
    565 }
    566 /*}}}*/
    567 /*FUNCTION Beam::Gradj{{{1*/
    568 void  Beam::Gradj(Vec gradient,int control_type){
    569         ISSMERROR(" not supported yet!");
    570 }
    571 /*}}}*/
    572 /*FUNCTION Beam::GradjB{{{1*/
    573 void  Beam::GradjB(Vec gradient){
    574         ISSMERROR(" not supported yet!");
    575 }
    576 /*}}}*/
    577 /*FUNCTION Beam::GradjDrag{{{1*/
    578 void  Beam::GradjDrag(Vec gradient){
    579         ISSMERROR(" not supported yet!");
    580 }
    581 /*}}}*/
    582 /*FUNCTION Beam::MassFlux{{{1*/
    583 double Beam::MassFlux( double* segment){
    584         ISSMERROR(" not supported yet!");
    585 }
    586 /*}}}*/
    587 /*FUNCTION Beam::Misfit{{{1*/
    588 double Beam::Misfit(void){
    589         ISSMERROR(" not supported yet!");
    590 }
    591 /*}}}*/
    592 /*FUNCTION Beam::SurfaceArea{{{1*/
    593 double Beam::SurfaceArea(void){
    594         ISSMERROR(" not supported yet!");
     1071/*FUNCTION Beam::IsInput{{{1*/
     1072bool Beam::IsInput(int name){
     1073        if (name==SurfaceSlopeXEnum ||
     1074                                name==SurfaceSlopeYEnum){
     1075                return true;
     1076        }
     1077        else return false;
    5951078}
    5961079/*}}}*/
     
    6011084}
    6021085/*}}}1*/
    603 /*FUNCTION Beam::InputUpdateFromVector(double* vector, int name, int type);{{{1*/
    604 void  Beam::InputUpdateFromVector(double* vector, int name, int type){
    605 
    606         /*Check that name is an element input*/
    607         if (!IsInput(name)) return;
    608         switch(type){
    609 
    610                 case VertexEnum:
    611 
    612                         /*New PentaVertexInpu*/
    613                         double values[2];
    614 
    615                         /*Get values on the 6 vertices*/
    616                         for (int i=0;i<2;i++){
    617                                 values[i]=vector[nodes[i]->GetVertexDof()];
    618                         }
    619 
    620                         /*update input*/
    621                         this->inputs->AddInput(new BeamVertexInput(name,values));
    622                         return;
    623 
    624                 default:
    625 
    626                         ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type));
    627         }
    628 }
    629 /*}}}*/
    630 /*FUNCTION Beam::InputUpdateFromVector(int* vector, int name, int type);{{{1*/
    631 void  Beam::InputUpdateFromVector(int* vector, int name, int type){
    632         ISSMERROR(" not supported yet!");
    633 }
    634 /*}}}*/
    635 /*FUNCTION Beam::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/
    636 void  Beam::InputUpdateFromVector(bool* vector, int name, int type){
    637         ISSMERROR(" not supported yet!");
    638 }
    639 /*}}}*/
    640 /*FUNCTION Beam::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){{{1*/
    641 void  Beam::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){
    642 
    643         ISSMERROR(" not supported yet!");
    644        
    645 }
    646 /*}}}*/
    647 /*FUNCTION Beam::PatchFill(int* pcount, Patch* patch){{{1*/
    648 void  Beam::PatchFill(int* pcount, Patch* patch){
    649 
    650         ISSMERROR(" not supported yet!");
    651 }
    652 /*}}}*/
    653 /*FUNCTION Beam::MinVel(double* pminvel, bool process_units);{{{1*/
    654 void  Beam::MinVel(double* pminvel, bool process_units){
    655 
    656         int i;
    657         int dim;
    658         const int numgrids=2;
    659         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    660         double  vx_values[numgrids];
    661         double  vy_values[numgrids];
    662         double  vz_values[numgrids];
    663         double  vel_values[numgrids];
    664         double  minvel;
    665 
    666         /*retrieve dim parameter: */
    667         parameters->FindParam(&dim,DimEnum);
    668 
    669         /*retrive velocity values at nodes */
    670         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    671         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    672         if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    673 
    674         /*now, compute minimum of velocity :*/
    675         if(dim==2){
    676                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
    677         }
    678         else{
    679                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
    680         }
    681 
    682         /*now, compute minimum:*/
    683         minvel=vel_values[0];
    684         for(i=1;i<numgrids;i++){
    685                 if (vel_values[i]<minvel)minvel=vel_values[i];
    686         }
    687 
    688         /*Assign output pointers:*/
    689         *pminvel=minvel;
    690 
    691 }
    692 /*}}}*/
    693 /*FUNCTION Beam::MaxVel(double* pmaxvel, bool process_units);{{{1*/
    694 void  Beam::MaxVel(double* pmaxvel, bool process_units){
    695 
    696         int i;
    697         int dim;
    698         const int numgrids=2;
    699         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    700         double  vx_values[numgrids];
    701         double  vy_values[numgrids];
    702         double  vz_values[numgrids];
    703         double  vel_values[numgrids];
    704         double  maxvel;
    705 
    706         /*retrieve dim parameter: */
    707         parameters->FindParam(&dim,DimEnum);
    708 
    709         /*retrive velocity values at nodes */
    710         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    711         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    712         if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    713 
    714         /*now, compute maximum of velocity :*/
    715         if(dim==2){
    716                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
    717         }
    718         else{
    719                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
    720         }
    721 
    722         /*now, compute maximum:*/
    723         maxvel=vel_values[0];
    724         for(i=1;i<numgrids;i++){
    725                 if (vel_values[i]>maxvel)maxvel=vel_values[i];
    726         }
    727 
    728         /*Assign output pointers:*/
    729         *pmaxvel=maxvel;
    730 
    731 }
    732 /*}}}*/
    733 /*FUNCTION Beam::MinVx(double* pminvx, bool process_units);{{{1*/
    734 void  Beam::MinVx(double* pminvx, bool process_units){
    735 
    736         int i;
    737         int dim;
    738         const int numgrids=2;
    739         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    740         double  vx_values[numgrids];
    741         double  minvx;
    742 
    743         /*retrieve dim parameter: */
    744         parameters->FindParam(&dim,DimEnum);
    745 
    746         /*retrive velocity values at nodes */
    747         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    748 
    749         /*now, compute minimum:*/
    750         minvx=vx_values[0];
    751         for(i=1;i<numgrids;i++){
    752                 if (vx_values[i]<minvx)minvx=vx_values[i];
    753         }
    754 
    755         /*Assign output pointers:*/
    756         *pminvx=minvx;
    757 
    758 }
    759 /*}}}*/
    760 /*FUNCTION Beam::MaxVx(double* pmaxvx, bool process_units);{{{1*/
    761 void  Beam::MaxVx(double* pmaxvx, bool process_units){
    762 
    763         int i;
    764         int dim;
    765         const int numgrids=2;
    766         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    767         double  vx_values[numgrids];
    768         double  maxvx;
    769 
    770         /*retrieve dim parameter: */
    771         parameters->FindParam(&dim,DimEnum);
    772 
    773         /*retrive velocity values at nodes */
    774         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    775 
    776         /*now, compute maximum:*/
    777         maxvx=vx_values[0];
    778         for(i=1;i<numgrids;i++){
    779                 if (vx_values[i]>maxvx)maxvx=vx_values[i];
    780         }
    781 
    782         /*Assign output pointers:*/
    783         *pmaxvx=maxvx;
    784 
    785 }
    786 /*}}}*/
    787 /*FUNCTION Beam::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/
    788 void  Beam::MaxAbsVx(double* pmaxabsvx, bool process_units){
    789 
    790         int i;
    791         int dim;
    792         const int numgrids=2;
    793         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    794         double  vx_values[numgrids];
    795         double  maxabsvx;
    796 
    797         /*retrieve dim parameter: */
    798         parameters->FindParam(&dim,DimEnum);
    799 
    800         /*retrive velocity values at nodes */
    801         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    802 
    803         /*now, compute maximum:*/
    804         maxabsvx=fabs(vx_values[0]);
    805         for(i=1;i<numgrids;i++){
    806                 if (fabs(vx_values[i])>maxabsvx)maxabsvx=fabs(vx_values[i]);
    807         }
    808 
    809         /*Assign output pointers:*/
    810         *pmaxabsvx=maxabsvx;
    811 }
    812 /*}}}*/
    813 /*FUNCTION Beam::MinVy(double* pminvy, bool process_units);{{{1*/
    814 void  Beam::MinVy(double* pminvy, bool process_units){
    815 
    816         int i;
    817         int dim;
    818         const int numgrids=2;
    819         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    820         double  vy_values[numgrids];
    821         double  minvy;
    822 
    823         /*retrieve dim parameter: */
    824         parameters->FindParam(&dim,DimEnum);
    825 
    826         /*retrive velocity values at nodes */
    827         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    828 
    829         /*now, compute minimum:*/
    830         minvy=vy_values[0];
    831         for(i=1;i<numgrids;i++){
    832                 if (vy_values[i]<minvy)minvy=vy_values[i];
    833         }
    834 
    835         /*Assign output pointers:*/
    836         *pminvy=minvy;
    837 
    838 }
    839 /*}}}*/
    840 /*FUNCTION Beam::MaxVy(double* pmaxvy, bool process_units);{{{1*/
    841 void  Beam::MaxVy(double* pmaxvy, bool process_units){
    842 
    843         int i;
    844         int dim;
    845         const int numgrids=2;
    846         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    847         double  vy_values[numgrids];
    848         double  maxvy;
    849 
    850         /*retrieve dim parameter: */
    851         parameters->FindParam(&dim,DimEnum);
    852 
    853         /*retrive velocity values at nodes */
    854         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    855 
    856         /*now, compute maximum:*/
    857         maxvy=vy_values[0];
    858         for(i=1;i<numgrids;i++){
    859                 if (vy_values[i]>maxvy)maxvy=vy_values[i];
    860         }
    861 
    862         /*Assign output pointers:*/
    863         *pmaxvy=maxvy;
    864 
    865 }
    866 /*}}}*/
    867 /*FUNCTION Beam::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/
    868 void  Beam::MaxAbsVy(double* pmaxabsvy, bool process_units){
    869 
    870         int i;
    871         int dim;
    872         const int numgrids=2;
    873         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    874         double  vy_values[numgrids];
    875         double  maxabsvy;
    876 
    877         /*retrieve dim parameter: */
    878         parameters->FindParam(&dim,DimEnum);
    879 
    880         /*retrive velocity values at nodes */
    881         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    882 
    883         /*now, compute maximum:*/
    884         maxabsvy=fabs(vy_values[0]);
    885         for(i=1;i<numgrids;i++){
    886                 if (fabs(vy_values[i])>maxabsvy)maxabsvy=fabs(vy_values[i]);
    887         }
    888 
    889         /*Assign output pointers:*/
    890         *pmaxabsvy=maxabsvy;
    891 }
    892 /*}}}*/
    893 /*FUNCTION Beam::MinVz(double* pminvz, bool process_units);{{{1*/
    894 void  Beam::MinVz(double* pminvz, bool process_units){
    895 
    896         int i;
    897         int dim;
    898         const int numgrids=2;
    899         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    900         double  vz_values[numgrids];
    901         double  minvz;
    902 
    903         /*retrieve dim parameter: */
    904         parameters->FindParam(&dim,DimEnum);
    905 
    906         /*retrive velocity values at nodes */
    907         inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    908 
    909         /*now, compute minimum:*/
    910         minvz=vz_values[0];
    911         for(i=1;i<numgrids;i++){
    912                 if (vz_values[i]<minvz)minvz=vz_values[i];
    913         }
    914 
    915         /*Assign output pointers:*/
    916         *pminvz=minvz;
    917 
    918 }
    919 /*}}}*/
    920 /*FUNCTION Beam::MaxVz(double* pmaxvz, bool process_units);{{{1*/
    921 void  Beam::MaxVz(double* pmaxvz, bool process_units){
    922 
    923         int i;
    924         int dim;
    925         const int numgrids=2;
    926         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    927         double  vz_values[numgrids];
    928         double  maxvz;
    929 
    930         /*retrieve dim parameter: */
    931         parameters->FindParam(&dim,DimEnum);
    932 
    933         /*retrive velocity values at nodes */
    934         inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    935 
    936         /*now, compute maximum:*/
    937         maxvz=vz_values[0];
    938         for(i=1;i<numgrids;i++){
    939                 if (vz_values[i]>maxvz)maxvz=vz_values[i];
    940         }
    941 
    942         /*Assign output pointers:*/
    943         *pmaxvz=maxvz;
    944 
    945 }
    946 /*}}}*/
    947 /*FUNCTION Beam::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/
    948 void  Beam::MaxAbsVz(double* pmaxabsvz, bool process_units){
    949 
    950         int i;
    951         int dim;
    952         const int numgrids=2;
    953         double  gaussgrids[numgrids][2]={{0,1},{1,0}};
    954         double  vz_values[numgrids];
    955         double  maxabsvz;
    956 
    957         /*retrieve dim parameter: */
    958         parameters->FindParam(&dim,DimEnum);
    959 
    960         /*retrive velocity values at nodes */
    961         inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    962 
    963         /*now, compute maximum:*/
    964         maxabsvz=fabs(vz_values[0]);
    965         for(i=1;i<numgrids;i++){
    966                 if (fabs(vz_values[i])>maxabsvz)maxabsvz=fabs(vz_values[i]);
    967         }
    968 
    969         /*Assign output pointers:*/
    970         *pmaxabsvz=maxabsvz;
    971 }
    972 /*}}}*/
    973 /*FUNCTION Beam::InputDuplicate(int original_enum,int new_enum){{{1*/
    974 void  Beam::InputDuplicate(int original_enum,int new_enum){
    975 
    976         Input* original=NULL;
    977         Input* copy=NULL;
    978 
    979         /*Make a copy of the original input: */
    980         original=(Input*)this->inputs->GetInput(original_enum);
    981         copy=(Input*)original->copy();
    982 
    983         /*Change copy enum to reinitialized_enum: */
    984         copy->ChangeEnum(new_enum);
    985 
    986         /*Add copy into inputs, it will wipe off the one already there: */
    987         inputs->AddObject((Input*)copy);
    988 }
    989 /*}}}*/
    990 /*FUNCTION Beam::InputScale(int enum_type,double scale_factor){{{1*/
    991 void  Beam::InputScale(int enum_type,double scale_factor){
    992 
    993         Input* input=NULL;
    994 
    995         /*Make a copy of the original input: */
    996         input=(Input*)this->inputs->GetInput(enum_type);
    997 
    998         /*Scale: */
    999         input->Scale(scale_factor);
    1000 }
    1001 /*}}}*/
    1002 /*FUNCTION Beam::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/
    1003 void  Beam::InputAXPY(int YEnum, double scalar, int XEnum){
    1004 
    1005         Input* xinput=NULL;
    1006         Input* yinput=NULL;
    1007 
    1008         /*Find x and y inputs: */
    1009         xinput=(Input*)this->inputs->GetInput(XEnum);
    1010         yinput=(Input*)this->inputs->GetInput(YEnum);
    1011 
    1012         /*some checks: */
    1013         if(!xinput || !yinput)ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!");
    1014         if(xinput->Enum()!=yinput->Enum())ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," and input ",EnumAsString(YEnum)," are not of the same type!");
    1015 
    1016         /*Scale: */
    1017         yinput->AXPY(xinput,scalar);
    1018 }
    1019 /*}}}*/
    1020 /*FUNCTION Beam::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/
    1021 void  Beam::InputControlConstrain(int control_type, double cm_min, double cm_max){
    1022 
    1023         Input* input=NULL;
    1024 
    1025         /*Find input: */
    1026         input=(Input*)this->inputs->GetInput(control_type);
    1027        
    1028         /*Do nothing if we  don't find it: */
    1029         if(!input)return;
    1030 
    1031         /*Constrain input using cm_min and cm_max: */
    1032         input->Constrain(cm_min,cm_max);
    1033 
    1034 }
    1035 /*}}}*/
    1036 /*FUNCTION Beam::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/
    1037 void  Beam::GetVectorFromInputs(Vec vector,int NameEnum){
    1038 
    1039         int i;
    1040         const int numvertices=2;
    1041         int doflist1[numvertices];
    1042 
    1043         /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */
    1044         for(i=0;i<this->inputs->Size();i++){
    1045                 Input* input=(Input*)this->inputs->GetObjectByOffset(i);
    1046                 if(input->EnumType()==NameEnum){
    1047                         /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
    1048                         this->GetDofList1(&doflist1[0]);
    1049                         input->GetVectorFromInputs(vector,&doflist1[0]);
    1050                         break;
    1051                 }
    1052         }
    1053 }
    1054 /*}}}*/
    1055 /*FUNCTION Beam::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/
    1056 void  Beam::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){
    1057 
    1058         int     i;
    1059         Input** new_inputs=NULL;
    1060         Input** old_inputs=NULL;
    1061         int     converged=1;
    1062 
    1063         new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs
    1064         old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs
    1065        
    1066         for(i=0;i<num_enums/2;i++){
    1067                 new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]);
    1068                 old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]);
    1069                 if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
    1070                 if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
    1071         }
    1072 
    1073         /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/
    1074         for(i=0;i<num_criterionenums;i++){
    1075                 IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]);
    1076                 if(eps[i]>criterionvalues[i]) converged=0;
    1077         }
    1078 
    1079         /*Assign output pointers:*/
    1080         *pconverged=converged;
    1081 
    1082 }
    1083 /*}}}*/
  • TabularUnified issm/trunk/src/c/objects/Elements/Beam.h

    r4249 r4250  
    4242                /*}}}*/
    4343                /*Object virtual functions definitions: {{{1*/
    44                 void  Echo();
    45                 void  DeepEcho();
    46                 int   Id();
    47                 int   MyRank();
    48                 void  Marshall(char** pmarshalled_dataset);
    49                 int   MarshallSize();
    50                 void  Demarshall(char** pmarshalled_dataset);
    51                 int   Enum();
    5244                Object* copy();
     45                void    DeepEcho();
     46                void    Demarshall(char** pmarshalled_dataset);
     47                void    Echo();
     48                int     Enum();
     49                int     Id();
     50                void    Marshall(char** pmarshalled_dataset);
     51                int     MarshallSize();
     52                int     MyRank();
    5353                /*}}}*/
    5454                /*Update virtual functions resolution: {{{1*/
  • TabularUnified issm/trunk/src/c/objects/Elements/Penta.cpp

    r4248 r4250  
    8888}
    8989/*}}}*/
    90 /*FUNCTION Penta::Update(IoModel* iomodel,int analysis_counter,int analysis_type) {{{1*/
    91 void Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type){
    92 
    93         /*Intermediaries*/
    94         IssmInt i;
    95         int penta_node_ids[6];
    96         int penta_vertex_ids[6];
    97         double nodeinputs[6];
    98 
    99         /*Checks if debuging*/
    100         /*{{{2*/
    101         ISSMASSERT(iomodel->elements);
    102         /*}}}*/
    103 
    104         /*Recover vertices ids needed to initialize inputs*/
    105         for(i=0;i<6;i++){
    106                 penta_vertex_ids[i]=(int)iomodel->elements[6*index+i]; //ids for vertices are in the elements array from Matlab
    107         }
    108 
    109         /*Recover nodes ids needed to initialize the node hook.*/
    110         for(i=0;i<6;i++){ //go recover node ids, needed to initialize the node hook.
    111                 penta_node_ids[i]=(int)iomodel->elements[6*index+i]; //ids for vertices are in the elements array from Matlab
    112         }
    113 
    114         /*hooks: */
    115         this->SetHookNodes(penta_node_ids,analysis_counter); this->nodes=NULL; //set hook to nodes, for this analysis type
    116 
    117         //add as many inputs per element as requested:
    118         if (iomodel->thickness) {
    119                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->thickness[penta_vertex_ids[i]-1];
    120                 this->inputs->AddInput(new PentaVertexInput(ThicknessEnum,nodeinputs));
    121         }
    122         if (iomodel->surface) {
    123                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->surface[penta_vertex_ids[i]-1];
    124                 this->inputs->AddInput(new PentaVertexInput(SurfaceEnum,nodeinputs));
    125         }
    126         if (iomodel->bed) {
    127                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->bed[penta_vertex_ids[i]-1];
    128                 this->inputs->AddInput(new PentaVertexInput(BedEnum,nodeinputs));
    129         }
    130         if (iomodel->drag_coefficient) {
    131                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->drag_coefficient[penta_vertex_ids[i]-1];
    132                 this->inputs->AddInput(new PentaVertexInput(DragCoefficientEnum,nodeinputs));
    133 
    134                 if (iomodel->drag_p) this->inputs->AddInput(new DoubleInput(DragPEnum,iomodel->drag_p[index]));
    135                 if (iomodel->drag_q) this->inputs->AddInput(new DoubleInput(DragQEnum,iomodel->drag_q[index]));
    136                 this->inputs->AddInput(new IntInput(DragTypeEnum,iomodel->drag_type));
    137 
    138         }
    139         if (iomodel->melting_rate) {
    140                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->melting_rate[penta_vertex_ids[i]-1]/iomodel->yts;
    141                 this->inputs->AddInput(new PentaVertexInput(MeltingRateEnum,nodeinputs));
    142         }
    143         if (iomodel->accumulation_rate) {
    144                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->accumulation_rate[penta_vertex_ids[i]-1]/iomodel->yts;
    145                 this->inputs->AddInput(new PentaVertexInput(AccumulationRateEnum,nodeinputs));
    146         }
    147         if (iomodel->geothermalflux) {
    148                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->geothermalflux[penta_vertex_ids[i]-1];
    149                 this->inputs->AddInput(new PentaVertexInput(GeothermalFluxEnum,nodeinputs));
    150         }       
    151         if (iomodel->pressure) {
    152                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->pressure[penta_vertex_ids[i]-1];
    153                 this->inputs->AddInput(new PentaVertexInput(PressureEnum,nodeinputs));
    154         }
    155         if (iomodel->temperature) {
    156                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->temperature[penta_vertex_ids[i]-1];
    157                 this->inputs->AddInput(new PentaVertexInput(TemperatureEnum,nodeinputs));
    158         }
    159         if (iomodel->dhdt) {
    160                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->dhdt[penta_vertex_ids[i]-1];
    161                 this->inputs->AddInput(new PentaVertexInput(DhDtEnum,nodeinputs));
    162         }
    163         /*vx,vy and vz: */
    164         if (iomodel->vx) {
    165                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->vx[penta_vertex_ids[i]-1]/iomodel->yts;
    166                 this->inputs->AddInput(new PentaVertexInput(VxEnum,nodeinputs));
    167                 this->inputs->AddInput(new PentaVertexInput(VxOldEnum,nodeinputs));
    168         }
    169         if (iomodel->vy) {
    170                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->vy[penta_vertex_ids[i]-1]/iomodel->yts;
    171                 this->inputs->AddInput(new PentaVertexInput(VyEnum,nodeinputs));
    172                 this->inputs->AddInput(new PentaVertexInput(VyOldEnum,nodeinputs));
    173         }
    174         if (iomodel->vz) {
    175                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->vz[penta_vertex_ids[i]-1]/iomodel->yts;
    176                 this->inputs->AddInput(new PentaVertexInput(VzEnum,nodeinputs));
    177                 this->inputs->AddInput(new PentaVertexInput(VzOldEnum,nodeinputs));
    178         }
    179         if (iomodel->vx_obs) {
    180                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->vx_obs[penta_vertex_ids[i]-1]/iomodel->yts;
    181                 this->inputs->AddInput(new PentaVertexInput(VxObsEnum,nodeinputs));
    182         }
    183         if (iomodel->vy_obs) {
    184                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->vy_obs[penta_vertex_ids[i]-1]/iomodel->yts;
    185                 this->inputs->AddInput(new PentaVertexInput(VyObsEnum,nodeinputs));
    186         }
    187         if (iomodel->vz_obs) {
    188                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->vz_obs[penta_vertex_ids[i]-1]/iomodel->yts;
    189                 this->inputs->AddInput(new PentaVertexInput(VzObsEnum,nodeinputs));
    190         }
    191         if (iomodel->weights) {
    192                 for(i=0;i<6;i++)nodeinputs[i]=iomodel->weights[penta_vertex_ids[i]-1];
    193                 this->inputs->AddInput(new PentaVertexInput(WeightsEnum,nodeinputs));
    194         }
    195 
    196         /*default vx,vy and vz: either observation or 0 */
    197         if (!iomodel->vx){
    198                 if (iomodel->vx_obs) for(i=0;i<6;i++)nodeinputs[i]=iomodel->vx_obs[penta_vertex_ids[i]-1]/iomodel->yts;
    199                 else                 for(i=0;i<6;i++)nodeinputs[i]=0;
    200                 this->inputs->AddInput(new PentaVertexInput(VxEnum,nodeinputs));
    201                 this->inputs->AddInput(new PentaVertexInput(VxOldEnum,nodeinputs));
    202         }
    203         if (!iomodel->vy){
    204                 if (iomodel->vy_obs) for(i=0;i<6;i++)nodeinputs[i]=iomodel->vy_obs[penta_vertex_ids[i]-1]/iomodel->yts;
    205                 else                 for(i=0;i<6;i++)nodeinputs[i]=0;
    206                 this->inputs->AddInput(new PentaVertexInput(VyEnum,nodeinputs));
    207                 this->inputs->AddInput(new PentaVertexInput(VyOldEnum,nodeinputs));
    208         }
    209         if (!iomodel->vz){
    210                 if (iomodel->vz_obs) for(i=0;i<6;i++)nodeinputs[i]=iomodel->vz_obs[penta_vertex_ids[i]-1]/iomodel->yts;
    211                 else                 for(i=0;i<6;i++)nodeinputs[i]=0;
    212                 this->inputs->AddInput(new PentaVertexInput(VzEnum,nodeinputs));
    213                 this->inputs->AddInput(new PentaVertexInput(VzOldEnum,nodeinputs));
    214         }
    215         if (iomodel->elementoniceshelf) this->inputs->AddInput(new BoolInput(ElementOnIceShelfEnum,(IssmBool)iomodel->elementoniceshelf[index]));
    216         if (iomodel->elementonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->elementonbed[index]));
    217         if (iomodel->elementonwater) this->inputs->AddInput(new BoolInput(ElementOnWaterEnum,(IssmBool)iomodel->elementonwater[index]));
    218         if (iomodel->elementonsurface) this->inputs->AddInput(new BoolInput(ElementOnSurfaceEnum,(IssmBool)iomodel->elementonsurface[index]));
    219 
    220         //elements of type 3 are macayeal type penta. we collapse the formulation on their base.
    221         if(iomodel->elements_type){
    222                 if (*(iomodel->elements_type+2*i+0)==MacAyealFormulationEnum){
    223                         collapse[analysis_counter]=true;
    224                 }
    225                 else{
    226                         collapse[analysis_counter]=false;
    227                 }
    228         }
    229 }
    230 /*}}}*/
    23190
    23291/*Object virtual functions definitions: */
    233 /*FUNCTION Penta::Echo{{{1*/
    234 
    235 void Penta::Echo(void){
    236         this->DeepEcho();
     92/*FUNCTION Penta::copy {{{1*/
     93Object* Penta::copy() {
     94
     95        int i;
     96
     97        Penta* penta=NULL;
     98
     99        penta=new Penta();
     100
     101        /*copy fields: */
     102        penta->id=this->id;
     103        if(this->inputs){
     104                penta->inputs=(Inputs*)this->inputs->Copy();
     105        }
     106        else{
     107                penta->inputs=new Inputs();
     108        }
     109        if(this->results){
     110                penta->results=(Results*)this->results->Copy();
     111        }
     112        else{
     113                penta->results=new Results();
     114        }
     115        /*point parameters: */
     116        penta->parameters=this->parameters;
     117
     118        /*now deal with hooks and objects: */
     119        penta->InitHookNodes(this->numanalyses);
     120        for(i=0;i<this->numanalyses;i++)penta->hnodes[i].copy(&this->hnodes[i]);
     121        penta->hmatice.copy(&this->hmatice);
     122        penta->hmatpar.copy(&this->hmatpar);
     123        penta->hneighbors.copy(&this->hneighbors);
     124
     125        /*recover objects: */
     126        penta->nodes=(Node**)xmalloc(6*sizeof(Node*)); //we cannot rely on an analysis_counter to tell us which analysis_type we are running, so we just copy the nodes.
     127        for(i=0;i<6;i++)penta->nodes[i]=this->nodes[i];
     128        penta->matice=(Matice*)penta->hmatice.delivers();
     129        penta->matpar=(Matpar*)penta->hmatpar.delivers();
     130        penta->neighbors=(Penta**)penta->hneighbors.deliverp();
     131
     132        return penta;
    237133}
    238134/*}}}*/
     
    264160}
    265161/*}}}*/
     162/*FUNCTION Penta::Demarshall {{{1*/
     163void  Penta::Demarshall(char** pmarshalled_dataset){
     164
     165        char* marshalled_dataset=NULL;
     166        int   i;
     167
     168        /*recover marshalled_dataset: */
     169        marshalled_dataset=*pmarshalled_dataset;
     170
     171        /*this time, no need to get enum type, the pointer directly points to the beginning of the
     172         *object data (thanks to DataSet::Demarshall):*/
     173
     174        memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
     175        memcpy(&numanalyses,marshalled_dataset,sizeof(numanalyses));marshalled_dataset+=sizeof(numanalyses);
     176
     177        /*allocate dynamic memory: */
     178        collapse=(bool*)xmalloc(numanalyses*sizeof(bool));
     179        InitHookNodes(numanalyses);
     180
     181        /*demarshall hooks: */
     182        for(i=0;i<numanalyses;i++)hnodes[i].Demarshall(&marshalled_dataset);
     183        hmatice.Demarshall(&marshalled_dataset);
     184        hmatpar.Demarshall(&marshalled_dataset);
     185        hneighbors.Demarshall(&marshalled_dataset);
     186
     187        /*pointers are garbage, until configuration is carried out: */
     188        nodes=NULL;
     189        matice=NULL;
     190        matpar=NULL;
     191        neighbors=NULL;
     192       
     193        /*demarshall inputs and results: */
     194        inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset);
     195        results=(Results*)DataSetDemarshallRaw(&marshalled_dataset);
     196
     197        /*demarshall internal parameters: */
     198        memcpy(collapse,marshalled_dataset,numanalyses*sizeof(bool));marshalled_dataset+=numanalyses*sizeof(bool);
     199
     200        /*parameters: may not exist even yet, so let Configure handle it: */
     201        this->parameters=NULL;
     202
     203        /*return: */
     204        *pmarshalled_dataset=marshalled_dataset;
     205        return;
     206}
     207/*}}}*/
     208/*FUNCTION Penta::Echo{{{1*/
     209
     210void Penta::Echo(void){
     211        this->DeepEcho();
     212}
     213/*}}}*/
     214/*FUNCTION Penta::Enum {{{1*/
     215int Penta::Enum(void){
     216
     217        return PentaEnum;
     218
     219}
     220/*}}}*/
    266221/*FUNCTION Penta::Id {{{1*/
    267222int    Penta::Id(void){
    268223        return id;
    269 }
    270 /*}}}*/
    271 /*FUNCTION Penta::MyRank {{{1*/
    272 int    Penta::MyRank(void){
    273         extern int my_rank;
    274         return my_rank;
    275224}
    276225/*}}}*/
     
    347296}
    348297/*}}}*/
    349 /*FUNCTION Penta::Demarshall {{{1*/
    350 void  Penta::Demarshall(char** pmarshalled_dataset){
    351 
    352         char* marshalled_dataset=NULL;
    353         int   i;
    354 
    355         /*recover marshalled_dataset: */
    356         marshalled_dataset=*pmarshalled_dataset;
    357 
    358         /*this time, no need to get enum type, the pointer directly points to the beginning of the
    359          *object data (thanks to DataSet::Demarshall):*/
    360 
    361         memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
    362         memcpy(&numanalyses,marshalled_dataset,sizeof(numanalyses));marshalled_dataset+=sizeof(numanalyses);
    363 
    364         /*allocate dynamic memory: */
    365         collapse=(bool*)xmalloc(numanalyses*sizeof(bool));
    366         InitHookNodes(numanalyses);
    367 
    368         /*demarshall hooks: */
    369         for(i=0;i<numanalyses;i++)hnodes[i].Demarshall(&marshalled_dataset);
    370         hmatice.Demarshall(&marshalled_dataset);
    371         hmatpar.Demarshall(&marshalled_dataset);
    372         hneighbors.Demarshall(&marshalled_dataset);
    373 
    374         /*pointers are garbage, until configuration is carried out: */
    375         nodes=NULL;
    376         matice=NULL;
    377         matpar=NULL;
    378         neighbors=NULL;
     298/*FUNCTION Penta::MyRank {{{1*/
     299int    Penta::MyRank(void){
     300        extern int my_rank;
     301        return my_rank;
     302}
     303/*}}}*/
     304
     305/*Update virtual functions definitions: */
     306/*FUNCTION Penta::InputUpdateFromConstant(bool value, int name);{{{1*/
     307void  Penta::InputUpdateFromConstant(bool constant, int name){
     308        /*Nothing updated for now*/
     309}
     310/*}}}*/
     311/*FUNCTION Penta::InputUpdateFromConstant(double value, int name);{{{1*/
     312void  Penta::InputUpdateFromConstant(double constant, int name){
     313        /*Nothing updated for now*/
     314}
     315/*}}}*/
     316/*FUNCTION Penta::InputUpdateFromConstant(int value, int name);{{{1*/
     317void  Penta::InputUpdateFromConstant(int constant, int name){
     318        /*Nothing updated for now*/
     319}
     320/*}}}*/
     321/*FUNCTION Penta::InputUpdateFromSolution {{{1*/
     322void  Penta::InputUpdateFromSolution(double* solution){
     323
     324        int analysis_type;
     325
     326        /*retreive parameters: */
     327        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     328
     329        /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
     330        if (analysis_type==ControlAnalysisEnum){
     331                InputUpdateFromSolutionDiagnosticHoriz( solution);
     332        }
     333        else if (analysis_type==DiagnosticHorizAnalysisEnum){
     334                InputUpdateFromSolutionDiagnosticHoriz( solution);
     335        }
     336        else if (analysis_type==DiagnosticStokesAnalysisEnum){
     337                InputUpdateFromSolutionDiagnosticStokes( solution);
     338        }
     339        else if (analysis_type==SlopeAnalysisEnum){
     340                InputUpdateFromSolutionSlopeCompute( solution);
     341        }
     342        else if (analysis_type==PrognosticAnalysisEnum){
     343                InputUpdateFromSolutionPrognostic( solution);
     344        }
     345        else if (analysis_type==Prognostic2AnalysisEnum){
     346                InputUpdateFromSolutionPrognostic2(solution);
     347        }
     348        else if (analysis_type==BalancedthicknessAnalysisEnum){
     349                InputUpdateFromSolutionBalancedthickness( solution);
     350        }
     351        else if (analysis_type==Balancedthickness2AnalysisEnum){
     352                InputUpdateFromSolutionBalancedthickness2( solution);
     353        }
     354        else if (analysis_type==BalancedvelocitiesAnalysisEnum){
     355                InputUpdateFromSolutionBalancedvelocities( solution);
     356        }
     357        else{
     358                ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
     359        }
     360}
     361/*}}}*/
     362/*FUNCTION Penta::InputUpdateFromVector(double* vector, int name, int type);{{{1*/
     363void  Penta::InputUpdateFromVector(double* vector, int name, int type){
     364
     365        /*Check that name is an element input*/
     366        if (!IsInput(name)) return;
     367
     368        switch(type){
     369
     370                case VertexEnum:
     371
     372                        /*New PentaVertexInpu*/
     373                        double values[6];
     374
     375                        /*Get values on the 6 vertices*/
     376                        for (int i=0;i<6;i++){
     377                                values[i]=vector[this->nodes[i]->GetVertexDof()];
     378                        }
     379
     380                        /*update input*/
     381                        this->inputs->AddInput(new PentaVertexInput(name,values));
     382                        return;
     383
     384                default:
     385
     386                        ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type));
     387        }
     388}
     389/*}}}*/
     390/*FUNCTION Penta::InputUpdateFromVector(int* vector, int name, int type);{{{1*/
     391void  Penta::InputUpdateFromVector(int* vector, int name, int type){
     392        ISSMERROR(" not supported yet!");
     393}
     394/*}}}*/
     395/*FUNCTION Penta::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/
     396void  Penta::InputUpdateFromVector(bool* vector, int name, int type){
     397        ISSMERROR(" not supported yet!");
     398}
     399/*}}}*/
     400
     401/*Element virtual functions definitions: */
     402/*FUNCTION Penta::ComputeBasalStress {{{1*/
     403void  Penta::ComputeBasalStress(Vec sigma_b){
     404
     405        int i,j;
     406        const int numgrids=6;
     407        int    doflist[numgrids];
     408        double xyz_list[numgrids][3];
     409        double xyz_list_tria[3][3];
     410
     411        /*Parameters*/
     412        double rho_ice,gravity;
     413        double surface_normal[3];
     414        double bed_normal[3];
     415        double bed;
     416        double basalforce[3];
     417        double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     418        double devstresstensor[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     419        double stresstensor[6]={0.0};
     420        double viscosity;
     421        int analysis_type,sub_analysis_type;
     422
     423        int  dofv[3]={0,1,2};
     424        int  dofp[1]={3};
     425        double Jdet2d;
     426        Tria* tria=NULL;
     427
     428        /*Gauss*/
     429        int     num_gauss,ig;
     430        double* first_gauss_area_coord  =  NULL;
     431        double* second_gauss_area_coord =  NULL;
     432        double* third_gauss_area_coord  =  NULL;
     433        double* gauss_weights           =  NULL;
     434        double  gauss_weight;
     435        double  gauss_coord[4];
     436
     437        /*Output*/
     438        double pressure;
     439        double sigma_xx,sigma_yy,sigma_zz;
     440        double sigma_xy,sigma_xz,sigma_yz;
     441        double surface=0;
     442        double value=0;
    379443       
    380         /*demarshall inputs and results: */
    381         inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset);
    382         results=(Results*)DataSetDemarshallRaw(&marshalled_dataset);
    383 
    384         /*demarshall internal parameters: */
    385         memcpy(collapse,marshalled_dataset,numanalyses*sizeof(bool));marshalled_dataset+=numanalyses*sizeof(bool);
    386 
    387         /*parameters: may not exist even yet, so let Configure handle it: */
    388         this->parameters=NULL;
    389 
    390         /*return: */
    391         *pmarshalled_dataset=marshalled_dataset;
    392         return;
    393 }
    394 /*}}}*/
    395 /*FUNCTION Penta::Enum {{{1*/
    396 int Penta::Enum(void){
    397 
    398         return PentaEnum;
    399 
    400 }
    401 /*}}}*/
    402 /*FUNCTION Penta::copy {{{1*/
    403 Object* Penta::copy() {
     444        /*flags: */
     445        bool onbed;
     446
     447        /*parameters: */
     448        double stokesreconditioning;
     449
     450
     451        /*retrive parameters: */
     452        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     453        parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
     454
     455        /*Check analysis_types*/
     456        if (analysis_type!=DiagnosticAnalysisEnum || sub_analysis_type!=StokesAnalysisEnum) ISSMERROR("Not supported yet!");
     457
     458        /*recover some inputs: */
     459        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     460
     461        /*retrieve some parameters: */
     462        this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum);
     463       
     464        if(!onbed){
     465                //put zero
     466                VecSetValue(sigma_b,id-1,0.0,INSERT_VALUES);
     467                return;
     468        }
     469
     470        /*recovre material parameters: */
     471        rho_ice=matpar->GetRhoIce();
     472        gravity=matpar->GetG();
     473
     474        /* Get node coordinates and dof list: */
     475        GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
     476        for(i=0;i<3;i++){
     477                for(j=0;j<3;j++){
     478                        xyz_list_tria[i][j]=xyz_list[i][j];
     479                }
     480        }
     481
     482        /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
     483        GaussTria(&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights,2);
     484
     485        /* Start  looping on the number of gaussian points: */
     486        for (ig=0; ig<num_gauss; ig++){
     487
     488                        /*Pick up the gaussian point: */
     489                        gauss_weight=*(gauss_weights+ig);
     490                        gauss_coord[0]=*(first_gauss_area_coord+ig);
     491                        gauss_coord[1]=*(second_gauss_area_coord+ig);
     492                        gauss_coord[2]=*(third_gauss_area_coord+ig);
     493                        gauss_coord[3]=-1.0; //take the base
     494
     495                        /*Compute strain rate viscosity and pressure: */
     496                        inputs->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
     497                        matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
     498                        inputs->GetParameterValue(&pressure, &gauss_coord[0],PressureEnum);
     499
     500                        /*Compute Stress*/
     501                        sigma_xx=viscosity*epsilon[0]-pressure*stokesreconditioning; // sigma = nu eps - pressure
     502                        sigma_yy=viscosity*epsilon[1]-pressure*stokesreconditioning;
     503                        sigma_zz=viscosity*epsilon[2]-pressure*stokesreconditioning;
     504                        sigma_xy=viscosity*epsilon[3];
     505                        sigma_xz=viscosity*epsilon[4];
     506                        sigma_yz=viscosity*epsilon[5];
     507
     508                        /*Get normal vector to the bed */
     509                        SurfaceNormal(&surface_normal[0],xyz_list_tria);
     510                        bed_normal[0] = - surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result
     511                        bed_normal[1] = - surface_normal[1];
     512                        bed_normal[2] = - surface_normal[2];
     513
     514                        /*basalforce*/
     515                        basalforce[0] += sigma_xx*bed_normal[0] + sigma_xy*bed_normal[1] + sigma_xz*bed_normal[2];
     516                        basalforce[1] += sigma_xy*bed_normal[0] + sigma_yy*bed_normal[1] + sigma_yz*bed_normal[2];
     517                        basalforce[2] += sigma_xz*bed_normal[0] + sigma_yz*bed_normal[1] + sigma_zz*bed_normal[2];
     518
     519                        /*Get the Jacobian determinant */
     520                        tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0],gauss_coord);
     521                        value+=sigma_zz*Jdet2d*gauss_weight;
     522                        surface+=Jdet2d*gauss_weight;
     523        }
     524        value=value/surface;
     525
     526        /*Add value to output*/
     527        VecSetValue(sigma_b,id-1,(const double)value,INSERT_VALUES);
     528}
     529/*}}}*/
     530/*FUNCTION Penta::ComputePressure {{{1*/
     531void  Penta::ComputePressure(Vec pg){
    404532
    405533        int i;
    406 
    407         Penta* penta=NULL;
    408 
    409         penta=new Penta();
    410 
    411         /*copy fields: */
    412         penta->id=this->id;
    413         if(this->inputs){
    414                 penta->inputs=(Inputs*)this->inputs->Copy();
    415         }
    416         else{
    417                 penta->inputs=new Inputs();
    418         }
    419         if(this->results){
    420                 penta->results=(Results*)this->results->Copy();
    421         }
    422         else{
    423                 penta->results=new Results();
    424         }
    425         /*point parameters: */
    426         penta->parameters=this->parameters;
    427 
    428         /*now deal with hooks and objects: */
    429         penta->InitHookNodes(this->numanalyses);
    430         for(i=0;i<this->numanalyses;i++)penta->hnodes[i].copy(&this->hnodes[i]);
    431         penta->hmatice.copy(&this->hmatice);
    432         penta->hmatpar.copy(&this->hmatpar);
    433         penta->hneighbors.copy(&this->hneighbors);
    434 
    435         /*recover objects: */
    436         penta->nodes=(Node**)xmalloc(6*sizeof(Node*)); //we cannot rely on an analysis_counter to tell us which analysis_type we are running, so we just copy the nodes.
    437         for(i=0;i<6;i++)penta->nodes[i]=this->nodes[i];
    438         penta->matice=(Matice*)penta->hmatice.delivers();
    439         penta->matpar=(Matpar*)penta->hmatpar.delivers();
    440         penta->neighbors=(Penta**)penta->hneighbors.deliverp();
    441 
    442         return penta;
    443 }
    444 /*}}}*/
    445 
    446 
    447 /*Penta functionality: */
     534        const int numgrids=6;
     535        int    doflist[numgrids];
     536        double pressure[numgrids];
     537        double rho_ice,g;
     538        double surface[numgrids];
     539        double xyz_list[numgrids][3];
     540        double gauss[numgrids][numgrids]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     541
     542        /*inputs: */
     543        bool onwater;
     544
     545        /*retrieve inputs :*/
     546        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     547
     548        /*If on water, skip: */
     549        if(onwater)return;
     550
     551        /*Get node data: */
     552        GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
     553
     554        /*pressure is lithostatic: */
     555        //md.pressure=md.rho_ice*md.g*(md.surface-md.z); a la matlab
     556
     557        /*Get dof list on which we will plug the pressure values: */
     558        GetDofList1(&doflist[0]);
     559
     560        /*recover value of surface at grids: */
     561        inputs->GetParameterValues(&surface[0],&gauss[0][0],6,SurfaceEnum);
     562
     563        /*pressure is lithostatic: */
     564        rho_ice=matpar->GetRhoIce();
     565        g=matpar->GetG();
     566        for(i=0;i<numgrids;i++){
     567                pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
     568        }
     569
     570        /*plug local pressure values into global pressure vector: */
     571        VecSetValues(pg,numgrids,doflist,(const double*)pressure,INSERT_VALUES);
     572
     573}
     574/*}}}*/
     575/*FUNCTION Penta::ComputeStrainRate {{{1*/
     576void  Penta::ComputeStrainRate(Vec eps){
     577
     578        ISSMERROR("Not implemented yet");
     579
     580}
     581/*}}}*/
    448582                /*FUNCTION Penta::Configure {{{1*/
    449583void  Penta::Configure(Elements* elementsin, Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){
     
    471605}
    472606/*}}}*/
     607/*FUNCTION Penta::CostFunction {{{1*/
     608double Penta::CostFunction(void){
     609
     610        double J;
     611        Tria* tria=NULL;
     612
     613        /*flags: */
     614        bool onbed;
     615        bool onwater;
     616        bool collapse;
     617        bool onsurface;
     618
     619        /*recover some inputs: */
     620        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     621        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     622        inputs->GetParameterValue(&collapse,CollapseEnum);
     623        inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
     624
     625        /*If on water, return 0: */
     626        if(onwater)return 0;
     627
     628        /*Bail out if this element if:
     629         * -> Non collapsed and not on the surface
     630         * -> collapsed (2d model) and not on bed) */
     631        if ((!collapse && !onsurface) || (collapse && !onbed)){
     632                return 0;
     633        }
     634        else if (collapse){
     635
     636                /*This element should be collapsed into a tria element at its base. Create this tria element,
     637                 * and compute CostFunction*/
     638                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
     639                J=tria->CostFunction();
     640                delete tria;
     641                return J;
     642        }
     643        else{
     644
     645                tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
     646                J=tria->CostFunction();
     647                delete tria;
     648                return J;
     649        }
     650}
     651/*}}}*/
     652/*FUNCTION Penta::CreateKMatrix {{{1*/
     653void  Penta::CreateKMatrix(Mat Kgg){
     654
     655        int analysis_type;
     656
     657        /*retrive parameters: */
     658        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     659
     660        /*if debugging mode, check that all pointers exist*/
     661        ISSMASSERT(this->nodes && this->matice && this->matpar && this->neighbors && this->parameters && this->inputs);
     662
     663        /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
     664        if (analysis_type==ControlAnalysisEnum){
     665                CreateKMatrixDiagnosticHoriz( Kgg);
     666        }
     667        else if (analysis_type==DiagnosticHorizAnalysisEnum){
     668                CreateKMatrixDiagnosticHoriz( Kgg);
     669        }
     670        else if (analysis_type==DiagnosticHutterAnalysisEnum){
     671                CreateKMatrixDiagnosticHutter( Kgg);
     672        }
     673        else if (analysis_type==DiagnosticVertAnalysisEnum){
     674                CreateKMatrixDiagnosticVert( Kgg);
     675        }
     676        else if (analysis_type==DiagnosticStokesAnalysisEnum){
     677                CreateKMatrixDiagnosticStokes( Kgg);
     678        }
     679        else if (analysis_type==SlopeAnalysisEnum){
     680                CreateKMatrixSlopeCompute( Kgg);
     681        }
     682        else if (analysis_type==PrognosticAnalysisEnum){
     683                CreateKMatrixPrognostic( Kgg);
     684        }
     685        else if (analysis_type==BalancedthicknessAnalysisEnum){
     686                CreateKMatrixBalancedthickness( Kgg);
     687        }
     688        else if (analysis_type==BalancedvelocitiesAnalysisEnum){
     689                CreateKMatrixBalancedvelocities( Kgg);
     690        }
     691        else if (analysis_type==ThermalAnalysisEnum){
     692                CreateKMatrixThermal( Kgg);
     693        }
     694        else if (analysis_type==MeltingAnalysisEnum){
     695                CreateKMatrixMelting( Kgg);
     696        }
     697        else ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
     698
     699}
     700/*}}}*/
     701/*FUNCTION Penta::CreatePVector {{{1*/
     702void  Penta::CreatePVector(Vec pg){
     703
     704        int analysis_type,sub_analysis_type;
     705
     706        /*retrive parameters: */
     707        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     708        parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
     709
     710        /*if debugging mode, check that all pointers exist*/
     711        ISSMASSERT(this->nodes && this->matice && this->matpar && this->neighbors && this->parameters && this->inputs);
     712
     713        /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
     714        if (analysis_type==ControlAnalysisEnum){
     715                CreatePVectorDiagnosticHoriz( pg);
     716        }
     717        else if (analysis_type==DiagnosticHorizAnalysisEnum){
     718                CreatePVectorDiagnosticHoriz( pg);
     719        }
     720        else if (analysis_type==DiagnosticHutterAnalysisEnum){
     721                CreatePVectorDiagnosticHutter( pg);
     722        }
     723        else if (analysis_type==DiagnosticVertAnalysisEnum){
     724                CreatePVectorDiagnosticVert( pg);
     725        }
     726        else if (analysis_type==DiagnosticStokesAnalysisEnum){
     727                CreatePVectorDiagnosticStokes( pg);
     728        }
     729        else if (analysis_type==SlopeAnalysisEnum){
     730                CreatePVectorSlopeCompute( pg);
     731        }
     732        else if (analysis_type==PrognosticAnalysisEnum){
     733                CreatePVectorPrognostic( pg);
     734        }
     735        else if (analysis_type==BalancedthicknessAnalysisEnum){
     736                CreatePVectorBalancedthickness( pg);
     737        }
     738        else if (analysis_type==BalancedvelocitiesAnalysisEnum){
     739                CreatePVectorBalancedvelocities( pg);
     740        }
     741        else if (analysis_type==ThermalAnalysisEnum){
     742                CreatePVectorThermal( pg);
     743        }
     744        else if (analysis_type==MeltingAnalysisEnum){
     745                CreatePVectorMelting( pg);
     746        }
     747        else ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
     748
     749}
     750/*}}}*/
     751/*FUNCTION Penta::Du {{{1*/
     752void  Penta::Du(Vec du_g){
     753
     754        int i;
     755        Tria* tria=NULL;
     756
     757        /*inputs: */
     758        bool onwater;
     759        bool collapse;
     760        bool onsurface;
     761        bool onbed;
     762
     763        /*retrieve inputs :*/
     764        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     765        inputs->GetParameterValue(&collapse,CollapseEnum);
     766        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     767        inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
     768
     769        /*If on water, skip: */
     770        if(onwater)return;
     771
     772        /*Bail out if this element if:
     773         * -> Non collapsed and not on the surface
     774         * -> collapsed (2d model) and not on bed) */
     775        if ((!collapse && !onsurface) || (collapse && !onbed)){
     776                return;
     777        }
     778        else if (collapse){
     779
     780                /*This element should be collapsed into a tria element at its base. Create this tria element,
     781                 * and compute Du*/
     782                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
     783                tria->Du(du_g);
     784                delete tria;
     785                return;
     786        }
     787        else{
     788
     789                tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
     790                tria->Du(du_g);
     791                delete tria;
     792                return;
     793        }
     794}
     795/*}}}*/
     796/*FUNCTION Penta::GetBedList {{{1*/
     797void Penta::GetBedList(double* bedlist){
     798
     799        const int numgrids=6;
     800        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     801       
     802        inputs->GetParameterValues(bedlist,&gaussgrids[0][0],6,BedEnum);
     803
     804}
     805/*}}}*/
     806/*FUNCTION Penta::GetMatPar {{{1*/
     807void* Penta::GetMatPar(){
     808
     809        return matpar;
     810}
     811/*}}}*/
     812/*FUNCTION Penta::GetNodes {{{1*/
     813void  Penta::GetNodes(void** vpnodes){
     814
     815        int i;
     816        Node** pnodes=NULL;
     817       
     818        /*virtual object: */
     819        pnodes=(Node**)vpnodes;
     820
     821        for(i=0;i<6;i++){
     822                pnodes[i]=nodes[i];
     823        }
     824}
     825/*}}}*/
     826/*FUNCTION Penta::GetOnBed {{{1*/
     827bool Penta::GetOnBed(){
     828       
     829        bool onbed;
     830
     831        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     832
     833        return onbed;
     834}
     835/*}}}*/
     836/*FUNCTION Penta::GetShelf {{{1*/
     837bool   Penta::GetShelf(){
     838        bool onshelf;
     839
     840        /*retrieve inputs :*/
     841        inputs->GetParameterValue(&onshelf,ElementOnIceShelfEnum);
     842
     843        return onshelf;
     844}
     845/*}}}*/
     846/*FUNCTION Penta::GetSolutionFromInputs(Vec solution){{{1*/
     847void  Penta::GetSolutionFromInputs(Vec solution){
     848
     849        int analysis_type,sub_analysis_type;
     850
     851        /*retrive parameters: */
     852        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     853        parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
     854
     855
     856        /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
     857        if (analysis_type==DiagnosticAnalysisEnum){
     858                if (sub_analysis_type==HorizAnalysisEnum){
     859                        GetSolutionFromInputsDiagnosticHoriz(solution);
     860                }
     861                else if(sub_analysis_type==VertAnalysisEnum){
     862                        GetSolutionFromInputsDiagnosticVert(solution);
     863                }
     864                else if(sub_analysis_type==StokesAnalysisEnum){
     865                        GetSolutionFromInputsDiagnosticStokes(solution);
     866                }
     867                else ISSMERROR("sub_analysis: %i (%s) not supported yet",sub_analysis_type,EnumAsString(sub_analysis_type));
     868        }
     869        else{
     870                ISSMERROR("analysis: %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
     871        }
     872}
     873/*}}}*/
     874/*FUNCTION Penta::GetThicknessList {{{1*/
     875void Penta::GetThicknessList(double* thickness_list){
     876
     877        const int numgrids=6;
     878        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     879        inputs->GetParameterValues(thickness_list,&gaussgrids[0][0],6,ThicknessEnum);
     880
     881}
     882/*}}}*/
     883/*FUNCTION Penta::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/
     884void  Penta::GetVectorFromInputs(Vec vector,int NameEnum){
     885
     886        int i;
     887        const int numvertices=6;
     888        int doflist1[numvertices];
     889
     890        /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */
     891        for(i=0;i<this->inputs->Size();i++){
     892                Input* input=(Input*)this->inputs->GetObjectByOffset(i);
     893                if(input->EnumType()==NameEnum){
     894                        /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
     895                        this->GetDofList1(&doflist1[0]);
     896                        input->GetVectorFromInputs(vector,&doflist1[0]);
     897                        break;
     898                }
     899        }
     900}
     901/*}}}*/
     902/*FUNCTION Penta::Gradj {{{1*/
     903void  Penta::Gradj(Vec gradient,int control_type){
     904
     905        /*inputs: */
     906        bool onwater;
     907
     908        /*retrieve inputs :*/
     909        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     910
     911        /*If on water, skip grad (=0): */
     912        if(onwater)return;
     913
     914        if (control_type==DragCoefficientEnum){
     915                GradjDrag(gradient);
     916        }
     917        else if (control_type=RheologyBEnum){
     918                GradjB(gradient);
     919        }
     920        else ISSMERROR("%s%i","control type not supported yet: ",control_type);
     921}
     922/*}}}*/
     923/*FUNCTION Penta::GradjDrag {{{1*/
     924void  Penta::GradjDrag(Vec gradient){
     925
     926        int i;
     927        Tria* tria=NULL;
     928        TriaVertexInput* triavertexinput=NULL;
     929        double temp_gradient[6]={0,0,0,0,0,0};
     930
     931        /*inputs: */
     932        bool onwater;
     933        bool onbed;
     934        bool shelf;
     935        int analysis_type,sub_analysis_type;
     936
     937        /*retrieve parameters: */
     938        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     939        parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
     940
     941        /*retrieve inputs :*/
     942        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     943        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     944        inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
     945
     946        /*If on water, skip: */
     947        if(onwater)return;
     948
     949        /*If on shelf, skip: */
     950        if(shelf)return;
     951
     952        /*Bail out if this element does not touch the bedrock: */
     953        if (!onbed) return;
     954
     955        if (sub_analysis_type==HorizAnalysisEnum){
     956
     957                /*MacAyeal or Pattyn*/
     958                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
     959                tria->GradjDrag(gradient);
     960                delete tria;
     961        }
     962        else if (sub_analysis_type==StokesAnalysisEnum){
     963
     964                /*Stokes*/
     965                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
     966                tria->GradjDragStokes(gradient);
     967                delete tria;
     968        }
     969        else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
     970
     971
     972}
     973/*}}}*/
     974/*FUNCTION Penta::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/
     975void  Penta::InputAXPY(int YEnum, double scalar, int XEnum){
     976
     977        Input* xinput=NULL;
     978        Input* yinput=NULL;
     979
     980        /*Find x and y inputs: */
     981        xinput=(Input*)this->inputs->GetInput(XEnum);
     982        yinput=(Input*)this->inputs->GetInput(YEnum);
     983
     984        /*some checks: */
     985        if(!xinput || !yinput)ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!");
     986        if(xinput->Enum()!=yinput->Enum())ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," and input ",EnumAsString(YEnum)," are not of the same type!");
     987
     988        /*Scale: */
     989        yinput->AXPY(xinput,scalar);
     990}
     991/*}}}*/
     992/*FUNCTION Penta::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/
     993void  Penta::InputControlConstrain(int control_type, double cm_min, double cm_max){
     994
     995        Input* input=NULL;
     996
     997        /*Find input: */
     998        input=(Input*)this->inputs->GetInput(control_type);
     999       
     1000        /*Do nothing if we  don't find it: */
     1001        if(!input)return;
     1002
     1003        /*Constrain input using cm_min and cm_max: */
     1004        input->Constrain(cm_min,cm_max);
     1005
     1006}
     1007/*}}}*/
     1008/*FUNCTION Penta::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/
     1009void  Penta::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){
     1010
     1011        int     i;
     1012        Input** new_inputs=NULL;
     1013        Input** old_inputs=NULL;
     1014        int     converged=1;
     1015
     1016        new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs
     1017        old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs
     1018       
     1019        for(i=0;i<num_enums/2;i++){
     1020                new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]);
     1021                old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]);
     1022                if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
     1023                if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
     1024        }
     1025
     1026        /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/
     1027        for(i=0;i<num_criterionenums;i++){
     1028                IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]);
     1029                if(eps[i]>criterionvalues[i]) converged=0;
     1030        }
     1031
     1032        /*Assign output pointers:*/
     1033        *pconverged=converged;
     1034
     1035}
     1036/*}}}*/
     1037/*FUNCTION Penta::InputDepthAverageAtBase{{{1*/
     1038void  Penta::InputDepthAverageAtBase(int enum_type,int average_enum_type){
     1039        ISSMERROR("Not implemented yet (see Penta::InputExtrude and Node::FieldDepthAverageAtBase)");
     1040}
     1041/*}}}*/
     1042/*FUNCTION Penta::InputDuplicate(int original_enum,int new_enum){{{1*/
     1043void  Penta::InputDuplicate(int original_enum,int new_enum){
     1044
     1045        Input* original=NULL;
     1046        Input* copy=NULL;
     1047
     1048        /*Make a copy of the original input: */
     1049        original=(Input*)this->inputs->GetInput(original_enum);
     1050        copy=(Input*)original->copy();
     1051
     1052        /*Change copy enum to reinitialized_enum: */
     1053        copy->ChangeEnum(new_enum);
     1054
     1055        /*Add copy into inputs, it will wipe off the one already there: */
     1056        inputs->AddObject((Input*)copy);
     1057}
     1058/*}}}*/
     1059/*FUNCTION Penta::InputScale(int enum_type,double scale_factor){{{1*/
     1060void  Penta::InputScale(int enum_type,double scale_factor){
     1061
     1062        Input* input=NULL;
     1063
     1064        /*Make a copy of the original input: */
     1065        input=(Input*)this->inputs->GetInput(enum_type);
     1066
     1067        /*Scale: */
     1068        input->Scale(scale_factor);
     1069}
     1070/*}}}*/
     1071/*FUNCTION Penta::InputToResult(int enum_type,int step,double time){{{1*/
     1072void  Penta::InputToResult(int enum_type,int step,double time){
     1073
     1074        int    i;
     1075        bool   found = false;
     1076        Input *input = NULL;
     1077
     1078        /*Go through all the input objects, and find the one corresponding to enum_type, if it exists: */
     1079        for (i=0;i<this->inputs->Size();i++){
     1080                input=(Input*)this->inputs->GetObjectByOffset(i);
     1081                if (input->EnumType()==enum_type){
     1082                        found=true;
     1083                        break;
     1084                }
     1085        }
     1086
     1087        /*If we don't find it, no big deal, just don't do the transfer. Otherwise, build a new Result
     1088         * object out of the input, with the additional step and time information: */
     1089        this->results->AddObject((Object*)input->SpawnResult(step,time));
     1090
     1091}
     1092/*}}}*/
     1093/*FUNCTION Penta::MassFlux {{{1*/
     1094double Penta::MassFlux( double* segment){
     1095        ISSMERROR(" not supported yet!");
     1096}
     1097/*}}}*/
     1098/*FUNCTION Penta::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/
     1099void  Penta::MaxAbsVx(double* pmaxabsvx, bool process_units){
     1100
     1101        int i;
     1102        int dim;
     1103        const int numgrids=6;
     1104        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1105        double  vx_values[numgrids];
     1106        double  maxabsvx;
     1107
     1108        /*retrieve dim parameter: */
     1109        parameters->FindParam(&dim,DimEnum);
     1110
     1111        /*retrive velocity values at nodes */
     1112        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     1113
     1114        /*now, compute maximum:*/
     1115        maxabsvx=fabs(vx_values[0]);
     1116        for(i=1;i<numgrids;i++){
     1117                if (fabs(vx_values[i])>maxabsvx)maxabsvx=fabs(vx_values[i]);
     1118        }
     1119
     1120        /*Assign output pointers:*/
     1121        *pmaxabsvx=maxabsvx;
     1122}
     1123/*}}}*/
     1124/*FUNCTION Penta::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/
     1125void  Penta::MaxAbsVy(double* pmaxabsvy, bool process_units){
     1126
     1127        int i;
     1128        int dim;
     1129        const int numgrids=6;
     1130        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1131        double  vy_values[numgrids];
     1132        double  maxabsvy;
     1133
     1134        /*retrieve dim parameter: */
     1135        parameters->FindParam(&dim,DimEnum);
     1136
     1137        /*retrive velocity values at nodes */
     1138        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     1139
     1140        /*now, compute maximum:*/
     1141        maxabsvy=fabs(vy_values[0]);
     1142        for(i=1;i<numgrids;i++){
     1143                if (fabs(vy_values[i])>maxabsvy)maxabsvy=fabs(vy_values[i]);
     1144        }
     1145
     1146        /*Assign output pointers:*/
     1147        *pmaxabsvy=maxabsvy;
     1148}
     1149/*}}}*/
     1150/*FUNCTION Penta::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/
     1151void  Penta::MaxAbsVz(double* pmaxabsvz, bool process_units){
     1152
     1153        int i;
     1154        int dim;
     1155        const int numgrids=6;
     1156        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1157        double  vz_values[numgrids];
     1158        double  maxabsvz;
     1159
     1160        /*retrieve dim parameter: */
     1161        parameters->FindParam(&dim,DimEnum);
     1162
     1163        /*retrive velocity values at nodes */
     1164        inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     1165
     1166        /*now, compute maximum:*/
     1167        maxabsvz=fabs(vz_values[0]);
     1168        for(i=1;i<numgrids;i++){
     1169                if (fabs(vz_values[i])>maxabsvz)maxabsvz=fabs(vz_values[i]);
     1170        }
     1171
     1172        /*Assign output pointers:*/
     1173        *pmaxabsvz=maxabsvz;
     1174}
     1175/*}}}*/
     1176/*FUNCTION Penta::MaxVel(double* pmaxvel, bool process_units);{{{1*/
     1177void  Penta::MaxVel(double* pmaxvel, bool process_units){
     1178
     1179        int i;
     1180        int dim;
     1181        const int numgrids=6;
     1182        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1183        double  vx_values[numgrids];
     1184        double  vy_values[numgrids];
     1185        double  vz_values[numgrids];
     1186        double  vel_values[numgrids];
     1187        double  maxvel;
     1188
     1189        /*retrieve dim parameter: */
     1190        parameters->FindParam(&dim,DimEnum);
     1191
     1192        /*retrive velocity values at nodes */
     1193        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     1194        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     1195        if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     1196
     1197        /*now, compute maximum of velocity :*/
     1198        if(dim==2){
     1199                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
     1200        }
     1201        else{
     1202                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
     1203        }
     1204
     1205        /*now, compute maximum:*/
     1206        maxvel=vel_values[0];
     1207        for(i=1;i<numgrids;i++){
     1208                if (vel_values[i]>maxvel)maxvel=vel_values[i];
     1209        }
     1210
     1211        /*Assign output pointers:*/
     1212        *pmaxvel=maxvel;
     1213
     1214}
     1215/*}}}*/
     1216/*FUNCTION Penta::MaxVx(double* pmaxvx, bool process_units);{{{1*/
     1217void  Penta::MaxVx(double* pmaxvx, bool process_units){
     1218
     1219        int i;
     1220        int dim;
     1221        const int numgrids=6;
     1222        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1223        double  vx_values[numgrids];
     1224        double  maxvx;
     1225
     1226        /*retrieve dim parameter: */
     1227        parameters->FindParam(&dim,DimEnum);
     1228
     1229        /*retrive velocity values at nodes */
     1230        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     1231
     1232        /*now, compute maximum:*/
     1233        maxvx=vx_values[0];
     1234        for(i=1;i<numgrids;i++){
     1235                if (vx_values[i]>maxvx)maxvx=vx_values[i];
     1236        }
     1237
     1238        /*Assign output pointers:*/
     1239        *pmaxvx=maxvx;
     1240
     1241}
     1242/*}}}*/
     1243/*FUNCTION Penta::MaxVy(double* pmaxvy, bool process_units);{{{1*/
     1244void  Penta::MaxVy(double* pmaxvy, bool process_units){
     1245
     1246        int i;
     1247        int dim;
     1248        const int numgrids=6;
     1249        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1250        double  vy_values[numgrids];
     1251        double  maxvy;
     1252
     1253        /*retrieve dim parameter: */
     1254        parameters->FindParam(&dim,DimEnum);
     1255
     1256        /*retrive velocity values at nodes */
     1257        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     1258
     1259        /*now, compute maximum:*/
     1260        maxvy=vy_values[0];
     1261        for(i=1;i<numgrids;i++){
     1262                if (vy_values[i]>maxvy)maxvy=vy_values[i];
     1263        }
     1264
     1265        /*Assign output pointers:*/
     1266        *pmaxvy=maxvy;
     1267
     1268}
     1269/*}}}*/
     1270/*FUNCTION Penta::MaxVz(double* pmaxvz, bool process_units);{{{1*/
     1271void  Penta::MaxVz(double* pmaxvz, bool process_units){
     1272
     1273        int i;
     1274        int dim;
     1275        const int numgrids=6;
     1276        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1277        double  vz_values[numgrids];
     1278        double  maxvz;
     1279
     1280        /*retrieve dim parameter: */
     1281        parameters->FindParam(&dim,DimEnum);
     1282
     1283        /*retrive velocity values at nodes */
     1284        inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     1285
     1286        /*now, compute maximum:*/
     1287        maxvz=vz_values[0];
     1288        for(i=1;i<numgrids;i++){
     1289                if (vz_values[i]>maxvz)maxvz=vz_values[i];
     1290        }
     1291
     1292        /*Assign output pointers:*/
     1293        *pmaxvz=maxvz;
     1294
     1295}
     1296/*}}}*/
     1297/*FUNCTION Penta::MinVel(double* pminvel, bool process_units);{{{1*/
     1298void  Penta::MinVel(double* pminvel, bool process_units){
     1299
     1300        int i;
     1301        int dim;
     1302        const int numgrids=6;
     1303        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1304        double  vx_values[numgrids];
     1305        double  vy_values[numgrids];
     1306        double  vz_values[numgrids];
     1307        double  vel_values[numgrids];
     1308        double  minvel;
     1309
     1310        /*retrieve dim parameter: */
     1311        parameters->FindParam(&dim,DimEnum);
     1312
     1313        /*retrive velocity values at nodes */
     1314        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     1315        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     1316        if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     1317
     1318        /*now, compute minimum of velocity :*/
     1319        if(dim==2){
     1320                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
     1321        }
     1322        else{
     1323                for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
     1324        }
     1325
     1326        /*now, compute minimum:*/
     1327        minvel=vel_values[0];
     1328        for(i=1;i<numgrids;i++){
     1329                if (vel_values[i]<minvel)minvel=vel_values[i];
     1330        }
     1331
     1332        /*Assign output pointers:*/
     1333        *pminvel=minvel;
     1334
     1335}
     1336/*}}}*/
     1337/*FUNCTION Penta::MinVx(double* pminvx, bool process_units);{{{1*/
     1338void  Penta::MinVx(double* pminvx, bool process_units){
     1339
     1340        int i;
     1341        int dim;
     1342        const int numgrids=6;
     1343        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1344        double  vx_values[numgrids];
     1345        double  minvx;
     1346
     1347        /*retrieve dim parameter: */
     1348        parameters->FindParam(&dim,DimEnum);
     1349
     1350        /*retrive velocity values at nodes */
     1351        inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
     1352
     1353        /*now, compute minimum:*/
     1354        minvx=vx_values[0];
     1355        for(i=1;i<numgrids;i++){
     1356                if (vx_values[i]<minvx)minvx=vx_values[i];
     1357        }
     1358
     1359        /*Assign output pointers:*/
     1360        *pminvx=minvx;
     1361
     1362}
     1363/*}}}*/
     1364/*FUNCTION Penta::MinVy(double* pminvy, bool process_units);{{{1*/
     1365void  Penta::MinVy(double* pminvy, bool process_units){
     1366
     1367        int i;
     1368        int dim;
     1369        const int numgrids=6;
     1370        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1371        double  vy_values[numgrids];
     1372        double  minvy;
     1373
     1374        /*retrieve dim parameter: */
     1375        parameters->FindParam(&dim,DimEnum);
     1376
     1377        /*retrive velocity values at nodes */
     1378        inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
     1379
     1380        /*now, compute minimum:*/
     1381        minvy=vy_values[0];
     1382        for(i=1;i<numgrids;i++){
     1383                if (vy_values[i]<minvy)minvy=vy_values[i];
     1384        }
     1385
     1386        /*Assign output pointers:*/
     1387        *pminvy=minvy;
     1388
     1389}
     1390/*}}}*/
     1391/*FUNCTION Penta::MinVz(double* pminvz, bool process_units);{{{1*/
     1392void  Penta::MinVz(double* pminvz, bool process_units){
     1393
     1394        int i;
     1395        int dim;
     1396        const int numgrids=6;
     1397        double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
     1398        double  vz_values[numgrids];
     1399        double  minvz;
     1400
     1401        /*retrieve dim parameter: */
     1402        parameters->FindParam(&dim,DimEnum);
     1403
     1404        /*retrive velocity values at nodes */
     1405        inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
     1406
     1407        /*now, compute minimum:*/
     1408        minvz=vz_values[0];
     1409        for(i=1;i<numgrids;i++){
     1410                if (vz_values[i]<minvz)minvz=vz_values[i];
     1411        }
     1412
     1413        /*Assign output pointers:*/
     1414        *pminvz=minvz;
     1415
     1416}
     1417/*}}}*/
     1418/*FUNCTION Penta::Misfit {{{1*/
     1419double Penta::Misfit(void){
     1420
     1421        double J;
     1422        Tria* tria=NULL;
     1423
     1424        /*inputs: */
     1425        bool onwater;
     1426        bool collapse;
     1427        bool onsurface;
     1428        bool onbed;
     1429
     1430        /*retrieve inputs :*/
     1431        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     1432        inputs->GetParameterValue(&collapse,CollapseEnum);
     1433        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     1434        inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
     1435
     1436        /*If on water, return 0: */
     1437        if(onwater)return 0;
     1438
     1439        /*Bail out if this element if:
     1440         * -> Non collapsed and not on the surface
     1441         * -> collapsed (2d model) and not on bed) */
     1442        if ((!collapse && !onsurface) || (collapse && !onbed)){
     1443                return 0;
     1444        }
     1445        else if (collapse){
     1446
     1447                /*This element should be collapsed into a tria element at its base. Create this tria element,
     1448                 * and compute Misfit*/
     1449                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
     1450                J=tria->Misfit();
     1451                delete tria;
     1452                return J;
     1453        }
     1454        else{
     1455
     1456                tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
     1457                J=tria->Misfit();
     1458                delete tria;
     1459                return J;
     1460        }
     1461}
     1462/*}}}*/
     1463/*FUNCTION Penta::PatchFill(int* pcount, Patch* patch){{{1*/
     1464void  Penta::PatchFill(int* pcount, Patch* patch){
     1465
     1466        int i;
     1467        int count;
     1468        int vertices_ids[6];
     1469
     1470
     1471        /*recover pointer: */
     1472        count=*pcount;
     1473               
     1474        /*will be needed later: */
     1475        for(i=0;i<6;i++) vertices_ids[i]=nodes[i]->GetVertexId(); //vertices id start at column 3 of the patch.
     1476
     1477        for(i=0;i<this->results->Size();i++){
     1478                ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i);
     1479
     1480                /*For this result,fill the information in the Patch object (element id + vertices ids), and then hand
     1481                 *it to the result object, to fill the rest: */
     1482                patch->fillelementinfo(count,this->id,vertices_ids,6);
     1483                elementresult->PatchFill(count,patch);
     1484
     1485                /*increment counter: */
     1486                count++;
     1487        }
     1488
     1489        /*Assign output pointers:*/
     1490        *pcount=count;
     1491}
     1492/*FUNCTION Penta::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){{{1*/
     1493void  Penta::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){
     1494
     1495        int     i;
     1496       
     1497        /*output: */
     1498        int     numrows     = 0;
     1499        int     numvertices = 0;
     1500        int     numnodes    = 0;
     1501
     1502        /*Go through all the results objects, and update the counters: */
     1503        for (i=0;i<this->results->Size();i++){
     1504                ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i);
     1505                /*first, we have one more result: */
     1506                numrows++;
     1507                /*now, how many vertices and how many nodal values for this result? :*/
     1508                numvertices=6; //this is a penta element, with 6 vertices
     1509                numnodes=elementresult->NumberOfNodalValues(); //ask result object.
     1510        }
     1511
     1512        /*Assign output pointers:*/
     1513        *pnumrows=numrows;
     1514        *pnumvertices=numvertices;
     1515        *pnumnodes=numnodes;
     1516       
     1517}
     1518/*}}}*/
     1519/*FUNCTION Penta::ProcessResultsUnits(void){{{1*/
     1520void  Penta::ProcessResultsUnits(void){
     1521
     1522        int i;
     1523
     1524        for(i=0;i<this->results->Size();i++){
     1525                ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i);
     1526                elementresult->ProcessUnits(this->parameters);
     1527        }
     1528
     1529}
     1530/*}}}*/
     1531/*FUNCTION Penta::SurfaceArea {{{1*/
     1532double Penta::SurfaceArea(void){
     1533
     1534        double S;
     1535        Tria* tria=NULL;
     1536
     1537        /*inputs: */
     1538        bool onwater;
     1539        bool collapse;
     1540        bool onsurface;
     1541        bool onbed;
     1542
     1543        /*retrieve inputs :*/
     1544        inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
     1545        inputs->GetParameterValue(&collapse,CollapseEnum);
     1546        inputs->GetParameterValue(&onbed,ElementOnBedEnum);
     1547        inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
     1548
     1549        /*If on water, return 0: */
     1550        if(onwater)return 0;
     1551
     1552        /*Bail out if this element if:
     1553         * -> Non collapsed and not on the surface
     1554         * -> collapsed (2d model) and not on bed) */
     1555        if ((!collapse && !onsurface) || (collapse && !onbed)){
     1556                return 0;
     1557        }
     1558        else if (collapse){
     1559
     1560                /*This element should be collapsed into a tria element at its base. Create this tria element,
     1561                 * and compute SurfaceArea*/
     1562                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
     1563                S=tria->SurfaceArea();
     1564                delete tria;
     1565                return S;
     1566        }
     1567        else{
     1568
     1569                tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
     1570                S=tria->SurfaceArea();
     1571                delete tria;
     1572                return S;
     1573        }
     1574}
     1575/*}}}*/
     1576/*FUNCTION Penta::Update(IoModel* iomodel,int analysis_counter,int analysis_type) {{{1*/
     1577void Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type){
     1578
     1579        /*Intermediaries*/
     1580        IssmInt i;
     1581        int penta_node_ids[6];
     1582        int penta_vertex_ids[6];
     1583        double nodeinputs[6];
     1584
     1585        /*Checks if debuging*/
     1586        /*{{{2*/
     1587        ISSMASSERT(iomodel->elements);
     1588        /*}}}*/
     1589
     1590        /*Recover vertices ids needed to initialize inputs*/
     1591        for(i=0;i<6;i++){
     1592                penta_vertex_ids[i]=(int)iomodel->elements[6*index+i]; //ids for vertices are in the elements array from Matlab
     1593        }
     1594
     1595        /*Recover nodes ids needed to initialize the node hook.*/
     1596        for(i=0;i<6;i++){ //go recover node ids, needed to initialize the node hook.
     1597                penta_node_ids[i]=(int)iomodel->elements[6*index+i]; //ids for vertices are in the elements array from Matlab
     1598        }
     1599
     1600        /*hooks: */
     1601        this->SetHookNodes(penta_node_ids,analysis_counter); this->nodes=NULL; //set hook to nodes, for this analysis type
     1602
     1603        //add as many inputs per element as requested:
     1604        if (iomodel->thickness) {
     1605                for(i=0;i<6;i++)nodeinputs[i]=iomodel->thickness[penta_vertex_ids[i]-1];
     1606                this->inputs->AddInput(new PentaVertexInput(ThicknessEnum,nodeinputs));
     1607        }
     1608        if (iomodel->surface) {
     1609                for(i=0;i<6;i++)nodeinputs[i]=iomodel->surface[penta_vertex_ids[i]-1];
     1610                this->inputs->AddInput(new PentaVertexInput(SurfaceEnum,nodeinputs));
     1611        }
     1612        if (iomodel->bed) {
     1613                for(i=0;i<6;i++)nodeinputs[i]=iomodel->bed[penta_vertex_ids[i]-1];
     1614                this->inputs->AddInput(new PentaVertexInput(BedEnum,nodeinputs));
     1615        }
     1616        if (iomodel->drag_coefficient) {
     1617                for(i=0;i<6;i++)nodeinputs[i]=iomodel->drag_coefficient[penta_vertex_ids[i]-1];
     1618                this->inputs->AddInput(new PentaVertexInput(DragCoefficientEnum,nodeinputs));
     1619
     1620                if (iomodel->drag_p) this->inputs->AddInput(new DoubleInput(DragPEnum,iomodel->drag_p[index]));
     1621                if (iomodel->drag_q) this->inputs->AddInput(new DoubleInput(DragQEnum,iomodel->drag_q[index]));
     1622                this->inputs->AddInput(new IntInput(DragTypeEnum,iomodel->drag_type));
     1623
     1624        }
     1625        if (iomodel->melting_rate) {
     1626                for(i=0;i<6;i++)nodeinputs[i]=iomodel->melting_rate[penta_vertex_ids[i]-1]/iomodel->yts;
     1627                this->inputs->AddInput(new PentaVertexInput(MeltingRateEnum,nodeinputs));
     1628        }
     1629        if (iomodel->accumulation_rate) {
     1630                for(i=0;i<6;i++)nodeinputs[i]=iomodel->accumulation_rate[penta_vertex_ids[i]-1]/iomodel->yts;
     1631                this->inputs->AddInput(new PentaVertexInput(AccumulationRateEnum,nodeinputs));
     1632        }
     1633        if (iomodel->geothermalflux) {
     1634                for(i=0;i<6;i++)nodeinputs[i]=iomodel->geothermalflux[penta_vertex_ids[i]-1];
     1635                this->inputs->AddInput(new PentaVertexInput(GeothermalFluxEnum,nodeinputs));
     1636        }       
     1637        if (iomodel->pressure) {
     1638                for(i=0;i<6;i++)nodeinputs[i]=iomodel->pressure[penta_vertex_ids[i]-1];
     1639                this->inputs->AddInput(new PentaVertexInput(PressureEnum,nodeinputs));
     1640        }
     1641        if (iomodel->temperature) {
     1642                for(i=0;i<6;i++)nodeinputs[i]=iomodel->temperature[penta_vertex_ids[i]-1];
     1643                this->inputs->AddInput(new PentaVertexInput(TemperatureEnum,nodeinputs));
     1644        }
     1645        if (iomodel->dhdt) {
     1646                for(i=0;i<6;i++)nodeinputs[i]=iomodel->dhdt[penta_vertex_ids[i]-1];
     1647                this->inputs->AddInput(new PentaVertexInput(DhDtEnum,nodeinputs));
     1648        }
     1649        /*vx,vy and vz: */
     1650        if (iomodel->vx) {
     1651                for(i=0;i<6;i++)nodeinputs[i]=iomodel->vx[penta_vertex_ids[i]-1]/iomodel->yts;
     1652                this->inputs->AddInput(new PentaVertexInput(VxEnum,nodeinputs));
     1653                this->inputs->AddInput(new PentaVertexInput(VxOldEnum,nodeinputs));
     1654        }
     1655        if (iomodel->vy) {
     1656                for(i=0;i<6;i++)nodeinputs[i]=iomodel->vy[penta_vertex_ids[i]-1]/iomodel->yts;
     1657                this->inputs->AddInput(new PentaVertexInput(VyEnum,nodeinputs));
     1658                this->inputs->AddInput(new PentaVertexInput(VyOldEnum,nodeinputs));
     1659        }
     1660        if (iomodel->vz) {
     1661                for(i=0;i<6;i++)nodeinputs[i]=iomodel->vz[penta_vertex_ids[i]-1]/iomodel->yts;
     1662                this->inputs->AddInput(new PentaVertexInput(VzEnum,nodeinputs));
     1663                this->inputs->AddInput(new PentaVertexInput(VzOldEnum,nodeinputs));
     1664        }
     1665        if (iomodel->vx_obs) {
     1666                for(i=0;i<6;i++)nodeinputs[i]=iomodel->vx_obs[penta_vertex_ids[i]-1]/iomodel->yts;
     1667                this->inputs->AddInput(new PentaVertexInput(VxObsEnum,nodeinputs));
     1668        }
     1669        if (iomodel->vy_obs) {
     1670                for(i=0;i<6;i++)nodeinputs[i]=iomodel->vy_obs[penta_vertex_ids[i]-1]/iomodel->yts;
     1671                this->inputs->AddInput(new PentaVertexInput(VyObsEnum,nodeinputs));
     1672        }
     1673        if (iomodel->vz_obs) {
     1674                for(i=0;i<6;i++)nodeinputs[i]=iomodel->vz_obs[penta_vertex_ids[i]-1]/iomodel->yts;
     1675                this->inputs->AddInput(new PentaVertexInput(VzObsEnum,nodeinputs));
     1676        }
     1677        if (iomodel->weights) {
     1678                for(i=0;i<6;i++)nodeinputs[i]=iomodel->weights[penta_vertex_ids[i]-1];
     1679                this->inputs->AddInput(new PentaVertexInput(WeightsEnum,nodeinputs));
     1680        }
     1681
     1682        /*default vx,vy and vz: either observation or 0 */
     1683        if (!iomodel->vx){
     1684                if (iomodel->vx_obs) for(i=0;i<6;i++)nodeinputs[i]=iomodel->vx_obs[penta_vertex_ids[i]-1]/iomodel->yts;
     1685                else                 for(i=0;i<6;i++)nodeinputs[i]=0;
     1686                this->inputs->AddInput(new PentaVertexInput(VxEnum,nodeinputs));
     1687                this->inputs->AddInput(new PentaVertexInput(VxOldEnum,nodeinputs));
     1688        }
     1689        if (!iomodel->vy){
     1690                if (iomodel->vy_obs) for(i=0;i<6;i++)nodeinputs[i]=iomodel->vy_obs[penta_vertex_ids[i]-1]/iomodel->yts;
     1691                else                 for(i=0;i<6;i++)nodeinputs[i]=0;
     1692                this->inputs->AddInput(new PentaVertexInput(VyEnum,nodeinputs));
     1693                this->inputs->AddInput(new PentaVertexInput(VyOldEnum,nodeinputs));
     1694        }
     1695        if (!iomodel->vz){
     1696                if (iomodel->vz_obs) for(i=0;i<6;i++)nodeinputs[i]=iomodel->vz_obs[penta_vertex_ids[i]-1]/iomodel->yts;
     1697                else                 for(i=0;i<6;i++)nodeinputs[i]=0;
     1698                this->inputs->AddInput(new PentaVertexInput(VzEnum,nodeinputs));
     1699                this->inputs->AddInput(new PentaVertexInput(VzOldEnum,nodeinputs));
     1700        }
     1701        if (iomodel->elementoniceshelf) this->inputs->AddInput(new BoolInput(ElementOnIceShelfEnum,(IssmBool)iomodel->elementoniceshelf[index]));
     1702        if (iomodel->elementonbed) this->inputs->AddInput(new BoolInput(ElementOnBedEnum,(IssmBool)iomodel->elementonbed[index]));
     1703        if (iomodel->elementonwater) this->inputs->AddInput(new BoolInput(ElementOnWaterEnum,(IssmBool)iomodel->elementonwater[index]));
     1704        if (iomodel->elementonsurface) this->inputs->AddInput(new BoolInput(ElementOnSurfaceEnum,(IssmBool)iomodel->elementonsurface[index]));
     1705
     1706        //elements of type 3 are macayeal type penta. we collapse the formulation on their base.
     1707        if(iomodel->elements_type){
     1708                if (*(iomodel->elements_type+2*i+0)==MacAyealFormulationEnum){
     1709                        collapse[analysis_counter]=true;
     1710                }
     1711                else{
     1712                        collapse[analysis_counter]=false;
     1713                }
     1714        }
     1715}
     1716/*}}}*/
     1717/*FUNCTION Penta::UpdateGeometry{{{1*/
     1718void  Penta::UpdateGeometry(void){
     1719
     1720        /*Intermediaries*/
     1721        int i;
     1722        double rho_ice,rho_water;
     1723
     1724        /*If shelf: hydrostatic equilibrium*/
     1725        if (this->GetShelf()){
     1726
     1727                /*recover material parameters: */
     1728                rho_ice=matpar->GetRhoIce();
     1729                rho_water=matpar->GetRhoWater();
     1730
     1731                /*Create New Surface: s = (1-rho_ice/rho_water) h*/
     1732                InputDuplicate(ThicknessEnum,SurfaceEnum);     //1: copy thickness into surface
     1733                InputScale(SurfaceEnum,(1-rho_ice/rho_water)); //2: surface = surface * (1-di)
     1734
     1735                /*Create New Bed b = -rho_ice/rho_water h*/
     1736                InputDuplicate(ThicknessEnum,BedEnum);         //1: copy thickness into bed
     1737                InputScale(BedEnum, -rho_ice/rho_water);       //2: bed = bed * (-di)
     1738        }
     1739
     1740        /*If sheet: surface = bed + thickness*/
     1741        else{
     1742
     1743                /*The bed does not change, update surface only s = b + h*/
     1744                InputDuplicate(BedEnum,SurfaceEnum);          //1: copy bed into surface
     1745                InputAXPY(SurfaceEnum,1.0,ThicknessEnum);     //2: surface = surface + 1 * thickness
     1746        }
     1747
     1748}
     1749/*}}}*/
     1750
     1751/*Penta specific routines: */
    4731752/*FUNCTION Penta::SpawnTria {{{1*/
    4741753void*  Penta::SpawnTria(int g0, int g1, int g2){
     
    6021881}
    6031882/*}}}*/
    604 /*FUNCTION Penta::InputToResult(int enum_type,int step,double time){{{1*/
    605 void  Penta::InputToResult(int enum_type,int step,double time){
    606 
    607         int    i;
    608         bool   found = false;
    609         Input *input = NULL;
    610 
    611         /*Go through all the input objects, and find the one corresponding to enum_type, if it exists: */
    612         for (i=0;i<this->inputs->Size();i++){
    613                 input=(Input*)this->inputs->GetObjectByOffset(i);
    614                 if (input->EnumType()==enum_type){
    615                         found=true;
    616                         break;
    617                 }
    618         }
    619 
    620         /*If we don't find it, no big deal, just don't do the transfer. Otherwise, build a new Result
    621          * object out of the input, with the additional step and time information: */
    622         this->results->AddObject((Object*)input->SpawnResult(step,time));
    623 
    624 }
    625 /*}}}*/
    626 /*FUNCTION Penta::ProcessResultsUnits(void){{{1*/
    627 void  Penta::ProcessResultsUnits(void){
    628 
    629         int i;
    630 
    631         for(i=0;i<this->results->Size();i++){
    632                 ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i);
    633                 elementresult->ProcessUnits(this->parameters);
    634         }
    635 
    636 }
    637 /*}}}*/
    638 
    639 /*updates: */
    6401883/*FUNCTION Penta::UpdateFromDakota {{{1*/
    6411884void  Penta::UpdateFromDakota(void* vinputs){
     
    6451888}
    6461889/*}}}*/
    647 /*FUNCTION Penta::UpdateGeometry{{{1*/
    648 void  Penta::UpdateGeometry(void){
    649 
    650         /*Intermediaries*/
    651         int i;
    652         double rho_ice,rho_water;
    653 
    654         /*If shelf: hydrostatic equilibrium*/
    655         if (this->GetShelf()){
    656 
    657                 /*recover material parameters: */
    658                 rho_ice=matpar->GetRhoIce();
    659                 rho_water=matpar->GetRhoWater();
    660 
    661                 /*Create New Surface: s = (1-rho_ice/rho_water) h*/
    662                 InputDuplicate(ThicknessEnum,SurfaceEnum);     //1: copy thickness into surface
    663                 InputScale(SurfaceEnum,(1-rho_ice/rho_water)); //2: surface = surface * (1-di)
    664 
    665                 /*Create New Bed b = -rho_ice/rho_water h*/
    666                 InputDuplicate(ThicknessEnum,BedEnum);         //1: copy thickness into bed
    667                 InputScale(BedEnum, -rho_ice/rho_water);       //2: bed = bed * (-di)
    668         }
    669 
    670         /*If sheet: surface = bed + thickness*/
    671         else{
    672 
    673                 /*The bed does not change, update surface only s = b + h*/
    674                 InputDuplicate(BedEnum,SurfaceEnum);          //1: copy bed into surface
    675                 InputAXPY(SurfaceEnum,1.0,ThicknessEnum);     //2: surface = surface + 1 * thickness
    676         }
    677 
    678 }
    679 /*}}}*/
    680 /*FUNCTION Penta::InputUpdateFromSolution {{{1*/
    681 void  Penta::InputUpdateFromSolution(double* solution){
    682 
    683         int analysis_type;
    684 
    685         /*retreive parameters: */
    686         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    687 
    688         /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
    689         if (analysis_type==ControlAnalysisEnum){
    690                 InputUpdateFromSolutionDiagnosticHoriz( solution);
    691         }
    692         else if (analysis_type==DiagnosticHorizAnalysisEnum){
    693                 InputUpdateFromSolutionDiagnosticHoriz( solution);
    694         }
    695         else if (analysis_type==DiagnosticStokesAnalysisEnum){
    696                 InputUpdateFromSolutionDiagnosticStokes( solution);
    697         }
    698         else if (analysis_type==SlopeAnalysisEnum){
    699                 InputUpdateFromSolutionSlopeCompute( solution);
    700         }
    701         else if (analysis_type==PrognosticAnalysisEnum){
    702                 InputUpdateFromSolutionPrognostic( solution);
    703         }
    704         else if (analysis_type==Prognostic2AnalysisEnum){
    705                 InputUpdateFromSolutionPrognostic2(solution);
    706         }
    707         else if (analysis_type==BalancedthicknessAnalysisEnum){
    708                 InputUpdateFromSolutionBalancedthickness( solution);
    709         }
    710         else if (analysis_type==Balancedthickness2AnalysisEnum){
    711                 InputUpdateFromSolutionBalancedthickness2( solution);
    712         }
    713         else if (analysis_type==BalancedvelocitiesAnalysisEnum){
    714                 InputUpdateFromSolutionBalancedvelocities( solution);
    715         }
    716         else{
    717                 ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
    718         }
    719 }
    720 /*Object functions*/
    7211890/*FUNCTION Penta::InputUpdateFromSolutionDiagnosticHoriz {{{1*/
    7221891void  Penta::InputUpdateFromSolutionDiagnosticHoriz(double* solution){
     
    8672036}
    8682037/*}}}*/
    869 /*FUNCTION Penta::GetSolutionFromInputs(Vec solution){{{1*/
    870 void  Penta::GetSolutionFromInputs(Vec solution){
    871 
    872         int analysis_type,sub_analysis_type;
    873 
    874         /*retrive parameters: */
    875         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    876         parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
    877 
    878 
    879         /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
    880         if (analysis_type==DiagnosticAnalysisEnum){
    881                 if (sub_analysis_type==HorizAnalysisEnum){
    882                         GetSolutionFromInputsDiagnosticHoriz(solution);
    883                 }
    884                 else if(sub_analysis_type==VertAnalysisEnum){
    885                         GetSolutionFromInputsDiagnosticVert(solution);
    886                 }
    887                 else if(sub_analysis_type==StokesAnalysisEnum){
    888                         GetSolutionFromInputsDiagnosticStokes(solution);
    889                 }
    890                 else ISSMERROR("sub_analysis: %i (%s) not supported yet",sub_analysis_type,EnumAsString(sub_analysis_type));
    891         }
    892         else{
    893                 ISSMERROR("analysis: %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
    894         }
    895 }
    896 /*}}}*/
    8972038/*FUNCTION Penta::GetSolutionFromInputsDiagnosticHoriz(Vec solution){{{1*/
    8982039void  Penta::GetSolutionFromInputsDiagnosticHoriz(Vec solution){
     
    10022143}
    10032144/*}}}*/
    1004 
    1005 /*Object functions*/
    10062145/*FUNCTION Penta::IsInput{{{1*/
    10072146bool Penta::IsInput(int name){
     
    10422181        upper_penta=(Penta*)neighbors[1]; //first one under, second one above
    10432182        return upper_penta;
    1044 
    1045 }
    1046 /*}}}*/
    1047 /*FUNCTION Penta::ComputeBasalStress {{{1*/
    1048 void  Penta::ComputeBasalStress(Vec sigma_b){
    1049 
    1050         int i,j;
    1051         const int numgrids=6;
    1052         int    doflist[numgrids];
    1053         double xyz_list[numgrids][3];
    1054         double xyz_list_tria[3][3];
    1055 
    1056         /*Parameters*/
    1057         double rho_ice,gravity;
    1058         double surface_normal[3];
    1059         double bed_normal[3];
    1060         double bed;
    1061         double basalforce[3];
    1062         double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    1063         double devstresstensor[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    1064         double stresstensor[6]={0.0};
    1065         double viscosity;
    1066         int analysis_type,sub_analysis_type;
    1067 
    1068         int  dofv[3]={0,1,2};
    1069         int  dofp[1]={3};
    1070         double Jdet2d;
    1071         Tria* tria=NULL;
    1072 
    1073         /*Gauss*/
    1074         int     num_gauss,ig;
    1075         double* first_gauss_area_coord  =  NULL;
    1076         double* second_gauss_area_coord =  NULL;
    1077         double* third_gauss_area_coord  =  NULL;
    1078         double* gauss_weights           =  NULL;
    1079         double  gauss_weight;
    1080         double  gauss_coord[4];
    1081 
    1082         /*Output*/
    1083         double pressure;
    1084         double sigma_xx,sigma_yy,sigma_zz;
    1085         double sigma_xy,sigma_xz,sigma_yz;
    1086         double surface=0;
    1087         double value=0;
    1088        
    1089         /*flags: */
    1090         bool onbed;
    1091 
    1092         /*parameters: */
    1093         double stokesreconditioning;
    1094 
    1095 
    1096         /*retrive parameters: */
    1097         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    1098         parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
    1099 
    1100         /*Check analysis_types*/
    1101         if (analysis_type!=DiagnosticAnalysisEnum || sub_analysis_type!=StokesAnalysisEnum) ISSMERROR("Not supported yet!");
    1102 
    1103         /*recover some inputs: */
    1104         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    1105 
    1106         /*retrieve some parameters: */
    1107         this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum);
    1108        
    1109         if(!onbed){
    1110                 //put zero
    1111                 VecSetValue(sigma_b,id-1,0.0,INSERT_VALUES);
    1112                 return;
    1113         }
    1114 
    1115         /*recovre material parameters: */
    1116         rho_ice=matpar->GetRhoIce();
    1117         gravity=matpar->GetG();
    1118 
    1119         /* Get node coordinates and dof list: */
    1120         GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
    1121         for(i=0;i<3;i++){
    1122                 for(j=0;j<3;j++){
    1123                         xyz_list_tria[i][j]=xyz_list[i][j];
    1124                 }
    1125         }
    1126 
    1127         /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
    1128         GaussTria(&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights,2);
    1129 
    1130         /* Start  looping on the number of gaussian points: */
    1131         for (ig=0; ig<num_gauss; ig++){
    1132 
    1133                         /*Pick up the gaussian point: */
    1134                         gauss_weight=*(gauss_weights+ig);
    1135                         gauss_coord[0]=*(first_gauss_area_coord+ig);
    1136                         gauss_coord[1]=*(second_gauss_area_coord+ig);
    1137                         gauss_coord[2]=*(third_gauss_area_coord+ig);
    1138                         gauss_coord[3]=-1.0; //take the base
    1139 
    1140                         /*Compute strain rate viscosity and pressure: */
    1141                         inputs->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss_coord,VxEnum,VyEnum,VzEnum);
    1142                         matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
    1143                         inputs->GetParameterValue(&pressure, &gauss_coord[0],PressureEnum);
    1144 
    1145                         /*Compute Stress*/
    1146                         sigma_xx=viscosity*epsilon[0]-pressure*stokesreconditioning; // sigma = nu eps - pressure
    1147                         sigma_yy=viscosity*epsilon[1]-pressure*stokesreconditioning;
    1148                         sigma_zz=viscosity*epsilon[2]-pressure*stokesreconditioning;
    1149                         sigma_xy=viscosity*epsilon[3];
    1150                         sigma_xz=viscosity*epsilon[4];
    1151                         sigma_yz=viscosity*epsilon[5];
    1152 
    1153                         /*Get normal vector to the bed */
    1154                         SurfaceNormal(&surface_normal[0],xyz_list_tria);
    1155                         bed_normal[0] = - surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result
    1156                         bed_normal[1] = - surface_normal[1];
    1157                         bed_normal[2] = - surface_normal[2];
    1158 
    1159                         /*basalforce*/
    1160                         basalforce[0] += sigma_xx*bed_normal[0] + sigma_xy*bed_normal[1] + sigma_xz*bed_normal[2];
    1161                         basalforce[1] += sigma_xy*bed_normal[0] + sigma_yy*bed_normal[1] + sigma_yz*bed_normal[2];
    1162                         basalforce[2] += sigma_xz*bed_normal[0] + sigma_yz*bed_normal[1] + sigma_zz*bed_normal[2];
    1163 
    1164                         /*Get the Jacobian determinant */
    1165                         tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0],gauss_coord);
    1166                         value+=sigma_zz*Jdet2d*gauss_weight;
    1167                         surface+=Jdet2d*gauss_weight;
    1168         }
    1169         value=value/surface;
    1170 
    1171         /*Add value to output*/
    1172         VecSetValue(sigma_b,id-1,(const double)value,INSERT_VALUES);
    1173 }
    1174 /*}}}*/
    1175 /*FUNCTION Penta::ComputePressure {{{1*/
    1176 void  Penta::ComputePressure(Vec pg){
    1177 
    1178         int i;
    1179         const int numgrids=6;
    1180         int    doflist[numgrids];
    1181         double pressure[numgrids];
    1182         double rho_ice,g;
    1183         double surface[numgrids];
    1184         double xyz_list[numgrids][3];
    1185         double gauss[numgrids][numgrids]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    1186 
    1187         /*inputs: */
    1188         bool onwater;
    1189 
    1190         /*retrieve inputs :*/
    1191         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    1192 
    1193         /*If on water, skip: */
    1194         if(onwater)return;
    1195 
    1196         /*Get node data: */
    1197         GetVerticesCoordinates(&xyz_list[0][0], nodes, numgrids);
    1198 
    1199         /*pressure is lithostatic: */
    1200         //md.pressure=md.rho_ice*md.g*(md.surface-md.z); a la matlab
    1201 
    1202         /*Get dof list on which we will plug the pressure values: */
    1203         GetDofList1(&doflist[0]);
    1204 
    1205         /*recover value of surface at grids: */
    1206         inputs->GetParameterValues(&surface[0],&gauss[0][0],6,SurfaceEnum);
    1207 
    1208         /*pressure is lithostatic: */
    1209         rho_ice=matpar->GetRhoIce();
    1210         g=matpar->GetG();
    1211         for(i=0;i<numgrids;i++){
    1212                 pressure[i]=rho_ice*g*(surface[i]-xyz_list[i][2]);
    1213         }
    1214 
    1215         /*plug local pressure values into global pressure vector: */
    1216         VecSetValues(pg,numgrids,doflist,(const double*)pressure,INSERT_VALUES);
    1217 
    1218 }
    1219 /*}}}*/
    1220 /*FUNCTION Penta::ComputeStrainRate {{{1*/
    1221 void  Penta::ComputeStrainRate(Vec eps){
    1222 
    1223         ISSMERROR("Not implemented yet");
    1224 
    1225 }
    1226 /*}}}*/
    1227 /*FUNCTION Penta::CostFunction {{{1*/
    1228 double Penta::CostFunction(void){
    1229 
    1230         double J;
    1231         Tria* tria=NULL;
    1232 
    1233         /*flags: */
    1234         bool onbed;
    1235         bool onwater;
    1236         bool collapse;
    1237         bool onsurface;
    1238 
    1239         /*recover some inputs: */
    1240         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    1241         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    1242         inputs->GetParameterValue(&collapse,CollapseEnum);
    1243         inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
    1244 
    1245         /*If on water, return 0: */
    1246         if(onwater)return 0;
    1247 
    1248         /*Bail out if this element if:
    1249          * -> Non collapsed and not on the surface
    1250          * -> collapsed (2d model) and not on bed) */
    1251         if ((!collapse && !onsurface) || (collapse && !onbed)){
    1252                 return 0;
    1253         }
    1254         else if (collapse){
    1255 
    1256                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    1257                  * and compute CostFunction*/
    1258                 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
    1259                 J=tria->CostFunction();
    1260                 delete tria;
    1261                 return J;
    1262         }
    1263         else{
    1264 
    1265                 tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
    1266                 J=tria->CostFunction();
    1267                 delete tria;
    1268                 return J;
    1269         }
    1270 }
    1271 /*}}}*/
    1272 /*FUNCTION Penta::CreateKMatrix {{{1*/
    1273 void  Penta::CreateKMatrix(Mat Kgg){
    1274 
    1275         int analysis_type;
    1276 
    1277         /*retrive parameters: */
    1278         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    1279 
    1280         /*if debugging mode, check that all pointers exist*/
    1281         ISSMASSERT(this->nodes && this->matice && this->matpar && this->neighbors && this->parameters && this->inputs);
    1282 
    1283         /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
    1284         if (analysis_type==ControlAnalysisEnum){
    1285                 CreateKMatrixDiagnosticHoriz( Kgg);
    1286         }
    1287         else if (analysis_type==DiagnosticHorizAnalysisEnum){
    1288                 CreateKMatrixDiagnosticHoriz( Kgg);
    1289         }
    1290         else if (analysis_type==DiagnosticHutterAnalysisEnum){
    1291                 CreateKMatrixDiagnosticHutter( Kgg);
    1292         }
    1293         else if (analysis_type==DiagnosticVertAnalysisEnum){
    1294                 CreateKMatrixDiagnosticVert( Kgg);
    1295         }
    1296         else if (analysis_type==DiagnosticStokesAnalysisEnum){
    1297                 CreateKMatrixDiagnosticStokes( Kgg);
    1298         }
    1299         else if (analysis_type==SlopeAnalysisEnum){
    1300                 CreateKMatrixSlopeCompute( Kgg);
    1301         }
    1302         else if (analysis_type==PrognosticAnalysisEnum){
    1303                 CreateKMatrixPrognostic( Kgg);
    1304         }
    1305         else if (analysis_type==BalancedthicknessAnalysisEnum){
    1306                 CreateKMatrixBalancedthickness( Kgg);
    1307         }
    1308         else if (analysis_type==BalancedvelocitiesAnalysisEnum){
    1309                 CreateKMatrixBalancedvelocities( Kgg);
    1310         }
    1311         else if (analysis_type==ThermalAnalysisEnum){
    1312                 CreateKMatrixThermal( Kgg);
    1313         }
    1314         else if (analysis_type==MeltingAnalysisEnum){
    1315                 CreateKMatrixMelting( Kgg);
    1316         }
    1317         else ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
    13182183
    13192184}
     
    23533218}
    23543219/*}}}*/
    2355 /*FUNCTION Penta::CreatePVector {{{1*/
    2356 void  Penta::CreatePVector(Vec pg){
    2357 
    2358         int analysis_type,sub_analysis_type;
    2359 
    2360         /*retrive parameters: */
    2361         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2362         parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
    2363 
    2364         /*if debugging mode, check that all pointers exist*/
    2365         ISSMASSERT(this->nodes && this->matice && this->matpar && this->neighbors && this->parameters && this->inputs);
    2366 
    2367         /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
    2368         if (analysis_type==ControlAnalysisEnum){
    2369                 CreatePVectorDiagnosticHoriz( pg);
    2370         }
    2371         else if (analysis_type==DiagnosticHorizAnalysisEnum){
    2372                 CreatePVectorDiagnosticHoriz( pg);
    2373         }
    2374         else if (analysis_type==DiagnosticHutterAnalysisEnum){
    2375                 CreatePVectorDiagnosticHutter( pg);
    2376         }
    2377         else if (analysis_type==DiagnosticVertAnalysisEnum){
    2378                 CreatePVectorDiagnosticVert( pg);
    2379         }
    2380         else if (analysis_type==DiagnosticStokesAnalysisEnum){
    2381                 CreatePVectorDiagnosticStokes( pg);
    2382         }
    2383         else if (analysis_type==SlopeAnalysisEnum){
    2384                 CreatePVectorSlopeCompute( pg);
    2385         }
    2386         else if (analysis_type==PrognosticAnalysisEnum){
    2387                 CreatePVectorPrognostic( pg);
    2388         }
    2389         else if (analysis_type==BalancedthicknessAnalysisEnum){
    2390                 CreatePVectorBalancedthickness( pg);
    2391         }
    2392         else if (analysis_type==BalancedvelocitiesAnalysisEnum){
    2393                 CreatePVectorBalancedvelocities( pg);
    2394         }
    2395         else if (analysis_type==ThermalAnalysisEnum){
    2396                 CreatePVectorThermal( pg);
    2397         }
    2398         else if (analysis_type==MeltingAnalysisEnum){
    2399                 CreatePVectorMelting( pg);
    2400         }
    2401         else ISSMERROR("analysis %i (%s) not supported yet",analysis_type,EnumAsString(analysis_type));
    2402 
    2403 }
    2404 /*}}}*/
    24053220/*FUNCTION Penta::CreatePVectorBalancedthickness {{{1*/
    24063221void Penta::CreatePVectorBalancedthickness( Vec pg){
     
    32424057}
    32434058/*}}}*/
    3244 /*FUNCTION Penta::Du {{{1*/
    3245 void  Penta::Du(Vec du_g){
    3246 
    3247         int i;
    3248         Tria* tria=NULL;
    3249 
    3250         /*inputs: */
    3251         bool onwater;
    3252         bool collapse;
    3253         bool onsurface;
    3254         bool onbed;
    3255 
    3256         /*retrieve inputs :*/
    3257         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    3258         inputs->GetParameterValue(&collapse,CollapseEnum);
    3259         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    3260         inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
    3261 
    3262         /*If on water, skip: */
    3263         if(onwater)return;
    3264 
    3265         /*Bail out if this element if:
    3266          * -> Non collapsed and not on the surface
    3267          * -> collapsed (2d model) and not on bed) */
    3268         if ((!collapse && !onsurface) || (collapse && !onbed)){
    3269                 return;
    3270         }
    3271         else if (collapse){
    3272 
    3273                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    3274                  * and compute Du*/
    3275                 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
    3276                 tria->Du(du_g);
    3277                 delete tria;
    3278                 return;
    3279         }
    3280         else{
    3281 
    3282                 tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
    3283                 tria->Du(du_g);
    3284                 delete tria;
    3285                 return;
    3286         }
    3287 }
    3288 /*}}}*/
    32894059/*FUNCTION Penta::VecExtrude {{{1*/
    32904060void  Penta::VecExtrude(Vec vector,double* vector_serial,int iscollapsed){
     
    33894159
    33904160        return;
    3391 }
    3392 /*}}}*/
    3393 /*FUNCTION Penta::InputDepthAverageAtBase{{{1*/
    3394 void  Penta::InputDepthAverageAtBase(int enum_type,int average_enum_type){
    3395         ISSMERROR("Not implemented yet (see Penta::InputExtrude and Node::FieldDepthAverageAtBase)");
    33964161}
    33974162/*}}}*/
     
    35584323                B[i]=dh1dh6[2][i]; 
    35594324        }
    3560 
    3561 }
    3562 /*}}}*/
    3563 /*FUNCTION Penta::GetBedList {{{1*/
    3564 void Penta::GetBedList(double* bedlist){
    3565 
    3566         const int numgrids=6;
    3567         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    3568        
    3569         inputs->GetParameterValues(bedlist,&gaussgrids[0][0],6,BedEnum);
    35704325
    35714326}
     
    41274882}
    41284883/*}}}*/
    4129 /*FUNCTION Penta::GetMatPar {{{1*/
    4130 void* Penta::GetMatPar(){
    4131 
    4132         return matpar;
    4133 }
    4134 /*}}}*/
    41354884/*FUNCTION Penta::GetMatrixInvert {{{1*/
    41364885void Penta::GetMatrixInvert(double*  Ke_invert, double* Ke){
     
    43765125}
    43775126/*}}}*/
    4378 /*FUNCTION Penta::GetNodes {{{1*/
    4379 void  Penta::GetNodes(void** vpnodes){
    4380 
    4381         int i;
    4382         Node** pnodes=NULL;
    4383        
    4384         /*virtual object: */
    4385         pnodes=(Node**)vpnodes;
    4386 
    4387         for(i=0;i<6;i++){
    4388                 pnodes[i]=nodes[i];
    4389         }
    4390 }
    4391 /*}}}*/
    4392 /*FUNCTION Penta::GetOnBed {{{1*/
    4393 bool Penta::GetOnBed(){
    4394        
    4395         bool onbed;
    4396 
    4397         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    4398 
    4399         return onbed;
    4400 }
    4401 /*}}}*/
    44025127/*FUNCTION Penta::GetParameterDerivativeValue {{{1*/
    44035128void Penta::GetParameterDerivativeValue(double* p, double* p_list,double* xyz_list, double* gauss_coord){
     
    44715196}
    44725197/*}}}*/
    4473 /*FUNCTION Penta::GetShelf {{{1*/
    4474 bool   Penta::GetShelf(){
    4475         bool onshelf;
    4476 
    4477         /*retrieve inputs :*/
    4478         inputs->GetParameterValue(&onshelf,ElementOnIceShelfEnum);
    4479 
    4480         return onshelf;
    4481 }
    4482 /*}}}*/
    4483 /*FUNCTION Penta::GetThicknessList {{{1*/
    4484 void Penta::GetThicknessList(double* thickness_list){
    4485 
    4486         const int numgrids=6;
    4487         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    4488         inputs->GetParameterValues(thickness_list,&gaussgrids[0][0],6,ThicknessEnum);
    4489 
    4490 }
    4491 /*}}}*/
    4492 /*FUNCTION Penta::Gradj {{{1*/
    4493 void  Penta::Gradj(Vec gradient,int control_type){
    4494 
    4495         /*inputs: */
    4496         bool onwater;
    4497 
    4498         /*retrieve inputs :*/
    4499         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    4500 
    4501         /*If on water, skip grad (=0): */
    4502         if(onwater)return;
    4503 
    4504         if (control_type==DragCoefficientEnum){
    4505                 GradjDrag(gradient);
    4506         }
    4507         else if (control_type=RheologyBEnum){
    4508                 GradjB(gradient);
    4509         }
    4510         else ISSMERROR("%s%i","control type not supported yet: ",control_type);
    4511 }
    4512 /*}}}*/
    4513 /*FUNCTION Penta::GradjDrag {{{1*/
    4514 void  Penta::GradjDrag(Vec gradient){
    4515 
    4516         int i;
    4517         Tria* tria=NULL;
    4518         TriaVertexInput* triavertexinput=NULL;
    4519         double temp_gradient[6]={0,0,0,0,0,0};
    4520 
    4521         /*inputs: */
    4522         bool onwater;
    4523         bool onbed;
    4524         bool shelf;
    4525         int analysis_type,sub_analysis_type;
    4526 
    4527         /*retrieve parameters: */
    4528         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    4529         parameters->FindParam(&sub_analysis_type,AnalysisTypeEnum);
    4530 
    4531         /*retrieve inputs :*/
    4532         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    4533         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    4534         inputs->GetParameterValue(&shelf,ElementOnIceShelfEnum);
    4535 
    4536         /*If on water, skip: */
    4537         if(onwater)return;
    4538 
    4539         /*If on shelf, skip: */
    4540         if(shelf)return;
    4541 
    4542         /*Bail out if this element does not touch the bedrock: */
    4543         if (!onbed) return;
    4544 
    4545         if (sub_analysis_type==HorizAnalysisEnum){
    4546 
    4547                 /*MacAyeal or Pattyn*/
    4548                 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
    4549                 tria->GradjDrag(gradient);
    4550                 delete tria;
    4551         }
    4552         else if (sub_analysis_type==StokesAnalysisEnum){
    4553 
    4554                 /*Stokes*/
    4555                 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
    4556                 tria->GradjDragStokes(gradient);
    4557                 delete tria;
    4558         }
    4559         else ISSMERROR("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet");
    4560 
    4561 
    4562 }
    4563 /*}}}*/
    45645198/*FUNCTION Penta::GradjB {{{1*/
    45655199void  Penta::GradjB(Vec gradient){
     
    46005234       
    46015235
    4602 }
    4603 /*}}}*/
    4604 /*FUNCTION Penta::MassFlux {{{1*/
    4605 double Penta::MassFlux( double* segment){
    4606         ISSMERROR(" not supported yet!");
    4607 }
    4608 /*}}}*/
    4609 /*FUNCTION Penta::Misfit {{{1*/
    4610 double Penta::Misfit(void){
    4611 
    4612         double J;
    4613         Tria* tria=NULL;
    4614 
    4615         /*inputs: */
    4616         bool onwater;
    4617         bool collapse;
    4618         bool onsurface;
    4619         bool onbed;
    4620 
    4621         /*retrieve inputs :*/
    4622         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    4623         inputs->GetParameterValue(&collapse,CollapseEnum);
    4624         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    4625         inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
    4626 
    4627         /*If on water, return 0: */
    4628         if(onwater)return 0;
    4629 
    4630         /*Bail out if this element if:
    4631          * -> Non collapsed and not on the surface
    4632          * -> collapsed (2d model) and not on bed) */
    4633         if ((!collapse && !onsurface) || (collapse && !onbed)){
    4634                 return 0;
    4635         }
    4636         else if (collapse){
    4637 
    4638                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    4639                  * and compute Misfit*/
    4640                 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
    4641                 J=tria->Misfit();
    4642                 delete tria;
    4643                 return J;
    4644         }
    4645         else{
    4646 
    4647                 tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
    4648                 J=tria->Misfit();
    4649                 delete tria;
    4650                 return J;
    4651         }
    46525236}
    46535237/*}}}*/
     
    47465330}
    47475331/*}}}1*/
    4748 /*FUNCTION Penta::SurfaceArea {{{1*/
    4749 double Penta::SurfaceArea(void){
    4750 
    4751         double S;
    4752         Tria* tria=NULL;
    4753 
    4754         /*inputs: */
    4755         bool onwater;
    4756         bool collapse;
    4757         bool onsurface;
    4758         bool onbed;
    4759 
    4760         /*retrieve inputs :*/
    4761         inputs->GetParameterValue(&onwater,ElementOnWaterEnum);
    4762         inputs->GetParameterValue(&collapse,CollapseEnum);
    4763         inputs->GetParameterValue(&onbed,ElementOnBedEnum);
    4764         inputs->GetParameterValue(&onsurface,ElementOnSurfaceEnum);
    4765 
    4766         /*If on water, return 0: */
    4767         if(onwater)return 0;
    4768 
    4769         /*Bail out if this element if:
    4770          * -> Non collapsed and not on the surface
    4771          * -> collapsed (2d model) and not on bed) */
    4772         if ((!collapse && !onsurface) || (collapse && !onbed)){
    4773                 return 0;
    4774         }
    4775         else if (collapse){
    4776 
    4777                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    4778                  * and compute SurfaceArea*/
    4779                 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria (lower face).
    4780                 S=tria->SurfaceArea();
    4781                 delete tria;
    4782                 return S;
    4783         }
    4784         else{
    4785 
    4786                 tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face).
    4787                 S=tria->SurfaceArea();
    4788                 delete tria;
    4789                 return S;
    4790         }
    4791 }
    4792 /*}}}*/
    47935332/*FUNCTION Penta::SurfaceNormal {{{1*/
    47945333void Penta::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){
     
    48175356}
    48185357/*}}}*/
    4819 /*FUNCTION Penta::InputUpdateFromVector(double* vector, int name, int type);{{{1*/
    4820 void  Penta::InputUpdateFromVector(double* vector, int name, int type){
    4821 
    4822         /*Check that name is an element input*/
    4823         if (!IsInput(name)) return;
    4824 
    4825         switch(type){
    4826 
    4827                 case VertexEnum:
    4828 
    4829                         /*New PentaVertexInpu*/
    4830                         double values[6];
    4831 
    4832                         /*Get values on the 6 vertices*/
    4833                         for (int i=0;i<6;i++){
    4834                                 values[i]=vector[this->nodes[i]->GetVertexDof()];
    4835                         }
    4836 
    4837                         /*update input*/
    4838                         this->inputs->AddInput(new PentaVertexInput(name,values));
    4839                         return;
    4840 
    4841                 default:
    4842 
    4843                         ISSMERROR("type %i (%s) not implemented yet",type,EnumAsString(type));
    4844         }
    4845 }
    4846 /*}}}*/
    4847 /*FUNCTION Penta::InputUpdateFromVector(int* vector, int name, int type);{{{1*/
    4848 void  Penta::InputUpdateFromVector(int* vector, int name, int type){
    4849         ISSMERROR(" not supported yet!");
    4850 }
    4851 /*}}}*/
    4852 /*FUNCTION Penta::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/
    4853 void  Penta::InputUpdateFromVector(bool* vector, int name, int type){
    4854         ISSMERROR(" not supported yet!");
    4855 }
    4856 /*}}}*/
    4857 /*FUNCTION Penta::InputUpdateFromConstant(int value, int name);{{{1*/
    4858 void  Penta::InputUpdateFromConstant(int constant, int name){
    4859         /*Nothing updated for now*/
    4860 }
    4861 /*}}}*/
    4862 /*FUNCTION Penta::InputUpdateFromConstant(bool value, int name);{{{1*/
    4863 void  Penta::InputUpdateFromConstant(bool constant, int name){
    4864         /*Nothing updated for now*/
    4865 }
    4866 /*}}}*/
    4867 /*FUNCTION Penta::InputUpdateFromConstant(double value, int name);{{{1*/
    4868 void  Penta::InputUpdateFromConstant(double constant, int name){
    4869         /*Nothing updated for now*/
    4870 }
    4871 /*}}}*/
    4872 /*FUNCTION Penta::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){{{1*/
    4873 void  Penta::PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes){
    4874 
    4875         int     i;
    4876        
    4877         /*output: */
    4878         int     numrows     = 0;
    4879         int     numvertices = 0;
    4880         int     numnodes    = 0;
    4881 
    4882         /*Go through all the results objects, and update the counters: */
    4883         for (i=0;i<this->results->Size();i++){
    4884                 ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i);
    4885                 /*first, we have one more result: */
    4886                 numrows++;
    4887                 /*now, how many vertices and how many nodal values for this result? :*/
    4888                 numvertices=6; //this is a penta element, with 6 vertices
    4889                 numnodes=elementresult->NumberOfNodalValues(); //ask result object.
    4890         }
    4891 
    4892         /*Assign output pointers:*/
    4893         *pnumrows=numrows;
    4894         *pnumvertices=numvertices;
    4895         *pnumnodes=numnodes;
    4896        
    4897 }
    4898 /*}}}*/
    4899 /*FUNCTION Penta::PatchFill(int* pcount, Patch* patch){{{1*/
    4900 void  Penta::PatchFill(int* pcount, Patch* patch){
    4901 
    4902         int i;
    4903         int count;
    4904         int vertices_ids[6];
    4905 
    4906 
    4907         /*recover pointer: */
    4908         count=*pcount;
    4909                
    4910         /*will be needed later: */
    4911         for(i=0;i<6;i++) vertices_ids[i]=nodes[i]->GetVertexId(); //vertices id start at column 3 of the patch.
    4912 
    4913         for(i=0;i<this->results->Size();i++){
    4914                 ElementResult* elementresult=(ElementResult*)this->results->GetObjectByOffset(i);
    4915 
    4916                 /*For this result,fill the information in the Patch object (element id + vertices ids), and then hand
    4917                  *it to the result object, to fill the rest: */
    4918                 patch->fillelementinfo(count,this->id,vertices_ids,6);
    4919                 elementresult->PatchFill(count,patch);
    4920 
    4921                 /*increment counter: */
    4922                 count++;
    4923         }
    4924 
    4925         /*Assign output pointers:*/
    4926         *pcount=count;
    4927 }
    4928 /*FUNCTION Penta::MinVel(double* pminvel, bool process_units);{{{1*/
    4929 void  Penta::MinVel(double* pminvel, bool process_units){
    4930 
    4931         int i;
    4932         int dim;
    4933         const int numgrids=6;
    4934         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    4935         double  vx_values[numgrids];
    4936         double  vy_values[numgrids];
    4937         double  vz_values[numgrids];
    4938         double  vel_values[numgrids];
    4939         double  minvel;
    4940 
    4941         /*retrieve dim parameter: */
    4942         parameters->FindParam(&dim,DimEnum);
    4943 
    4944         /*retrive velocity values at nodes */
    4945         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    4946         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    4947         if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    4948 
    4949         /*now, compute minimum of velocity :*/
    4950         if(dim==2){
    4951                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
    4952         }
    4953         else{
    4954                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
    4955         }
    4956 
    4957         /*now, compute minimum:*/
    4958         minvel=vel_values[0];
    4959         for(i=1;i<numgrids;i++){
    4960                 if (vel_values[i]<minvel)minvel=vel_values[i];
    4961         }
    4962 
    4963         /*Assign output pointers:*/
    4964         *pminvel=minvel;
    4965 
    4966 }
    4967 /*}}}*/
    4968 /*FUNCTION Penta::MaxVel(double* pmaxvel, bool process_units);{{{1*/
    4969 void  Penta::MaxVel(double* pmaxvel, bool process_units){
    4970 
    4971         int i;
    4972         int dim;
    4973         const int numgrids=6;
    4974         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    4975         double  vx_values[numgrids];
    4976         double  vy_values[numgrids];
    4977         double  vz_values[numgrids];
    4978         double  vel_values[numgrids];
    4979         double  maxvel;
    4980 
    4981         /*retrieve dim parameter: */
    4982         parameters->FindParam(&dim,DimEnum);
    4983 
    4984         /*retrive velocity values at nodes */
    4985         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    4986         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    4987         if(dim==3) inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    4988 
    4989         /*now, compute maximum of velocity :*/
    4990         if(dim==2){
    4991                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2));
    4992         }
    4993         else{
    4994                 for(i=0;i<numgrids;i++)vel_values[i]=sqrt(pow(vx_values[i],2)+pow(vy_values[i],2)+pow(vz_values[i],2));
    4995         }
    4996 
    4997         /*now, compute maximum:*/
    4998         maxvel=vel_values[0];
    4999         for(i=1;i<numgrids;i++){
    5000                 if (vel_values[i]>maxvel)maxvel=vel_values[i];
    5001         }
    5002 
    5003         /*Assign output pointers:*/
    5004         *pmaxvel=maxvel;
    5005 
    5006 }
    5007 /*}}}*/
    5008 /*FUNCTION Penta::MinVx(double* pminvx, bool process_units);{{{1*/
    5009 void  Penta::MinVx(double* pminvx, bool process_units){
    5010 
    5011         int i;
    5012         int dim;
    5013         const int numgrids=6;
    5014         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5015         double  vx_values[numgrids];
    5016         double  minvx;
    5017 
    5018         /*retrieve dim parameter: */
    5019         parameters->FindParam(&dim,DimEnum);
    5020 
    5021         /*retrive velocity values at nodes */
    5022         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    5023 
    5024         /*now, compute minimum:*/
    5025         minvx=vx_values[0];
    5026         for(i=1;i<numgrids;i++){
    5027                 if (vx_values[i]<minvx)minvx=vx_values[i];
    5028         }
    5029 
    5030         /*Assign output pointers:*/
    5031         *pminvx=minvx;
    5032 
    5033 }
    5034 /*}}}*/
    5035 /*FUNCTION Penta::MaxVx(double* pmaxvx, bool process_units);{{{1*/
    5036 void  Penta::MaxVx(double* pmaxvx, bool process_units){
    5037 
    5038         int i;
    5039         int dim;
    5040         const int numgrids=6;
    5041         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5042         double  vx_values[numgrids];
    5043         double  maxvx;
    5044 
    5045         /*retrieve dim parameter: */
    5046         parameters->FindParam(&dim,DimEnum);
    5047 
    5048         /*retrive velocity values at nodes */
    5049         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    5050 
    5051         /*now, compute maximum:*/
    5052         maxvx=vx_values[0];
    5053         for(i=1;i<numgrids;i++){
    5054                 if (vx_values[i]>maxvx)maxvx=vx_values[i];
    5055         }
    5056 
    5057         /*Assign output pointers:*/
    5058         *pmaxvx=maxvx;
    5059 
    5060 }
    5061 /*}}}*/
    5062 /*FUNCTION Penta::MaxAbsVx(double* pmaxabsvx, bool process_units);{{{1*/
    5063 void  Penta::MaxAbsVx(double* pmaxabsvx, bool process_units){
    5064 
    5065         int i;
    5066         int dim;
    5067         const int numgrids=6;
    5068         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5069         double  vx_values[numgrids];
    5070         double  maxabsvx;
    5071 
    5072         /*retrieve dim parameter: */
    5073         parameters->FindParam(&dim,DimEnum);
    5074 
    5075         /*retrive velocity values at nodes */
    5076         inputs->GetParameterValues(&vx_values[0],&gaussgrids[0][0],numgrids,VxEnum);
    5077 
    5078         /*now, compute maximum:*/
    5079         maxabsvx=fabs(vx_values[0]);
    5080         for(i=1;i<numgrids;i++){
    5081                 if (fabs(vx_values[i])>maxabsvx)maxabsvx=fabs(vx_values[i]);
    5082         }
    5083 
    5084         /*Assign output pointers:*/
    5085         *pmaxabsvx=maxabsvx;
    5086 }
    5087 /*}}}*/
    5088 /*FUNCTION Penta::MinVy(double* pminvy, bool process_units);{{{1*/
    5089 void  Penta::MinVy(double* pminvy, bool process_units){
    5090 
    5091         int i;
    5092         int dim;
    5093         const int numgrids=6;
    5094         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5095         double  vy_values[numgrids];
    5096         double  minvy;
    5097 
    5098         /*retrieve dim parameter: */
    5099         parameters->FindParam(&dim,DimEnum);
    5100 
    5101         /*retrive velocity values at nodes */
    5102         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    5103 
    5104         /*now, compute minimum:*/
    5105         minvy=vy_values[0];
    5106         for(i=1;i<numgrids;i++){
    5107                 if (vy_values[i]<minvy)minvy=vy_values[i];
    5108         }
    5109 
    5110         /*Assign output pointers:*/
    5111         *pminvy=minvy;
    5112 
    5113 }
    5114 /*}}}*/
    5115 /*FUNCTION Penta::MaxVy(double* pmaxvy, bool process_units);{{{1*/
    5116 void  Penta::MaxVy(double* pmaxvy, bool process_units){
    5117 
    5118         int i;
    5119         int dim;
    5120         const int numgrids=6;
    5121         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5122         double  vy_values[numgrids];
    5123         double  maxvy;
    5124 
    5125         /*retrieve dim parameter: */
    5126         parameters->FindParam(&dim,DimEnum);
    5127 
    5128         /*retrive velocity values at nodes */
    5129         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    5130 
    5131         /*now, compute maximum:*/
    5132         maxvy=vy_values[0];
    5133         for(i=1;i<numgrids;i++){
    5134                 if (vy_values[i]>maxvy)maxvy=vy_values[i];
    5135         }
    5136 
    5137         /*Assign output pointers:*/
    5138         *pmaxvy=maxvy;
    5139 
    5140 }
    5141 /*}}}*/
    5142 /*FUNCTION Penta::MaxAbsVy(double* pmaxabsvy, bool process_units);{{{1*/
    5143 void  Penta::MaxAbsVy(double* pmaxabsvy, bool process_units){
    5144 
    5145         int i;
    5146         int dim;
    5147         const int numgrids=6;
    5148         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5149         double  vy_values[numgrids];
    5150         double  maxabsvy;
    5151 
    5152         /*retrieve dim parameter: */
    5153         parameters->FindParam(&dim,DimEnum);
    5154 
    5155         /*retrive velocity values at nodes */
    5156         inputs->GetParameterValues(&vy_values[0],&gaussgrids[0][0],numgrids,VyEnum);
    5157 
    5158         /*now, compute maximum:*/
    5159         maxabsvy=fabs(vy_values[0]);
    5160         for(i=1;i<numgrids;i++){
    5161                 if (fabs(vy_values[i])>maxabsvy)maxabsvy=fabs(vy_values[i]);
    5162         }
    5163 
    5164         /*Assign output pointers:*/
    5165         *pmaxabsvy=maxabsvy;
    5166 }
    5167 /*}}}*/
    5168 /*FUNCTION Penta::MinVz(double* pminvz, bool process_units);{{{1*/
    5169 void  Penta::MinVz(double* pminvz, bool process_units){
    5170 
    5171         int i;
    5172         int dim;
    5173         const int numgrids=6;
    5174         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5175         double  vz_values[numgrids];
    5176         double  minvz;
    5177 
    5178         /*retrieve dim parameter: */
    5179         parameters->FindParam(&dim,DimEnum);
    5180 
    5181         /*retrive velocity values at nodes */
    5182         inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    5183 
    5184         /*now, compute minimum:*/
    5185         minvz=vz_values[0];
    5186         for(i=1;i<numgrids;i++){
    5187                 if (vz_values[i]<minvz)minvz=vz_values[i];
    5188         }
    5189 
    5190         /*Assign output pointers:*/
    5191         *pminvz=minvz;
    5192 
    5193 }
    5194 /*}}}*/
    5195 /*FUNCTION Penta::MaxVz(double* pmaxvz, bool process_units);{{{1*/
    5196 void  Penta::MaxVz(double* pmaxvz, bool process_units){
    5197 
    5198         int i;
    5199         int dim;
    5200         const int numgrids=6;
    5201         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5202         double  vz_values[numgrids];
    5203         double  maxvz;
    5204 
    5205         /*retrieve dim parameter: */
    5206         parameters->FindParam(&dim,DimEnum);
    5207 
    5208         /*retrive velocity values at nodes */
    5209         inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    5210 
    5211         /*now, compute maximum:*/
    5212         maxvz=vz_values[0];
    5213         for(i=1;i<numgrids;i++){
    5214                 if (vz_values[i]>maxvz)maxvz=vz_values[i];
    5215         }
    5216 
    5217         /*Assign output pointers:*/
    5218         *pmaxvz=maxvz;
    5219 
    5220 }
    5221 /*}}}*/
    5222 /*FUNCTION Penta::MaxAbsVz(double* pmaxabsvz, bool process_units);{{{1*/
    5223 void  Penta::MaxAbsVz(double* pmaxabsvz, bool process_units){
    5224 
    5225         int i;
    5226         int dim;
    5227         const int numgrids=6;
    5228         double  gaussgrids[numgrids][4]={{1,0,0,-1},{0,1,0,-1},{0,0,1,-1},{1,0,0,1},{0,1,0,1},{0,0,1,1}};
    5229         double  vz_values[numgrids];
    5230         double  maxabsvz;
    5231 
    5232         /*retrieve dim parameter: */
    5233         parameters->FindParam(&dim,DimEnum);
    5234 
    5235         /*retrive velocity values at nodes */
    5236         inputs->GetParameterValues(&vz_values[0],&gaussgrids[0][0],numgrids,VzEnum);
    5237 
    5238         /*now, compute maximum:*/
    5239         maxabsvz=fabs(vz_values[0]);
    5240         for(i=1;i<numgrids;i++){
    5241                 if (fabs(vz_values[i])>maxabsvz)maxabsvz=fabs(vz_values[i]);
    5242         }
    5243 
    5244         /*Assign output pointers:*/
    5245         *pmaxabsvz=maxabsvz;
    5246 }
    5247 /*}}}*/
    5248 /*FUNCTION Penta::InputDuplicate(int original_enum,int new_enum){{{1*/
    5249 void  Penta::InputDuplicate(int original_enum,int new_enum){
    5250 
    5251         Input* original=NULL;
    5252         Input* copy=NULL;
    5253 
    5254         /*Make a copy of the original input: */
    5255         original=(Input*)this->inputs->GetInput(original_enum);
    5256         copy=(Input*)original->copy();
    5257 
    5258         /*Change copy enum to reinitialized_enum: */
    5259         copy->ChangeEnum(new_enum);
    5260 
    5261         /*Add copy into inputs, it will wipe off the one already there: */
    5262         inputs->AddObject((Input*)copy);
    5263 }
    5264 /*}}}*/
    5265 /*FUNCTION Penta::InputScale(int enum_type,double scale_factor){{{1*/
    5266 void  Penta::InputScale(int enum_type,double scale_factor){
    5267 
    5268         Input* input=NULL;
    5269 
    5270         /*Make a copy of the original input: */
    5271         input=(Input*)this->inputs->GetInput(enum_type);
    5272 
    5273         /*Scale: */
    5274         input->Scale(scale_factor);
    5275 }
    5276 /*}}}*/
    5277 /*FUNCTION Penta::InputAXPY(int YEnum, double scalar, int XEnum);{{{1*/
    5278 void  Penta::InputAXPY(int YEnum, double scalar, int XEnum){
    5279 
    5280         Input* xinput=NULL;
    5281         Input* yinput=NULL;
    5282 
    5283         /*Find x and y inputs: */
    5284         xinput=(Input*)this->inputs->GetInput(XEnum);
    5285         yinput=(Input*)this->inputs->GetInput(YEnum);
    5286 
    5287         /*some checks: */
    5288         if(!xinput || !yinput)ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," or input ",EnumAsString(YEnum)," could not be found!");
    5289         if(xinput->Enum()!=yinput->Enum())ISSMERROR("%s%s%s%s%s"," input ",EnumAsString(XEnum)," and input ",EnumAsString(YEnum)," are not of the same type!");
    5290 
    5291         /*Scale: */
    5292         yinput->AXPY(xinput,scalar);
    5293 }
    5294 /*}}}*/
    5295 /*FUNCTION Penta::InputControlConstrain(int control_type, double cm_min, double cm_max){{{1*/
    5296 void  Penta::InputControlConstrain(int control_type, double cm_min, double cm_max){
    5297 
    5298         Input* input=NULL;
    5299 
    5300         /*Find input: */
    5301         input=(Input*)this->inputs->GetInput(control_type);
    5302        
    5303         /*Do nothing if we  don't find it: */
    5304         if(!input)return;
    5305 
    5306         /*Constrain input using cm_min and cm_max: */
    5307         input->Constrain(cm_min,cm_max);
    5308 
    5309 }
    5310 /*}}}*/
    5311 /*FUNCTION Penta::GetVectorFromInputs(Vec vector,int NameEnum){{{1*/
    5312 void  Penta::GetVectorFromInputs(Vec vector,int NameEnum){
    5313 
    5314         int i;
    5315         const int numvertices=6;
    5316         int doflist1[numvertices];
    5317 
    5318         /*Find NameEnum input in the inputs dataset, and get it to fill in the vector: */
    5319         for(i=0;i<this->inputs->Size();i++){
    5320                 Input* input=(Input*)this->inputs->GetObjectByOffset(i);
    5321                 if(input->EnumType()==NameEnum){
    5322                         /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
    5323                         this->GetDofList1(&doflist1[0]);
    5324                         input->GetVectorFromInputs(vector,&doflist1[0]);
    5325                         break;
    5326                 }
    5327         }
    5328 }
    5329 /*}}}*/
    5330 /*FUNCTION Penta::InputConvergence(int* pconverged, double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){{{1*/
    5331 void  Penta::InputConvergence(int* pconverged,double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){
    5332 
    5333         int     i;
    5334         Input** new_inputs=NULL;
    5335         Input** old_inputs=NULL;
    5336         int     converged=1;
    5337 
    5338         new_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the new inputs
    5339         old_inputs=(Input**)xmalloc(num_enums/2*sizeof(Input*)); //half the enums are for the old inputs
    5340        
    5341         for(i=0;i<num_enums/2;i++){
    5342                 new_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+0]);
    5343                 old_inputs[i]=(Input*)this->inputs->GetInput(enums[2*i+1]);
    5344                 if(!new_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
    5345                 if(!old_inputs[i])ISSMERROR("%s%s"," could not find input with enum ",EnumAsString(enums[2*i+0]));
    5346         }
    5347 
    5348         /*ok, we've got the inputs (new and old), now loop throught the number of criterions and fill the eps array:*/
    5349         for(i=0;i<num_criterionenums;i++){
    5350                 IsInputConverged(eps+i,new_inputs,old_inputs,num_enums/2,criterionenums[i]);
    5351                 if(eps[i]>criterionvalues[i]) converged=0;
    5352         }
    5353 
    5354         /*Assign output pointers:*/
    5355         *pconverged=converged;
    5356 
    5357 }
    5358 /*}}}*/
  • TabularUnified issm/trunk/src/c/objects/Elements/Penta.h

    r4249 r4250  
    6262                void  InputUpdateFromConstant(int constant, int name);
    6363                void  InputUpdateFromSolution(double* solutiong);
    64                 void  InputUpdateFromSolutionBalancedthickness( double* solutiong);
    65                 void  InputUpdateFromSolutionBalancedthickness2( double* solutiong);
    66                 void  InputUpdateFromSolutionBalancedvelocities( double* solutiong);
    67                 void  InputUpdateFromSolutionDiagnosticHoriz( double* solutiong);
    68                 void  InputUpdateFromSolutionDiagnosticStokes( double* solutiong);
    69                 void  InputUpdateFromSolutionPrognostic( double* solutiong);
    70                 void  InputUpdateFromSolutionPrognostic2(double* solutiong);
    71                 void  InputUpdateFromSolutionSlopeCompute( double* solutiong);
    7264                void  InputUpdateFromVector(bool* vector, int name, int type);
    7365                void  InputUpdateFromVector(double* vector, int name, int type);
    7466                void  InputUpdateFromVector(int* vector, int name, int type);
    75                 void  UpdateFromDakota(void* inputs);
    7667                /*}}}*/
    7768                /*Element virtual functions definitions: {{{1*/
     
    178169                Penta*    GetUpperElement(void);
    179170                void      InputExtrude(int enum_type);
     171                void      InputUpdateFromSolutionBalancedthickness( double* solutiong);
     172                void      InputUpdateFromSolutionBalancedthickness2( double* solutiong);
     173                void      InputUpdateFromSolutionBalancedvelocities( double* solutiong);
     174                void      InputUpdateFromSolutionDiagnosticHoriz( double* solutiong);
     175                void      InputUpdateFromSolutionDiagnosticStokes( double* solutiong);
     176                void      InputUpdateFromSolutionPrognostic( double* solutiong);
     177                void      InputUpdateFromSolutionPrognostic2(double* solutiong);
     178                void      InputUpdateFromSolutionSlopeCompute( double* solutiong);
    180179                bool      IsInput(int name);
    181180                bool      IsOnSurface(void);
     
    187186                void*     SpawnTria(int g0, int g1, int g2);
    188187                void      SurfaceNormal(double* surface_normal, double xyz_list[3][3]);
     188                void      UpdateFromDakota(void* inputs);
    189189                void      VecExtrude(Vec vector,double* vector_serial,int iscollapsed);
    190190                /*}}}*/
Note: See TracChangeset for help on using the changeset viewer.