source: issm/oecreview/Archive/18296-19100/ISSM-18343-18344.diff

Last change on this file was 19102, checked in by Mathieu Morlighem, 10 years ago

NEW: added 18296-19100

File size: 24.0 KB
  • ../trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp

     
    7070        if(stabilization==3){
    7171                iomodel->FetchDataToInput(elements,MasstransportSpcthicknessEnum); //for DG, we need the spc in the element
    7272        }
     73        if(stabilization==4){
     74                iomodel->FetchDataToInput(elements,MasstransportSpcthicknessEnum); //for FCT, we need the spc in the element (penlaties)
     75        }
    7376
    7477        if(iomodel->domaintype!=Domain2DhorizontalEnum){
    7578                iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
     
    147150        int stabilization;
    148151        iomodel->Constant(&stabilization,MasstransportStabilizationEnum);
    149152
    150         /*Do not add constraints in DG, they are weakly imposed*/
     153        /*Do not add constraints in DG,  they are weakly imposed*/
    151154        if(stabilization!=3){
    152155                IoModelToConstraintsx(constraints,iomodel,MasstransportSpcthicknessEnum,MasstransportAnalysisEnum,P1Enum);
    153156        }
     157        /*Do not add constraints in FCT, they are imposed using penalties*/
    154158}/*}}}*/
    155159void MasstransportAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
    156160
     
    674678
    675679}/*}}}*/
    676680void MasstransportAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
    677            _error_("not implemented yet");
     681        element->GetSolutionFromInputsOneDof(solution,ThicknessEnum);
    678682}/*}}}*/
    679683void MasstransportAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index){/*{{{*/
    680684        _error_("Not implemented yet");
     
    772776        }
    773777        return;
    774778}/*}}}*/
     779
     780/*Flux Correction Transport*/
     781void           MasstransportAnalysis::LumpedMassMatrix(Vector<IssmDouble>** pMlff,FemModel* femmodel){/*{{{*/
     782
     783        /*Intermediaries*/
     784        int  configuration_type;
     785
     786        /*Initialize Lumped mass matrix (actually we just save its diagonal)*/
     787        femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
     788        int fsize      = femmodel->nodes->NumberOfDofs(configuration_type,FsetEnum);
     789        int flocalsize = femmodel->nodes->NumberOfDofsLocal(configuration_type,FsetEnum);
     790        Vector<IssmDouble>* Mlff = new Vector<IssmDouble>(flocalsize,fsize);
     791
     792        /*Create and assemble matrix*/
     793        for(int i=0;i<femmodel->elements->Size();i++){
     794                Element*       element = dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     795                ElementMatrix* MLe     = this->CreateMassMatrix(element);
     796                if(MLe){
     797                        MLe->Lump();
     798                        MLe->AddDiagonalToGlobal(Mlff);
     799                }
     800                delete MLe;
     801        }
     802        Mlff->Assemble();
     803
     804        /*Assign output pointer*/
     805        *pMlff=Mlff;
     806}/*}}}*/
     807ElementMatrix* MasstransportAnalysis::CreateMassMatrix(Element* element){/*{{{*/
     808
     809        /* Check if ice in element */
     810        if(!element->IsIceInElement()) return NULL;
     811
     812        /*Intermediaries*/
     813        IssmDouble  D,Jdet;
     814        IssmDouble* xyz_list = NULL;
     815
     816        /*Fetch number of nodes and dof for this finite element*/
     817        int numnodes = element->GetNumberOfNodes();
     818
     819        /*Initialize Element vector and other vectors*/
     820        ElementMatrix* Me     = element->NewElementMatrix();
     821        IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
     822
     823        /*Retrieve all inputs and parameters*/
     824        element->GetVerticesCoordinates(&xyz_list);
     825
     826        /* Start  looping on the number of gaussian points: */
     827        Gauss* gauss=element->NewGauss(2);
     828        for(int ig=gauss->begin();ig<gauss->end();ig++){
     829                gauss->GaussPoint(ig);
     830
     831                element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     832                element->NodalFunctions(basis,gauss);
     833
     834                D=gauss->weight*Jdet;
     835                TripleMultiply(basis,1,numnodes,1,
     836                                        &D,1,1,0,
     837                                        basis,1,numnodes,0,
     838                                        &Me->values[0],1);
     839        }
     840
     841        /*Clean up and return*/
     842        xDelete<IssmDouble>(xyz_list);
     843        xDelete<IssmDouble>(basis);
     844        delete gauss;
     845        return Me;
     846}/*}}}*/
     847void           MasstransportAnalysis::FctKMatrix(Matrix<IssmDouble>** pKff,Matrix<IssmDouble>** pKfs,FemModel* femmodel){/*{{{*/
     848
     849        /*Output*/
     850        Matrix<IssmDouble>* Kff = NULL;
     851        Matrix<IssmDouble>* Kfs = NULL;
     852
     853        /*Initialize Jacobian Matrix*/
     854        AllocateSystemMatricesx(&Kff,&Kfs,NULL,NULL,femmodel);
     855
     856        /*Create and assemble matrix*/
     857        for(int i=0;i<femmodel->elements->Size();i++){
     858                Element*       element = dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     859                ElementMatrix* Ke     = this->CreateFctKMatrix(element);
     860                if(Ke) Ke->AddToGlobal(Kff,Kfs);
     861                delete Ke;
     862        }
     863        Kff->Assemble();
     864        Kfs->Assemble();
     865
     866        /*Assign output pointer*/
     867        *pKff=Kff;
     868        *pKfs=Kfs;
     869}/*}}}*/
     870ElementMatrix* MasstransportAnalysis::CreateFctKMatrix(Element* element){/*{{{*/
     871
     872        /* Check if ice in element */
     873        if(!element->IsIceInElement()) return NULL;
     874
     875        /*Intermediaries */
     876        IssmDouble Jdet;
     877        IssmDouble vx,vy;
     878        IssmDouble* xyz_list = NULL;
     879
     880        /*Fetch number of nodes and dof for this finite element*/
     881        int numnodes = element->GetNumberOfNodes();
     882        int dim      = 2;
     883
     884        /*Initialize Element vector and other vectors*/
     885        ElementMatrix* Ke     = element->NewElementMatrix();
     886        IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
     887        IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
     888        IssmDouble*    D      = xNewZeroInit<IssmDouble>(dim*dim);
     889
     890        /*Retrieve all inputs and parameters*/
     891        element->GetVerticesCoordinates(&xyz_list);
     892        Input* vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
     893        Input* vyaverage_input=element->GetInput(VyEnum); _assert_(vyaverage_input);
     894
     895        /* Start  looping on the number of gaussian points: */
     896        Gauss* gauss=element->NewGauss(2);
     897        for(int ig=gauss->begin();ig<gauss->end();ig++){
     898                gauss->GaussPoint(ig);
     899
     900                element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     901                GetB(B,element,dim,xyz_list,gauss);
     902                GetBprime(Bprime,element,dim,xyz_list,gauss);
     903                vxaverage_input->GetInputValue(&vx,gauss);
     904                vyaverage_input->GetInputValue(&vy,gauss);
     905
     906                D[0*dim+0] = -gauss->weight*vx*Jdet;
     907                D[1*dim+1] = -gauss->weight*vy*Jdet;
     908
     909                TripleMultiply(B,dim,numnodes,1,
     910                                        D,dim,dim,0,
     911                                        Bprime,dim,numnodes,0,
     912                                        &Ke->values[0],1);
     913
     914        }
     915
     916        /*Clean up and return*/
     917        xDelete<IssmDouble>(xyz_list);
     918        xDelete<IssmDouble>(B);
     919        xDelete<IssmDouble>(Bprime);
     920        xDelete<IssmDouble>(D);
     921        delete gauss;
     922        return Ke;
     923}/*}}}*/
  • ../trunk-jpl/src/c/analyses/MasstransportAnalysis.h

     
    3535                void GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index);
    3636                void InputUpdateFromSolution(IssmDouble* solution,Element* element);
    3737                void UpdateConstraints(FemModel* femmodel);
     38
     39                /*FCT*/
     40                void           LumpedMassMatrix(Vector<IssmDouble>** pMLff,FemModel* femmodel);
     41                void           FctKMatrix(Matrix<IssmDouble>** pKff,Matrix<IssmDouble>** pKfs,FemModel* femmodel);
     42                ElementMatrix* CreateMassMatrix(Element* element);
     43                ElementMatrix* CreateFctKMatrix(Element* element);
    3844};
    3945#endif
  • ../trunk-jpl/src/c/solutionsequences/solutionsequence_fct.cpp

     
     1/*!\file: solutionsequence_linear.cpp
     2 * \brief: numerical core of linear solutions
     3 */
     4
     5#include "../toolkits/toolkits.h"
     6#include "../classes/classes.h"
     7#include "../shared/shared.h"
     8#include "../modules/modules.h"
     9
     10void solutionsequence_fct(FemModel* femmodel){
     11
     12        /*intermediary: */
     13        Vector<IssmDouble>*  Mlf = NULL;
     14        Matrix<IssmDouble>*  Kff = NULL;
     15        Matrix<IssmDouble>*  Kfs = NULL;
     16        Vector<IssmDouble>*  ug  = NULL;
     17        Vector<IssmDouble>*  uf  = NULL;
     18        Vector<IssmDouble>*  ys  = NULL;
     19
     20        IssmDouble theta,deltat;
     21        int        dof,ncols,ncols2,ncols3,rstart,rend;
     22        int        configuration_type,analysis_type;
     23        double     d,diagD,mi;
     24        double     dmax = 0.;
     25        int*       cols  = NULL;
     26        int*       cols2 = NULL;
     27        int*       cols3 = NULL;
     28        double*    vals  = NULL;
     29        double*    vals2 = NULL;
     30        double*    vals3 = NULL;
     31
     32        /*Create analysis*/
     33        MasstransportAnalysis* analysis = new MasstransportAnalysis();
     34
     35        /*Recover parameters: */
     36        femmodel->parameters->FindParam(&deltat,TimesteppingTimeStepEnum);
     37        femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
     38        femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     39        femmodel->UpdateConstraintsx();
     40        theta = 0.5;
     41
     42        /*Create lumped mass matrix*/
     43        analysis->LumpedMassMatrix(&Mlf,femmodel);
     44        analysis->FctKMatrix(&Kff,&Kfs,femmodel);
     45
     46        /*Create Dff Matrix*/
     47        #ifdef _HAVE_PETSC_
     48        Mat Kff_transp = NULL;
     49        Mat Dff_petsc  = NULL;
     50        Mat LHS        = NULL;
     51        Mat Kff_petsc  = Kff->pmatrix->matrix;
     52        Vec Mlf_petsc  = Mlf->pvector->vector;
     53        MatTranspose(Kff_petsc,MAT_INITIAL_MATRIX,&Kff_transp);
     54        MatDuplicate(Kff_petsc,MAT_SHARE_NONZERO_PATTERN,&Dff_petsc);
     55        MatGetOwnershipRange(Kff_transp,&rstart,&rend);
     56        for(int row=rstart; row<rend; row++){
     57                diagD = 0.;
     58                MatGetRow(Kff_petsc ,row,&ncols, (const int**)&cols, (const double**)&vals);
     59                MatGetRow(Kff_transp,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     60                _assert_(ncols==ncols2);
     61                for(int j=0; j<ncols; j++) {
     62                        _assert_(cols[j]==cols2[j]);
     63                        d = max(max(-vals[j],-vals2[j]),0.);
     64                        MatSetValues(Dff_petsc,1,&row,1,&cols[j],(const double*)&d,INSERT_VALUES);
     65                        if(cols[j]!=row) diagD -= d;
     66                }
     67                MatSetValues(Dff_petsc,1,&row,1,&row,(const double*)&diagD,INSERT_VALUES);
     68                MatRestoreRow(Kff_petsc, row,&ncols, (const int**)&cols, (const double**)&vals);
     69                MatRestoreRow(Kff_transp,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     70        }
     71        MatAssemblyBegin(Dff_petsc,MAT_FINAL_ASSEMBLY);
     72        MatAssemblyEnd(  Dff_petsc,MAT_FINAL_ASSEMBLY);
     73        MatFree(&Kff_transp);
     74
     75        /*Create LHS: [ML − theta*detlat *(K+D)^n+1]*/
     76        MatDuplicate(Kff_petsc,MAT_SHARE_NONZERO_PATTERN,&LHS);
     77        for(int row=rstart; row<rend; row++){
     78                MatGetRow(Kff_petsc,row,&ncols, (const int**)&cols, (const double**)&vals);
     79                MatGetRow(Dff_petsc,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     80                _assert_(ncols==ncols2);
     81                for(int j=0; j<ncols; j++) {
     82                        _assert_(cols[j]==cols2[j]);
     83                        d = -theta*deltat*(vals[j] + vals2[j]);
     84                        if(cols[j]==row){
     85                                VecGetValues(Mlf_petsc,1,(const int*)&cols[j],&mi);
     86                                d += mi;
     87                        }
     88                        if(fabs(d)>dmax) dmax = fabs(d);
     89                        MatSetValues(LHS,1,&row,1,&cols[j],(const double*)&d,INSERT_VALUES);
     90                }
     91                MatRestoreRow(Kff_petsc,row,&ncols, (const int**)&cols, (const double**)&vals);
     92                MatRestoreRow(Dff_petsc,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     93        }
     94
     95        /*Penalize Dirichlet boundary*/
     96        dmax = dmax * 1.e+3;
     97        for(int i=0;i<femmodel->constraints->Size();i++){
     98                Constraint* constraint=(Constraint*)femmodel->constraints->GetObjectByOffset(i);
     99                if(constraint->InAnalysis(analysis_type)){
     100                        constraint->PenaltyDofAndValue(&dof,&d,femmodel->nodes,femmodel->parameters);
     101                        if(dof!=-1){
     102                                MatSetValues(LHS,1,&dof,1,&dof,(const double*)&dmax,INSERT_VALUES);
     103                        }
     104                }
     105        }
     106        MatAssemblyBegin(LHS,MAT_FINAL_ASSEMBLY);
     107        MatAssemblyEnd(  LHS,MAT_FINAL_ASSEMBLY);
     108
     109        /*Create RHS: [ML + (1 − theta) deltaT L^n] u^n */
     110        GetSolutionFromInputsx(&ug,femmodel);
     111        Reducevectorgtofx(&uf, ug, femmodel->nodes,femmodel->parameters);
     112        delete ug;
     113        Vec u  = uf->pvector->vector;
     114        Vec Ku = NULL;
     115        Vec Du = NULL;
     116        Vec RHS = NULL;
     117        VecDuplicate(u,&Ku);
     118        VecDuplicate(u,&Du);
     119        VecDuplicate(u,&RHS);
     120        MatMult(Kff_petsc,u,Ku);
     121        MatMult(Dff_petsc,u,Du);
     122        VecPointwiseMult(RHS,Mlf_petsc,u);
     123        VecAXPBYPCZ(RHS,(1-theta)*deltat,(1-theta)*deltat,1,Ku,Du);// RHS = M*u + (1-theta)*deltat*K*u + (1-theta)*deltat*D*u
     124        VecFree(&Ku);
     125        VecFree(&Du);
     126        MatFree(&Dff_petsc);
     127        delete uf;
     128
     129        /*Penalize Dirichlet boundary*/
     130        for(int i=0;i<femmodel->constraints->Size();i++){
     131                Constraint* constraint=(Constraint*)femmodel->constraints->GetObjectByOffset(i);
     132                if(constraint->InAnalysis(analysis_type)){
     133                        constraint->PenaltyDofAndValue(&dof,&d,femmodel->nodes,femmodel->parameters);
     134                        d = d*dmax;
     135                        if(dof!=-1){
     136                                VecSetValues(RHS,1,&dof,(const double*)&d,INSERT_VALUES);
     137                        }
     138                }
     139        }
     140
     141        /*Go solve!*/
     142        SolverxPetsc(&u,LHS,RHS,NULL,NULL, femmodel->parameters);
     143        MatFree(&LHS);
     144        VecFree(&RHS);
     145        uf =new Vector<IssmDouble>(u);
     146        VecFree(&u);
     147
     148        Mergesolutionfromftogx(&ug, uf,ys,femmodel->nodes,femmodel->parameters);delete uf; delete ys;
     149        InputUpdateFromSolutionx(femmodel,ug);
     150        delete ug; 
     151
     152        #else
     153        _error_("PETSc needs to be installed");
     154        #endif
     155
     156        delete Mlf;
     157        delete Kff;
     158        delete Kfs;
     159        delete analysis;
     160
     161}
  • ../trunk-jpl/src/c/solutionsequences/solutionsequences.h

     
    1515void solutionsequence_hydro_nonlinear(FemModel* femmodel);
    1616void solutionsequence_nonlinear(FemModel* femmodel,bool conserve_loads);
    1717void solutionsequence_newton(FemModel* femmodel);
     18void solutionsequence_fct(FemModel* femmodel);
    1819void solutionsequence_FScoupling_nonlinear(FemModel* femmodel,bool conserve_loads);
    1920void solutionsequence_linear(FemModel* femmodel);
    2021void solutionsequence_la(FemModel* femmodel);
  • ../trunk-jpl/src/c/Makefile.am

     
    353353                                        ./solutionsequences/solutionsequence_linear.cpp\
    354354                                        ./solutionsequences/solutionsequence_nonlinear.cpp\
    355355                                        ./solutionsequences/solutionsequence_newton.cpp\
     356                                        ./solutionsequences/solutionsequence_fct.cpp\
    356357                                        ./solutionsequences/convergence.cpp\
    357358                                        ./classes/Options/Options.h\
    358359                                        ./classes/Options/Options.cpp\
  • ../trunk-jpl/src/c/cores/masstransport_core.cpp

     
    1515        int    numoutputs,domaintype;
    1616        bool   save_results;
    1717        bool   isFS,isfreesurface,dakota_analysis;
    18         int    solution_type;
     18        int    solution_type,stabilization;
    1919        char** requested_outputs = NULL;
    2020
    2121        /*activate configuration*/
     
    2828        femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
    2929        femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
    3030        femmodel->parameters->FindParam(&numoutputs,MasstransportNumRequestedOutputsEnum);
     31        femmodel->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);
    3132        if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,MasstransportRequestedOutputsEnum);
    3233
    3334        /*Calculate new Surface Mass Balance (SMB)*/
     
    4849        }
    4950        else{
    5051                if(VerboseSolution()) _printf0_("   call computational core\n");
    51                 solutionsequence_linear(femmodel);
     52                if(stabilization==4){
     53                        solutionsequence_fct(femmodel);
     54                }
     55                else{
     56                        solutionsequence_linear(femmodel);
     57                }
    5258                femmodel->parameters->SetParam(ThicknessEnum,InputToExtrudeEnum);
    5359                extrudefrombase_core(femmodel);
    5460                femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
  • ../trunk-jpl/src/c/classes/matrix/ElementMatrix.cpp

     
    328328
    329329}
    330330/*}}}*/
     331void ElementMatrix::AddDiagonalToGlobal(Vector<IssmDouble>* pf){/*{{{*/
     332
     333        IssmDouble* localvalues=NULL;
     334
     335        /*Check that pf is not NULL*/
     336        _assert_(pf);
     337
     338        /*In debugging mode, check consistency (no NaN, and values not too big)*/
     339        this->CheckConsistency();
     340
     341        if(this->dofsymmetrical){
     342                /*only use row dofs to add values into global matrices: */
     343
     344                if(this->row_fsize){
     345                        /*first, retrieve values that are in the f-set from the g-set values matrix: */
     346                        localvalues=xNew<IssmDouble>(this->row_fsize);
     347                        for(int i=0;i<this->row_fsize;i++){
     348                                localvalues[i] = this->values[this->ncols*this->row_flocaldoflist[i]+ this->row_flocaldoflist[i]];
     349                        }
     350
     351                        /*add local values into global  matrix, using the fglobaldoflist: */
     352                        pf->SetValues(this->row_fsize,this->row_fglobaldoflist,localvalues,ADD_VAL);
     353
     354                        /*Free ressources:*/
     355                        xDelete<IssmDouble>(localvalues);
     356                }
     357        }
     358        else{
     359                _error_("non dofsymmetrical matrix AddToGlobal routine not support yet!");
     360        }
     361
     362}
     363/*}}}*/
    331364void ElementMatrix::CheckConsistency(void){/*{{{*/
    332365        /*Check element matrix values, only in debugging mode*/
    333366        #ifdef _ISSM_DEBUG_
  • ../trunk-jpl/src/c/classes/matrix/ElementMatrix.h

     
    5959                /*ElementMatrix specific routines*/
    6060                void AddToGlobal(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs);
    6161                void AddToGlobal(Matrix<IssmDouble>* Jff);
     62                void AddDiagonalToGlobal(Vector<IssmDouble>* pf);
    6263                void Echo(void);
    6364                void CheckConsistency(void);
    6465                void StaticCondensation(int numindices,int* indices);
  • ../trunk-jpl/src/c/classes/Constraints/SpcDynamic.h

     
    3737                /*Constraint virtual functions definitions: {{{*/
    3838                void   ConstrainNode(Nodes* nodes,Parameters* parameters);
    3939                bool   InAnalysis(int analysis_type);
     40                void   PenaltyDofAndValue(int* dof,IssmDouble* value,Nodes* nodes,Parameters* parameters){_error_("not implemented yet");};
    4041                /*}}}*/
    4142                /*SpcDynamic management:{{{ */
    4243                int    GetNodeId();
  • ../trunk-jpl/src/c/classes/Constraints/SpcStatic.h

     
    3636                /*Constraint virtual functions definitions: {{{*/
    3737                void   ConstrainNode(Nodes* nodes,Parameters* parameters);
    3838                bool   InAnalysis(int analysis_type);
     39                void   PenaltyDofAndValue(int* dof,IssmDouble* value,Nodes* nodes,Parameters* parameters){_error_("not implemented yet");};
    3940                /*}}}*/
    4041                /*SpcStatic management:{{{ */
    4142                int    GetNodeId();
  • ../trunk-jpl/src/c/classes/Constraints/SpcTransient.h

     
    1313class SpcTransient: public Constraint{
    1414
    1515        private:
    16                 int     sid; /*! id, to track it*/
    17                 int     nodeid; /*!node id*/
    18                 int dof; /*!component*/
    19                 IssmDouble* values; /*different values in time*/
    20                 IssmDouble* times; /*different time steps*/
    21                 int nsteps; /*number of time steps*/
    22                 int analysis_type;
     16                bool        penalty;         /*Is this a penalty constraint */
     17                int         sid;             /* id, to track it             */
     18                int         nodeid;          /*node id                      */
     19                int         dof;             /*component                    */
     20                IssmDouble *values;          /*different values in time     */
     21                IssmDouble *times;           /*different time steps         */
     22                int         nsteps;          /*number of time steps         */
     23                int         analysis_type;
    2324
    2425        public:
    2526
     
    3839                /*Constraint virtual functions definitions: {{{*/
    3940                void   ConstrainNode(Nodes* nodes,Parameters* parameters);
    4041                bool   InAnalysis(int analysis_type);
     42                void   PenaltyDofAndValue(int* dof,IssmDouble* value,Nodes* nodes,Parameters* parameters);
    4143                /*}}}*/
    4244                /*SpcTransient management:{{{ */
    4345                int    GetNodeId();
  • ../trunk-jpl/src/c/classes/Constraints/Constraint.h

     
    2020
    2121                virtual      ~Constraint(){};
    2222                virtual void ConstrainNode(Nodes* nodes,Parameters* parameters)=0;
     23                virtual void PenaltyDofAndValue(int* dof,IssmDouble* value,Nodes* nodes,Parameters* parameters)=0;
    2324                virtual bool InAnalysis(int analysis_type)=0;
    2425
    2526};
  • ../trunk-jpl/src/c/classes/Constraints/SpcTransient.cpp

     
    1414
    1515/*SpcTransient constructors and destructor*/
    1616SpcTransient::SpcTransient(){/*{{{*/
    17         sid=-1;
    18         nodeid=-1;
    19         dof=-1;
    20         values=NULL;
    21         times=NULL;
    22         nsteps=-1;
    23         analysis_type=-1;
     17        penalty       = false;
     18        sid           = -1;
     19        nodeid        = -1;
     20        dof           = -1;
     21        values        = NULL;
     22        times         = NULL;
     23        nsteps        = -1;
     24        analysis_type = -1;
    2425        return;
    2526}
    2627/*}}}*/
    2728SpcTransient::SpcTransient(int spc_sid,int spc_nodeid, int spc_dof,int spc_nsteps, IssmDouble* spc_times, IssmDouble* spc_values,int spc_analysis_type){/*{{{*/
    2829
    29         sid=spc_sid;
    30         nodeid=spc_nodeid;
    31         dof=spc_dof;
    32         nsteps=spc_nsteps;
     30        penalty= false;
     31        sid    = spc_sid;
     32        nodeid = spc_nodeid;
     33        dof    = spc_dof;
     34        nsteps = spc_nsteps;
    3335        if(spc_nsteps){
    34                 values=xNew<IssmDouble>(spc_nsteps);
    35                 times=xNew<IssmDouble>(spc_nsteps);
     36                values = xNew<IssmDouble>(spc_nsteps);
     37                times  = xNew<IssmDouble>(spc_nsteps);
    3638                xMemCpy<IssmDouble>(values,spc_values,nsteps);
    3739                xMemCpy<IssmDouble>(times,spc_times,nsteps);
    3840        }
     
    6870        this->Echo();
    6971}               
    7072/*}}}*/
    71 int    SpcTransient::Id(void){ return sid; }/*{{{*/
     73int  SpcTransient::Id(void){/*{{{*/
     74        return sid;
     75}
    7276/*}}}*/
    7377int SpcTransient::ObjectEnum(void){/*{{{*/
    7478
     
    100104        /*Chase through nodes and find the node to which this SpcTransient applys: */
    101105        node=(Node*)nodes->GetObjectById(NULL,nodeid);
    102106
    103         if(node){ //in case the spc is dealing with a node on another cpu
     107        if(!this->penalty && node){ //in case the spc is dealing with a node on another cpu
    104108
    105109                /*Retrieve time in parameters: */
    106110                parameters->FindParam(&time,TimeEnum);
     
    136140        }
    137141}
    138142/*}}}*/
     143void SpcTransient::PenaltyDofAndValue(int* pdof,IssmDouble* pvalue,Nodes* nodes,Parameters* parameters){/*{{{*/
    139144
     145        if(!this->penalty) _error_("cannot return dof and value for non penalty constraint");
     146
     147        Node       *node  = NULL;
     148        IssmDouble  time  = 0.;
     149        int         i,gdof;
     150        IssmDouble  alpha = -1.;
     151        IssmDouble  value;
     152        bool        found = false;
     153
     154        /*Chase through nodes and find the node to which this SpcTransient applys: */
     155        node=(Node*)nodes->GetObjectById(NULL,nodeid);
     156
     157        if(node){ //in case the spc is dealing with a node on another cpu
     158
     159                /*Retrieve time in parameters: */
     160                parameters->FindParam(&time,TimeEnum);
     161
     162                /*Now, go fetch value for this time: */
     163                if (time<=times[0]){
     164                        value=values[0];
     165                        found=true;
     166                }
     167                else if (time>=times[nsteps-1]){
     168                        value=values[nsteps-1];
     169                        found=true;
     170                }
     171                else{
     172                        for(i=0;i<nsteps-1;i++){
     173                                if (times[i]<=time && time<times[i+1]){
     174                                        alpha=(time-times[i])/(times[i+1]-times[i]);
     175                                        value=(1-alpha)*values[i]+alpha*values[i+1];
     176                                        found=true;
     177                                        break;
     178                                }
     179                        }
     180                }
     181                if(!found)_error_("could not find time segment for constraint");
     182
     183                /*Get gdof */
     184                gdof = node->GetDof(dof,GsetEnum);
     185                if(xIsNan<IssmDouble>(value)){
     186                        gdof = -1;
     187                }
     188        }
     189        else{
     190                value = NAN;
     191                gdof = -1;
     192        }
     193
     194        /*Assign output pointers*/
     195        *pdof   = gdof;
     196        *pvalue = value;
     197}
     198/*}}}*/
     199
    140200/*SpcTransient functions*/
    141201int SpcTransient::GetDof(){/*{{{*/
    142202        return dof;
  • ../trunk-jpl/src/c

Note: See TracBrowser for help on using the repository browser.