Changeset 27004


Ignore:
Timestamp:
05/13/22 06:38:23 (3 years ago)
Author:
Cheng Gong
Message:

ADD: stablization=6 for levelset functions using FAB+SUPG

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

Legend:

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

    r26972 r27004  
    1010#include "../modules/modules.h"
    1111#include "../solutionsequences/solutionsequences.h"
     12#include <math.h>
    1213
    1314void LevelsetAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
     
    423424                                break;
    424425                        }
     426                        case 6:{
     427                                /*SUPG*/
     428                                IssmDouble vx,vy;
     429                                mf_vx_input->GetInputAverage(&vx);
     430                                mf_vy_input->GetInputAverage(&vy);
     431                                vel=sqrt(vx*vx+vy*vy)+1.e-8;
     432                                IssmDouble ECN, K;
     433                                ECN = vel *dt /h;
     434                                K = 1./tanh(ECN) - 1./ECN;
     435//                              if (ECN<1e-6) K = ECN /3.0;
     436
     437                                /*According to Hilmar, xi=K is too large*/
     438                                IssmPDouble xi=0.1*K;
     439
     440                                IssmDouble  tau=xi*h/(2*vel);
     441                                Input* levelset_input = NULL;
     442
     443
     444                                IssmDouble kappa;
     445                                IssmDouble p=4, q=4;
     446                                IssmDouble phi[3];
     447
     448                           levelset_input=basalelement->GetInput(MaskIceLevelsetEnum); _assert_(levelset_input);
     449                                levelset_input->GetInputValue(&phi[0], gauss);
     450
     451                                IssmDouble dphidx=0., dphidy=0.;
     452                                IssmDouble nphi;
     453
     454                                for(int i=0;i<numnodes;i++){
     455                                        dphidx += phi[i]*dbasis[0*numnodes+i];
     456                                        dphidy += phi[i]*dbasis[1*numnodes+i];
     457                                }
     458                                nphi = sqrt(dphidx*dphidx+dphidy*dphidy);
     459                       
     460                                if (nphi >= 1) {
     461                                        kappa = 1 - 1.0/nphi;
     462                                }
     463                                else {
     464                                        kappa = 0.5/M_PI *sin(2*M_PI*nphi)/nphi;
     465                                }
     466
     467                                kappa = kappa * vel / h;
     468
     469                                /*Mass matrix - part 2*/
     470                                for(int i=0;i<numnodes;i++){
     471                                        for(int j=0;j<numnodes;j++){
     472                                                Ke->values[i*numnodes+j]+=gauss->weight*Jdet*tau*basis[j]*(vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i]);
     473                                        }
     474                                }
     475
     476                                /*Advection matrix - part 2, A*/
     477                                for(int i=0;i<numnodes;i++){
     478                                        for(int j=0;j<numnodes;j++){
     479                                                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]);
     480                                        }
     481                                }
     482                                /*Add the pertubation term \nabla\cdot(\kappa*\nabla\phi)*/
     483                                for(int i=0;i<numnodes;i++){
     484                                        for(int j=0;j<numnodes;j++){
     485                                                for(int k=0;k<dim;k++){
     486                                                                Ke->values[i*numnodes+j]+= dt*gauss->weight*Jdet*kappa*dbasis[k*numnodes+j]*dbasis[k*numnodes+i];
     487                                                }
     488                                        }
     489                                }
     490
     491                                break;
     492                        }
    425493                        default:
    426494                                _error_("unknown type of stabilization in LevelsetAnalysis.cpp");
     
    458526        IssmDouble*    basis = xNew<IssmDouble>(numnodes);
    459527        IssmDouble*    dbasis = NULL;
    460         if(stabilization==5) dbasis= xNew<IssmDouble>(2*numnodes);
     528        if((stabilization==5) |(stabilization == 6)) dbasis= xNew<IssmDouble>(2*numnodes);
    461529
    462530        /*Retrieve all inputs and parameters*/
     
    479547
    480548                if(stabilization==5){ /*SUPG*/
    481          IssmDouble vx,vy,vel;
     549                        IssmDouble vx,vy,vel;
    482550                        basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
    483551                        mf_vx_input->GetInputAverage(&vx);
     
    492560                        }
    493561                }
     562                else if (stabilization ==6) {
     563                        IssmDouble vx,vy,vel;
     564                        basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
     565                        mf_vx_input->GetInputAverage(&vx);
     566                        mf_vy_input->GetInputAverage(&vy);
     567                        vel=sqrt(vx*vx+vy*vy)+1.e-8;
     568
     569                        IssmDouble ECN, K;
     570                        ECN = vel *dt /h;
     571                        K = 1./tanh(ECN) - 1./ECN;
     572        //              if (ECN<1e-6) K = ECN /3.0;
     573
     574                        /*According to Hilmar, xi=K is too large*/
     575                        IssmPDouble xi=0.1*K;
     576
     577                        IssmDouble  tau=xi*h/(2*vel);
     578
     579                        /*Force vector - part 2*/
     580                        for(int i=0;i<numnodes;i++){
     581                                pe->values[i]+=Jdet*gauss->weight*lsf*tau*(vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i]);
     582                        }
     583                }
    494584        }
    495585
     
    497587        xDelete<IssmDouble>(xyz_list);
    498588        xDelete<IssmDouble>(basis);
    499    xDelete<IssmDouble>(dbasis);
     589        xDelete<IssmDouble>(dbasis);
    500590        basalelement->FindParam(&domaintype,DomainTypeEnum);
    501591        if(basalelement->IsSpawnedElement()){basalelement->DeleteMaterials(); delete basalelement;};
  • issm/trunk-jpl/src/m/classes/levelset.m

    r26421 r27004  
    6262
    6363                        md = checkfield(md,'fieldname','levelset.spclevelset','Inf',1,'timeseries',1);
    64                         md = checkfield(md,'fieldname','levelset.stabilization','values',[0 1 2 5]);
     64                        md = checkfield(md,'fieldname','levelset.stabilization','values',[0 1 2 5 6]);
    6565                        md = checkfield(md,'fieldname','levelset.kill_icebergs','numel',1,'values',[0 1]);
    6666                        md = checkfield(md,'fieldname','levelset.migration_max','numel',1,'NaN',1,'Inf',1,'>',0);
Note: See TracChangeset for help on using the changeset viewer.