Changeset 19386


Ignore:
Timestamp:
06/03/15 06:25:50 (10 years ago)
Author:
cborstad
Message:

CHG: working to implement flux corrected transport for damage evolution

Location:
issm/trunk-jpl/src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/analyses/DamageEvolutionAnalysis.cpp

    r19384 r19386  
    115115
    116116                /* no source term; damage handled in stress balance */
    117                 f[i]=0;
     117                f[i]=0.;
    118118        }
    119119
     
    632632}/*}}}*/
    633633void           DamageEvolutionAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
    634            _error_("not implemented yet");
     634        element->GetSolutionFromInputsOneDof(solution,DamageDbarEnum);
    635635}/*}}}*/
    636636void           DamageEvolutionAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index){/*{{{*/
     
    686686        return;
    687687}/*}}}*/
     688
     689/*Flux Correction Transport*/
     690ElementMatrix* DamageEvolutionAnalysis::CreateFctKMatrix(Element* element){/*{{{*/
     691
     692        /* Check if ice in element */
     693        if(!element->IsIceInElement()) return NULL;
     694
     695        /*Intermediaries */
     696        IssmDouble Jdet;
     697        IssmDouble vx,vy;
     698        IssmDouble* xyz_list = NULL;
     699
     700        /*Fetch number of nodes and dof for this finite element*/
     701        int numnodes = element->GetNumberOfNodes();
     702        int dim      = 2;
     703
     704        /*Initialize Element vector and other vectors*/
     705        ElementMatrix* Ke     = element->NewElementMatrix();
     706        IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
     707        IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
     708        IssmDouble*    D      = xNewZeroInit<IssmDouble>(dim*dim);
     709
     710        /*Retrieve all inputs and parameters*/
     711        element->GetVerticesCoordinates(&xyz_list);
     712        Input* vxaverage_input=element->GetInput(VxEnum); _assert_(vxaverage_input);
     713        Input* vyaverage_input=element->GetInput(VyEnum); _assert_(vyaverage_input);
     714
     715        /* Start  looping on the number of gaussian points: */
     716        Gauss* gauss=element->NewGauss(2);
     717        for(int ig=gauss->begin();ig<gauss->end();ig++){
     718                gauss->GaussPoint(ig);
     719
     720                element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     721                GetB(B,element,dim,xyz_list,gauss);
     722                GetBprime(Bprime,element,dim,xyz_list,gauss);
     723                vxaverage_input->GetInputValue(&vx,gauss);
     724                vyaverage_input->GetInputValue(&vy,gauss);
     725
     726                D[0*dim+0] = -gauss->weight*vx*Jdet;
     727                D[1*dim+1] = -gauss->weight*vy*Jdet;
     728
     729                TripleMultiply(B,dim,numnodes,1,
     730                                        D,dim,dim,0,
     731                                        Bprime,dim,numnodes,0,
     732                                        &Ke->values[0],1);
     733
     734        }
     735
     736        /*Clean up and return*/
     737        xDelete<IssmDouble>(xyz_list);
     738        xDelete<IssmDouble>(B);
     739        xDelete<IssmDouble>(Bprime);
     740        xDelete<IssmDouble>(D);
     741        delete gauss;
     742        return Ke;
     743}/*}}}*/
     744ElementMatrix* DamageEvolutionAnalysis::CreateMassMatrix(Element* element){/*{{{*/
     745
     746        /* Check if ice in element */
     747        if(!element->IsIceInElement()) return NULL;
     748
     749        /*Intermediaries*/
     750        IssmDouble  D,Jdet;
     751        IssmDouble* xyz_list = NULL;
     752
     753        /*Fetch number of nodes and dof for this finite element*/
     754        int numnodes = element->GetNumberOfNodes();
     755
     756        /*Initialize Element vector and other vectors*/
     757        ElementMatrix* Me     = element->NewElementMatrix();
     758        IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
     759
     760        /*Retrieve all inputs and parameters*/
     761        element->GetVerticesCoordinates(&xyz_list);
     762
     763        /* Start  looping on the number of gaussian points: */
     764        Gauss* gauss=element->NewGauss(2);
     765        for(int ig=gauss->begin();ig<gauss->end();ig++){
     766                gauss->GaussPoint(ig);
     767
     768                element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     769                element->NodalFunctions(basis,gauss);
     770
     771                D=gauss->weight*Jdet;
     772                TripleMultiply(basis,1,numnodes,1,
     773                                        &D,1,1,0,
     774                                        basis,1,numnodes,0,
     775                                        &Me->values[0],1);
     776        }
     777
     778        /*Clean up and return*/
     779        xDelete<IssmDouble>(xyz_list);
     780        xDelete<IssmDouble>(basis);
     781        delete gauss;
     782        return Me;
     783}/*}}}*/
     784void           DamageEvolutionAnalysis::FctKMatrix(Matrix<IssmDouble>** pKff,Matrix<IssmDouble>** pKfs,FemModel* femmodel){/*{{{*/
     785
     786        /*Output*/
     787        Matrix<IssmDouble>* Kff = NULL;
     788        Matrix<IssmDouble>* Kfs = NULL;
     789
     790        /*Initialize Jacobian Matrix*/
     791        AllocateSystemMatricesx(&Kff,&Kfs,NULL,NULL,femmodel);
     792
     793        /*Create and assemble matrix*/
     794        for(int i=0;i<femmodel->elements->Size();i++){
     795                Element*       element = xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
     796                ElementMatrix* Ke     = this->CreateFctKMatrix(element);
     797                if(Ke) Ke->AddToGlobal(Kff,Kfs);
     798                delete Ke;
     799        }
     800        Kff->Assemble();
     801        Kfs->Assemble();
     802
     803        /*Assign output pointer*/
     804        *pKff=Kff;
     805        if(pKfs){
     806                *pKfs=Kfs;
     807        }
     808        else{
     809                delete Kfs;
     810        }
     811}/*}}}*/
     812void           DamageEvolutionAnalysis::LumpedMassMatrix(Vector<IssmDouble>** pMlff,FemModel* femmodel){/*{{{*/
     813
     814        /*Intermediaries*/
     815        int  configuration_type;
     816
     817        /*Initialize Lumped mass matrix (actually we just save its diagonal)*/
     818        femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
     819        int fsize      = femmodel->nodes->NumberOfDofs(configuration_type,FsetEnum);
     820        int flocalsize = femmodel->nodes->NumberOfDofsLocal(configuration_type,FsetEnum);
     821        Vector<IssmDouble>* Mlff = new Vector<IssmDouble>(flocalsize,fsize);
     822
     823        /*Create and assemble matrix*/
     824        for(int i=0;i<femmodel->elements->Size();i++){
     825                Element*       element = xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
     826                ElementMatrix* MLe     = this->CreateMassMatrix(element);
     827                if(MLe){
     828                        MLe->Lump();
     829                        MLe->AddDiagonalToGlobal(Mlff);
     830                }
     831                delete MLe;
     832        }
     833        Mlff->Assemble();
     834
     835        /*Assign output pointer*/
     836        *pMlff=Mlff;
     837}/*}}}*/
     838void           DamageEvolutionAnalysis::MassMatrix(Matrix<IssmDouble>** pMff,FemModel* femmodel){/*{{{*/
     839
     840        /*Initialize Mass matrix*/
     841        Matrix<IssmDouble> *Mff = NULL;
     842        AllocateSystemMatricesx(&Mff,NULL,NULL,NULL,femmodel);
     843
     844        /*Create and assemble matrix*/
     845        for(int i=0;i<femmodel->elements->Size();i++){
     846                Element*       element = xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
     847                ElementMatrix* MLe     = this->CreateMassMatrix(element);
     848                if(MLe){
     849                        MLe->AddToGlobal(Mff);
     850                }
     851                delete MLe;
     852        }
     853        Mff->Assemble();
     854
     855        /*Assign output pointer*/
     856        *pMff=Mff;
     857}/*}}}*/
  • issm/trunk-jpl/src/c/analyses/DamageEvolutionAnalysis.h

    r19384 r19386  
    3535                void           InputUpdateFromSolution(IssmDouble* solution,Element* element);
    3636                void           UpdateConstraints(FemModel* femmodel);
     37
     38                /*FCT*/
     39                ElementMatrix* CreateFctKMatrix(Element* element);
     40                ElementMatrix* CreateMassMatrix(Element* element);
     41                void           FctKMatrix(Matrix<IssmDouble>** pKff,Matrix<IssmDouble>** pKfs,FemModel* femmodel);
     42                void           LumpedMassMatrix(Vector<IssmDouble>** pMLff,FemModel* femmodel);
     43                void           MassMatrix(Matrix<IssmDouble>** pMff,FemModel* femmodel);
    3744};
    3845#endif
  • issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp

    r19381 r19386  
    876876        iomodel->Constant(&materials_type,MaterialsEnum);
    877877        if(materials_type==MatdamageiceEnum){
    878                 parameters->AddObject(iomodel->CopyConstantObject(DamageC1Enum));
     878                parameters->AddObject(iomodel->CopyConstantObject(DamageLawEnum));
    879879                parameters->AddObject(iomodel->CopyConstantObject(DamageKappaEnum));
    880880                parameters->AddObject(iomodel->CopyConstantObject(DamageStressThresholdEnum));
  • issm/trunk-jpl/src/c/cores/damage_core.cpp

    r18470 r19386  
    11/*
    2  * \brief: damgage_core.cpp: core for the damage solution
     2 * \brief: damage_core.cpp: core for the damage solution
    33 */
    44
     
    1515        bool   save_results;
    1616        bool   dakota_analysis     = false;
    17         int    solution_type;
     17        int    solution_type,stabilization;
    1818        int    numoutputs          = 0;
    1919        char   **requested_outputs = NULL;
     
    2525        femmodel->parameters->FindParam(&numoutputs,DamageEvolutionNumRequestedOutputsEnum);
    2626        if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,DamageEvolutionRequestedOutputsEnum);
     27        femmodel->parameters->FindParam(&stabilization,DamageStabilizationEnum);
    2728
    2829        if(VerboseSolution()) _printf0_("   computing damage\n");
    2930        femmodel->SetCurrentConfiguration(DamageEvolutionAnalysisEnum);
    30         solutionsequence_linear(femmodel);
     31        if(stabilization==4){
     32                solutionsequence_fct(femmodel);
     33        }
     34        else{
     35                solutionsequence_linear(femmodel);
     36        }
    3137
    3238        if(save_results){
  • issm/trunk-jpl/src/c/solutionsequences/solutionsequence_fct.cpp

    r18978 r19386  
    1 /*!\file: solutionsequence_linear.cpp
    2  * \brief: numerical core of linear solutions
     1/*!\file: solutionsequence_fct.cpp
     2 * \brief: numerical core of flux corrected transport solution
    33 */
    44
     
    77#include "../shared/shared.h"
    88#include "../modules/modules.h"
     9#include "../analyses/analyses.h"
    910
    1011#ifdef _HAVE_PETSC_
     
    119120}/*}}}*/
    120121void CreateRHS(Vec* pRHS,Mat K,Mat D,Vec Ml,Vec u,IssmDouble theta,IssmDouble deltat,IssmDouble dmax,FemModel* femmodel,int configuration_type){/*{{{*/
    121         /*Create Left Hand side of Lower order solution
     122        /*Create Right Hand side of Lower order solution
    122123         *
    123124         * RHS = [ML + (1 − theta) deltaT L^n] u^n
     
    166167}/*}}}*/
    167168void RichardsonUdot(Vec* pudot,Vec u,Vec Ml,Mat K,Mat Mc){/*{{{*/
    168         /*Use Richardson's formulato get udot using 5 steps and an initial guess of 0
     169        /*Use Richardson's formula to get udot using 5 steps and an initial guess of 0
    169170         *
    170171         * udot_new = udot_old + Ml^-1 (K^(n+1) u - Mc udot_old)
     
    336337}/*}}}*/
    337338#endif
    338 void solutionsequence_fct(FemModel* femmodel){
     339void solutionsequence_fct(FemModel* femmodel){/*{{{*/
    339340
    340341        /*intermediary: */
    341342        IssmDouble           theta,deltat,dmax;
    342         int                  configuration_type;
     343        int                  configuration_type,analysis_type;
    343344        Vector<IssmDouble>*  Ml = NULL;
    344345        Matrix<IssmDouble>*  K  = NULL;
     
    346347        Vector<IssmDouble>*  ug = NULL;
    347348        Vector<IssmDouble>*  uf = NULL;
    348 
    349         /*Create analysis*/
    350         MasstransportAnalysis* analysis = new MasstransportAnalysis();
     349        MasstransportAnalysis* manalysis = NULL;
     350        DamageEvolutionAnalysis* danalysis = NULL;
    351351
    352352        /*Recover parameters: */
     
    356356        theta = 0.5;
    357357
    358         /*Create lumped mass matrix*/
    359         analysis->LumpedMassMatrix(&Ml,femmodel);
    360         analysis->MassMatrix(&Mc,femmodel);
    361         analysis->FctKMatrix(&K,NULL,femmodel);
    362         delete analysis;
     358        /*Create analysis*/
     359        femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     360        switch(analysis_type){
     361                case MasstransportAnalysisEnum:
     362                        manalysis = new MasstransportAnalysis();
     363                        manalysis->LumpedMassMatrix(&Ml,femmodel);
     364                        manalysis->MassMatrix(&Mc,femmodel);
     365                        manalysis->FctKMatrix(&K,NULL,femmodel);
     366                        break;
     367                case DamageEvolutionAnalysisEnum:
     368                        danalysis = new DamageEvolutionAnalysis();
     369                        danalysis->LumpedMassMatrix(&Ml,femmodel);
     370                        danalysis->MassMatrix(&Mc,femmodel);
     371                        danalysis->FctKMatrix(&K,NULL,femmodel);
     372                        break;
     373                default: _error_("analysis type " << EnumToStringx(analysis_type) << " not supported for FCT\n");
     374        }
     375        delete manalysis;
     376        delete danalysis;
    363377
    364378        #ifdef _HAVE_PETSC_
     
    442456        _error_("PETSc needs to be installed");
    443457        #endif
    444 }
     458}/*}}}*/
  • issm/trunk-jpl/src/m/classes/damage.m

    r19384 r19386  
    142142                                md = checkfield(md,'fieldname','damage.spcdamage','timeseries',1);
    143143                                md = checkfield(md,'fieldname','damage.max_damage','<',1,'>=',0);
    144                                 md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0 1 2]);
     144                                md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0 1 2 4]);
    145145                                md = checkfield(md,'fieldname','damage.maxiter','>=0',0);
    146146                                md = checkfield(md,'fieldname','damage.elementinterp','values',{'P1','P2'});
     
    178178                                fielddisplay(self,'max_damage','maximum possible damage (0<=max_damage<1)');
    179179                               
    180                                 fielddisplay(self,'stabilization','0: no, 1: artificial_diffusivity, 2: SUPG');
     180                                fielddisplay(self,'stabilization','0: no, 1: artificial_diffusivity, 2: SUPG (not working), 4: flux corrected transport');
    181181                                fielddisplay(self,'maxiter','maximum number of non linear iterations');
    182182                                fielddisplay(self,'elementinterp','interpolation scheme for finite elements {''P1'',''P2''}');
  • issm/trunk-jpl/src/m/classes/damage.py

    r19384 r19386  
    5656                        s+="%s\n" % fielddisplay(self,"max_damage","maximum possible damage (0<=max_damage<1)")
    5757
    58                         s+="%s\n" % fielddisplay(self,"stabilization","0: no, 1: artificial_diffusivity, 2: SUPG")
     58                        s+="%s\n" % fielddisplay(self,"stabilization","0: no, 1: artificial_diffusivity, 2: SUPG (not working), 4: Flux corrected transport")
    5959                        s+="%s\n" % fielddisplay(self,"maxiter","maximum number of non linear iterations")
    6060                        s+="%s\n" %     fielddisplay(self,"elementinterp","interpolation scheme for finite elements [''P1'',''P2'']")
     
    126126                        md = checkfield(md,'fieldname','damage.law','numel',[1],'values',[0,1,2,3])
    127127                        md = checkfield(md,'fieldname','damage.spcdamage','timeseries',1)
    128                         md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0,1,2])
     128                        md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0,1,2,4])
    129129                        md = checkfield(md,'fieldname','damage.maxiter','>=0',0)
    130130                        md = checkfield(md,'fieldname','damage.elementinterp','values',['P1','P2'])
  • issm/trunk-jpl/src/m/mech/mechanicalproperties.m

    r17757 r19386  
    6262        nu(location)=B_bar(location);
    6363elseif isa(md.materials,'matdamageice')
     64        % FIXME this needs to use md.damage.D or damage from a solution
    6465        Zinv=md.materials.rheology_Z(index)*summation/3;
    6566        location=find(second_inv~=0);
  • issm/trunk-jpl/src/m/mech/mechanicalproperties.py

    r17818 r19386  
    7777        elif 'matdamageice' in md.materials.__module__:
    7878                print 'computing damage-dependent properties!'
     79                # FIXME might be using damage from a solution, not the initial md.damage.D
    7980                Zinv=npy.dot(1-md.damage.D[index-1],summation/3.).reshape(-1,)
    8081                location=npy.nonzero(second_inv)
Note: See TracChangeset for help on using the changeset viewer.