Changeset 20117


Ignore:
Timestamp:
02/11/16 10:59:52 (9 years ago)
Author:
jbondzio
Message:

CHG: Enabling extrapolation for level-set-method in 3d; Cleanup of transient_core

Location:
issm/trunk-jpl
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/Makefile.am

    r20061 r20117  
    257257                                        ./cores/damage_core.cpp\
    258258                                        ./cores/levelsetfunctionslope_core.cpp\
     259                                        ./cores/levelset_core.cpp\
    259260                                        ./modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp\
    260261                                        ./classes/Loads/Riftfront.cpp\
  • issm/trunk-jpl/src/c/analyses/ExtrapolationAnalysis.cpp

    r18929 r20117  
    5959        bool save_results;
    6060        int extvar_enum;
    61    femmodel->parameters->FindParam(&extvar_enum, ExtrapolationVariableEnum);
     61        femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
     62        femmodel->parameters->FindParam(&extvar_enum, ExtrapolationVariableEnum);
    6263
    6364        /*activate formulation: */
     
    6768        solutionsequence_linear(femmodel);
    6869
    69         save_results=true;
    7070        if(save_results){
    7171                if(VerboseSolution()) _printf0_("   saving results\n");
    72                 int outputs[2] = {VxEnum,VyEnum};
    73                 femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],2);
     72                femmodel->RequestedOutputsx(&femmodel->results,&extvar_enum,1);
    7473        }
    7574}/*}}}*/
     
    8483ElementMatrix* ExtrapolationAnalysis::CreateKMatrix(Element* element){/*{{{*/
    8584
    86         if(!element->IsOnBase()) return NULL;
    87         Element* basalelement = element->SpawnBasalElement();
    88 
    8985        /*Intermediaries */
    90         int                domaintype,dim;
    91         int        i,row,col,stabilization;
    92         bool       extrapolatebydiffusion = true;
     86        int     dim, domaintype, extrapolationcase;
     87        int     i,row,col,stabilization;
     88        bool    extrapolatebydiffusion;
    9389        IssmDouble Jdet,D_scalar,h;
    9490        IssmDouble norm_dlsf;
    9591        IssmDouble hx,hy,hz,kappa;
    96         IssmDouble* xyz_list = NULL;
    97 
    98         /*Get problem dimension*/
    99         basalelement->FindParam(&domaintype,DomainTypeEnum);
     92        IssmDouble*     xyz_list = NULL;
     93        Element*                workelement=NULL;
     94
     95        /*Get problem case*/
     96        extrapolationcase=GetExtrapolationCase(element);
     97        switch(extrapolationcase){
     98                case 0:
     99                        if(!element->IsOnBase()) return NULL;
     100                        workelement = element->SpawnBasalElement();
     101                        break;
     102                case 1: case 2: case 3: workelement=element; break;
     103        }
     104        /* get extrapolation dimension */
     105        workelement->FindParam(&domaintype,DomainTypeEnum);
    100106        switch(domaintype){
    101                 case Domain2DverticalEnum:   dim = 1; break;
    102                 case Domain2DhorizontalEnum: dim = 2; break;
    103                 case Domain3DEnum:           dim = 2; break;
    104                 default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
     107                case Domain2DverticalEnum: dim=1; break;
     108                case Domain2DhorizontalEnum: dim=2; break;
     109                case Domain3DEnum: dim=3; break;
    105110        }
    106111
    107112        /*Fetch number of nodes and dof for this finite element*/
    108         int numnodes = basalelement->GetNumberOfNodes();
     113        int numnodes = workelement->GetNumberOfNodes();
    109114
    110115        /*Initialize Element vector and other vectors*/
    111         ElementMatrix* Ke     = basalelement->NewElementMatrix();
     116        ElementMatrix* Ke     = workelement->NewElementMatrix();
    112117        IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
    113118        IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
     
    117122
    118123        /*Retrieve all inputs and parameters*/
    119         Input* lsf_slopex_input=basalelement->GetInput(LevelsetfunctionSlopeXEnum); _assert_(lsf_slopex_input);
    120         Input* lsf_slopey_input=basalelement->GetInput(LevelsetfunctionSlopeYEnum); _assert_(lsf_slopey_input);
    121         basalelement->GetVerticesCoordinates(&xyz_list);
    122         h = basalelement->CharacteristicLength();
     124        Input* lsf_slopex_input=workelement->GetInput(LevelsetfunctionSlopeXEnum); _assert_(lsf_slopex_input);
     125        Input* lsf_slopey_input=workelement->GetInput(LevelsetfunctionSlopeYEnum); _assert_(lsf_slopey_input);
     126        workelement->GetVerticesCoordinates(&xyz_list);
    123127
    124128        /* Start  looping on the number of gaussian points: */
    125         Gauss* gauss=basalelement->NewGauss(2);
     129        Gauss* gauss=workelement->NewGauss(2);
    126130        for(int ig=gauss->begin();ig<gauss->end();ig++){/*{{{*/
    127131                gauss->GaussPoint(ig);
    128132
    129                 basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
    130                 GetB(B,basalelement,xyz_list,gauss);
    131                 GetBprime(Bprime,basalelement,xyz_list,gauss);
     133                workelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
     134                GetB(B,workelement,xyz_list,gauss,dim);
     135                GetBprime(Bprime,workelement,xyz_list,gauss,dim);
    132136               
    133137                D_scalar=gauss->weight*Jdet;
    134138
     139                extrapolatebydiffusion=true;
    135140                if(extrapolatebydiffusion){
    136141                        /* diffuse values outward */
    137142                        for(row=0;row<dim;row++)
    138143                                for(col=0;col<dim;col++)
    139                                         if(row==col)
     144                                        if(row==col && row<2) //extrapolate only in xy-plane
    140145                                                D[row*dim+col] = D_scalar;
    141146                                        else
     
    151156                        /* Get normal on ice boundary */
    152157                        lsf_slopex_input->GetInputValue(&dlsf[0],gauss);
    153                         lsf_slopey_input->GetInputValue(&dlsf[1],gauss);
     158                        if(dim>1)
     159                                lsf_slopey_input->GetInputValue(&dlsf[1],gauss);
     160                        if(dim>2)
     161                                dlsf[2]=0.;
    154162                        norm_dlsf=0.;
    155163                        for(i=0;i<dim;i++)      norm_dlsf+=dlsf[i]*dlsf[i];
     
    172180                                                &Ke->values[0],1);
    173181
    174                         /* Stabilization *//*{{{*/
     182                        /* stabilization *//*{{{*/
     183                        /* do not use streamline upwinding for extrapolation: it yields oscillating results due to diffusion along normal direction, but none across */
    175184                        stabilization=1;
    176185                        if (stabilization==0){/* no stabilization, do nothing*/}
    177186                        else if(stabilization==1){
    178187                                /* Artificial Diffusion */
    179                                 basalelement->ElementSizes(&hx,&hy,&hz);
    180                                 h=sqrt( pow(hx*normal[0],2) + pow(hy*normal[1],2));
     188                                workelement->ElementSizes(&hx,&hy,&hz);
     189                                h=sqrt(pow(hx*normal[0],2) + pow(hy*normal[1],2));
    181190                                kappa=h/2.+1.e-14;
    182191                                for(row=0;row<dim;row++)
     
    191200                                                        &Ke->values[0],1);
    192201                        }
    193                         else if(stabilization==2){
    194                                 /*Streamline upwinding - do not use this for extrapolation: yields oscillating results due to smoothing along normal, not across */
    195                                 for(row=0;row<dim;row++)
    196                                         for(col=0;col<dim;col++)
    197                                                 D[row*dim+col]=h/(2.*1.)*normal[row]*normal[col];
    198 
    199                                 TripleMultiply(Bprime,dim,numnodes,1,
    200                                                         D,dim,dim,0,
    201                                                         Bprime,dim,numnodes,0,
    202                                                         &Ke->values[0],1);
    203                         }/*}}}*/
     202                        /*}}}*/
    204203                }
    205204        }/*}}}*/
     
    213212        xDelete<IssmDouble>(normal);
    214213        delete gauss;
    215         if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
     214        if(extrapolationcase==0){workelement->DeleteMaterials(); delete workelement;};
    216215        return Ke;
    217216
     
    219218ElementVector* ExtrapolationAnalysis::CreatePVector(Element* element){/*{{{*/
    220219
    221         if(!element->IsOnBase()) return NULL;
    222         Element* basalelement = element->SpawnBasalElement();
    223 
    224220        /*Intermediaries */
    225         int i, domaintype;
    226        
     221        Element* workelement=NULL;
     222
     223        /*Get problem dimension*/
     224        int extrapolationcase=GetExtrapolationCase(element);
     225        switch(extrapolationcase){
     226                case 0:
     227                        if(!element->IsOnBase()) return NULL;
     228                        workelement = element->SpawnBasalElement();
     229                        break;
     230                case 1: case 2: case 3: workelement=element; break;
     231        }
     232
    227233        /*Fetch number of nodes */
    228         int numnodes = basalelement->GetNumberOfNodes();
     234        int numnodes = workelement->GetNumberOfNodes();
    229235
    230236        /*Initialize Element vector*/
    231         ElementVector* pe = basalelement->NewElementVector();
    232         for(i=0;i<numnodes;i++)
     237        ElementVector* pe = workelement->NewElementVector();
     238        for(int i=0;i<numnodes;i++)
    233239                pe->values[i]=0.;
    234240
    235         basalelement->FindParam(&domaintype,DomainTypeEnum);
    236         if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
     241        if(extrapolationcase==0){workelement->DeleteMaterials(); delete workelement;};
    237242        return pe;
    238243}/*}}}*/
    239 void           ExtrapolationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
     244void           ExtrapolationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss, int dim){/*{{{*/
    240245        /*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.
    241246         * For node i, Bi can be expressed in the actual coordinate system
     
    256261
    257262        /*Build B: */
    258         for(int i=0;i<numnodes;i++){
    259                 B[numnodes*0+i] = basis[i];
    260                 B[numnodes*1+i] = basis[i];
    261         }
     263        for(int i=0;i<numnodes;i++)
     264                for(int d=0;d<dim;d++)
     265                        B[numnodes*d+i] = basis[i];
    262266
    263267        /*Clean-up*/
    264268        xDelete<IssmDouble>(basis);
    265269}/*}}}*/
    266 void           ExtrapolationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
     270void           ExtrapolationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss, int dim){/*{{{*/
    267271        /*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2.
    268272         * For node i, Bi' can be expressed in the actual coordinate system
     
    279283
    280284        /*Get nodal functions derivatives*/
    281         IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
     285        IssmDouble* dbasis=xNew<IssmDouble>(dim*numnodes);
    282286        element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
    283287
    284288        /*Build B': */
    285         for(int i=0;i<numnodes;i++){
    286                 Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
    287                 Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
    288         }
     289        for(int i=0;i<numnodes;i++)
     290                for(int d=0;d<dim;d++)
     291                        Bprime[numnodes*d+i] = dbasis[d*numnodes+i];
    289292
    290293        /*Clean-up*/
     
    300303void           ExtrapolationAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
    301304
     305        int extrapolationvariable, extrapolationcase;
     306        extrapolationcase=GetExtrapolationCase(element);
     307        element->FindParam(&extrapolationvariable, ExtrapolationVariableEnum);
     308        switch(extrapolationcase){
     309                case 0:
     310                        element->InputUpdateFromSolutionOneDof(solution,extrapolationvariable);
     311                        break;
     312                case 1:
     313                        element->InputUpdateFromSolutionOneDof(solution,extrapolationvariable);
     314                        break;
     315                case 2:
     316                        element->InputUpdateFromSolutionOneDofCollapsed(solution,extrapolationvariable);
     317                        break;
     318                case 3:
     319                        element->InputUpdateFromSolutionOneDof(solution,extrapolationvariable);
     320                        break;
     321        }
     322}/*}}}*/
     323int                             ExtrapolationAnalysis::GetExtrapolationCase(Element* element){/*{{{*/
     324
     325        /* Get case of extrapolation, depending on domain quality, and extrapolation variable */
    302326        int domaintype, extrapolationvariable;
     327        int extrapolationcase;
    303328        element->FindParam(&domaintype,DomainTypeEnum);
    304         element->FindParam(&extrapolationvariable, ExtrapolationVariableEnum);
    305329        switch(domaintype){
    306                 case Domain2DhorizontalEnum:
    307                         element->InputUpdateFromSolutionOneDof(solution,extrapolationvariable);
    308                         break;
    309                 case Domain3DEnum:
    310                         element->InputUpdateFromSolutionOneDofCollapsed(solution,extrapolationvariable);
    311                         break;
    312                 default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
    313         }
     330                case Domain2DverticalEnum: extrapolationcase=0; break;
     331                case Domain2DhorizontalEnum: extrapolationcase=1;break;
     332                case Domain3DEnum: 
     333                        element->FindParam(&extrapolationvariable, ExtrapolationVariableEnum);
     334                        if(extrapolationvariable==ThicknessEnum) extrapolationcase=2; // scalar fields that are constant along z-axis
     335                        else extrapolationcase=3; // scalar fields that vary along z-axis
     336                        break;
     337        }
     338        return extrapolationcase;
    314339}/*}}}*/
    315340void           ExtrapolationAnalysis::SetConstraintsOnIce(Element* element){/*{{{*/
  • issm/trunk-jpl/src/c/analyses/ExtrapolationAnalysis.h

    r18929 r20117  
    2626        ElementMatrix* CreateKMatrix(Element* element);
    2727        ElementVector* CreatePVector(Element* element);
    28         void           GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
    29         void           GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
     28        void           GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss, int dim);
     29        void           GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss, int dim);
    3030        void           GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
    3131        void           GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_index);
    3232        void           InputUpdateFromSolution(IssmDouble* solution,Element* element);
     33        int                             GetExtrapolationCase(Element* element);
    3334        void           SetConstraintsOnIce(Element* element);
    3435        void           UpdateConstraints(FemModel* femmodel);
  • issm/trunk-jpl/src/c/classes/Node.cpp

    r19199 r20117  
    9595                                analysis_enum==HydrologyDCInefficientAnalysisEnum ||
    9696                                analysis_enum==HydrologyDCEfficientAnalysisEnum ||
    97                                 analysis_enum==LevelsetAnalysisEnum ||
    98                                 analysis_enum==ExtrapolationAnalysisEnum
     97                                analysis_enum==LevelsetAnalysisEnum
    9998                                ){
    10099                if(iomodel->domaintype!=Domain2DhorizontalEnum){
  • issm/trunk-jpl/src/c/cores/cores.h

    r20007 r20117  
    2424void surfaceslope_core(FemModel* femmodel);
    2525void levelsetfunctionslope_core(FemModel* femmodel);
     26void levelset_core(FemModel* femmodel);
    2627void bedslope_core(FemModel* femmodel);
    2728void meshdeformation_core(FemModel* femmodel);
  • issm/trunk-jpl/src/c/cores/transient_core.cpp

    r19749 r20117  
    102102                if(isdamageevolution) damage_core(femmodel);
    103103
    104                 if(islevelset){
    105                         if(iscalving) Calvingx(femmodel);
    106                         if(VerboseSolution()) _printf0_("   computing levelset transport\n");
    107                         /* smoothen slope of lsf for computation of normal on ice domain*/
    108                         levelsetfunctionslope_core(femmodel);
     104                if(islevelset)  levelset_core(femmodel);
    109105
    110                         /* extrapolate velocities onto domain with no ice */
    111                         Analysis* extanalysis = new ExtrapolationAnalysis();
    112                         const int nvars=3;
    113                         int vars[nvars] = {VxEnum, VyEnum, ThicknessEnum};
    114                         for(int iv=0;iv<nvars;iv++){
    115                                 femmodel->parameters->SetParam(vars[iv],ExtrapolationVariableEnum);
    116                                 extanalysis->Core(femmodel);
    117                         }
    118                         delete extanalysis;     
    119 
    120                         /* solve level set equation */
    121                         analysis = new LevelsetAnalysis();
    122                         analysis->Core(femmodel);
    123                         delete analysis;
    124 
    125                         /* update vertices included for next calculation */
    126                         GetMaskOfIceVerticesLSMx(femmodel);
    127 
    128                         /* add computation domain mask to outputs */
    129                         int outputs[1] = {IceMaskNodeActivationEnum};
    130                         femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1);
    131                 }
    132 
     106                /* from here on, prepare geometry for next time step*/
    133107                if(issmb)smb_core(femmodel);
    134108
     
    155129                }
    156130
    157                 /*Calculate new Basal melting on Floating ice*/
     131                /*Calculate new basal melting on floating ice*/
    158132                FloatingiceMeltingRatex(femmodel);
    159133               
Note: See TracChangeset for help on using the changeset viewer.