Changeset 26420


Ignore:
Timestamp:
09/01/21 18:23:05 (4 years ago)
Author:
Mathieu Morlighem
Message:

CHG: added new stabilization schemes for levelset transport

File:
1 edited

Legend:

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

    r26328 r26420  
    215215        IssmDouble*    basis    = xNew<IssmDouble>(numnodes);
    216216        IssmDouble*    dbasis   = xNew<IssmDouble>(2*numnodes);
    217         IssmDouble*    Bprime = NULL;
    218         if(stabilization==2){
    219                 Bprime   = xNew<IssmDouble>(dim*numnodes);
    220         }
    221217
    222218        /*Retrieve all inputs and parameters*/
     
    224220        basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
    225221        basalelement->FindParam(&migrationmax,MigrationMaxEnum);
     222
     223        h = element->CharacteristicLength();
    226224
    227225        Input* mf_vx_input        = NULL;
     
    291289                switch(stabilization){
    292290                        case 0:
    293                                 // no stabilization, do nothing
     291                                /*Nothing to be done*/
    294292                                break;
    295293                        case 1:
     
    309307                                  {
    310308                                        /* Streamline Upwinding */
    311                                         basalelement->ElementSizes(&hx,&hy,&hz);
    312                                         h=sqrt( pow(hx*w[0]/vel,2) + pow(hy*w[1]/vel,2) );
     309                                        mf_vx_input->GetInputAverage(&w[0]);
     310                                        mf_vy_input->GetInputAverage(&w[1]);
     311                                        vel=sqrt(w[0]*w[0]+w[1]*w[1])+1.e-8;
     312                                        IssmDouble tau=h/(2*vel);
    313313                                        for(int i=0;i<numnodes;i++){
    314314                                                for(int j=0;j<numnodes;j++){
    315                                                         Ke->values[i*numnodes+j] += D_scalar*h/(2.*vel)*(
    316                                                                                 dbasis[0*numnodes+i] *(w[0]*w[0]*dbasis[0*numnodes+j] + w[0]*w[1]*dbasis[1*numnodes+j]) +
    317                                                                                 dbasis[1*numnodes+i] *(w[1]*w[0]*dbasis[0*numnodes+j] + w[1]*w[1]*dbasis[1*numnodes+j])
    318                                                                                 );
     315                                                        Ke->values[i*numnodes+j]+=dt*gauss->weight*Jdet*tau*(
     316                                                                                w[0]*dbasis[0*numnodes+i]+w[1]*dbasis[1*numnodes+i])*(w[0]*dbasis[0*numnodes+j]+w[1]*dbasis[1*numnodes+j]);
    319317                                                }
    320318                                        }
    321319                                  }
    322320                                break;
     321                        case 5:{
     322                                /*SUPG*/
     323                                mf_vx_input->GetInputAverage(&w[0]);
     324                                mf_vy_input->GetInputAverage(&w[1]);
     325                                vel=sqrt(w[0]*w[0]+w[1]*w[1])+1.e-8;
     326                                IssmPDouble xi=1.;
     327                                IssmDouble  tau=xi*h/(2*vel);
     328
     329                                IssmDouble vx,vy;
     330                                vx = w[0]; vy = w[1];
     331                                /*Mass matrix - part 2*/
     332                                for(int i=0;i<numnodes;i++){
     333                                        for(int j=0;j<numnodes;j++){
     334                                                Ke->values[i*numnodes+j]+=gauss->weight*Jdet*tau*basis[j]*(vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i]);
     335                                        }
     336                                }
     337
     338                                /*Advection matrix - part 2, A*/
     339                                for(int i=0;i<numnodes;i++){
     340                                        for(int j=0;j<numnodes;j++){
     341                                                Ke->values[i*numnodes+j]+=dt*gauss->weight*Jdet*tau*(vx*dbasis[0*numnodes+j]+vy*dbasis[1*numnodes+j])*(vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i]);
     342                                        }
     343                                }
     344
     345                                break;
     346                        }
    323347                        default:
    324348                                _error_("unknown type of stabilization in LevelsetAnalysis.cpp");
     
    330354        xDelete<IssmDouble>(basis);
    331355        xDelete<IssmDouble>(dbasis);
    332         xDelete<IssmDouble>(Bprime);
    333356        delete gauss;
    334357        if(basalelement->IsSpawnedElement()){basalelement->DeleteMaterials(); delete basalelement;};
     
    341364
    342365        /*Intermediaries */
    343         int domaintype;
     366        int         domaintype,stabilization;
    344367        IssmDouble  Jdet,dt;
    345368        IssmDouble  lsf;
     
    348371        /*Fetch number of nodes and dof for this finite element*/
    349372        int numnodes = basalelement->GetNumberOfNodes();
     373        basalelement->FindParam(&stabilization,MasstransportStabilizationEnum);
    350374
    351375        /*Initialize Element vector*/
    352376        ElementVector* pe = basalelement->NewElementVector();
    353         basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
    354 
    355         if(dt!=0.){
    356                 /*Initialize basis vector*/
    357                 IssmDouble*    basis = xNew<IssmDouble>(numnodes);
    358 
    359                 /*Retrieve all inputs and parameters*/
    360                 basalelement->GetVerticesCoordinates(&xyz_list);
    361                 Input* levelset_input  = basalelement->GetInput(MaskIceLevelsetEnum); _assert_(levelset_input);
    362 
    363                 /* Start  looping on the number of gaussian points: */
    364                 Gauss* gauss=basalelement->NewGauss(2);
    365                 while(gauss->next()){
    366                         basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
    367                         basalelement->NodalFunctions(basis,gauss);
    368 
    369                         /* old function value */
    370                         levelset_input->GetInputValue(&lsf,gauss);
    371                         for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*lsf*basis[i];
    372                 }
    373 
    374                 /*Clean up and return*/
    375                 xDelete<IssmDouble>(xyz_list);
    376                 xDelete<IssmDouble>(basis);
    377                 basalelement->FindParam(&domaintype,DomainTypeEnum);
    378                 if(basalelement->IsSpawnedElement()){basalelement->DeleteMaterials(); delete basalelement;};
    379                 delete gauss;
    380         }
     377        basalelement->FindParam(&dt,TimesteppingTimeStepEnum); _assert_(dt>0.);
     378
     379        /*Initialize basis vector*/
     380        IssmDouble*    basis = xNew<IssmDouble>(numnodes);
     381        IssmDouble*    dbasis = NULL;
     382        if(stabilization==5) dbasis= xNew<IssmDouble>(2*numnodes);
     383
     384        /*Retrieve all inputs and parameters*/
     385        basalelement->GetVerticesCoordinates(&xyz_list);
     386        Input* levelset_input = basalelement->GetInput(MaskIceLevelsetEnum); _assert_(levelset_input);
     387        Input* mf_vx_input    = basalelement->GetInput(MovingFrontalVxEnum); _assert_(mf_vx_input);
     388        Input* mf_vy_input    = basalelement->GetInput(MovingFrontalVyEnum); _assert_(mf_vy_input);
     389
     390        IssmDouble h=element->CharacteristicLength();
     391
     392        /* Start  looping on the number of gaussian points: */
     393        Gauss* gauss=basalelement->NewGauss(2);
     394        while(gauss->next()){
     395                basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
     396                basalelement->NodalFunctions(basis,gauss);
     397
     398                /* old function value */
     399                levelset_input->GetInputValue(&lsf,gauss);
     400                for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*lsf*basis[i];
     401
     402                if(stabilization==5){ /*SUPG*/
     403         IssmDouble vx,vy,vel;
     404                        basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
     405                        mf_vx_input->GetInputAverage(&vx);
     406                        mf_vy_input->GetInputAverage(&vy);
     407                        vel=sqrt(vx*vx+vy*vy)+1.e-8;
     408                        IssmPDouble xi=1;
     409                        IssmDouble  tau=xi*h/(2*vel);
     410
     411                        /*Force vector - part 2*/
     412                        for(int i=0;i<numnodes;i++){
     413                                pe->values[i]+=Jdet*gauss->weight*lsf*(tau*vx*dbasis[0*numnodes+i]+tau*vy*dbasis[1*numnodes+i]);
     414                        }
     415                }
     416        }
     417
     418        /*Clean up and return*/
     419        xDelete<IssmDouble>(xyz_list);
     420        xDelete<IssmDouble>(basis);
     421   xDelete<IssmDouble>(dbasis);
     422        basalelement->FindParam(&domaintype,DomainTypeEnum);
     423        if(basalelement->IsSpawnedElement()){basalelement->DeleteMaterials(); delete basalelement;};
     424        delete gauss;
    381425
    382426        return pe;
Note: See TracChangeset for help on using the changeset viewer.