Changeset 17334


Ignore:
Timestamp:
02/21/14 10:24:59 (11 years ago)
Author:
jbondzio
Message:

ADD: LsfReinitializationAnalysis: CreateKMatrix, CreatePVector. Preparing Picard Iteration on Levelsetfunction for initialization.

Location:
issm/trunk-jpl/src
Files:
1 added
7 edited

Legend:

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

    r17307 r17334  
    55#include "../modules/modules.h"
    66
     7#include "../modules/GetVectorFromInputsx/GetVectorFromInputsx.h"
     8
    79/*Model processing*/
    810int  LsfReinitializationAnalysis::DofsPerNode(int** doflist,int meshtype,int approximation){/*{{{*/
     
    1315}/*}}}*/
    1416void LsfReinitializationAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
    15         /* Do nothing for now */
     17        int    finiteelement;
     18
     19        /*Finite element type*/
     20        finiteelement = P1Enum;
     21
     22        /*Update elements: */
     23        int counter=0;
     24        for(int i=0;i<iomodel->numberofelements;i++){
     25                if(iomodel->my_elements[i]){
     26                        Element* element=(Element*)elements->GetObjectByOffset(counter);
     27                        element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
     28                        counter++;
     29                }
     30        }
    1631}/*}}}*/
    1732void LsfReinitializationAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
    18         /* Do nothing for now */
     33        int finiteelement=P1Enum;
     34        ::CreateNodes(nodes,iomodel,LsfReinitializationAnalysisEnum,finiteelement);
    1935}/*}}}*/
    2036void LsfReinitializationAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
     
    2642
    2743/*Finite element Analysis*/
    28 void           LsfReinitializationAnalysis::Core(FemModel* femmodel){/*{{{*/
    29         _error_("not implemented yet");
     44void  LsfReinitializationAnalysis::Core(FemModel* femmodel){/*{{{*/
     45
     46        /*parameters: */
     47        bool save_results;
     48        femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
     49
     50        /*activate formulation: */
     51        femmodel->SetCurrentConfiguration(LsfReinitializationAnalysisEnum);
     52
     53        /* set spcs for reinitialization */
     54        if(VerboseSolution()) _printf0_("Update spcs for reinitialization:\n");
     55        UpdateReinitSPCs(femmodel);
     56
     57        if(VerboseSolution()) _printf0_("call computational core for reinitialization:\n");
     58//      solutionsequence_lsfreinit_linear(femmodel);
     59
     60        if(save_results){
     61                if(VerboseSolution()) _printf0_("   saving results\n");
     62                int outputs = MaskIceLevelsetEnum;
     63                femmodel->RequestedOutputsx(&femmodel->results,&outputs,1);
     64        }
     65
    3066}/*}}}*/
    3167ElementVector* LsfReinitializationAnalysis::CreateDVector(Element* element){/*{{{*/
    32         _error_("not implemented yet");
     68        /*Default, return NULL*/
     69        return NULL;
    3370}/*}}}*/
    3471ElementMatrix* LsfReinitializationAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/
     
    3673}/*}}}*/
    3774ElementMatrix* LsfReinitializationAnalysis::CreateKMatrix(Element* element){/*{{{*/
    38         _error_("not implemented yet");
     75
     76        /*Intermediaries */
     77        const int dim = 2;
     78        int        i,row,col,stabilization;
     79        IssmDouble Jdet,D_scalar,h;
     80        IssmDouble dlsf[3],normal[3];
     81        IssmDouble norm_dlsf;
     82        IssmDouble hx,hy,hz,kappa;
     83        IssmDouble* xyz_list = NULL;
     84
     85        /*Fetch number of nodes and dof for this finite element*/
     86        int numnodes = element->GetNumberOfNodes();
     87
     88        /*Initialize Element vector and other vectors*/
     89        ElementMatrix* Ke     = element->NewElementMatrix();
     90        IssmDouble*    B      = xNew<IssmDouble>(dim*numnodes);
     91        IssmDouble*    Bprime = xNew<IssmDouble>(dim*numnodes);
     92        IssmDouble     D[dim][dim];
     93
     94        /*Retrieve all inputs and parameters*/
     95        Input* lsfpicard_input=element->GetInput(LevelsetfunctionPicardEnum); _assert_(lsfpicard_input);
     96        element->GetVerticesCoordinates(&xyz_list);
     97        h = element->CharacteristicLength();
     98
     99        /* Start  looping on the number of gaussian points: */
     100        Gauss* gauss=element->NewGauss(2);
     101        for(int ig=gauss->begin();ig<gauss->end();ig++){/*{{{*/
     102                gauss->GaussPoint(ig);
     103
     104                element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     105                GetB(B,element,xyz_list,gauss);
     106                GetBprime(Bprime,element,xyz_list,gauss);
     107
     108                /* Get normal from last iteration on lsf */
     109                lsfpicard_input->GetInputDerivativeValue(&dlsf[0],xyz_list,gauss);
     110
     111                norm_dlsf=0.;
     112                for(i=0;i<dim;i++) norm_dlsf+=dlsf[i]*dlsf[i];
     113                norm_dlsf=sqrt(norm_dlsf); _assert_(norm_dlsf>0.);
     114                for(i=0;i<dim;i++)
     115                        normal[i]=dlsf[i]/norm_dlsf;
     116               
     117                D_scalar=gauss->weight*Jdet;
     118
     119                for(row=0;row<dim;row++)
     120                        for(col=0;col<dim;col++)
     121                                if(row==col)
     122                                        D[row][col]=D_scalar*normal[row];
     123                                else
     124                                        D[row][col]=0.;
     125                TripleMultiply(B,dim,numnodes,1,
     126                                        &D[0][0],dim,dim,0,
     127                                        Bprime,dim,numnodes,0,
     128                                        &Ke->values[0],1);
     129
     130                /* Stabilization *//*{{{*/
     131                stabilization=1;
     132                if (stabilization==0){/* no stabilization, do nothing*/}
     133                else if(stabilization==1){
     134                        /* Artificial Diffusion */
     135                        element->ElementSizes(&hx,&hy,&hz);
     136                        h=sqrt( pow(hx*normal[0],2) + pow(hy*normal[1],2));
     137                        kappa=h/2.;
     138                        D[0][0]=D_scalar*kappa;
     139                        D[0][1]=0.;
     140                        D[1][0]=0.;
     141                        D[1][1]=D_scalar*kappa;
     142                        TripleMultiply(Bprime,dim,numnodes,1,
     143                                                &D[0][0],dim,dim,0,
     144                                                Bprime,dim,numnodes,0,
     145                                                &Ke->values[0],1);
     146                }
     147                else if(stabilization==2){
     148                        /*Streamline upwinding - do not use this for extrapolation: yields oscillating results due to smoothing along normal, not across */
     149                        for(row=0;row<dim;row++)
     150                                for(col=0;col<dim;col++)
     151                                        D[row][col]=h/(2.*1.)*normal[row]*normal[col];
     152
     153                        TripleMultiply(Bprime,dim,numnodes,1,
     154                                                &D[0][0],dim,dim,0,
     155                                                Bprime,dim,numnodes,0,
     156                                                &Ke->values[0],1);
     157                }/*}}}*/
     158        }/*}}}*/
     159
     160        /*Clean up and return*/
     161        xDelete<IssmDouble>(xyz_list);
     162        xDelete<IssmDouble>(B);
     163        xDelete<IssmDouble>(Bprime);
     164        delete gauss;
     165        return Ke;
    39166}/*}}}*/
    40167ElementVector* LsfReinitializationAnalysis::CreatePVector(Element* element){/*{{{*/
    41         _error_("not implemented yet");
    42 }/*}}}*/
     168       
     169        /*Intermediaries */
     170        IssmDouble Jdet;
     171        IssmDouble* xyz_list = NULL;
     172       
     173        /*Fetch number of nodes */
     174        int numnodes = element->GetNumberOfNodes();
     175
     176        IssmDouble* basis = xNew<IssmDouble>(numnodes);
     177        element->GetVerticesCoordinates(&xyz_list);
     178
     179        /*Initialize Element vector*/
     180        ElementVector* pe = element->NewElementVector();
     181
     182        Gauss* gauss=element->NewGauss(2);
     183        for(int ig=gauss->begin();ig<gauss->end();ig++){
     184                gauss->GaussPoint(ig);
     185
     186                element->JacobianDeterminant(&Jdet,xyz_list,gauss);
     187                element->NodalFunctions(basis,gauss);
     188
     189                for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*basis[i];
     190        }
     191
     192        xDelete<IssmDouble>(basis);
     193        xDelete<IssmDouble>(xyz_list);
     194        return pe;
     195        }/*}}}*/
    43196void LsfReinitializationAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
    44197        _error_("not implemented yet");
     
    50203        _error_("not implemented yet");
    51204}/*}}}*/
     205void LsfReinitializationAnalysis::GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
     206        /*Compute B  matrix. B=[B1 B2 B3] where Bi is of size 3*NDOF2.
     207         * For node i, Bi can be expressed in the actual coordinate system
     208         * by:
     209         *       Bi=[ N ]
     210         *          [ N ]
     211         * where N is the finiteelement function for node i.
     212         *
     213         * We assume B_prog has been allocated already, of size: 2x(NDOF1*numnodes)
     214         */
     215
     216        /*Fetch number of nodes for this finite element*/
     217        int numnodes = element->GetNumberOfNodes();
     218
     219        /*Get nodal functions*/
     220        IssmDouble* basis=xNew<IssmDouble>(numnodes);
     221        element->NodalFunctions(basis,gauss);
     222
     223        /*Build B: */
     224        for(int i=0;i<numnodes;i++){
     225                B[numnodes*0+i] = basis[i];
     226                B[numnodes*1+i] = basis[i];
     227        }
     228
     229        /*Clean-up*/
     230        xDelete<IssmDouble>(basis);
     231}/*}}}*/
     232void LsfReinitializationAnalysis::GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
     233        /*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2.
     234         * For node i, Bi' can be expressed in the actual coordinate system
     235         * by:
     236         *       Bi_prime=[ dN/dx ]
     237         *                [ dN/dy ]
     238         * where N is the finiteelement function for node i.
     239         *
     240         * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
     241         */
     242
     243        /*Fetch number of nodes for this finite element*/
     244        int numnodes = element->GetNumberOfNodes();
     245
     246        /*Get nodal functions derivatives*/
     247        IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
     248        element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
     249
     250        /*Build B': */
     251        for(int i=0;i<numnodes;i++){
     252                Bprime[numnodes*0+i] = dbasis[0*numnodes+i];
     253                Bprime[numnodes*1+i] = dbasis[1*numnodes+i];
     254        }
     255
     256        /*Clean-up*/
     257        xDelete<IssmDouble>(dbasis);
     258
     259}/*}}}*/
    52260
    53261/* Other */
     262void LsfReinitializationAnalysis::UpdateReinitSPCs(FemModel* femmodel){/*{{{*/
     263
     264        int i,k, numnodes;
     265        Element* element;
     266        Node* node;
     267
     268        /* deactivate all spcs */
     269        for(i=0;i<femmodel->elements->Size();i++){
     270                element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     271                for(k=0;k<element->GetNumberOfNodes();k++){
     272                                node=element->GetNode(k);
     273                                node->DofInFSet(0);
     274                }
     275        }
     276
     277        SetDistanceOnIntersectedElements(femmodel);
     278
     279        /* reactivate spcs on elements intersected by zero levelset */
     280        for(i=0;i<femmodel->elements->Size();i++){
     281                element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     282                if(element->IsZeroLevelset(MaskIceLevelsetEnum)){
     283                        /*iterate over nodes and set spc */
     284                        numnodes=element->GetNumberOfNodes();
     285                        IssmDouble* lsf = xNew<IssmDouble>(numnodes);
     286                        element->GetInputListOnNodes(&lsf[0],MaskIceLevelsetEnum);
     287                        for(k=0;k<numnodes;k++){
     288                                node=element->GetNode(k);
     289                                node->ApplyConstraint(1,lsf[k]);
     290                        }
     291                        xDelete<IssmDouble>(lsf);
     292                }
     293        }
     294
     295}/*}}}*/
    54296void LsfReinitializationAnalysis::SetDistanceOnIntersectedElements(FemModel* femmodel){/*{{{*/
    55297
    56298        /* Intermediaries */
    57         int i;
     299        int i,k;
    58300
    59301        /*Initialize vector with number of vertices*/
    60302        int numvertices=femmodel->vertices->NumberOfVertices();
    61         Vector<IssmDouble>* vec_dist_zerolevelset=new Vector<IssmDouble>(numvertices); //vertices that have ice at next time step
    62 
    63         /*TODO: Fill vector with values of old level set function: */
    64         for(i=0;i<numvertices;i++){
    65                 vec_dist_zerolevelset->SetValue(i,0.,INS_VAL);
    66         }
     303        Element* element;
     304
     305        Vector<IssmDouble>* vec_dist_zerolevelset = NULL;
     306        GetVectorFromInputsx(&vec_dist_zerolevelset, femmodel, MaskIceLevelsetEnum, VertexEnum);
     307       
    67308        for(i=0;i<femmodel->elements->Size();i++){
    68                 Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     309                element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
     310                if(element->IsZeroLevelset(MaskIceLevelsetEnum))
     311                        for(k=0;k<element->GetNumberOfVertices();k++)
     312                                vec_dist_zerolevelset->SetValue(element->vertices[k]->Sid(),NAN,INS_VAL);
     313        }
     314
     315        for(i=0;i<femmodel->elements->Size();i++){
     316                element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
    69317                if(element->IsZeroLevelset(MaskIceLevelsetEnum))
    70318                        SetDistanceToZeroLevelsetElement(vec_dist_zerolevelset, element);
     
    103351
    104352        /* get sign of levelset function */
    105         for(i=0;i<numvertices;i++){
    106                 if(lsf[i]==0.)
    107                         sign_lsf[i]=1.;
    108                 else
    109                         sign_lsf[i]=lsf[i]/fabs(lsf[i]);
    110         }
     353        for(i=0;i<numvertices;i++)
     354                sign_lsf[i]=(lsf[i]>=0.?1.:-1.);
    111355
    112356        element->ZeroLevelsetCoordinates(&xyz_list_zero, xyz_list, MaskIceLevelsetEnum);
     
    127371        for(i=0;i<numvertices;i++){
    128372                vec_signed_dist->GetValue(&lsf_old, element->vertices[i]->Sid());
    129                 if(fabs(signed_dist[i])<fabs(lsf_old))
     373                if(isnan(lsf_old) || fabs(signed_dist[i])<fabs(lsf_old))
    130374                        vec_signed_dist->SetValue(element->vertices[i]->Sid(),signed_dist[i],INS_VAL);
    131375        }
  • issm/trunk-jpl/src/c/analyses/LsfReinitializationAnalysis.h

    r17307 r17334  
    2929        void InputUpdateFromSolution(IssmDouble* solution,Element* element);
    3030        void UpdateConstraints(FemModel* femmodel);
     31        void GetB(IssmDouble* B,Element* element,IssmDouble* xyz_list,Gauss* gauss);
     32        void GetBprime(IssmDouble* Bprime,Element* element,IssmDouble* xyz_list,Gauss* gauss);
    3133       
    3234        /* Other */
     35        void UpdateReinitSPCs(FemModel* femmodel);
    3336        void SetDistanceOnIntersectedElements(FemModel* femmodel);
    3437        void SetDistanceToZeroLevelsetElement(Vector<IssmDouble>* vec_dist, Element* element);
  • issm/trunk-jpl/src/c/classes/Elements/Element.cpp

    r17330 r17334  
    434434                                name==LevelsetfunctionSlopeXEnum ||
    435435                                name==LevelsetfunctionSlopeYEnum ||
     436                                name==LevelsetfunctionPicardEnum ||
    436437                                name==GradientEnum ||
    437438                                name==OldGradientEnum  ||
  • issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h

    r17305 r17334  
    682682        LevelsetfunctionSlopeXEnum,
    683683        LevelsetfunctionSlopeYEnum,
     684        LevelsetfunctionPicardEnum,
    684685        /*}}}*/
    685686        MaximumNumberOfDefinitionsEnum
  • issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp

    r17305 r17334  
    641641                case LevelsetfunctionSlopeXEnum : return "LevelsetfunctionSlopeX";
    642642                case LevelsetfunctionSlopeYEnum : return "LevelsetfunctionSlopeY";
     643                case LevelsetfunctionPicardEnum : return "LevelsetfunctionPicard";
    643644                case MaximumNumberOfDefinitionsEnum : return "MaximumNumberOfDefinitions";
    644645                default : return "unknown";
  • issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp

    r17305 r17334  
    656656              else if (strcmp(name,"LevelsetfunctionSlopeX")==0) return LevelsetfunctionSlopeXEnum;
    657657              else if (strcmp(name,"LevelsetfunctionSlopeY")==0) return LevelsetfunctionSlopeYEnum;
     658              else if (strcmp(name,"LevelsetfunctionPicard")==0) return LevelsetfunctionPicardEnum;
    658659              else if (strcmp(name,"MaximumNumberOfDefinitions")==0) return MaximumNumberOfDefinitionsEnum;
    659660         else stage=7;
  • issm/trunk-jpl/src/m/enum/EnumDefinitions.py

    r17305 r17334  
    633633def LevelsetfunctionSlopeXEnum(): return StringToEnum("LevelsetfunctionSlopeX")[0]
    634634def LevelsetfunctionSlopeYEnum(): return StringToEnum("LevelsetfunctionSlopeY")[0]
     635def LevelsetfunctionPicardEnum(): return StringToEnum("LevelsetfunctionPicard")[0]
    635636def MaximumNumberOfDefinitionsEnum(): return StringToEnum("MaximumNumberOfDefinitions")[0]
Note: See TracChangeset for help on using the changeset viewer.