Changeset 483


Ignore:
Timestamp:
05/18/09 16:55:54 (16 years ago)
Author:
Eric.Larour
Message:

Finished thermal and melting elemnets, as well as thermal constraints

Location:
issm/trunk/src/c
Files:
10 added
18 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/DataSet/DataSet.cpp

    r465 r483  
    10221022int   DataSet::RiftIsPresent(){
    10231023
    1024         return 0; //for now
    1025 
     1024        int i;
     1025       
     1026        vector<Object*>::iterator object;
     1027        Penpair* penpair=NULL;
     1028        int found=0;
     1029        int mpi_found=0;
     1030
     1031        /*go though loads, and figure out if one of the loads is a PenPair with numdof=2: */
     1032        for ( object=objects.begin() ; object < objects.end(); object++ ){
     1033
     1034                if((*object)->Enum()==PenpairEnum()){
     1035
     1036                        penpair=(Penpair*)(*object);
     1037                        if (penpair->GetNumDofs()==2){
     1038                                found=1;
     1039                                break;
     1040                        }
     1041                }
     1042        }
     1043
     1044        #ifdef _PARALLEL_
     1045        MPI_Reduce (&found,&mpi_found,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
     1046        MPI_Bcast(&mpi_found,1,MPI_INT,0,MPI_COMM_WORLD);               
     1047        found=mpi_found;
     1048        #endif
     1049
     1050        return found;
    10261051}
    10271052
     
    10381063int   DataSet::MeltingIsPresent(){
    10391064
    1040 
    1041         return 0; //for now
    1042        
     1065        int found=0;
     1066        int mpi_found=0;
     1067
     1068        vector<Object*>::iterator object;
     1069
     1070        for ( object=objects.begin() ; object < objects.end(); object++ ){
     1071
     1072                if((*object)->Enum()==PengridEnum()){
     1073                        found=1;
     1074                        break;
     1075                }
     1076        }       
     1077       
     1078        #ifdef _PARALLEL_
     1079        MPI_Reduce (&found,&mpi_found,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
     1080        MPI_Bcast(&mpi_found,1,MPI_INT,0,MPI_COMM_WORLD);               
     1081        found=mpi_found;
     1082        #endif
     1083
     1084        return found;
    10431085}
    10441086
     
    10471089void  DataSet::MeltingConstraints(int* pnum_unstable_constraints,void* inputs,int analysis_type,int sub_analysis_type){
    10481090
    1049         throw ErrorException(__FUNCT__," not implemented yet!");
    1050 
     1091        /* generic object pointer: */
     1092        vector<Object*>::iterator object;
     1093        Pengrid* pengrid=NULL;
     1094
     1095        int unstable;
     1096        int num_unstable_constraints=0;
     1097        int sum_num_unstable_constraints=0;
     1098
     1099        num_unstable_constraints=0;     
     1100
     1101        /*Enforce constraints: */
     1102        for ( object=objects.begin() ; object < objects.end(); object++ ){
     1103               
     1104                if((*object)->Enum()==PengridEnum()){
     1105
     1106                        pengrid=(Pengrid*)(*object);
     1107                        pengrid->PenaltyConstrain(&unstable,inputs,analysis_type,sub_analysis_type);
     1108
     1109                        num_unstable_constraints+=unstable;
     1110                }
     1111        }
     1112
     1113        #ifdef _PARALLEL_
     1114        MPI_Reduce (&num_unstable_constraints,&sum_num_unstable_constraints,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
     1115        MPI_Bcast(&sum_num_unstable_constraints,1,MPI_INT,0,MPI_COMM_WORLD);               
     1116        num_unstable_constraints=sum_num_unstable_constraints;
     1117        #endif
     1118
     1119        /*Assign output pointers: */
     1120        *pnum_unstable_constraints=num_unstable_constraints;
    10511121}
    10521122
  • issm/trunk/src/c/Makefile.am

    r472 r483  
    188188                                        ./ModelProcessorx/SlopeCompute/CreateLoadsSlopeCompute.cpp\
    189189                                        ./ModelProcessorx/Control/CreateParametersControl.cpp\
     190                                        ./ModelProcessorx/Thermal/CreateElementsNodesAndMaterialsThermal.cpp\
     191                                        ./ModelProcessorx/Thermal/CreateConstraintsThermal.cpp\
     192                                        ./ModelProcessorx/Thermal/CreateLoadsThermal.cpp\
     193                                        ./ModelProcessorx/Thermal/CreateParametersThermal.cpp\
     194                                        ./ModelProcessorx/Melting/CreateElementsNodesAndMaterialsMelting.cpp\
     195                                        ./ModelProcessorx/Melting/CreateConstraintsMelting.cpp\
     196                                        ./ModelProcessorx/Melting/CreateLoadsMelting.cpp\
     197                                        ./ModelProcessorx/Melting/CreateParametersMelting.cpp\
    190198                                        ./Dofx/Dofx.h\
    191199                                        ./Dofx/Dofx.cpp\
     
    434442                                        ./ModelProcessorx/SlopeCompute/CreateLoadsSlopeCompute.cpp\
    435443                                        ./ModelProcessorx/Control/CreateParametersControl.cpp\
     444                                        ./ModelProcessorx/Thermal/CreateElementsNodesAndMaterialsThermal.cpp\
     445                                        ./ModelProcessorx/Thermal/CreateConstraintsThermal.cpp\
     446                                        ./ModelProcessorx/Thermal/CreateLoadsThermal.cpp\
     447                                        ./ModelProcessorx/Thermal/CreateParametersThermal.cpp\
     448                                        ./ModelProcessorx/Melting/CreateElementsNodesAndMaterialsMelting.cpp\
     449                                        ./ModelProcessorx/Melting/CreateConstraintsMelting.cpp\
     450                                        ./ModelProcessorx/Melting/CreateLoadsMelting.cpp\
     451                                        ./ModelProcessorx/Melting/CreateParametersMelting.cpp\
    436452                                        ./Dofx/Dofx.h\
    437453                                        ./Dofx/Dofx.cpp\
  • issm/trunk/src/c/ModelProcessorx/CreateDataSets.cpp

    r465 r483  
    7373        else if (strcmp(model->analysis_type,"thermal")==0){
    7474
    75                 if ((strcmp(model->sub_analysis_type,"steady")==0) || (strcmp(model->sub_analysis_type,"transient")==0)){
    76                
    77                         //CreateElementsNodesAndMaterialsThermal(pelements,pnodes,pmaterials, model,model_handle);
    78                         //CreateConstraintsThermal(pconstraints,model,model_handle);
    79                         //CreateLoadsThermal(ploads,model,model_handle);
     75                CreateElementsNodesAndMaterialsThermal(pelements,pnodes,pmaterials, model,model_handle);
     76                CreateConstraintsThermal(pconstraints,model,model_handle);
     77                CreateLoadsThermal(ploads,model,model_handle);
    8078                                       
    81                 }
    82                 else if (strcmp(model->sub_analysis_type,"melting")==0){
     79        }
     80        else if (strcmp(model->analysis_type,"melting")==0){
    8381                       
    84                         //CreateElementsNodesAndMaterialsMelting(pelements,pnodes,pmaterials, model,model_handle);
    85                         //CreateConstraintsMelting(pconstraints,model,model_handle);
    86                         //CreateLoadsMelting(ploads,model,model_handle);
    87 
    88                 }
     82                CreateElementsNodesAndMaterialsMelting(pelements,pnodes,pmaterials, model,model_handle);
     83                CreateConstraintsMelting(pconstraints,model,model_handle);
     84                CreateLoadsMelting(ploads,model,model_handle);
    8985        }
    9086        else if (strcmp(model->analysis_type,"prognostic")==0){
  • issm/trunk/src/c/ModelProcessorx/DiagnosticHoriz/CreateElementsNodesAndMaterialsDiagnosticHoriz.cpp

    r465 r483  
    6262        double tria_melting[3];
    6363        double tria_accumulation[3];
     64        double tria_geothermalflux[3];
    6465        int    tria_friction_type;
    6566        double tria_p;
     
    293294
    294295                        /*Create tria element using its constructor:*/
    295                         tria=new Tria(tria_id, tria_mid, tria_mparid, tria_g, tria_h, tria_s, tria_b, tria_k, tria_melting,tria_accumulation,tria_friction_type, tria_p, tria_q, tria_shelf, tria_meanvel, tria_epsvel, tria_viscosity_overshoot);
     296                        tria=new Tria(tria_id, tria_mid, tria_mparid, tria_g, tria_h, tria_s, tria_b, tria_k, tria_melting,tria_accumulation,tria_geothermalflux,tria_friction_type, tria_p, tria_q, tria_shelf, tria_meanvel, tria_epsvel, tria_viscosity_overshoot);
    296297
    297298                        /*Add tria element to elements dataset: */
  • issm/trunk/src/c/ModelProcessorx/DiagnosticStokes/CreateLoadsDiagnosticStokes.cpp

    r431 r483  
    4343        /*pengrid intermediary data: */
    4444        int pengrid_id;
     45        int pengrid_mparid;
    4546        int pengrid_node_id;
    4647        int pengrid_dof;
     
    141142                        pengrid_dof=1;
    142143                        pengrid_penalty_offset=model->penalty_offset;
     144                        pengrid_mparid=model->numberofelements+1;//refers to the corresponding parmat property card
    143145
    144                         pengrid= new Pengrid(pengrid_id, pengrid_node_id,pengrid_dof, pengrid_active, pengrid_penalty_offset,pengrid_thermal_steadystate);
     146                        pengrid= new Pengrid(pengrid_id, pengrid_node_id,pengrid_mparid,pengrid_dof, pengrid_active, pengrid_penalty_offset,pengrid_thermal_steadystate);
    145147                       
    146148                        loads->AddObject(pengrid);
  • issm/trunk/src/c/ModelProcessorx/Model.h

    r465 r483  
    210210        void    CreateParametersControl(DataSet** pparameters,Model* model,ConstDataHandle model_handle);
    211211
     212        /*thermal:*/
     213        void    CreateElementsNodesAndMaterialsThermal(DataSet** pelements,DataSet** pnodes, DataSet** pmaterials, Model* model,ConstDataHandle model_handle);
     214        void    CreateConstraintsThermal(DataSet** pconstraints,Model* model,ConstDataHandle model_handle);
     215        void    CreateLoadsThermal(DataSet** ploads, Model* model, ConstDataHandle model_handle);
     216        void    CreateParametersThermal(DataSet** pparameters,Model* model,ConstDataHandle model_handle);
     217
     218        /*melting:*/
     219        void    CreateElementsNodesAndMaterialsMelting(DataSet** pelements,DataSet** pnodes, DataSet** pmaterials, Model* model,ConstDataHandle model_handle);
     220        void    CreateConstraintsMelting(DataSet** pconstraints,Model* model,ConstDataHandle model_handle);
     221        void    CreateLoadsMelting(DataSet** ploads, Model* model, ConstDataHandle model_handle);
     222        void    CreateParametersMelting(DataSet** pparameters,Model* model,ConstDataHandle model_handle);
     223
    212224
    213225#endif  /* _MODEL_H */
  • issm/trunk/src/c/ModelProcessorx/SlopeCompute/CreateElementsNodesAndMaterialsSlopeCompute.cpp

    r465 r483  
    5858        double tria_melting[3];
    5959        double tria_accumulation[3];
     60        double tria_geothermalflux[3];
    6061        int    tria_friction_type;
    6162        double tria_p;
     
    226227
    227228                        /*Create tria element using its constructor:*/
    228                         tria=new Tria(tria_id, tria_mid, tria_mparid, tria_g, tria_h, tria_s, tria_b, tria_k, tria_melting,tria_accumulation,tria_friction_type, tria_p, tria_q, tria_shelf, tria_meanvel, tria_epsvel, tria_viscosity_overshoot);
     229                        tria=new Tria(tria_id, tria_mid, tria_mparid, tria_g, tria_h, tria_s, tria_b, tria_k, tria_melting,tria_accumulation,tria_geothermalflux,tria_friction_type, tria_p, tria_q, tria_shelf, tria_meanvel, tria_epsvel, tria_viscosity_overshoot);
    229230
    230231                        /*Add tria element to elements dataset: */
  • issm/trunk/src/c/objects/Friction.cpp

    r394 r483  
    7272        double  velocity_x[numgrids];
    7373        double  velocity_y[numgrids];
     74        double  velocity_z[numgrids];
    7475        double  velocity_mag[numgrids];
    7576
     
    9091
    9192                //We need the velocity magnitude to evaluate the basal stress:
    92                 velocity_x[i]=*(friction->velocities+2*i+0); //velocities of size numgridsx2
    93                 velocity_y[i]=*(friction->velocities+2*i+1);
    94                 velocity_mag[i]=sqrt(pow(velocity_x[i],2)+pow(velocity_y[i],2));
     93                if(strcmp(friction->element_type,"2d")){
     94                        velocity_x[i]=*(friction->velocities+2*i+0); //velocities of size numgridsx2
     95                        velocity_y[i]=*(friction->velocities+2*i+1);
     96                        velocity_mag[i]=sqrt(pow(velocity_x[i],2)+pow(velocity_y[i],2));
     97                }
     98                else{
     99                        velocity_x[i]=*(friction->velocities+3*i+0); //velocities of size numgridsx3
     100                        velocity_y[i]=*(friction->velocities+3*i+1);
     101                        velocity_z[i]=*(friction->velocities+3*i+2);
     102                        velocity_mag[i]=sqrt(pow(velocity_x[i],2)+pow(velocity_y[i],2)+pow(velocity_z[i],2));
     103                }
    95104       
    96105                alpha2[i]=pow(friction->K[i],2)*pow(Neff[i],r)*pow(velocity_mag[i],(s-1));
  • issm/trunk/src/c/objects/Matpar.cpp

    r246 r483  
    172172        return new Matpar(*this);
    173173}
     174
     175double Matpar::GetMixedLayerCapacity(){
     176        return mixed_layer_capacity;
     177}
     178
     179double Matpar::GetThermalExchangeVelocity(){
     180        return thermal_exchange_velocity;
     181}
     182
     183double Matpar::GetHeatCapacity(){
     184        return heatcapacity;
     185}
     186               
     187double Matpar::GetThermalConductivity(){
     188        return thermalconductivity;
     189}
     190               
     191double Matpar::GetLatentHeat(){
     192        return latentheat;
     193}
     194double Matpar::GetBeta(){
     195        return beta;
     196}
     197double Matpar::GetMeltingPoint(){
     198        return meltingpoint;
     199}
     200
  • issm/trunk/src/c/objects/Matpar.h

    r246 r483  
    4444                double GetRhoIce();
    4545                double GetRhoWater();
     46                double GetMixedLayerCapacity();
     47                double GetThermalExchangeVelocity();
     48                double GetHeatCapacity();
     49                double GetThermalConductivity();
     50                double GetLatentHeat();
     51                double GetBeta();
     52                double GetMeltingPoint();
    4653                Object* copy();
    4754
  • issm/trunk/src/c/objects/Pengrid.cpp

    r468 r483  
    2222}
    2323
    24 Pengrid::Pengrid(int    pengrid_id, int pengrid_node_id,int pengrid_dof, int pengrid_active, double pengrid_penalty_offset,int pengrid_thermal_steadystate){
     24Pengrid::Pengrid(int    pengrid_id, int pengrid_mparid,int pengrid_node_id,int pengrid_dof, int pengrid_active, double pengrid_penalty_offset,int pengrid_thermal_steadystate){
    2525       
    2626        id=pengrid_id;
     27        mparid=pengrid_mparid;
    2728        dof=pengrid_dof;
    2829        active=pengrid_active;
     
    3334        node_offset=UNDEF;
    3435        node=NULL;
     36        matpar=NULL;
     37        matpar_offset=UNDEF;
    3538
    3639        return;
     
    4548        printf("Pengrid:\n");
    4649        printf("   id: %i\n",id);
     50        printf("   mparid: %i\n",mparid);
    4751        printf("   dof: %i\n",dof);
    4852        printf("   active: %i\n",active);
     
    5155        printf("   node_id: [%i]\n",node_id);
    5256        printf("   node_offset: [%i]\n",node_offset);
     57        printf("   matpar_offset=%i\n",matpar_offset);
    5358       
    5459        if(node)node->Echo();
     60        if(matpar)matpar->Echo();
    5561        return;
    5662}
     
    7278        /*marshall Pengrid data: */
    7379        memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
     80        memcpy(marshalled_dataset,&mparid,sizeof(mparid));marshalled_dataset+=sizeof(mparid);
    7481        memcpy(marshalled_dataset,&dof,sizeof(dof));marshalled_dataset+=sizeof(dof);
    7582        memcpy(marshalled_dataset,&active,sizeof(active));marshalled_dataset+=sizeof(active);
     
    7885        memcpy(marshalled_dataset,&node_id,sizeof(node_id));marshalled_dataset+=sizeof(node_id);
    7986        memcpy(marshalled_dataset,&node_offset,sizeof(node_offset));marshalled_dataset+=sizeof(node_offset);
     87        memcpy(marshalled_dataset,&matpar,sizeof(matpar));marshalled_dataset+=sizeof(matpar);
     88        memcpy(marshalled_dataset,&matpar_offset,sizeof(matpar_offset));marshalled_dataset+=sizeof(matpar_offset);
    8089
    8190        *pmarshalled_dataset=marshalled_dataset;
     
    8695
    8796        return sizeof(id)+
     97                sizeof(mparid)+
    8898                sizeof(dof)+
    8999                sizeof(active)+
     
    92102                sizeof(node_id)+
    93103                sizeof(node_offset)+
     104                +sizeof(matpar)
     105                +sizeof(matpar_offset)+
    94106                sizeof(int); //sizeof(int) for enum type
    95107}
     
    117129        memcpy(&node_id,marshalled_dataset,sizeof(node_id));marshalled_dataset+=sizeof(node_id);
    118130        memcpy(&node_offset,marshalled_dataset,sizeof(node_offset));marshalled_dataset+=sizeof(node_offset);
     131        memcpy(&matpar,marshalled_dataset,sizeof(matpar));marshalled_dataset+=sizeof(matpar);
     132        memcpy(&matpar_offset,marshalled_dataset,sizeof(matpar_offset));marshalled_dataset+=sizeof(matpar_offset);
     133
    119134
    120135        node=NULL;
     136        matpar=NULL;
    121137
    122138        /*return: */
     
    143159
    144160        DataSet* nodesin=NULL;
     161        DataSet* materialsin=NULL;
    145162
    146163        /*Recover pointers :*/
    147164        nodesin=(DataSet*)pnodesin;
     165        materialsin=(DataSet*)pmaterialsin;
    148166
    149167        /*Link this load with its nodes: */
    150168        ResolvePointers((Object**)&node,&node_id,&node_offset,1,nodesin);
    151 
     169        ResolvePointers((Object**)&matpar,&mparid,&matpar_offset,1,materialsin);
    152170}
    153171
     
    184202
    185203                PenaltyCreateKMatrixDiagnosticStokes( Kgg,inputs,kmax,analysis_type,sub_analysis_type);
     204        }
     205        else if (analysis_type==ThermalAnalysisEnum()){
     206               
     207                PenaltyCreateKMatrixThermal( Kgg,inputs,kmax,analysis_type,sub_analysis_type);
     208               
     209        }
     210        else if (analysis_type==MeltingAnalysisEnum()){
     211                       
     212                PenaltyCreateKMatrixMelting( Kgg,inputs,kmax,analysis_type,sub_analysis_type);
    186213
    187214        }
     
    202229        int       numberofdofspernode;
    203230
    204         int dofs1=0;
    205         int dofs2=1;
     231        int dofs1[1]={0};
     232        int dofs2[1]={1};
    206233        double slope[2];
    207234        int found=0;
     
    217244       
    218245        /*recover slope: */
    219         found=inputs->Recover("bedslopex",&slope[0],1,&dofs1,numgrids,(void**)&node);
     246        found=inputs->Recover("bedslopex",&slope[0],1,dofs1,numgrids,(void**)&node);
    220247        if(!found)throw ErrorException(__FUNCT__," bedslopex needed in inputs!");
    221         found=inputs->Recover("bedslopey",&slope[1],1,&dofs2,numgrids,(void**)&node);
     248        found=inputs->Recover("bedslopey",&slope[1],1,dofs2,numgrids,(void**)&node);
    222249        if(!found)throw ErrorException(__FUNCT__," bedslopey needed in inputs!");
    223250
     
    232259
    233260#undef __FUNCT__
     261#define __FUNCT__ "Pengrid::PenaltyCreateKMatrixThermal"
     262void  Pengrid::PenaltyCreateKMatrixThermal(Mat Kgg,void* vinputs,double kmax,int analysis_type,int sub_analysis_type){
     263
     264        int found=0;
     265       
     266        const int numgrids=1;
     267        const int NDOF1=1;
     268        const int numdof=numgrids*NDOF1;
     269        double Ke[numdof][numdof];
     270        int       doflist[numdof];
     271        int       numberofdofspernode;
     272
     273        ParameterInputs* inputs=NULL;
     274
     275        /*recover pointers: */
     276        inputs=(ParameterInputs*)vinputs;
     277
     278
     279        if(!active)return;
     280
     281        /*Get dof list: */
     282        GetDofList(&doflist[0],&numberofdofspernode);
     283
     284        Ke[0][0]=kmax*pow(10,penalty_offset);
     285       
     286        /*Add Ke to global matrix Kgg: */
     287        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES);
     288}
     289
     290#undef __FUNCT__
     291#define __FUNCT__ "Pengrid::PenaltyCreateKMatrixMelting"
     292void  Pengrid::PenaltyCreateKMatrixMelting(Mat Kgg,void* vinputs,double kmax,int analysis_type,int sub_analysis_type){
     293
     294        int found=0;
     295        const int numgrids=1;
     296        const int NDOF1=1;
     297        const int numdof=numgrids*NDOF1;
     298        double Ke[numdof][numdof]={0.0};
     299        int     dofs1[1]={0};
     300        int       doflist[numdof];
     301        int      numberofdofspernode;
     302        double  meltingpoint;
     303
     304        double pressure;
     305        double temperature;
     306        double beta,t_pmp;
     307
     308        ParameterInputs* inputs=NULL;
     309
     310        /*recover pointers: */
     311        inputs=(ParameterInputs*)vinputs;
     312
     313        found=inputs->Recover("pressure",&pressure,1,dofs1,numgrids,(void**)&node);
     314        if(!found)throw ErrorException(__FUNCT__," could not find pressure in inputs!");
     315
     316        found=inputs->Recover("temperature",&temperature,1,dofs1,numgrids,(void**)&node);
     317        if(!found)throw ErrorException(__FUNCT__," could not find temperature in inputs!");
     318
     319        /*Get dof list: */
     320        GetDofList(&doflist[0],&numberofdofspernode);
     321       
     322        //Compute pressure melting point
     323        meltingpoint=matpar->GetMeltingPoint();
     324        beta=matpar->GetBeta();
     325        t_pmp=meltingpoint-beta*pressure;
     326
     327        //Add penalty load
     328        if (temperature<t_pmp){ //If T<Tpmp, there must be no melting. Therefore, melting should be  constrained to 0 when T<Tpmp, instead of using spcs, use penalties
     329                Ke[0][0]=kmax*pow(10,penalty_offset);
     330        }
     331       
     332        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES);
     333}
     334
     335#undef __FUNCT__
    234336#define __FUNCT__ "Pengrid::PenaltyCreatePVector"
    235337void  Pengrid::PenaltyCreatePVector(Vec pg,void* inputs,double kmax,int analysis_type,int sub_analysis_type){
    236338
    237         /*No penalty applied, do nothing: */
    238         return;
     339        if (analysis_type==ThermalAnalysisEnum()){
     340               
     341                PenaltyCreatePVectorThermal( pg,inputs,kmax,analysis_type,sub_analysis_type);
     342               
     343        }
     344        else if (analysis_type==MeltingAnalysisEnum()){
     345                       
     346                PenaltyCreatePVectorMelting( pg,inputs,kmax,analysis_type,sub_analysis_type);
     347
     348        }
     349        else{
     350                throw ErrorException(__FUNCT__,exprintf("%s%i%s%i%s","analysis: ",analysis_type," and sub_analysis_type: ",sub_analysis_type," not supported yet"));
     351        }
    239352
    240353}
     
    259372        *pnumberofdofspernode=numberofdofspernode;
    260373}
     374
     375void  Pengrid::PenaltyCreatePVectorThermal(Vec pg, void* vinputs, double kmax,int analysis_type,int sub_analysis_type){
     376
     377        const int numgrids=1;
     378        const int NDOF1=1;
     379        const int numdof=numgrids*NDOF1;
     380        int       doflist[numdof];
     381        double  P_terms[numdof]={0.0};
     382        int    numberofdofspernode;
     383        int    found=0;
     384        double pressure;
     385        int dofs1[1]={0};
     386        double meltingpoint;
     387        double beta;
     388        double t_pmp;
     389
     390        ParameterInputs* inputs=NULL;
     391
     392        /*recover pointers: */
     393        inputs=(ParameterInputs*)vinputs;
     394
     395        if(!active)return;
     396
     397        /*Get dof list: */
     398        GetDofList(&doflist[0],&numberofdofspernode);
     399       
     400                //First recover pressure
     401                found=inputs->Recover("pressure",&pressure,1,dofs1,numgrids,(void**)&node);
     402                if(!found)throw ErrorException(__FUNCT__," could not find pressure in inputs!");
     403
     404                //Compute pressure melting point
     405                meltingpoint=matpar->GetMeltingPoint();
     406                beta=matpar->GetBeta();
     407                t_pmp=meltingpoint-beta*pressure;
     408
     409                //Add penalty load
     410                P_terms[0]=kmax*pow(10,penalty_offset)*t_pmp;
     411
     412                /*Add P_terms to global vector pg: */
     413                VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
     414}
     415
     416void  Pengrid::PenaltyCreatePVectorMelting(Vec pg, void* vinputs, double kmax,int analysis_type,int sub_analysis_type){
     417       
     418        const int numgrids=1;
     419        const int NDOF1=1;
     420        const int numdof=numgrids*NDOF1;
     421        int       doflist[numdof];
     422        double  P_terms[numdof]={0.0};
     423        int numberofdofspernode;
     424        int    found=0;
     425        int dofs1[1]={0};
     426        double pressure;
     427        double temperature;
     428        double melting_offset;
     429        double meltingpoint;
     430        double beta, heatcapacity;
     431        double latentheat;
     432        double t_pmp;
     433        double dt;
     434
     435        ParameterInputs* inputs=NULL;
     436
     437        /*recover pointers: */
     438        inputs=(ParameterInputs*)vinputs;
     439
     440        //First recover pressure,melting offset and temperature vectors
     441        found=inputs->Recover("pressure",&pressure,1,dofs1,numgrids,(void**)&node);
     442        if(!found)throw ErrorException(__FUNCT__," could not find pressure in inputs!");
     443
     444        found=inputs->Recover("temperature",&temperature,1,dofs1,numgrids,(void**)&node);
     445        if(!found)throw ErrorException(__FUNCT__," could not find temperature in inputs!");
     446
     447        found=inputs->Recover("melting_offset",&melting_offset);
     448        if(!found)throw ErrorException(__FUNCT__," could not find melting_offset in inputs!");
     449
     450        found=inputs->Recover("dt",&dt);
     451        if((!found) && (sub_analysis_type==TransientAnalysisEnum()))throw ErrorException(__FUNCT__," could not find dt in inputs!");
     452
     453
     454        meltingpoint=matpar->GetMeltingPoint();
     455        beta=matpar->GetBeta();
     456        heatcapacity=matpar->GetHeatCapacity();
     457        latentheat=matpar->GetLatentHeat();
     458
     459        //Compute pressure melting point
     460        t_pmp=meltingpoint-beta*pressure;
     461
     462        //Add penalty load
     463        //This time, the penalty must have the same value as the one used for the thermal computation
     464        //so that the corresponding melting can be computed correctly
     465        //In the thermal computation, we used kmax=melting_offset, and the same penalty_offset
     466        if (temperature<t_pmp){ //%no melting
     467                P_terms[0]=0;
     468        }
     469        else{
     470                if (sub_analysis_type==SteadyAnalysisEnum()){
     471                        P_terms[0]=melting_offset*pow(10,penalty_offset)*(temperature-t_pmp);
     472                }
     473                else{
     474                        P_terms[0]=melting_offset*pow(10,penalty_offset)*(temperature-t_pmp)/dt;
     475                }
     476        }
     477        /*Add P_terms to global vector pg: */
     478        VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
     479}
     480               
     481
     482#undef __FUNCT__
     483#define __FUNCT__ "Pengrid::PenaltyConstrain"
     484void  Pengrid::PenaltyConstrain(int* punstable,void* vinputs,int analysis_type,int sub_analysis_type){
     485
     486        //   The penalty is stable if it doesn't change during to successive iterations.   
     487
     488        int found=0;
     489        const int numgrids=1;
     490
     491
     492        double pressure;
     493        double temperature;
     494        double beta,t_pmp;
     495        double meltingpoint;
     496        int    new_active;
     497        int* dofs1={0};
     498        int  unstable=0;
     499       
     500        ParameterInputs* inputs=NULL;
     501
     502        /*recover pointers: */
     503        inputs=(ParameterInputs*)vinputs;
     504
     505
     506        //First recover beta, pressure and temperature vectors;
     507        found=inputs->Recover("pressure",&pressure,1,dofs1,numgrids,(void**)&node);
     508        if(!found)throw ErrorException(__FUNCT__," could not find pressure in inputs!");
     509
     510        found=inputs->Recover("temperature",&temperature,1,dofs1,numgrids,(void**)&node);
     511        if(!found)throw ErrorException(__FUNCT__," could not find temperature in inputs!");
     512
     513
     514        //Compute pressure melting point
     515        meltingpoint=matpar->GetMeltingPoint();
     516        beta=matpar->GetBeta();
     517
     518        t_pmp=meltingpoint-beta*pressure;
     519
     520        //Figure out if temperature is over melting_point, in which case, this penalty needs to be activated.
     521
     522        if (temperature>t_pmp){
     523                new_active=1;
     524        }
     525        else{
     526                new_active=0;
     527        }
     528
     529
     530        //Figure out stability of this penalty
     531        if (active==new_active){
     532                unstable=0;
     533        }
     534        else{
     535                unstable=1;
     536        }
     537       
     538        //Set penalty flag
     539        active=new_active;
     540
     541        //*Assign output pointers:*/
     542        *punstable=unstable;
     543}
  • issm/trunk/src/c/objects/Pengrid.h

    r465 r483  
    88#include "./Node.h"
    99#include "./Element.h"
     10#include "./Matpar.h"
    1011
    1112class Element;
     
    2526                int     node_offset;
    2627
     28                int mparid;
     29                Matpar* matpar;
     30                int   matpar_offset;
     31
    2732        public:
    2833
    2934                Pengrid();
    30                 Pengrid(int     id, int node_id,int dof, int active, double penalty_offset,int thermal_steadystate);
     35                Pengrid(int     id, int node_id,int mparid,int dof, int active, double penalty_offset,int thermal_steadystate);
    3136                ~Pengrid();
    3237
     
    4954                void  GetDofList(int* doflist,int* pnumberofdofspernode);
    5055                Object* copy();
    51 
     56                void  PenaltyCreateKMatrixThermal(Mat Kgg,void* vinputs,double kmax,int analysis_type,int sub_analysis_type);
     57                void  PenaltyCreateKMatrixMelting(Mat Kgg,void* vinputs,double kmax,int analysis_type,int sub_analysis_type);
     58                void  MatparConfiguration(Matpar* matpar,int matpar_offset);
     59                void  PenaltyCreatePVectorThermal(Vec pg, void* inputs, double kmax,int analysis_type,int sub_analysis_type);
     60                void  PenaltyCreatePVectorMelting(Vec pg, void* inputs, double kmax,int analysis_type,int sub_analysis_type);
     61                void  PenaltyConstrain(int* punstable,void* inputs,int analysis_type,int sub_analysis_type);
    5262};
    5363
  • issm/trunk/src/c/objects/Penpair.cpp

    r465 r483  
    260260        return new Penpair(*this);
    261261}
    262 
     262               
     263int   Penpair::GetNumDofs(){
     264        return numdofs;
     265}
     266
  • issm/trunk/src/c/objects/Penpair.h

    r465 r483  
    5858                void  PenaltyCreateKMatrix(Mat Kgg,void* inputs,double kmax,int analysis_type,int sub_analysis_type);
    5959                void  PenaltyCreatePVector(Vec pg,void* inputs,double kmax,int analysis_type,int sub_analysis_type);
     60                int   GetNumDofs();
    6061                Object* copy();
    6162};
  • issm/trunk/src/c/objects/Penta.cpp

    r468 r483  
    313313                CreateKMatrixSlopeCompute( Kgg,inputs,analysis_type,sub_analysis_type);
    314314        }
     315        else if (analysis_type==ThermalAnalysisEnum()){
     316               
     317                CreateKMatrixThermal( Kgg,inputs,analysis_type,sub_analysis_type);
     318        }
     319        else if (analysis_type==MeltingAnalysisEnum()){
     320               
     321                CreateKMatrixMelting( Kgg,inputs,analysis_type,sub_analysis_type);
     322        }
    315323        else{
    316324                throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","analysis: ",analysis_type," not supported yet"));
     
    834842
    835843                        /*Compute thickness: */
    836                         GetParameterValue(&thickness, &h[0],gauss_coord);
    837844
    838845                        /*Compute strain rate: */
     
    10141021                CreatePVectorSlopeCompute( pg,inputs,analysis_type,sub_analysis_type);
    10151022        }
     1023        else if (analysis_type==ThermalAnalysisEnum()){
     1024               
     1025                CreatePVectorThermal( pg,inputs,analysis_type,sub_analysis_type);
     1026        }
     1027        else if (analysis_type==MeltingAnalysisEnum()){
     1028               
     1029                CreatePVectorMelting( pg,inputs,analysis_type,sub_analysis_type);
     1030        }
    10161031        else{
    10171032                throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","analysis: ",analysis_type," not supported yet"));
     
    12081223        double   tria_melting[3];
    12091224        double   tria_accumulation[3];
     1225        double   tria_geothermalflux[3];
    12101226       
    12111227        /*configuration: */
     
    12381254        tria_accumulation[2]=accumulation[g2];
    12391255
     1256        tria_geothermalflux[0]=geothermalflux[g0];
     1257        tria_geothermalflux[1]=geothermalflux[g1];
     1258        tria_geothermalflux[2]=geothermalflux[g2];
     1259
    12401260        tria_node_ids[0]=node_ids[g0];
    12411261        tria_node_ids[1]=node_ids[g1];
     
    12501270        tria_node_offsets[2]=node_offsets[g2];
    12511271
    1252         tria= new Tria(id,mid,mparid,tria_node_ids,tria_h,tria_s,tria_b,tria_k, tria_melting, tria_accumulation, friction_type,p,q,shelf,meanvel,epsvel,viscosity_overshoot);
     1272        tria= new Tria(id,mid,mparid,tria_node_ids,tria_h,tria_s,tria_b,tria_k, tria_melting, tria_accumulation, tria_geothermalflux,friction_type,p,q,shelf,meanvel,epsvel,viscosity_overshoot);
    12531273
    12541274        tria->NodeConfiguration(tria_node_ids,tria_nodes,tria_node_offsets);
     
    31283148
    31293149}
     3150
     3151#undef __FUNCT__
     3152#define __FUNCT__ "Penta::CreateKMatrixThermal"
     3153void  Penta::CreateKMatrixThermal(Mat Kgg,void* vinputs,int analysis_type,int sub_analysis_type){
     3154
     3155        /* local declarations */
     3156        int i,j;
     3157        int found=0;
     3158
     3159        /* node data: */
     3160        const int    numgrids=6;
     3161        const int    NDOF1=1;
     3162        const int    numdof=NDOF1*numgrids;
     3163        double       xyz_list[numgrids][3];
     3164        int          doflist[numdof];
     3165        int          numberofdofspernode;
     3166
     3167        /* gaussian points: */
     3168        int     num_area_gauss,igarea,igvert;
     3169        double* first_gauss_area_coord  =  NULL;
     3170        double* second_gauss_area_coord =  NULL;
     3171        double* third_gauss_area_coord  =  NULL;
     3172        double* vert_gauss_coord = NULL;
     3173        double* area_gauss_weights  =  NULL;
     3174        double* vert_gauss_weights  =  NULL;
     3175        double  gauss_weight,area_gauss_weight,vert_gauss_weight;
     3176        double  gauss_coord[4];
     3177
     3178        int area_order=5;
     3179        int     num_vert_gauss=5;
     3180       
     3181        int            dofs[3]={0,1,2};
     3182        double         dt;
     3183        int            dt_exists;
     3184       
     3185        double         vxvyvz_list[numgrids][3];
     3186        double         vx_list[numgrids];
     3187        int            vx_list_exists;
     3188        double         u;
     3189        double         vy_list[numgrids];
     3190        int            vy_list_exists;
     3191        double         v;
     3192        double         vz_list[numgrids];
     3193        int            vz_list_exists;
     3194        double         w;
     3195
     3196        /* element parameters: */
     3197        int         onbed;
     3198        int         shelf;
     3199        int     steady_state;
     3200
     3201        /*matrices: */
     3202        double     K_terms[numdof][numdof]={0.0};
     3203        double     Ke_gaussian_conduct[numdof][numdof];
     3204        double     Ke_gaussian_advec[numdof][numdof];
     3205        double     Ke_gaussian_transient[numdof][numdof];
     3206        double     B[3][numdof];
     3207        double     Bprime[3][numdof];
     3208        double     B_conduct[3][numdof];
     3209        double     B_advec[3][numdof];
     3210        double     Bprime_advec[3][numdof];
     3211        double     L[numdof];
     3212        double     D_scalar;
     3213        double     D[3][3];
     3214        double     l1l2l3[3];
     3215        double     tl1l2l3D[3];
     3216        double     tBD[3][numdof];
     3217        double     tBD_conduct[3][numdof];
     3218        double     tBD_advec[3][numdof];
     3219        double     tLD[numdof];
     3220
     3221        double     Jdet;
     3222
     3223        /*Material properties: */
     3224        double         gravity,rho_ice,rho_water;
     3225        double         heatcapacity,thermalconductivity;
     3226        double         mixed_layer_capacity,thermal_exchange_velocity;
     3227
     3228        /*Collapsed formulation: */
     3229        Tria*  tria=NULL;
     3230        ParameterInputs* inputs=NULL;
     3231
     3232        /*recover pointers: */
     3233        inputs=(ParameterInputs*)vinputs;
     3234
     3235        /* Get node coordinates and dof list: */
     3236        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     3237        GetDofList(&doflist[0],&numberofdofspernode);
     3238       
     3239        // /*recovre material parameters: */
     3240        rho_water=matpar->GetRhoWater();
     3241        rho_ice=matpar->GetRhoIce();
     3242        gravity=matpar->GetG();
     3243        heatcapacity=matpar->GetHeatCapacity();
     3244        thermalconductivity=matpar->GetThermalConductivity();
     3245
     3246               
     3247        /*recover extra inputs from users, dt and velocity: */
     3248        found=inputs->Recover("velocity",&vxvyvz_list[0][0],3,dofs,numgrids,(void**)nodes);
     3249        if(!found)throw ErrorException(__FUNCT__," could not find velocity in inputs!");
     3250        found=inputs->Recover("dt",&dt);
     3251        if(!found)throw ErrorException(__FUNCT__," could not find dt in inputs!");
     3252
     3253        for(i=0;i<numgrids;i++){
     3254                vx_list[i]=vxvyvz_list[i][0];
     3255                vy_list[i]=vxvyvz_list[i][1];
     3256                vz_list[i]=vxvyvz_list[i][2];
     3257        }
     3258
     3259        /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore
     3260           get tria gaussian points as well as segment gaussian points. For tria gaussian
     3261           points, order of integration is 2, because we need to integrate the product tB*D*B'
     3262           which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian
     3263           points, same deal, which yields 3 gaussian points.: */
     3264       
     3265        /*Get gaussian points: */
     3266        area_order=2;
     3267        num_vert_gauss=2;
     3268
     3269        GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss);
     3270
     3271        /* Start  looping on the number of gaussian points: */
     3272        for (igarea=0; igarea<num_area_gauss; igarea++){
     3273                for (igvert=0; igvert<num_vert_gauss; igvert++){
     3274                        /*Pick up the gaussian point: */
     3275                        area_gauss_weight=*(area_gauss_weights+igarea);
     3276                        vert_gauss_weight=*(vert_gauss_weights+igvert);
     3277                        gauss_weight=area_gauss_weight*vert_gauss_weight;
     3278                        gauss_coord[0]=*(first_gauss_area_coord+igarea);
     3279                        gauss_coord[1]=*(second_gauss_area_coord+igarea);
     3280                        gauss_coord[2]=*(third_gauss_area_coord+igarea);
     3281                        gauss_coord[3]=*(vert_gauss_coord+igvert);
     3282
     3283                        /* Get Jacobian determinant: */
     3284                        GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
     3285
     3286                        /*Conduction: */
     3287
     3288                        /*Get B_conduct matrix: */
     3289                        GetB_conduct(&B_conduct[0][0],&xyz_list[0][0],gauss_coord);
     3290
     3291                        /*Build D: */
     3292                        D_scalar=gauss_weight*Jdet*(thermalconductivity/(rho_ice*heatcapacity));
     3293
     3294                        if(sub_analysis_type!=SteadyAnalysisEnum()){
     3295                                D_scalar=D_scalar*dt;
     3296                        }
     3297
     3298                        D[0][0]=D_scalar; D[0][1]=0; D[0][2]=0;
     3299                        D[1][0]=0; D[1][1]=D_scalar; D[1][2]=0;
     3300                        D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar;
     3301
     3302
     3303                        /*  Do the triple product B'*D*B: */
     3304                        MatrixMultiply(&B_conduct[0][0],3,numdof,1,&D[0][0],3,3,0,&tBD_conduct[0][0],0);
     3305                        MatrixMultiply(&tBD_conduct[0][0],numdof,3,0,&B_conduct[0][0],3,numdof,0,&Ke_gaussian_conduct[0][0],0);
     3306
     3307                        /*Advection: */
     3308
     3309                        /*Get B_advec and Bprime_advec matrices: */
     3310                        GetB_advec(&B_advec[0][0],&xyz_list[0][0],gauss_coord);
     3311                        GetBprime_advec(&Bprime_advec[0][0],&xyz_list[0][0],gauss_coord);
     3312
     3313
     3314                        //Build the D matrix
     3315                        GetParameterValue(&u, &vx_list[0],gauss_coord);
     3316                        GetParameterValue(&v, &vy_list[0],gauss_coord);
     3317                        GetParameterValue(&w, &vz_list[0],gauss_coord);
     3318
     3319                        D_scalar=gauss_weight*Jdet;
     3320
     3321                        if(sub_analysis_type!=SteadyAnalysisEnum()){
     3322                                D_scalar=D_scalar*dt;
     3323                        }
     3324
     3325                        D[0][0]=D_scalar*u;D[0][1]=0;         D[0][2]=0;
     3326                        D[1][0]=0;         D[1][1]=D_scalar*v;D[1][2]=0;
     3327                        D[2][0]=0;         D[2][1]=0;         D[2][2]=D_scalar*w;
     3328
     3329                        /*  Do the triple product B'*D*Bprime: */
     3330                        MatrixMultiply(&B_advec[0][0],3,numdof,1,&D[0][0],3,3,0,&tBD_advec[0][0],0);
     3331                        MatrixMultiply(&tBD_advec[0][0],numdof,3,0,&Bprime_advec[0][0],3,numdof,0,&Ke_gaussian_advec[0][0],0);
     3332
     3333
     3334                        /*Transient: */
     3335                        if(sub_analysis_type!=SteadyAnalysisEnum()){
     3336                                GetNodalFunctions(&L[0], gauss_coord);
     3337                                D_scalar=gauss_weight*Jdet;
     3338                                D_scalar=D_scalar;
     3339
     3340                                /*  Do the triple product L'*D*L: */
     3341                                MatrixMultiply(&L[0],numdof,1,0,&D_scalar,1,1,0,&tLD[0],0);
     3342                                MatrixMultiply(&tLD[0],numdof,1,0,&L[0],1,numdof,0,&Ke_gaussian_transient[0][0],0);
     3343                        }
     3344                        else{
     3345                                for(i=0;i<numdof;i++){
     3346                                        for(j=0;j<numdof;j++){
     3347                                                Ke_gaussian_transient[i][j]=0;
     3348                                        }
     3349                                }
     3350                        }
     3351                                       
     3352                        /*Add Ke_gaussian to pKe: */
     3353                        for(i=0;i<numdof;i++){
     3354                                for(j=0;j<numdof;j++){
     3355                                        K_terms[i][j]+=Ke_gaussian_conduct[i][j]+Ke_gaussian_advec[i][j]+Ke_gaussian_transient[i][j];
     3356                                }
     3357                        }
     3358                       
     3359                }
     3360        }
     3361       
     3362        //Ice/ocean heat exchange flux on ice shelf base
     3363
     3364        if(onbed && shelf){
     3365
     3366                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
     3367                tria->CreateKMatrixThermal(Kgg,inputs, analysis_type,sub_analysis_type);
     3368                delete tria;
     3369                return;
     3370        }
     3371
     3372        /*Add Ke_gg to global matrix Kgg: */
     3373        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
     3374
     3375        cleanup_and_return:
     3376        xfree((void**)&first_gauss_area_coord);
     3377        xfree((void**)&second_gauss_area_coord);
     3378        xfree((void**)&third_gauss_area_coord);
     3379        xfree((void**)&area_gauss_weights);
     3380        xfree((void**)&vert_gauss_weights);
     3381        xfree((void**)&vert_gauss_coord);
     3382
     3383}
     3384
     3385#undef __FUNCT__
     3386#define __FUNCT__ "Penta::GetB_conduct"
     3387void Penta::GetB_conduct(double* B_conduct, double* xyz_list, double* gauss_coord){
     3388
     3389        /*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID.
     3390         * For grid i, Bi' can be expressed in the basic coordinate system
     3391         * by:
     3392         *       Bi_conduct_basic=[ dh/dx ]
     3393         *                       [ dh/dy ]
     3394         *                       [ dh/dz ]
     3395         * where h is the interpolation function for grid i.
     3396         *
     3397         * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids)
     3398         */
     3399       
     3400        int i;
     3401        int calculationdof=3;
     3402        int numgrids=6;
     3403        int DOFPERGRID=1;
     3404
     3405        /*Same thing in the basic coordinate system: */
     3406        double dh1dh6_basic[calculationdof][numgrids];
     3407
     3408        /*Get dh1dh2dh3 in basic coordinates system : */
     3409        GetNodalFunctionsDerivativesBasic(&dh1dh6_basic[0][0],xyz_list,gauss_coord);
     3410
     3411        /*Build B': */
     3412        for (i=0;i<numgrids;i++){
     3413                *(B_conduct+DOFPERGRID*numgrids*0+DOFPERGRID*i)=dh1dh6_basic[0][i];
     3414                *(B_conduct+DOFPERGRID*numgrids*1+DOFPERGRID*i)=dh1dh6_basic[1][i];
     3415                *(B_conduct+DOFPERGRID*numgrids*2+DOFPERGRID*i)=dh1dh6_basic[2][i];
     3416        }
     3417}
     3418
     3419#undef __FUNCT__
     3420#define __FUNCT__ "Penta::GetB_advec"
     3421void Penta::GetB_advec(double* B_advec, double* xyz_list, double* gauss_coord){
     3422
     3423        /*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID.
     3424         * For grid i, Bi' can be expressed in the basic coordinate system
     3425         * by:
     3426         *       Bi_conduct_basic=[ h ]
     3427         *                       [ h ]
     3428         *                       [ h ]
     3429         * where h is the interpolation function for grid i.
     3430         *
     3431         * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids)
     3432         */
     3433       
     3434        int i;
     3435        int calculationdof=3;
     3436        int numgrids=6;
     3437        int DOFPERGRID=1;
     3438
     3439        /*Same thing in the basic coordinate system: */
     3440        double l1l6[6];
     3441
     3442        /*Get dh1dh2dh3 in basic coordinates system : */
     3443        GetNodalFunctions(l1l6, gauss_coord);
     3444
     3445        /*Build B': */
     3446        for (i=0;i<numgrids;i++){
     3447                *(B_advec+DOFPERGRID*numgrids*0+DOFPERGRID*i)=l1l6[i];
     3448                *(B_advec+DOFPERGRID*numgrids*1+DOFPERGRID*i)=l1l6[i];
     3449                *(B_advec+DOFPERGRID*numgrids*2+DOFPERGRID*i)=l1l6[i];
     3450        }
     3451}
     3452
     3453#undef __FUNCT__
     3454#define __FUNCT__ "Penta::GetBprime_advec"
     3455void Penta::GetBprime_advec(double* Bprime_advec, double* xyz_list, double* gauss_coord){
     3456
     3457
     3458        /*Compute B  matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 5*DOFPERGRID.
     3459         * For grid i, Bi' can be expressed in the basic coordinate system
     3460         * by:
     3461         *       Biprime_advec=[ dh/dx ]
     3462         *                       [ dh/dy ]
     3463         *                       [ dh/dz ]
     3464         * where h is the interpolation function for grid i.
     3465         *
     3466         * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids)
     3467         */
     3468       
     3469        int i;
     3470        int calculationdof=3;
     3471        int numgrids=6;
     3472        int DOFPERGRID=1;
     3473
     3474        /*Same thing in the basic coordinate system: */
     3475        double dh1dh6_basic[calculationdof][numgrids];
     3476
     3477        /*Get dh1dh2dh3 in basic coordinates system : */
     3478        GetNodalFunctionsDerivativesBasic(&dh1dh6_basic[0][0],xyz_list,gauss_coord);
     3479
     3480        /*Build B': */
     3481        for (i=0;i<numgrids;i++){
     3482                *(Bprime_advec+DOFPERGRID*numgrids*0+DOFPERGRID*i)=dh1dh6_basic[0][i];
     3483                *(Bprime_advec+DOFPERGRID*numgrids*1+DOFPERGRID*i)=dh1dh6_basic[1][i];
     3484                *(Bprime_advec+DOFPERGRID*numgrids*2+DOFPERGRID*i)=dh1dh6_basic[2][i];
     3485        }
     3486}
     3487
     3488#undef __FUNCT__
     3489#define __FUNCT__ "Penta::CreateKMatrixMelting"
     3490void  Penta::CreateKMatrixMelting(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type){
     3491       
     3492        Tria* tria=NULL;
     3493        if (!onbed){
     3494                return;
     3495        }
     3496        else{
     3497               
     3498                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
     3499                tria->CreateKMatrixMelting(Kgg,inputs, analysis_type,sub_analysis_type);
     3500                delete tria;
     3501                return;
     3502        }
     3503}
     3504
     3505#undef __FUNCT__
     3506#define __FUNCT__ "Penta::CreatePVectorThermal"
     3507void Penta::CreatePVectorThermal( Vec pg, void* vinputs,int analysis_type,int sub_analysis_type){
     3508
     3509
     3510        /*indexing: */
     3511        int i,j;
     3512        int found=0;
     3513
     3514        const int  numgrids=6;
     3515        const int  NDOF1=1;
     3516        const int  numdof=numgrids*NDOF1;
     3517        int        doflist[numdof];
     3518        int        numberofdofspernode;
     3519
     3520        /*Grid data: */
     3521        double        xyz_list[numgrids][3];
     3522       
     3523        /* gaussian points: */
     3524        int     num_area_gauss,igarea,igvert;
     3525        double* first_gauss_area_coord  =  NULL;
     3526        double* second_gauss_area_coord =  NULL;
     3527        double* third_gauss_area_coord  =  NULL;
     3528        double* vert_gauss_coord = NULL;
     3529        double* area_gauss_weights  =  NULL;
     3530        double* vert_gauss_weights  =  NULL;
     3531        double  gauss_weight,area_gauss_weight,vert_gauss_weight;
     3532        double  gauss_coord[4];
     3533        int area_order=2;
     3534        int     num_vert_gauss=3;
     3535       
     3536        double         dt;
     3537        double         vx_list[numgrids];
     3538        double         vy_list[numgrids];
     3539        double         vz_list[numgrids];
     3540        double         vxvyvz_list[numgrids][3];
     3541        double         pressure_list[3];
     3542        double         pressure;
     3543        double         temperature_list[numgrids];
     3544        double         temperature;
     3545
     3546        /*Material properties: */
     3547        double         gravity,rho_ice,rho_water;
     3548        double         mixed_layer_capacity,heatcapacity;
     3549        double         beta,meltingpoint,thermal_exchange_velocity;
     3550
     3551        /* element parameters: */
     3552        int     friction_type;
     3553       
     3554        int            dofs[3]={0,1,2};
     3555        int            dofs1[1]={0};
     3556
     3557        /*matrices: */
     3558        double     P_terms[numdof]={0.0};
     3559        double     L[numdof];
     3560        double     l1l2l3[3];
     3561        double     alpha2_list[3];
     3562        double     basalfriction_list[3]={0.0};
     3563        double     basalfriction;
     3564        double     epsilon[6];
     3565        double     epsilon_sqr[3][3];
     3566        double     epsilon_matrix[3][3];
     3567
     3568        double     Jdet;
     3569        double     viscosity;
     3570        double     epsilon_eff;
     3571        double     phi;
     3572        double     t_pmp;
     3573        double     scalar;
     3574        double     scalar_def;
     3575        double     scalar_ocean;
     3576        double     scalar_transient;
     3577
     3578        /*Collapsed formulation: */
     3579        Tria*  tria=NULL;
     3580        ParameterInputs* inputs=NULL;
     3581
     3582        /*recover pointers: */
     3583        inputs=(ParameterInputs*)vinputs;
     3584
     3585        /* Get node coordinates and dof list: */
     3586        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     3587        GetDofList(&doflist[0],&numberofdofspernode);
     3588       
     3589        // /*recovre material parameters: */
     3590        rho_water=matpar->GetRhoWater();
     3591        rho_ice=matpar->GetRhoIce();
     3592        gravity=matpar->GetG();
     3593        heatcapacity=matpar->GetHeatCapacity();
     3594        beta=matpar->GetBeta();
     3595        meltingpoint=matpar->GetMeltingPoint();
     3596
     3597        /*recover extra inputs from users, dt and velocity: */
     3598        found=inputs->Recover("velocity",&vxvyvz_list[0][0],3,dofs,numgrids,(void**)nodes);
     3599        if(!found)throw ErrorException(__FUNCT__," could not find velocity in inputs!");
     3600
     3601        found=inputs->Recover("dt",&dt);
     3602        if((!found) && (sub_analysis_type==TransientAnalysisEnum()))throw ErrorException(__FUNCT__," could not find dt in inputs!");
     3603       
     3604        found=inputs->Recover("pressure",&pressure_list[0],1,dofs1,numgrids,(void**)nodes);
     3605        if(!found)throw ErrorException(__FUNCT__," could not find pressure in inputs!");
     3606
     3607        found=inputs->Recover("temperature",&temperature_list[0],1,dofs1,numgrids,(void**)nodes);
     3608        if(!found)throw ErrorException(__FUNCT__," could not find temperature in inputs!");
     3609
     3610        for(i=0;i<numgrids;i++){
     3611                vx_list[i]=vxvyvz_list[i][0];
     3612                vy_list[i]=vxvyvz_list[i][1];
     3613                vz_list[i]=vxvyvz_list[i][2];
     3614        }       
     3615
     3616        /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore
     3617           get tria gaussian points as well as segment gaussian points. For tria gaussian
     3618           points, order of integration is 2, because we need to integrate the product tB*D*B'
     3619           which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian
     3620           points, same deal, which yields 3 gaussian points.: */
     3621       
     3622        /*Get gaussian points: */
     3623        GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss);
     3624
     3625        /* Start  looping on the number of gaussian points: */
     3626        for (igarea=0; igarea<num_area_gauss; igarea++){
     3627                for (igvert=0; igvert<num_vert_gauss; igvert++){
     3628                        /*Pick up the gaussian point: */
     3629                        area_gauss_weight=*(area_gauss_weights+igarea);
     3630                        vert_gauss_weight=*(vert_gauss_weights+igvert);
     3631                        gauss_weight=area_gauss_weight*vert_gauss_weight;
     3632                        gauss_coord[0]=*(first_gauss_area_coord+igarea);
     3633                        gauss_coord[1]=*(second_gauss_area_coord+igarea);
     3634                        gauss_coord[2]=*(third_gauss_area_coord+igarea);
     3635                        gauss_coord[3]=*(vert_gauss_coord+igvert);
     3636       
     3637                        /*Compute strain rate and viscosity: */
     3638                        GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord);
     3639                        matice->GetViscosity3d(&viscosity,&epsilon[0]);
     3640
     3641                        /* Get Jacobian determinant: */
     3642                        GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord);
     3643
     3644                        /* Get nodal functions */
     3645                        GetNodalFunctions(&L[0], gauss_coord);
     3646
     3647                        /*Build deformational heating: */
     3648                        GetPhi(&phi, &epsilon[0], viscosity);
     3649
     3650                        /*Build pe_gaussian */
     3651                        if(sub_analysis_type==SteadyAnalysisEnum()){
     3652                                scalar_def=phi/(rho_ice*heatcapacity)*Jdet*gauss_weight;
     3653                        }
     3654                        else{
     3655                                scalar_def=dt*phi/(rho_ice*heatcapacity)*Jdet*gauss_weight;
     3656                        }
     3657
     3658                        for(i=0;i<numgrids;i++){
     3659                                P_terms[i]+=scalar_def*L[i];
     3660                        }
     3661
     3662                        /* Build transient now */
     3663                        if(sub_analysis_type==TransientAnalysisEnum()){
     3664                                scalar_transient=temperature*Jdet*gauss_weight;
     3665                                for(i=0;i<numgrids;i++){
     3666                                        P_terms[i]+=scalar_transient*L[i];
     3667                                }
     3668                        }
     3669                }
     3670        }
     3671
     3672        /*Add pe_g to global vector pg: */
     3673        VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
     3674
     3675        /* Ice/ocean heat exchange flux on ice shelf base */
     3676        if(onbed && shelf){
     3677
     3678                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
     3679                tria->CreatePVectorThermalShelf(pg,inputs, analysis_type,sub_analysis_type);
     3680                delete tria;
     3681                return;
     3682        }
     3683
     3684        /* Geothermal flux on ice sheet base and basal friction */
     3685        if(onbed && !shelf){
     3686               
     3687                tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.
     3688                tria->CreatePVectorThermalSheet(pg,inputs, analysis_type,sub_analysis_type);
     3689                delete tria;
     3690                return;
     3691        }
     3692
     3693        cleanup_and_return:
     3694        xfree((void**)first_gauss_area_coord);
     3695        xfree((void**)second_gauss_area_coord);
     3696        xfree((void**)third_gauss_area_coord);
     3697        xfree((void**)vert_gauss_coord);
     3698        xfree((void**)area_gauss_weights);
     3699        xfree((void**)vert_gauss_weights);
     3700}
     3701
     3702#undef __FUNCT__
     3703#define __FUNCT__ "Penta::CreatePVectorMelting"
     3704void Penta::CreatePVectorMelting( Vec pg, void* vinputs,int analysis_type,int sub_analysis_type){
     3705        return;
     3706}
     3707
     3708#undef __FUNCT__
     3709#define __FUNCT__ "Penta::GetPhi"
     3710void Penta::GetPhi(double* phi, double*  epsilon, double viscosity){
     3711        /*Compute deformational heating from epsilon and viscosity */
     3712
     3713        double epsilon_matrix[3][3];
     3714        double epsilon_eff;
     3715        double epsilon_sqr[3][3];
     3716
     3717        /* Build epsilon matrix */
     3718        epsilon_matrix[0][0]=*(epsilon+0);
     3719        epsilon_matrix[1][0]=*(epsilon+3);
     3720        epsilon_matrix[2][0]=*(epsilon+4);
     3721        epsilon_matrix[0][1]=*(epsilon+3);
     3722        epsilon_matrix[1][1]=*(epsilon+1);
     3723        epsilon_matrix[2][1]=*(epsilon+5);
     3724        epsilon_matrix[0][2]=*(epsilon+4);
     3725        epsilon_matrix[1][2]=*(epsilon+5);
     3726        epsilon_matrix[2][2]=*(epsilon+2);
     3727
     3728        /* Effective value of epsilon_matrix */
     3729        epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2);
     3730        epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2);
     3731        epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2);
     3732        epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2);
     3733        epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2);
     3734        epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2);
     3735        epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2);
     3736        epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2);
     3737        epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2);
     3738
     3739        epsilon_eff=1/pow(2,1.0/2.0)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),1.0/2.0);
     3740        *phi=2*pow(epsilon_eff,2.0)*viscosity;
     3741}
  • issm/trunk/src/c/objects/Penta.h

    r465 r483  
    130130                void  ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp);
    131131                void  GetNodalFunctionsStokes(double* l1l7, double* gauss_coord);
     132                void  CreateKMatrixThermal(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type);
     133                void  GetB_conduct(double* B_conduct, double* xyz_list, double* gauss_coord);
     134                void  GetB_advec(double* B_advec, double* xyz_list, double* gauss_coord);
     135                void  GetBprime_advec(double* Bprime_advec, double* xyz_list, double* gauss_coord);
     136                void  CreateKMatrixMelting(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type);
     137                void  CreatePVectorThermal( Vec pg, void* vinputs,int analysis_type,int sub_analysis_type);
     138                void  CreatePVectorMelting( Vec pg, void* vinputs,int analysis_type,int sub_analysis_type);
     139                void  GetPhi(double* phi, double*  epsilon, double viscosity);
    132140
    133141
  • issm/trunk/src/c/objects/Tria.cpp

    r465 r483  
    3333
    3434Tria::Tria(int tria_id,int tria_mid,int tria_mparid,int tria_node_ids[3],double tria_h[3],double tria_s[3],double tria_b[3],double tria_k[3],double tria_melting[3],
    35                                 double tria_accumulation[3],int tria_friction_type,double tria_p,double tria_q,int tria_shelf,double tria_meanvel,double tria_epsvel,
     35                                double tria_accumulation[3],double tria_geothermalflux[3],int tria_friction_type,double tria_p,double tria_q,int tria_shelf,double tria_meanvel,double tria_epsvel,
    3636                                double tria_viscosity_overshoot){
    3737       
     
    5151                melting[i]=tria_melting[i];
    5252                accumulation[i]=tria_accumulation[i];
    53         }
     53                geothermalflux[i]=tria_geothermalflux[i]; }
    5454        matice=NULL;
    5555        matice_offset=UNDEF;
     
    8787        printf("   melting=[%g,%g,%g]\n",melting[0],melting[1],melting[2]);
    8888        printf("   accumulation=[%g,%g,%g]\n",accumulation[0],accumulation[1],accumulation[2]);
     89        printf("   geothermalflux=[%g,%g,%g]\n",geothermalflux[0],geothermalflux[1],geothermalflux[2]);
    8990        printf("   friction_type: %i\n",friction_type);
    9091        printf("   p: %g\n",p);
     
    136137        memcpy(marshalled_dataset,&melting,sizeof(melting));marshalled_dataset+=sizeof(melting);
    137138        memcpy(marshalled_dataset,&accumulation,sizeof(accumulation));marshalled_dataset+=sizeof(accumulation);
     139        memcpy(marshalled_dataset,&geothermalflux,sizeof(geothermalflux));marshalled_dataset+=sizeof(geothermalflux);
    138140        memcpy(marshalled_dataset,&friction_type,sizeof(friction_type));marshalled_dataset+=sizeof(friction_type);
    139141        memcpy(marshalled_dataset,&onbed,sizeof(onbed));marshalled_dataset+=sizeof(onbed);
     
    166168                +sizeof(melting)
    167169                +sizeof(accumulation)
     170                +sizeof(geothermalflux)
    168171                +sizeof(friction_type)
    169172                +sizeof(onbed)
     
    208211        memcpy(&melting,marshalled_dataset,sizeof(melting));marshalled_dataset+=sizeof(melting);
    209212        memcpy(&accumulation,marshalled_dataset,sizeof(accumulation));marshalled_dataset+=sizeof(accumulation);
     213        memcpy(&geothermalflux,marshalled_dataset,sizeof(geothermalflux));marshalled_dataset+=sizeof(geothermalflux);
    210214        memcpy(&friction_type,marshalled_dataset,sizeof(friction_type));marshalled_dataset+=sizeof(friction_type);
    211215        memcpy(&onbed,marshalled_dataset,sizeof(onbed));marshalled_dataset+=sizeof(onbed);
     
    264268
    265269#undef __FUNCT__
    266 #define __FUNCT__ "Tria::CreateKMatrix"
     270#define __FUNCT__ "Tria::reateKMatrix"
    267271
    268272void  Tria::CreateKMatrix(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type){
     
    305309        /* node data: */
    306310        const int    numgrids=3;
    307         const int    numdofs=2*numgrids;
     311        const int    numdof=2*numgrids;
    308312        double       xyz_list[numgrids][3];
    309         int          doflist[numdofs];
     313        int          doflist[numdof];
    310314        int          numberofdofspernode;
    311315       
     
    329333
    330334        /* matrices: */
    331         double B[3][numdofs];
    332         double Bprime[3][numdofs];
     335        double B[3][numdof];
     336        double Bprime[3][numdof];
    333337        double D[3][3]={{ 0,0,0 },{0,0,0},{0,0,0}};              // material matrix, simple scalar matrix.
    334338        double D_scalar;
    335339
    336340        /* local element matrices: */
    337         double Ke_gg[numdofs][numdofs]; //local element stiffness matrix
    338         double Ke_gg_gaussian[numdofs][numdofs]; //stiffness matrix evaluated at the gaussian point.
     341        double Ke_gg[numdof][numdof]; //local element stiffness matrix
     342        double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
    339343       
    340344        double Jdet;
     
    360364
    361365        /* Set Ke_gg to 0: */
    362         for(i=0;i<numdofs;i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]=0.0;
     366        for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]=0.0;
    363367
    364368        #ifdef _DEBUGELEMENTS_
     
    447451
    448452                /*  Do the triple product tB*D*Bprime: */
    449                 TripleMultiply( &B[0][0],3,numdofs,1,
     453                TripleMultiply( &B[0][0],3,numdof,1,
    450454                                          &D[0][0],3,3,0,
    451                                           &Bprime[0][0],3,numdofs,0,
     455                                          &Bprime[0][0],3,numdof,0,
    452456                                          &Ke_gg_gaussian[0][0],0);
    453457
    454458                /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
    455                 for( i=0; i<numdofs; i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
     459                for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
    456460               
    457461                #ifdef _DEBUGELEMENTS_
     
    459463                        printf("      B:\n");
    460464                        for(i=0;i<3;i++){
    461                                 for(j=0;j<numdofs;j++){
     465                                for(j=0;j<numdof;j++){
    462466                                        printf("%g ",B[i][j]);
    463467                                }
     
    466470                        printf("      Bprime:\n");
    467471                        for(i=0;i<3;i++){
    468                                 for(j=0;j<numdofs;j++){
     472                                for(j=0;j<numdof;j++){
    469473                                        printf("%g ",Bprime[i][j]);
    470474                                }
     
    476480
    477481        /*Add Ke_gg to global matrix Kgg: */
    478         MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
     482        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
    479483
    480484
     
    488492        if(my_rank==RANK && id==ELID){
    489493                printf("      Ke_gg erms:\n");
    490                 for( i=0; i<numdofs; i++){
    491                         for (j=0;j<numdofs;j++){
     494                for( i=0; i<numdof; i++){
     495                        for (j=0;j<numdof;j++){
    492496                                printf("%g ",Ke_gg[i][j]);
    493497                        }
     
    495499                }
    496500                printf("      Ke_gg row_indices:\n");
    497                 for( i=0; i<numdofs; i++){
     501                for( i=0; i<numdof; i++){
    498502                        printf("%i ",doflist[i]);
    499503                }
     
    520524        /* node data: */
    521525        const int    numgrids=3;
    522         const int    numdofs=2*numgrids;
     526        const int    numdof=2*numgrids;
    523527        double       xyz_list[numgrids][3];
    524         int          doflist[numdofs];
     528        int          doflist[numdof];
    525529        int          numberofdofspernode;
    526530       
     
    535539
    536540        /* matrices: */
    537         double L[2][numdofs];
     541        double L[2][numdof];
    538542        double DL[2][2]={{ 0,0 },{0,0}}; //for basal drag
    539543        double DL_scalar;
    540544
    541545        /* local element matrices: */
    542         double Ke_gg[numdofs][numdofs]; //local element stiffness matrix
    543         double Ke_gg_gaussian[numdofs][numdofs]; //stiffness matrix contribution from drag
     546        double Ke_gg[numdof][numdof]; //local element stiffness matrix
     547        double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix contribution from drag
    544548       
    545549        double Jdet;
     
    570574
    571575        /* Set Ke_gg to 0: */
    572         for(i=0;i<numdofs;i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]=0.0;
     576        for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]=0.0;
    573577
    574578        if (shelf){
     
    658662               
    659663                /*  Do the triple producte tL*D*L: */
    660                 TripleMultiply( &L[0][0],2,numdofs,1,
     664                TripleMultiply( &L[0][0],2,numdof,1,
    661665                                        &DL[0][0],2,2,0,
    662                                         &L[0][0],2,numdofs,0,
     666                                        &L[0][0],2,numdof,0,
    663667                                        &Ke_gg_gaussian[0][0],0);
    664668
    665                 for( i=0; i<numdofs; i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
     669                for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
    666670
    667671        } // for (ig=0; ig<num_gauss; ig++)
    668672
    669673        /*Add Ke_gg to global matrix Kgg: */
    670         MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
     674        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
    671675
    672676        cleanup_and_return:
     
    689693        const int    numgrids=3;
    690694        const int    NDOF1=1;
    691         const int    numdofs=NDOF1*numgrids;
     695        const int    numdof=NDOF1*numgrids;
    692696        double       xyz_list[numgrids][3];
    693         int          doflist[numdofs];
     697        int          doflist[numdof];
    694698        int          numberofdofspernode;
    695699       
     
    708712
    709713        /* local element matrices: */
    710         double Ke_gg[numdofs][numdofs]; //local element stiffness matrix
    711         double Ke_gg_gaussian[numdofs][numdofs]; //stiffness matrix evaluated at the gaussian point.
     714        double Ke_gg[numdof][numdof]; //local element stiffness matrix
     715        double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
    712716       
    713717        double Jdet;
     
    718722
    719723        /* Set Ke_gg to 0: */
    720         for(i=0;i<numdofs;i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]=0.0;
     724        for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]=0.0;
    721725
    722726        /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
     
    747751
    748752                /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */
    749                 for( i=0; i<numdofs; i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
     753                for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
    750754        } //for (ig=0; ig<num_gauss; ig++
    751755
    752756        /*Add Ke_gg to global matrix Kgg: */
    753         MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
     757        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
    754758               
    755759        cleanup_and_return:
     
    790794#undef __FUNCT__
    791795#define __FUNCT__ "Tria::CreatePVectorDiagnosticHoriz"
    792 
    793796void Tria::CreatePVectorDiagnosticHoriz( Vec pg, void* vinputs, int analysis_type,int sub_analysis_type){
    794797
     
    797800        /* node data: */
    798801        const int    numgrids=3;
    799         const int    numdofs=2*numgrids;
     802        const int    numdof=2*numgrids;
    800803        const int    NDOF2=2;
    801804        double       xyz_list[numgrids][3];
    802         int          doflist[numdofs];
     805        int          doflist[numdof];
    803806        int          numberofdofspernode;
    804807       
     
    824827
    825828        /*element vector at the gaussian points: */
    826         double  pe_g[numdofs];
    827         double  pe_g_gaussian[numdofs];
     829        double  pe_g[numdof];
     830        double  pe_g_gaussian[numdof];
    828831
    829832        /*input parameters for structural analysis (diagnostic): */
     
    840843
    841844        /* Set pe_g to 0: */
    842         for(i=0;i<numdofs;i++) pe_g[i]=0.0;
     845        for(i=0;i<numdof;i++) pe_g[i]=0.0;
    843846
    844847
     
    927930
    928931                /*Add pe_g_gaussian vector to pe_g: */
    929                 for( i=0; i<numdofs; i++)pe_g[i]+=pe_g_gaussian[i];
     932                for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
    930933
    931934        } //for (ig=0; ig<num_gauss; ig++)
     
    946949
    947950        /*Add pe_g to global vector pg: */
    948         VecSetValues(pg,numdofs,doflist,(const double*)pe_g,ADD_VALUES);
     951        VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
    949952
    950953        cleanup_and_return:
     
    966969        const int    numgrids=3;
    967970        const int    NDOF1=1;
    968         const int    numdofs=NDOF1*numgrids;
     971        const int    numdof=NDOF1*numgrids;
    969972        double       xyz_list[numgrids][3];
    970         int          doflist[numdofs];
     973        int          doflist[numdof];
    971974        int          numberofdofspernode;
    972975       
     
    987990
    988991        /*element vector at the gaussian points: */
    989         double  pe_g[numdofs];
    990         double  pe_g_gaussian[numdofs];
     992        double  pe_g[numdof];
     993        double  pe_g_gaussian[numdof];
    991994        double  param[3];
    992995        double  slope[2];
     
    9971000
    9981001        /* Set pe_g to 0: */
    999         for(i=0;i<numdofs;i++) pe_g[i]=0.0;
     1002        for(i=0;i<numdof;i++) pe_g[i]=0.0;
    10001003
    10011004        if ( (sub_analysis_type==SurfaceXAnalysisEnum()) || (sub_analysis_type==SurfaceYAnalysisEnum())){
    1002                 for(i=0;i<numdofs;i++) param[i]=s[i];
     1005                for(i=0;i<numdof;i++) param[i]=s[i];
    10031006        }
    10041007        if ( (sub_analysis_type==BedXAnalysisEnum()) || (sub_analysis_type==BedYAnalysisEnum())){
    1005                 for(i=0;i<numdofs;i++) param[i]=b[i];
     1008                for(i=0;i<numdof;i++) param[i]=b[i];
    10061009        }
    10071010
     
    10281031                /*Build pe_g_gaussian vector: */
    10291032                if ( (sub_analysis_type==SurfaceXAnalysisEnum()) || (sub_analysis_type==BedXAnalysisEnum())){
    1030                         for(i=0;i<numdofs;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[0]*l1l2l3[i];
     1033                        for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[0]*l1l2l3[i];
    10311034                }
    10321035                if ( (sub_analysis_type==SurfaceYAnalysisEnum()) || (sub_analysis_type==BedYAnalysisEnum())){
    1033                         for(i=0;i<numdofs;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[1]*l1l2l3[i];
     1036                        for(i=0;i<numdof;i++) pe_g_gaussian[i]=Jdet*gauss_weight*slope[1]*l1l2l3[i];
    10341037                }
    10351038
    10361039                /*Add pe_g_gaussian vector to pe_g: */
    1037                 for( i=0; i<numdofs; i++)pe_g[i]+=pe_g_gaussian[i];
     1040                for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
    10381041
    10391042        } //for (ig=0; ig<num_gauss; ig++)
    10401043
    10411044        /*Add pe_g to global vector pg: */
    1042         VecSetValues(pg,numdofs,doflist,(const double*)pe_g,ADD_VALUES);
     1045        VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
    10431046
    10441047        cleanup_and_return:
     
    10711074        inputs->Recover("drag",&k[0],1,dofs,3,(void**)nodes);
    10721075        inputs->Recover("melting",&melting[0],1,dofs,3,(void**)nodes);
    1073         inputs->Recover("accumulation_param",&accumulation[0],1,dofs,3,(void**)nodes);
     1076        inputs->Recover("accumulation",&accumulation[0],1,dofs,3,(void**)nodes);
     1077        inputs->Recover("geothermalflux",&geothermalflux[0],1,dofs,3,(void**)nodes);
    10741078       
    10751079        //Update material if necessary
     
    15561560        /* node data: */
    15571561        const int    numgrids=3;
    1558         const int    numdofs=2*numgrids;
     1562        const int    numdof=2*numgrids;
    15591563        const int    NDOF2=2;
    15601564        double       xyz_list[numgrids][3];
    1561         int          doflist[numdofs];
     1565        int          doflist[numdof];
    15621566        int          numberofdofspernode;
    15631567
     
    15881592
    15891593        /*element vector : */
    1590         double  due_g[numdofs];
    1591         double  due_g_gaussian[numdofs];
     1594        double  due_g[numdof];
     1595        double  due_g_gaussian[numdof];
    15921596
    15931597        /* Jacobian: */
     
    16131617
    16141618        /* Set due_g to 0: */
    1615         for(i=0;i<numdofs;i++) due_g[i]=0.0;
     1619        for(i=0;i<numdof;i++) due_g[i]=0.0;
    16161620
    16171621        /* Recover input data: */
     
    17351739               
    17361740                /*Add due_g_gaussian vector to due_g: */
    1737                 for( i=0; i<numdofs; i++){
     1741                for( i=0; i<numdof; i++){
    17381742                        due_g[i]+=due_g_gaussian[i];
    17391743                }
     
    17411745       
    17421746        /*Add due_g to global vector du_g: */
    1743         VecSetValues(du_g,numdofs,doflist,(const double*)due_g,ADD_VALUES);
     1747        VecSetValues(du_g,numdof,doflist,(const double*)due_g,ADD_VALUES);
    17441748       
    17451749        cleanup_and_return:
     
    17731777        const int    numgrids=3;
    17741778        const int    NDOF2=2;
    1775         const int    numdofs=NDOF2*numgrids;
     1779        const int    numdof=NDOF2*numgrids;
    17761780        double       xyz_list[numgrids][3];
    1777         int          doflist[numdofs];
     1781        int          doflist[numdof];
    17781782        int          numberofdofspernode;
    17791783
     
    18141818
    18151819        /*element vector at the gaussian points: */
    1816         double  grade_g[numdofs];
     1820        double  grade_g[numdof];
    18171821        double  grade_g_gaussian[numgrids];
    18181822
     
    18361840
    18371841        /* Set grade_g to 0: */
    1838         for(i=0;i<numdofs;i++) grade_g[i]=0.0;
     1842        for(i=0;i<numdof;i++) grade_g[i]=0.0;
    18391843
    18401844        /* recover input parameters: */
     
    19471951
    19481952        /*Add grade_g to global vector grad_g: */
    1949         VecSetValues(grad_g,numdofs,doflist,(const double*)grade_g,ADD_VALUES);
     1953        VecSetValues(grad_g,numdof,doflist,(const double*)grade_g,ADD_VALUES);
    19501954       
    19511955        cleanup_and_return:
     
    19671971        const int    NDOF1=1;
    19681972        const int    NDOF2=2;
    1969         const int    numdofs=NDOF2*numgrids;
     1973        const int    numdof=NDOF2*numgrids;
    19701974        double       xyz_list[numgrids][3];
    1971         int          doflist[numdofs];
     1975        int          doflist[numdof];
    19721976        int          numberofdofspernode;
    19731977
     
    19891993
    19901994        /*element vector at the gaussian points: */
    1991         double  grade_g[numdofs];
     1995        double  grade_g[numdof];
    19921996        double  grade_g_gaussian[numgrids];
    19931997
     
    20232027
    20242028        /* Set grade_g to 0: */
    2025         for(i=0;i<numdofs;i++) grade_g[i]=0.0;
     2029        for(i=0;i<numdof;i++) grade_g[i]=0.0;
    20262030
    20272031        /* recover input parameters: */
     
    20882092       
    20892093        /*Add grade_g to global vector grad_g: */
    2090         VecSetValues(grad_g,numdofs,doflist,(const double*)grade_g,ADD_VALUES);
     2094        VecSetValues(grad_g,numdof,doflist,(const double*)grade_g,ADD_VALUES);
    20912095       
    20922096        cleanup_and_return:
     
    21092113        /* node data: */
    21102114        const int    numgrids=3;
    2111         const int    numdofs=2*numgrids;
     2115        const int    numdof=2*numgrids;
    21122116        const int    NDOF2=2;
    21132117        double       xyz_list[numgrids][3];
    2114         int          doflist[numdofs];
     2118        int          doflist[numdof];
    21152119        int          numberofdofspernode;
    21162120
     
    22912295        const int    numgrids=3;
    22922296        const int    NDOF1=1;
    2293         const int    numdofs=NDOF1*numgrids;
     2297        const int    numdof=NDOF1*numgrids;
    22942298        double       xyz_list[numgrids][3];
    2295         int          doflist[numdofs];
     2299        int          doflist[numdof];
    22962300        int          numberofdofspernode;
    22972301
     
    23222326
    23232327        /* local element matrices: */
    2324         double Ke_gg[numdofs][numdofs]; //local element stiffness matrix
    2325         double Ke_gg_gaussian[numdofs][numdofs]; //stiffness matrix evaluated at the gaussian point.
     2328        double Ke_gg[numdof][numdof]; //local element stiffness matrix
     2329        double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point.
    23262330
    23272331        ParameterInputs* inputs=NULL;
     
    23352339
    23362340        /* Set Ke_gg to 0: */
    2337         for(i=0;i<numdofs;i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]=0.0;
     2341        for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]=0.0;
    23382342
    23392343        /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
     
    23942398
    23952399                /* Add the Ke_gg_gaussian, onto Ke_gg: */
    2396                 for( i=0; i<numdofs; i++) for(j=0;j<numdofs;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
     2400                for( i=0; i<numdof; i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];
    23972401
    23982402               
     
    24002404
    24012405        /*Add Ke_gg to global matrix Kgg: */
    2402         MatSetValues(Kgg,numdofs,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);
     2406        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES);
    24032407       
    24042408        cleanup_and_return:
     
    24192423        const int    numgrids=3;
    24202424        const int    NDOF1=1;
    2421         const int    numdofs=NDOF1*numgrids;
     2425        const int    numdof=NDOF1*numgrids;
    24222426        double       xyz_list[numgrids][3];
    2423         int          doflist[numdofs];
     2427        int          doflist[numdof];
    24242428        int          numberofdofspernode;
    24252429       
     
    24402444
    24412445        /*element vector at the gaussian points: */
    2442         double  pe_g[numdofs];
    2443         double  pe_g_gaussian[numdofs];
     2446        double  pe_g[numdof];
     2447        double  pe_g_gaussian[numdof];
    24442448
    24452449        /* matrices: */
     
    24712475
    24722476        /* Set pe_g to 0: */
    2473         for(i=0;i<numdofs;i++) pe_g[i]=0.0;
     2477        for(i=0;i<numdof;i++) pe_g[i]=0.0;
    24742478
    24752479        /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
     
    25112515       
    25122516                /*Add pe_g_gaussian vector to pe_g: */
    2513                 for( i=0; i<numdofs; i++)pe_g[i]+=pe_g_gaussian[i];
     2517                for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i];
    25142518       
    25152519        }
    25162520
    25172521        /*Add pe_g to global vector pg: */
    2518         VecSetValues(pg,numdofs,doflist,(const double*)pe_g,ADD_VALUES);
     2522        VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES);
    25192523
    25202524        cleanup_and_return:
     
    25502554
    25512555}
     2556
     2557#undef __FUNCT__
     2558#define __FUNCT__ "Tria::CreateKMatrixThermal"
     2559void  Tria::CreateKMatrixThermal(Mat Kgg,void* vinputs,int analysis_type,int sub_analysis_type){
     2560
     2561        int i,j;
     2562        int found=0;
     2563       
     2564        /* node data: */
     2565        const int    numgrids=3;
     2566        const int    NDOF1=1;
     2567        const int    numdof=NDOF1*numgrids;
     2568        double       xyz_list[numgrids][3];
     2569        int          doflist[numdof];
     2570        int          numberofdofspernode;
     2571
     2572        double mixed_layer_capacity;
     2573        double thermal_exchange_velocity;
     2574        double rho_water;
     2575        double rho_ice;
     2576        double heatcapacity;
     2577        double dt;
     2578
     2579        int     num_gauss,ig;
     2580        double* first_gauss_area_coord  =  NULL;
     2581        double* second_gauss_area_coord =  NULL;
     2582        double* third_gauss_area_coord  =  NULL;
     2583        double* gauss_weights           =  NULL;
     2584        double  gauss_weight;
     2585        double  gauss_coord[3];
     2586
     2587        /*matrices: */
     2588        double  Jdet;
     2589        double  K_terms[numdof][numdof]={0.0};
     2590        double  Ke_gaussian[numdof][numdof]={0.0};
     2591        double  l1l2l3[numgrids];
     2592        double     tl1l2l3D[3];
     2593        double  D_scalar;
     2594        ParameterInputs* inputs=NULL;
     2595
     2596        /*recover pointers: */
     2597        inputs=(ParameterInputs*)vinputs;
     2598
     2599        /*recover extra inputs from users, dt: */
     2600        inputs->Recover("dt",&dt);
     2601        if(!found)throw ErrorException(__FUNCT__," could not find dt in inputs!");
     2602
     2603        /* Get node coordinates and dof list: */
     2604        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     2605        GetDofList(&doflist[0],&numberofdofspernode);
     2606
     2607        //recover material parameters
     2608        mixed_layer_capacity=matpar->GetMixedLayerCapacity();
     2609        thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
     2610        rho_water=matpar->GetRhoWater();
     2611        rho_ice=matpar->GetRhoIce();
     2612        heatcapacity=matpar->GetHeatCapacity();
     2613
     2614
     2615        GaussTria (&num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
     2616
     2617        /* Start looping on the number of gauss (nodes on the bedrock) */
     2618        for (ig=0; ig<num_gauss; ig++){
     2619                gauss_weight=*(gauss_weights+ig);
     2620                gauss_coord[0]=*(first_gauss_area_coord+ig);
     2621                gauss_coord[1]=*(second_gauss_area_coord+ig);
     2622                gauss_coord[2]=*(third_gauss_area_coord+ig);
     2623               
     2624                //Get the Jacobian determinant
     2625                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);
     2626               
     2627                /*Get nodal functions values: */
     2628                GetNodalFunctions(&l1l2l3[0], gauss_coord);
     2629                               
     2630                /*Calculate DL on gauss point */
     2631                D_scalar=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(heatcapacity*rho_ice);
     2632                if(sub_analysis_type!=SteadyAnalysisEnum()){
     2633                        D_scalar=dt*D_scalar;
     2634                }
     2635
     2636                /*  Do the triple product tL*D*L: */
     2637                MatrixMultiply(&l1l2l3[0],numdof,1,0,&D_scalar,1,1,0,&tl1l2l3D[0],0);
     2638                MatrixMultiply(&tl1l2l3D[0],numdof,1,0,&l1l2l3[0],1,numdof,0,&Ke_gaussian[0][0],0);
     2639
     2640                for(i=0;i<3;i++){
     2641                        for(j=0;j<3;j++){
     2642                                K_terms[i][j]+=Ke_gaussian[i][j];
     2643                        }
     2644                }
     2645        }
     2646       
     2647        /*Add Ke_gg to global matrix Kgg: */
     2648        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
     2649
     2650        cleanup_and_return:
     2651        xfree((void**)&first_gauss_area_coord);
     2652        xfree((void**)&second_gauss_area_coord);
     2653        xfree((void**)&third_gauss_area_coord);
     2654        xfree((void**)&gauss_weights);
     2655
     2656}
     2657
     2658
     2659#undef __FUNCT__
     2660#define __FUNCT__ "Tria::CreateKMatrixMelting"
     2661void  Tria::CreateKMatrixMelting(Mat Kgg,void* vinputs,int analysis_type,int sub_analysis_type){
     2662       
     2663        /*indexing: */
     2664        int i,j;
     2665
     2666        const int  numgrids=3;
     2667        const int  NDOF1=1;
     2668        const int  numdof=numgrids*NDOF1;
     2669        int        doflist[numdof];
     2670        int        numberofdofspernode;
     2671
     2672        /*Grid data: */
     2673        double     xyz_list[numgrids][3];
     2674               
     2675        /*Material constants */
     2676        double     heatcapacity,latentheat;
     2677
     2678        /* gaussian points: */
     2679        int     num_area_gauss,ig;
     2680        double* gauss_weights  =  NULL;
     2681        double* first_gauss_area_coord  =  NULL;
     2682        double* second_gauss_area_coord =  NULL;
     2683        double* third_gauss_area_coord  =  NULL;
     2684        double  gauss_weight;
     2685        double  gauss_coord[3];
     2686
     2687        /*matrices: */
     2688        double     Jdet;
     2689        double     D_scalar;
     2690        double     K_terms[numdof][numdof]={0.0};
     2691        double     L[3];
     2692        double     tLD[3];
     2693        double     Ke_gaussian[numdof][numdof]={0.0};
     2694
     2695        /*Recover constants of ice */
     2696        latentheat=matpar->GetLatentHeat();
     2697        heatcapacity=matpar->GetHeatCapacity();
     2698
     2699        /* Get node coordinates and dof list: */
     2700        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     2701        GetDofList(&doflist[0],&numberofdofspernode);
     2702
     2703        /* Get gaussian points and weights: */
     2704        GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
     2705
     2706        /* Start looping on the number of gauss  (nodes on the bedrock) */
     2707        for (ig=0; ig<num_area_gauss; ig++){
     2708                gauss_weight=*(gauss_weights+ig);
     2709                gauss_coord[0]=*(first_gauss_area_coord+ig);
     2710                gauss_coord[1]=*(second_gauss_area_coord+ig);
     2711                gauss_coord[2]=*(third_gauss_area_coord+ig);
     2712               
     2713                //Get the Jacobian determinant
     2714                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);
     2715               
     2716                /*Get L matrix : */
     2717                GetL(&L[0], &xyz_list[0][0], gauss_coord,NDOF1);
     2718                               
     2719                /*Calculate DL on gauss point */
     2720                D_scalar=latentheat/heatcapacity*gauss_weight*Jdet;
     2721
     2722                /*  Do the triple product tL*D*L: */
     2723                MatrixMultiply(&L[0],numdof,1,0,&D_scalar,1,1,0,&tLD[0],0);
     2724                MatrixMultiply(&tLD[0],numdof,1,0,&L[0],1,numdof,0,&Ke_gaussian[0][0],0);
     2725
     2726                for(i=0;i<numgrids;i++){
     2727                        for(j=0;j<numgrids;j++){
     2728                        K_terms[i][j]+=Ke_gaussian[i][j];
     2729                        }
     2730                }
     2731        }
     2732       
     2733        /*Add Ke_gg to global matrix Kgg: */
     2734        MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES);
     2735
     2736        cleanup_and_return:
     2737        xfree((void**)&first_gauss_area_coord);
     2738        xfree((void**)&second_gauss_area_coord);
     2739        xfree((void**)&third_gauss_area_coord);
     2740        xfree((void**)&gauss_weights);
     2741
     2742}
     2743
     2744
     2745#undef __FUNCT__
     2746#define __FUNCT__ "Tria::CreatePVectorThermalShelf"
     2747void Tria::CreatePVectorThermalShelf( Vec pg, void* vinputs, int analysis_type,int sub_analysis_type){
     2748
     2749        int i,found;
     2750       
     2751        const int  numgrids=3;
     2752        const int  NDOF1=1;
     2753        const int  numdof=numgrids*NDOF1;
     2754        int        doflist[numdof];
     2755        int        numberofdofspernode;
     2756        double       xyz_list[numgrids][3];
     2757
     2758        double mixed_layer_capacity;
     2759        double thermal_exchange_velocity;
     2760        double rho_water;
     2761        double rho_ice;
     2762        double heatcapacity;
     2763        double beta;
     2764        double meltingpoint;
     2765
     2766        /*inputs: */
     2767        double dt;
     2768        double pressure_list[3];
     2769        double pressure;
     2770
     2771        /* gaussian points: */
     2772        int     num_area_gauss,ig;
     2773        double* gauss_weights  =  NULL;
     2774        double* first_gauss_area_coord  =  NULL;
     2775        double* second_gauss_area_coord =  NULL;
     2776        double* third_gauss_area_coord  =  NULL;
     2777        double  gauss_weight;
     2778        double  gauss_coord[3];
     2779        int     dofs1[1]={0};
     2780
     2781        /*matrices: */
     2782        double  Jdet;
     2783        double  P_terms[numdof];
     2784        double  l1l2l3[numgrids];
     2785
     2786        double  t_pmp;
     2787        double  scalar_ocean;
     2788
     2789        ParameterInputs* inputs=NULL;
     2790
     2791        /*recover pointers: */
     2792        inputs=(ParameterInputs*)vinputs;
     2793       
     2794        /* Get node coordinates and dof list: */
     2795        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     2796        GetDofList(&doflist[0],&numberofdofspernode);
     2797
     2798        //recover material parameters
     2799        mixed_layer_capacity=matpar->GetMixedLayerCapacity();
     2800        thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();
     2801        rho_water=matpar->GetRhoWater();
     2802        rho_ice=matpar->GetRhoIce();
     2803        heatcapacity=matpar->GetHeatCapacity();
     2804        beta=matpar->GetBeta();
     2805        meltingpoint=matpar->GetMeltingPoint();
     2806
     2807
     2808        /*recover extra inputs from users, dt and velocity: */
     2809        found=inputs->Recover("dt",&dt);
     2810        if((!found) && (sub_analysis_type==TransientAnalysisEnum()))throw ErrorException(__FUNCT__," could not find dt in inputs!");
     2811       
     2812        found=inputs->Recover("pressure",&pressure_list[0],1,dofs1,numgrids,(void**)nodes);
     2813        if(!found)throw ErrorException(__FUNCT__," could not find pressure in inputs!");
     2814
     2815        /* Ice/ocean heat exchange flux on ice shelf base */
     2816
     2817        GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
     2818
     2819        /* Start looping on the number of gauss 2d (nodes on the bedrock) */
     2820        for (ig=0; ig<num_area_gauss; ig++){
     2821                gauss_weight=*(gauss_weights+ig);
     2822                gauss_coord[0]=*(first_gauss_area_coord+ig);
     2823                gauss_coord[1]=*(second_gauss_area_coord+ig);
     2824                gauss_coord[2]=*(third_gauss_area_coord+ig);
     2825
     2826                //Get the Jacobian determinant
     2827                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);
     2828
     2829                /*Get nodal functions values: */
     2830                GetNodalFunctions(&l1l2l3[0], gauss_coord);
     2831
     2832                /*Get geothermal flux and basal friction */
     2833                GetParameterValue(&pressure,&pressure_list[0],gauss_coord);
     2834                t_pmp=meltingpoint-beta*pressure;
     2835
     2836                /*Calculate scalar parameter*/
     2837                scalar_ocean=gauss_weight*Jdet*rho_water*mixed_layer_capacity*thermal_exchange_velocity*t_pmp/(heatcapacity*rho_ice);
     2838                if(sub_analysis_type==TransientAnalysisEnum()){
     2839                        scalar_ocean=dt*scalar_ocean;
     2840                }
     2841
     2842                for(i=0;i<3;i++){
     2843                        P_terms[i]+=scalar_ocean*l1l2l3[i];
     2844                }
     2845        }
     2846
     2847        /*Add pe_g to global vector pg: */
     2848        VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
     2849
     2850        cleanup_and_return:
     2851        xfree((void**)&first_gauss_area_coord);
     2852        xfree((void**)&second_gauss_area_coord);
     2853        xfree((void**)&third_gauss_area_coord);
     2854        xfree((void**)&gauss_weights);
     2855
     2856}
     2857#undef __FUNCT__
     2858#define __FUNCT__ "Tria::CreatePVectorThermalSheet"
     2859void Tria::CreatePVectorThermalSheet( Vec pg, void* vinputs, int analysis_type,int sub_analysis_type){
     2860
     2861        int i,found;
     2862       
     2863        const int  numgrids=3;
     2864        const int  NDOF1=1;
     2865        const int  numdof=numgrids*NDOF1;
     2866        int        doflist[numdof];
     2867        int        numberofdofspernode;
     2868        double       xyz_list[numgrids][3];
     2869        double     vxvyvz_list[numgrids][3];
     2870        double     vx_list[numgrids];
     2871        double     vy_list[numgrids];
     2872
     2873        double rho_ice;
     2874        double heatcapacity;
     2875
     2876        /*inputs: */
     2877        double dt;
     2878        double pressure_list[3];
     2879        double pressure;
     2880        double alpha2_list[3];
     2881        double basalfriction_list[3];
     2882        double basalfriction;
     2883        double geothermalflux_value;
     2884
     2885        /* gaussian points: */
     2886        int     num_area_gauss,ig;
     2887        double* gauss_weights  =  NULL;
     2888        double* first_gauss_area_coord  =  NULL;
     2889        double* second_gauss_area_coord =  NULL;
     2890        double* third_gauss_area_coord  =  NULL;
     2891        double  gauss_weight;
     2892        double  gauss_coord[3];
     2893        int     dofs1[1]={0};
     2894
     2895        /*matrices: */
     2896        double  Jdet;
     2897        double  P_terms[numdof];
     2898        double  l1l2l3[numgrids];
     2899        double  scalar;
     2900
     2901        int     dofs[3]={0,1,2};
     2902
     2903        ParameterInputs* inputs=NULL;
     2904
     2905        /*recover pointers: */
     2906        inputs=(ParameterInputs*)vinputs;
     2907       
     2908        /* Get node coordinates and dof list: */
     2909        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     2910        GetDofList(&doflist[0],&numberofdofspernode);
     2911
     2912        //recover material parameters
     2913        rho_ice=matpar->GetRhoIce();
     2914        heatcapacity=matpar->GetHeatCapacity();
     2915
     2916
     2917        /*recover extra inputs from users, dt and velocity: */
     2918        found=inputs->Recover("dt",&dt);
     2919        if((!found) && (sub_analysis_type==TransientAnalysisEnum()))throw ErrorException(__FUNCT__," could not find dt in inputs!");
     2920       
     2921        found=inputs->Recover("velocity",&vxvyvz_list[0][0],3,dofs,numgrids,(void**)nodes);
     2922        if(!found)throw ErrorException(__FUNCT__," could not find velocity in inputs!");
     2923
     2924        for(i=0;i<numgrids;i++){
     2925                vx_list[i]=vxvyvz_list[i][0];
     2926                vy_list[i]=vxvyvz_list[i][1];
     2927        }       
     2928
     2929        /*Build alpha2_list used by drag stiffness matrix*/
     2930        Friction* friction=NewFriction();
     2931       
     2932        /*Initialize all fields: */
     2933        if (friction_type!=2)throw ErrorException(__FUNCT__," non-viscous friction not supported yet!");
     2934       
     2935        friction->element_type=(char*)xmalloc((strlen("3d")+1)*sizeof(char));
     2936        strcpy(friction->element_type,"3d");
     2937       
     2938        friction->gravity=matpar->GetG();
     2939        friction->rho_ice=matpar->GetRhoIce();
     2940        friction->rho_water=matpar->GetRhoWater();
     2941        friction->K=&k[0];
     2942        friction->bed=&b[0];
     2943        friction->thickness=&h[0];
     2944        friction->velocities=&vxvyvz_list[0][0];
     2945        friction->p=p;
     2946        friction->q=q;
     2947
     2948        /*Compute alpha2_list: */
     2949        FrictionGetAlpha2(&alpha2_list[0],friction);
     2950
     2951        /*Erase friction object: */
     2952        DeleteFriction(&friction);
     2953
     2954        /* Compute basal friction */
     2955        for(i=0;i<numgrids;i++){
     2956                basalfriction_list[i]= alpha2_list[i]*(pow(vx_list[i],2.0)+pow(vy_list[i],2.0));
     2957        }
     2958       
     2959        /* Ice/ocean heat exchange flux on ice shelf base */
     2960        GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
     2961
     2962        /* Start looping on the number of gauss 2d (nodes on the bedrock) */
     2963        for (ig=0; ig<num_area_gauss; ig++){
     2964                gauss_weight=*(gauss_weights+ig);
     2965                gauss_coord[0]=*(first_gauss_area_coord+ig);
     2966                gauss_coord[1]=*(second_gauss_area_coord+ig);
     2967                gauss_coord[2]=*(third_gauss_area_coord+ig);
     2968
     2969                //Get the Jacobian determinant
     2970                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0], gauss_coord);
     2971
     2972                /*Get nodal functions values: */
     2973                GetNodalFunctions(&l1l2l3[0], gauss_coord);
     2974
     2975                /*Get geothermal flux and basal friction */
     2976                GetParameterValue(&geothermalflux_value,&geothermalflux[0],gauss_coord);
     2977                GetParameterValue(&basalfriction,&basalfriction_list[0],gauss_coord);
     2978
     2979                /*Calculate scalar parameter*/
     2980                scalar=gauss_weight*Jdet*(basalfriction+geothermalflux_value)/(heatcapacity*rho_ice);
     2981                if(sub_analysis_type==TransientAnalysisEnum()){
     2982                        scalar=dt*scalar;
     2983                }
     2984
     2985                for(i=0;i<3;i++){
     2986                        P_terms[i]+=scalar*l1l2l3[i];
     2987                }
     2988        }
     2989
     2990        /*Add pe_g to global vector pg: */
     2991        VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES);
     2992
     2993        cleanup_and_return:
     2994        xfree((void**)&first_gauss_area_coord);
     2995        xfree((void**)&second_gauss_area_coord);
     2996        xfree((void**)&third_gauss_area_coord);
     2997        xfree((void**)&gauss_weights);
     2998
     2999}
     3000
     3001
  • issm/trunk/src/c/objects/Tria.h

    r465 r483  
    4040                double melting[3];
    4141                double accumulation[3];
     42                double geothermalflux[3];
    4243                int    friction_type;
    4344                double p;
     
    5253
    5354                Tria();
    54                 Tria(int id,int mid,int mparid,int node_ids[3],double h[3],double s[3],double b[3],double k[3],double melting[3],double accumulation[3],
     55                Tria(int id,int mid,int mparid,int node_ids[3],double h[3],double s[3],double b[3],double k[3],double melting[3],double accumulation[3],double geothermalflux[3],
    5556                                int friction_type,double p,double q,int shelf,double meanvel,double epsvel,double viscosity_overshoot);
    5657                ~Tria();
     
    108109                void  MatparConfiguration(Matpar* matpar,int matpar_offset);
    109110                void  ComputePressure(Vec p_g);
     111                void  CreateKMatrixThermal(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type);
     112                void  CreateKMatrixMelting(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type);
     113                void  CreatePVectorThermalShelf( Vec pg, void* vinputs, int analysis_type,int sub_analysis_type);
     114                void  CreatePVectorThermalSheet( Vec pg, void* vinputs, int analysis_type,int sub_analysis_type);
    110115
    111116
Note: See TracChangeset for help on using the changeset viewer.