Changeset 18345


Ignore:
Timestamp:
08/08/14 08:34:32 (11 years ago)
Author:
Mathieu Morlighem
Message:

NEW: added Higher Order Flux correction

Location:
issm/trunk-jpl/src/c
Files:
3 edited

Legend:

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

    r18344 r18345  
    805805        *pMlff=Mlff;
    806806}/*}}}*/
     807void           MasstransportAnalysis::MassMatrix(Matrix<IssmDouble>** pMff,FemModel* femmodel){/*{{{*/
     808
     809        /*Initialize Mass matrix*/
     810        Matrix<IssmDouble> *Mff = NULL;
     811        AllocateSystemMatricesx(&Mff,NULL,NULL,NULL,femmodel);
     812
     813        /*Create and assemble matrix*/
     814        for(int i=0;i<femmodel->elements->Size();i++){
     815                Element*       element = dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     816                ElementMatrix* MLe     = this->CreateMassMatrix(element);
     817                if(MLe){
     818                        MLe->AddToGlobal(Mff);
     819                }
     820                delete MLe;
     821        }
     822        Mff->Assemble();
     823
     824        /*Assign output pointer*/
     825        *pMff=Mff;
     826}/*}}}*/
    807827ElementMatrix* MasstransportAnalysis::CreateMassMatrix(Element* element){/*{{{*/
    808828
     
    866886        /*Assign output pointer*/
    867887        *pKff=Kff;
    868         *pKfs=Kfs;
     888        if(pKfs){
     889                *pKfs=Kfs;
     890        }
     891        else{
     892                delete Kfs;
     893        }
    869894}/*}}}*/
    870895ElementMatrix* MasstransportAnalysis::CreateFctKMatrix(Element* element){/*{{{*/
  • issm/trunk-jpl/src/c/analyses/MasstransportAnalysis.h

    r18344 r18345  
    3939                /*FCT*/
    4040                void           LumpedMassMatrix(Vector<IssmDouble>** pMLff,FemModel* femmodel);
     41                void           MassMatrix(Matrix<IssmDouble>** pMff,FemModel* femmodel);
    4142                void           FctKMatrix(Matrix<IssmDouble>** pKff,Matrix<IssmDouble>** pKfs,FemModel* femmodel);
    4243                ElementMatrix* CreateMassMatrix(Element* element);
  • issm/trunk-jpl/src/c/solutionsequences/solutionsequence_fct.cpp

    r18344 r18345  
    1111
    1212        /*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;
     13        Vector<IssmDouble>*  Ml = NULL;
     14        Matrix<IssmDouble>*  K  = NULL;
     15        Matrix<IssmDouble>*  Mc = NULL;
     16        Vector<IssmDouble>*  ug = NULL;
     17        Vector<IssmDouble>*  uf = NULL;
     18        Vector<IssmDouble>*  ys = NULL;
    1919
    2020        IssmDouble theta,deltat;
     
    4141
    4242        /*Create lumped mass matrix*/
    43         analysis->LumpedMassMatrix(&Mlf,femmodel);
    44         analysis->FctKMatrix(&Kff,&Kfs,femmodel);
    45 
    46         /*Create Dff Matrix*/
     43        analysis->LumpedMassMatrix(&Ml,femmodel);
     44        analysis->MassMatrix(&Mc,femmodel);
     45        analysis->FctKMatrix(&K,NULL,femmodel);
     46
     47        /*Create D Matrix*/
    4748        #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);
     49        Mat K_transp = NULL;
     50        Mat D_petsc  = NULL;
     51        Mat LHS      = NULL;
     52        Mat K_petsc  = K->pmatrix->matrix;
     53        Vec Ml_petsc = Ml->pvector->vector;
     54        Mat Mc_petsc = Mc->pmatrix->matrix;
     55        MatTranspose(K_petsc,MAT_INITIAL_MATRIX,&K_transp);
     56        MatDuplicate(K_petsc,MAT_SHARE_NONZERO_PATTERN,&D_petsc);
     57        MatGetOwnershipRange(K_transp,&rstart,&rend);
    5658        for(int row=rstart; row<rend; row++){
    5759                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                MatGetRow(K_petsc ,row,&ncols, (const int**)&cols, (const double**)&vals);
     61                MatGetRow(K_transp,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
    6062                _assert_(ncols==ncols2);
    6163                for(int j=0; j<ncols; j++) {
    6264                        _assert_(cols[j]==cols2[j]);
    6365                        d = max(max(-vals[j],-vals2[j]),0.);
    64                         MatSetValues(Dff_petsc,1,&row,1,&cols[j],(const double*)&d,INSERT_VALUES);
     66                        MatSetValues(D_petsc,1,&row,1,&cols[j],(const double*)&d,INSERT_VALUES);
    6567                        if(cols[j]!=row) diagD -= d;
    6668                }
    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);
     69                MatSetValues(D_petsc,1,&row,1,&row,(const double*)&diagD,INSERT_VALUES);
     70                MatRestoreRow(K_petsc, row,&ncols, (const int**)&cols, (const double**)&vals);
     71                MatRestoreRow(K_transp,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     72        }
     73        MatAssemblyBegin(D_petsc,MAT_FINAL_ASSEMBLY);
     74        MatAssemblyEnd(  D_petsc,MAT_FINAL_ASSEMBLY);
     75        MatFree(&K_transp);
    7476
    7577        /*Create LHS: [ML − theta*detlat *(K+D)^n+1]*/
    76         MatDuplicate(Kff_petsc,MAT_SHARE_NONZERO_PATTERN,&LHS);
     78        MatDuplicate(K_petsc,MAT_SHARE_NONZERO_PATTERN,&LHS);
    7779        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                MatGetRow(K_petsc,row,&ncols, (const int**)&cols, (const double**)&vals);
     81                MatGetRow(D_petsc,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
    8082                _assert_(ncols==ncols2);
    8183                for(int j=0; j<ncols; j++) {
     
    8385                        d = -theta*deltat*(vals[j] + vals2[j]);
    8486                        if(cols[j]==row){
    85                                 VecGetValues(Mlf_petsc,1,(const int*)&cols[j],&mi);
     87                                VecGetValues(Ml_petsc,1,(const int*)&cols[j],&mi);
    8688                                d += mi;
    8789                        }
     
    8991                        MatSetValues(LHS,1,&row,1,&cols[j],(const double*)&d,INSERT_VALUES);
    9092                }
    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                MatRestoreRow(K_petsc,row,&ncols, (const int**)&cols, (const double**)&vals);
     94                MatRestoreRow(D_petsc,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
    9395        }
    9496
     
    118120        VecDuplicate(u,&Du);
    119121        VecDuplicate(u,&RHS);
    120         MatMult(Kff_petsc,u,Ku);
    121         MatMult(Dff_petsc,u,Du);
    122         VecPointwiseMult(RHS,Mlf_petsc,u);
     122        MatMult(K_petsc,u,Ku);
     123        MatMult(D_petsc,u,Du);
     124        VecPointwiseMult(RHS,Ml_petsc,u);
    123125        VecAXPBYPCZ(RHS,(1-theta)*deltat,(1-theta)*deltat,1,Ku,Du);// RHS = M*u + (1-theta)*deltat*K*u + (1-theta)*deltat*D*u
    124126        VecFree(&Ku);
    125127        VecFree(&Du);
    126         MatFree(&Dff_petsc);
    127128        delete uf;
    128129
     
    138139                }
    139140        }
     141        VecAssemblyBegin(RHS);
     142        VecAssemblyEnd(  RHS);
    140143
    141144        /*Go solve!*/
     
    143146        MatFree(&LHS);
    144147        VecFree(&RHS);
     148
     149        /*Richardson to calculate udot*/
     150        Vec udot = NULL;
     151        VecDuplicate(u,&udot);
     152        VecZeroEntries(udot);
     153        Vec temp1 = NULL; VecDuplicate(u,&temp1);
     154        Vec temp2 = NULL; VecDuplicate(u,&temp2);
     155        for(int i=0;i<5;i++){
     156                /*udot_new = udot_old + Ml^-1 (K^(n+1) u -- Mc udot_old)*/
     157                MatMult(Mc_petsc,udot,temp1);
     158                MatMult(K_petsc, u,   temp2);
     159                VecAXPBY(temp2,-1.,1.,temp1); // temp2 = (K^(n+1) u -- Mc udot_old)
     160                VecPointwiseDivide(temp1,temp2,Ml_petsc); //temp1 = Ml^-1 temp2
     161                VecAXPBY(udot,1.,1.,temp1);
     162        }
     163        VecFree(&temp1);
     164        VecFree(&temp2);
     165
     166        /*Serialize u and udot*/
     167        IssmDouble* udot_serial = NULL;
     168        IssmDouble* u_serial    = NULL;
     169        VecToMPISerial(&udot_serial,udot,IssmComm::GetComm());
     170        VecToMPISerial(&u_serial   ,u   ,IssmComm::GetComm());
     171
     172
     173        /*Anti diffusive fluxes*/
     174        Mat F    = NULL;
     175        Vec Fbar = NULL;
     176        VecDuplicate(u,&Fbar);
     177        MatDuplicate(D_petsc,MAT_SHARE_NONZERO_PATTERN,&F);
     178        for(int row=rstart; row<rend; row++){
     179                MatGetRow(Mc_petsc,row,&ncols, (const int**)&cols, (const double**)&vals);
     180                MatGetRow(D_petsc ,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     181                _assert_(ncols==ncols2);
     182                mi = 0.;
     183                for(int j=0; j<ncols; j++) {
     184                        _assert_(cols[j]==cols2[j]);
     185                        d = vals[j]*(udot_serial[row] - udot_serial[cols[j]]) + vals2[j]*(u_serial[row] - u_serial[cols[j]]);
     186                        if(row!=cols[j]) mi += d;
     187                        MatSetValues(F,1,&row,1,&cols[j],(const double*)&d,INSERT_VALUES);
     188
     189                }
     190                VecSetValue(Fbar,row,(const double)mi,INSERT_VALUES);
     191                MatRestoreRow(Mc_petsc, row,&ncols, (const int**)&cols, (const double**)&vals);
     192                MatRestoreRow(D_petsc,row,&ncols2,(const int**)&cols2,(const double**)&vals2);
     193        }
     194        MatAssemblyBegin(F,MAT_FINAL_ASSEMBLY);
     195        MatAssemblyEnd(  F,MAT_FINAL_ASSEMBLY);
     196        VecAssemblyBegin(Fbar);
     197        VecAssemblyEnd(  Fbar);
     198
     199        MatFree(&D_petsc);
     200        MatFree(&F);
     201        delete Mc;
     202        xDelete<IssmDouble>(udot_serial);
     203        xDelete<IssmDouble>(u_serial);
     204
     205        /*Compute solution u^n+1 = u_L + deltat Ml^-1 fbar*/
     206        VecDuplicate(u,&temp1);
     207        VecPointwiseDivide(temp1,Fbar,Ml_petsc); //temp1 = Ml^-1 temp2
     208        VecAXPBY(udot,1.,1.,temp1);
     209        VecAXPY(u,deltat,temp1);
     210        VecFree(&Fbar);
     211        VecFree(&udot);
     212        VecFree(&temp1);
     213
    145214        uf =new Vector<IssmDouble>(u);
    146215        VecFree(&u);
     
    154223        #endif
    155224
    156         delete Mlf;
    157         delete Kff;
    158         delete Kfs;
     225        delete Ml;
     226        delete K;
    159227        delete analysis;
    160228
Note: See TracChangeset for help on using the changeset viewer.