Changeset 18344


Ignore:
Timestamp:
08/07/14 16:21:11 (11 years ago)
Author:
Mathieu Morlighem
Message:

NEW: added Low order scheme of Flux Transport Correction ALgorithm

Location:
issm/trunk-jpl/src/c
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c

    • Property svn:ignore
      •  

        old new  
        55*.obj
        66*.exe
         7issm
         8kriging
        79appscan.*
        810ouncemake*
  • issm/trunk-jpl/src/c/Makefile.am

    r18333 r18344  
    354354                                        ./solutionsequences/solutionsequence_nonlinear.cpp\
    355355                                        ./solutionsequences/solutionsequence_newton.cpp\
     356                                        ./solutionsequences/solutionsequence_fct.cpp\
    356357                                        ./solutionsequences/convergence.cpp\
    357358                                        ./classes/Options/Options.h\
  • issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.cpp

    r18337 r18344  
    7070        if(stabilization==3){
    7171                iomodel->FetchDataToInput(elements,MasstransportSpcthicknessEnum); //for DG, we need the spc in the element
     72        }
     73        if(stabilization==4){
     74                iomodel->FetchDataToInput(elements,MasstransportSpcthicknessEnum); //for FCT, we need the spc in the element (penlaties)
    7275        }
    7376
     
    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){/*{{{*/
     
    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){/*{{{*/
     
    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}/*}}}*/
  • issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.h

    r18057 r18344  
    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
  • issm/trunk-jpl/src/c/classes/Constraints/Constraint.h

    r15067 r18344  
    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
  • issm/trunk-jpl/src/c/classes/Constraints/SpcDynamic.h

    r15067 r18344  
    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:{{{ */
  • issm/trunk-jpl/src/c/classes/Constraints/SpcStatic.h

    r15067 r18344  
    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:{{{ */
  • issm/trunk-jpl/src/c/classes/Constraints/SpcTransient.cpp

    r18064 r18344  
    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}
     
    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);
     
    6971}               
    7072/*}}}*/
    71 int    SpcTransient::Id(void){ return sid; }/*{{{*/
     73int  SpcTransient::Id(void){/*{{{*/
     74        return sid;
     75}
    7276/*}}}*/
    7377int SpcTransient::ObjectEnum(void){/*{{{*/
     
    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: */
     
    137141}
    138142/*}}}*/
     143void SpcTransient::PenaltyDofAndValue(int* pdof,IssmDouble* pvalue,Nodes* nodes,Parameters* parameters){/*{{{*/
     144
     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/*}}}*/
    139199
    140200/*SpcTransient functions*/
  • issm/trunk-jpl/src/c/classes/Constraints/SpcTransient.h

    r15067 r18344  
    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:
     
    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:{{{ */
  • issm/trunk-jpl/src/c/classes/matrix/ElementMatrix.cpp

    r18339 r18344  
    322322                }
    323323
     324        }
     325        else{
     326                _error_("non dofsymmetrical matrix AddToGlobal routine not support yet!");
     327        }
     328
     329}
     330/*}}}*/
     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                }
    324357        }
    325358        else{
  • issm/trunk-jpl/src/c/classes/matrix/ElementMatrix.h

    r18339 r18344  
    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);
  • issm/trunk-jpl/src/c/cores/masstransport_core.cpp

    r18237 r18344  
    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
     
    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
     
    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);
  • issm/trunk-jpl/src/c/solutionsequences/solutionsequences.h

    r18179 r18344  
    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);
Note: See TracChangeset for help on using the changeset viewer.