Ignore:
Timestamp:
06/01/22 05:01:48 (3 years ago)
Author:
Mathieu Morlighem
Message:

merged trunk-jpl and trunk for revision 27033

Location:
issm/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk

  • issm/trunk/src

  • issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp

    r26744 r27035  
    8080        iomodel->FetchDataToInput(inputs,elements,"md.mask.ice_levelset",MaskIceLevelsetEnum);
    8181        iomodel->FetchDataToInput(inputs,elements,"md.initialization.vx",VxEnum);
     82        iomodel->FetchDataToInput(inputs,elements,"md.initialization.vy",VyEnum);
    8283        if(iomodel->domaintype!=Domain2DhorizontalEnum){
    8384                iomodel->FetchDataToInput(inputs,elements,"md.mesh.vertexonsurface",MeshVertexonsurfaceEnum);
     
    111112}/*}}}*/
    112113ElementMatrix* FreeSurfaceTopAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
    113 _error_("Not implemented");
     114        _error_("Not implemented");
    114115}/*}}}*/
    115116ElementMatrix* FreeSurfaceTopAnalysis::CreateKMatrix(Element* element){/*{{{*/
     
    120121        IssmDouble *xyz_list  = NULL;
    121122        IssmDouble  Jdet,D_scalar,dt,h;
    122         IssmDouble  vel,vx,vy;
     123        IssmDouble  vel,vx,vy,tau;
    123124
    124125        /*Get top element*/
     
    195196                }
    196197
    197                 if(stabilization==2){
     198                if(stabilization==1){
     199                        /*artifical diffusion*/
     200                        if(dim==1){
     201                                vx_input->GetInputAverage(&vx);
     202                                D[0]=h/2.*fabs(vx);
     203                        }
     204                        else{
     205                                vx_input->GetInputAverage(&vx);
     206                                vy_input->GetInputAverage(&vy);
     207
     208                                D[0*dim+0]=h/2.0*fabs(vx);
     209                                D[1*dim+1]=h/2.0*fabs(vy);
     210                        }
     211                }
     212                else if(stabilization==2){
    198213                        /*Streamline upwinding*/
    199214                        if(dim==1){
     
    209224                        }
    210225                }
    211                 else if(stabilization==1){
    212                         /*SSA*/
     226                else if(stabilization==5){
     227                        /*SUPG*/
    213228                        if(dim==1){
    214229                                vx_input->GetInputAverage(&vx);
    215                                 D[0]=h/2.*fabs(vx);
     230                                tau=h/(2.*fabs(vx)+1e-10);
    216231                        }
    217232                        else{
    218233                                vx_input->GetInputAverage(&vx);
    219234                                vy_input->GetInputAverage(&vy);
    220 
    221                                 D[0*dim+0]=h/2.0*fabs(vx);
    222                                 D[1*dim+1]=h/2.0*fabs(vy);
     235                                tau=1*h/(2.*pow(vx*vx+vy*vy,0.5)+1e-10);
    223236                        }
    224237                }
     
    229242                                        for(int j=0;j<numnodes;j++){
    230243                                                Ke->values[i*numnodes+j] += (
    231                                                                         dbasis[0*numnodes+i] *(D[0*dim+0]*dbasis[0*numnodes+j] + D[0*dim+1]*dbasis[1*numnodes+j]) +
    232                                                                         dbasis[1*numnodes+i] *(D[1*dim+0]*dbasis[0*numnodes+j] + D[1*dim+1]*dbasis[1*numnodes+j])
    233                                                                         );
     244                                                                dbasis[0*numnodes+i] *(D[0*dim+0]*dbasis[0*numnodes+j] + D[0*dim+1]*dbasis[1*numnodes+j]) +
     245                                                                dbasis[1*numnodes+i] *(D[1*dim+0]*dbasis[0*numnodes+j] + D[1*dim+1]*dbasis[1*numnodes+j])
     246                                                                );
    234247                                        }
    235248                                }
     
    237250                        else{
    238251                                for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j] += dbasis[0*numnodes+i]*D[0]*dbasis[0*numnodes+j];
     252                        }
     253                }
     254                else if(stabilization==5){
     255                        D_scalar=gauss->weight*Jdet*dt;
     256                        if(dim==2){
     257                                for(int i=0;i<numnodes;i++){
     258                                        for(int j=0;j<numnodes;j++){
     259                                                Ke->values[i*numnodes+j]+=tau*D_scalar*
     260                                                        (vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i])*
     261                                                        (vx*dbasis[0*numnodes+j]+vy*dbasis[1*numnodes+j]);
     262                                        }
     263                                }
     264                        }
     265                        else{
     266                                for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j]+=tau*D_scalar*(vx*dbasis[0*numnodes+i])*(vx*dbasis[0*numnodes+j]);
    239267                        }
    240268                }
     
    251279}/*}}}*/
    252280ElementVector* FreeSurfaceTopAnalysis::CreatePVector(Element* element){/*{{{*/
     281
    253282        /*Intermediaries*/
    254         int         domaintype,dim;
     283        int         domaintype,dim,stabilization;
    255284        IssmDouble  Jdet,dt;
    256         IssmDouble  ms,surface,vz;
     285        IssmDouble  ms,surface,vx,vy,vz,tau;
    257286        Element*    topelement = NULL;
    258287        IssmDouble *xyz_list  = NULL;
     
    284313        ElementVector* pe    = topelement->NewElementVector();
    285314        IssmDouble*    basis = xNew<IssmDouble>(numnodes);
     315        IssmDouble*    dbasis = xNew<IssmDouble>(dim*numnodes);
    286316
    287317        /*Retrieve all inputs and parameters*/
    288318        topelement->GetVerticesCoordinates(&xyz_list);
    289319        topelement->FindParam(&dt,TimesteppingTimeStepEnum);
    290         Input* ms_input      = topelement->GetInput(SmbMassBalanceEnum);  _assert_(ms_input);
    291         Input* surface_input = topelement->GetInput(SurfaceEnum);                     _assert_(surface_input);
    292         Input* vz_input      = NULL;
     320        Input *ms_input      = topelement->GetInput(SmbMassBalanceEnum); _assert_(ms_input);
     321        Input *surface_input = topelement->GetInput(SurfaceEnum);        _assert_(surface_input);
     322        Input *vz_input      = NULL;
     323        Input *vx_input      = NULL;
     324        Input *vy_input      = NULL;
    293325        switch(dim){
    294                 case 1: vz_input = topelement->GetInput(VyEnum); _assert_(vz_input); break;
    295                 case 2: vz_input = topelement->GetInput(VzEnum); _assert_(vz_input); break;
     326                case 1:
     327                        vx_input=topelement->GetInput(VxEnum); _assert_(vx_input);
     328                        vz_input = topelement->GetInput(VyEnum) ; _assert_(vz_input);
     329                        break;
     330                case 2:
     331                        vx_input=topelement->GetInput(VxEnum); _assert_(vx_input);
     332                        vy_input = topelement->GetInput(VyEnum); _assert_(vy_input);
     333                        vz_input = topelement->GetInput(VzEnum); _assert_(vz_input);
     334                        break;
    296335                default: _error_("not implemented");
    297336        }
     337        IssmDouble h = topelement->CharacteristicLength();
    298338
    299339        /*Initialize mb_correction to 0, do not forget!:*/
     
    312352        }
    313353
     354        if(stabilization==5){
     355                /*SUPG*/
     356                topelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
     357                if(dim==1){
     358                        vx_input->GetInputAverage(&vx);
     359                        tau=h/(2.*fabs(vx)+1e-10);
     360                        for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(dt*ms+dt*vz)*tau*(vx*dbasis[0*numnodes+i]);
     361                }
     362                else{
     363                        vx_input->GetInputAverage(&vx);
     364                        vy_input->GetInputAverage(&vy);
     365                        tau=h/(2.*pow(vx*vx+vy*vy,0.5)+1e-10);
     366                        for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(dt*ms+dt*vz)*tau*(vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i]);
     367                }
     368        }
     369
    314370        /*Clean up and return*/
    315371        xDelete<IssmDouble>(xyz_list);
    316372        xDelete<IssmDouble>(basis);
     373        xDelete<IssmDouble>(dbasis);
    317374        delete gauss;
    318375        if(topelement->IsSpawnedElement()){topelement->DeleteMaterials(); delete topelement;};
     
    321378}/*}}}*/
    322379void           FreeSurfaceTopAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
    323            _error_("not implemented yet");
     380        _error_("not implemented yet");
    324381}/*}}}*/
    325382void           FreeSurfaceTopAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element*  element,int control_type,int control_interp,int control_index){/*{{{*/
     
    329386
    330387        element->InputUpdateFromSolutionOneDof(solution,SurfaceEnum);
     388
     389        /*Now, we need to do some "processing"*/
     390        int numvertices = element->GetNumberOfVertices();
     391        int        migration_style;
     392
     393        IssmDouble* surface = xNew<IssmDouble>(numvertices);
     394        IssmDouble* newsurface = xNew<IssmDouble>(numvertices);
     395        IssmDouble* thickness = xNew<IssmDouble>(numvertices);
     396        IssmDouble* base = xNew<IssmDouble>(numvertices);
     397        IssmDouble* bed = xNew<IssmDouble>(numvertices);
     398        IssmDouble* phi = xNew<IssmDouble>(numvertices);
     399        IssmDouble* sealevel = xNew<IssmDouble>(numvertices);
     400
     401        IssmDouble minthickness = element->FindParam(MasstransportMinThicknessEnum);
     402        IssmDouble rho_ice      = element->FindParam(MaterialsRhoIceEnum);
     403        IssmDouble rho_water    = element->FindParam(MaterialsRhoSeawaterEnum);
     404
     405        bool isgroundingline;
     406        element->FindParam(&isgroundingline,TransientIsgroundinglineEnum);
     407        element->FindParam(&migration_style,GroundinglineMigrationEnum);
     408        if(isgroundingline) element->GetInputListOnVertices(&bed[0],BedEnum);
     409
     410        element->GetInputListOnVertices(&base[0],BaseEnum);
     411        element->GetInputListOnVertices(&surface[0],SurfaceEnum);
     412        element->GetInputListOnVertices(&phi[0],MaskOceanLevelsetEnum);
     413        element->GetInputListOnVertices(&sealevel[0],SealevelEnum);
     414
     415        for(int i=0;i<numvertices;i++){
     416                newsurface[i]=surface[i];
     417                thickness[i]=surface[i]-base[i];
     418                /*Check solution*/
     419                if(xIsNan<IssmDouble>(thickness[i])) _error_("NaN found in solution vector");
     420                if(xIsInf<IssmDouble>(thickness[i])) _error_("Inf found in solution vector");
     421
     422                /* check for thickness<minthickness */
     423                if(thickness[i]<minthickness){
     424                        thickness[i]=minthickness;
     425                        if(phi[i]>0.){
     426                                if(base[i]<=bed[i]) base[i] = bed[i];
     427                                newsurface[i] = base[i]+minthickness;
     428                        }else{
     429                                // assume floatation condition
     430                                newsurface[i] = (1.-rho_ice/rho_water)*minthickness;
     431                                base[i] = -rho_ice/rho_water*minthickness;
     432                        }
     433                }
     434
     435                /* update thickness */
     436                thickness[i]=newsurface[i]-base[i];
     437                /* some checks */
     438                if(thickness[i]<0.) _error_("thickness<0");
     439                if(newsurface[i]<base[i]) _error_("surface<base");
     440        }
     441
     442        /* update inputs */
     443        element->AddInput(BaseEnum,base,element->GetElementType());
     444        element->AddInput(SurfaceEnum,newsurface,element->GetElementType());
     445        element->AddInput(ThicknessEnum,thickness,element->GetElementType());
     446
     447        /* Free resources */
     448        xDelete<IssmDouble>(newsurface);
     449        xDelete<IssmDouble>(surface);
     450        xDelete<IssmDouble>(thickness);
     451        xDelete<IssmDouble>(base);
     452        xDelete<IssmDouble>(bed);
     453        xDelete<IssmDouble>(phi);
     454        xDelete<IssmDouble>(sealevel);
    331455}/*}}}*/
    332456void           FreeSurfaceTopAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
Note: See TracChangeset for help on using the changeset viewer.