Ignore:
Timestamp:
08/09/17 10:26:20 (8 years ago)
Author:
tsantos
Message:

NEW: adaptive mesh refinement with Bamg for grounding line and ice front dynamics

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/AdaptiveMeshRefinement.cpp

    r21806 r21919  
    1010
    1111#include "./AdaptiveMeshRefinement.h"
    12 #include "TPZVTKGeoMesh.h"
    13 #include "../shared/shared.h"
    14 #include "pzgeotriangle.h"
    15 #include "pzreftriangle.h"
     12
    1613using namespace pzgeom;
    1714
     
    4037        this->sid2index.resize(cp.sid2index.size());
    4138        for(int i=0;i<cp.sid2index.size();i++) this->sid2index[i]=cp.sid2index[i];
    42        
     39        this->index2sid.clear();
     40        this->index2sid.resize(cp.index2sid.size());
     41        for(int i=0;i<cp.index2sid.size();i++) this->index2sid[i]=cp.index2sid[i];
     42        this->specialelementsindex.clear();
     43        this->specialelementsindex.resize(cp.specialelementsindex.size());
     44        for(int i=0;i<cp.specialelementsindex.size();i++) this->specialelementsindex[i]=cp.specialelementsindex[i];
     45
    4346        return *this;
    44 
    4547}
    4648/*}}}*/
    4749AdaptiveMeshRefinement::~AdaptiveMeshRefinement(){/*{{{*/
    48        
    49         bool ismismip = false;
    50         if(ismismip){//itapopo
    51                 TPZFileStream fstr;
    52                 std::stringstream ss;
    53            
    54                 ss << this->levelmax;
    55                 std::string AMRfile     = "/home/santos/L" + ss.str() + "_amr.txt";
    56        
    57                 fstr.OpenWrite(AMRfile.c_str());
    58                 int withclassid = 1;
    59                 this->Write(fstr,withclassid);
    60         }
    6150        this->CleanUp();
    6251        gRefDBase.clear();
     
    7362        this->regionlevelmax            = -1;
    7463        this->sid2index.clear();
     64        this->index2sid.clear();
     65        this->specialelementsindex.clear();
    7566}
    7667/*}}}*/
     
    8475        this->regionlevel1              = -1;
    8576        this->regionlevelmax            = -1;
     77        this->step                                      = 0;
     78        this->smooth_frequency  = 1;
    8679        this->sid2index.clear();
    87 }
    88 /*}}}*/
    89 int AdaptiveMeshRefinement::ClassId() const{/*{{{*/
    90     return 13829430; //Antartic area with ice shelves (km^2)
    91 }
    92 /*}}}*/
    93 void AdaptiveMeshRefinement::Read(TPZStream &buf,void *context){/*{{{*/
    94 
    95         try
    96         {
    97                 /* Read the id context*/
    98                 TPZSaveable::Read(buf,context);
    99                 /* Read class id*/
    100                 int classid;
    101                 buf.Read(&classid,1);
    102                 /* Verify the class id*/
    103       if(classid!=this->ClassId()) _error_("AdaptiveMeshRefinement::Read: Error in restoring AdaptiveMeshRefinement!\n");
    104                 /* Read simple attributes */
    105                 buf.Read(&this->levelmax,1);
    106                 buf.Read(&this->elementswidth,1);
    107                 buf.Read(&this->regionlevel1,1);
    108                 buf.Read(&this->regionlevelmax,1);
    109                 /* Read vector attributes*/
    110                 int size;
    111                 buf.Read(&size,1);
    112                 int* psid2index=xNew<int>(size);
    113                 buf.Read(psid2index,size);
    114                 this->sid2index.clear();
    115                 this->sid2index.assign(psid2index,psid2index+size);
    116                 /* Read geometric mesh (father)*/
    117                 TPZSaveable *sv1 = TPZSaveable::Restore(buf,0);
    118                 this->fathermesh = dynamic_cast<TPZGeoMesh*>(sv1);
    119                 /* Read geometric mesh (current)*/
    120                 TPZSaveable *sv2 = TPZSaveable::Restore(buf,0);
    121                 this->currentmesh = dynamic_cast<TPZGeoMesh*>(sv2);
    122                 /* Cleanup*/
    123                 xDelete<int>(psid2index);
    124         }
    125         catch(const std::exception& e)
    126         {
    127                 _error_("AdaptiveMeshRefinement::Read: Exception catched!\n");
    128         }
    129 
    130 }
    131 /*}}}*/
    132 template class TPZRestoreClass<AdaptiveMeshRefinement,13829430>;/*{{{*/
    133 /*}}}*/
    134 void AdaptiveMeshRefinement::Write(TPZStream &buf,int withclassid){/*{{{*/
    135    
    136         try
    137         {
    138                 /* Write context (this class) class ID*/
    139                 TPZSaveable::Write(buf,withclassid);
    140                 /* Write this class id*/
    141                 int classid = this->ClassId();
    142                 buf.Write(&classid,1);
    143                 /* Write simple attributes */
    144                 buf.Write(&this->levelmax,1);
    145                 buf.Write(&this->elementswidth,1);
    146                 buf.Write(&this->regionlevel1,1);
    147                 buf.Write(&this->regionlevelmax,1);
    148                 /* Write vector attributes*/
    149                 int size=this->sid2index.size();
    150                 int* psid2index=&this->sid2index[0];
    151                 buf.Write(&size,1);//vector size
    152                 buf.Write(psid2index,this->sid2index.size());
    153                 /* Write the geometric mesh*/
    154                 this->fathermesh->Write(buf,this->ClassId());
    155                 this->currentmesh->Write(buf,this->ClassId());
    156     }
    157     catch(const std::exception& e)
    158     {
    159                 _error_("AdaptiveMeshRefinement::Write: Exception catched!\n");
    160     }
     80        this->index2sid.clear();
     81        this->specialelementsindex.clear();
    16182}
    16283/*}}}*/
     
    17697        if(numberofelements!=this->sid2index.size()) _error_("Impossible to execute refinement: sid2index.size is not equal to numberofelements!\n");
    17798
    178         /*Execute the refinement.*/
    179         this->RefinementProcess(amr_verbose,partiallyfloatedelements,masklevelset,deviatorictensorerror,thicknesserror);
    180    
    181         /*Get new geometric mesh in ISSM data structure*/
    182         this->GetMesh(newnumberofvertices,newnumberofelements,x,y,elementslist);
    183        
    184         /*Verify the new geometry*/
    185         this->CheckMesh(newnumberofvertices,newnumberofelements,this->elementswidth,x,y,elementslist);
    186 
    187 }
    188 /*}}}*/
    189 void AdaptiveMeshRefinement::RefinementProcess(bool &amr_verbose,double* partiallyfloatedelements,double* masklevelset,
    190                                                                                                                                 double* deviatorictensorerror,double* thicknesserror){/*{{{*/
    191    
    192         if(amr_verbose) _printf_("\n\trefinement process started (level max = " << this->levelmax << ")\n");
    193        
    194         /*Intermediaries*/
    195         TPZGeoMesh* nohangingnodesmesh=NULL;
     99        /*Combine the fields*/
    196100        double mean_mask                = 0;
    197101        double mean_tauerror = 0;
    198102        double mean_Herror      = 0;
    199         double group_error      = 0;
    200    
     103        int* fmask                              = xNew<int>(numberofelements);
     104        int* ftauerror                  = xNew<int>(numberofelements);
     105        int* fHerror                    = xNew<int>(numberofelements);
     106        int* phi                                        = xNew<int>(numberofelements);
    201107        /*Calculate mean values*/
    202108        for(int i=0;i<this->sid2index.size();i++){
     
    208114        mean_tauerror   /= this->sid2index.size();
    209115        mean_Herror             /= this->sid2index.size();
    210 
     116        /*Filter to thickness*/
     117        for(int i=0;i<this->sid2index.size();i++){
     118                fmask[i]=0;
     119                if(thicknesserror[i]>mean_Herror) fmask[i]=1;
     120        }
     121        /*Filter to tau*/
     122        for(int i=0;i<this->sid2index.size();i++){
     123                ftauerror[i]=0;
     124                if(deviatorictensorerror[i]>mean_tauerror) ftauerror[i]=1;
     125        }
     126        /*Sum*/
     127        for(int i=0;i<this->sid2index.size();i++){
     128                phi[i]=ftauerror[i]+fmask[i];
     129        }
     130
     131        /*Execute the refinement.*/
     132        this->RefinementProcess(amr_verbose,partiallyfloatedelements,masklevelset,deviatorictensorerror,thicknesserror);
     133   
     134        /*Get new geometric mesh in ISSM data structure*/
     135        this->GetMesh(newnumberofvertices,newnumberofelements,x,y,elementslist);
     136
     137        std::ofstream file("/home/santos/mesh.vtk");
     138        TPZVTKGeoMesh::PrintGMeshVTK(this->currentmesh,file);
     139
     140        /*Verify the new geometry*/
     141        this->CheckMesh(newnumberofvertices,newnumberofelements,this->elementswidth,x,y,elementslist);
     142
     143}
     144/*}}}*/
     145void AdaptiveMeshRefinement::RefinementProcess(bool &amr_verbose,double* partiallyfloatedelements,double* masklevelset,double* deviatorictensorerror,double* thicknesserror){/*{{{*/
     146   
     147        if(amr_verbose) _printf_("\n\trefinement process started (level max = " << this->levelmax << ")\n");
     148       
     149        /*Intermediaries*/
     150        TPZGeoMesh* nohangingnodesmesh=NULL;
     151
     152        //itapopo
     153        this->step++;
     154
     155        double mean_mask                = 0;
     156        double mean_tauerror = 0;
     157        double mean_Herror      = 0;
     158        double group_Herror     = 0;
     159        int index,sid;
     160        std::vector<int> specialfatherindex; specialfatherindex.clear();
     161
     162        /*Calculate mean values*/
     163        for(int i=0;i<this->sid2index.size();i++){
     164                mean_mask               += masklevelset[i];
     165                mean_tauerror   += deviatorictensorerror[i];
     166                mean_Herror             += thicknesserror[i];
     167        }
     168        mean_mask               /= this->sid2index.size();
     169        mean_tauerror   /= this->sid2index.size();
     170        mean_Herror             /= this->sid2index.size();
     171
     172        if(amr_verbose) _printf_("\t\tdeal with special elements...\n");
     173        /*Deal with special elements*/
     174        for(int i=0;i<this->specialelementsindex.size();i++){
     175                if(this->specialelementsindex[i]==-1) continue;
     176                /*Get special element and verify*/
     177                TPZGeoEl* geoel=this->currentmesh->Element(this->specialelementsindex[i]);
     178                if(!geoel)_error_("special element (sid) "<<i<<" is null!\n");
     179                if(geoel->HasSubElement())_error_("special element (sid) "<<i<<" has "<<geoel->NSubElements()<<" subelements!\n");
     180                if(geoel->MaterialId()!=this->GetElemMaterialID()) _error_("geoel->MaterialId is not GetElemMaterialID!\n");
     181                if(!geoel->Father())_error_("father of special element (sid) "<<i<<" is null!\n");
     182               
     183                /*Get element's siblings and verify*/
     184                TPZGeoEl* father=geoel->Father();
     185                TPZVec<TPZGeoEl *> siblings;
     186                father->GetHigherSubElements(siblings);
     187                std::vector<int> sidvec; sidvec.resize(siblings.size());
     188                for (int j=0;j<siblings.size();j++){
     189                        if(!siblings[j]) _error_("special element (sid) "<<i<<" has a null siblings null!\n");
     190                        sidvec[j]=this->index2sid[siblings[j]->Index()];
     191                }
     192               
     193                /*Now, reset the data strucure and verify if the siblings should be deleted*/   
     194                if(siblings.size()<4){
     195                        /*Reset subelements in the father*/
     196                        father->ResetSubElements();
     197                }else{
     198                        if(siblings.size()!=4) _error_("element (index) "<<father->Index()<<" has "<<father->NSubElements()<<" subelements!\n");
     199                }
     200                for (int j=0;j<siblings.size();j++){
     201                        for(int k=0;k<this->specialelementsindex.size();k++){
     202                                if(this->specialelementsindex[k]==siblings[j]->Index()){
     203                                        index                                                                   = siblings[j]->Index();
     204                                        if(index<0) _error_("index is null!\n");
     205                                        sid                                                                     = this->index2sid[index];
     206                                        if(sid<0) _error_("sid is null!\n");
     207                                        this->specialelementsindex[k]   = -1;
     208                                        this->index2sid[index]                  = -1;
     209                                        this->sid2index[sid]                            = -1;
     210                                }
     211                        }
     212                        if(siblings.size()<4){
     213                                /*Ok, the special element can be deleted*/
     214                                siblings[j]->ResetSubElements();
     215                                this->currentmesh->DeleteElement(siblings[j],siblings[j]->Index());
     216                        }
     217                }
     218               
     219                /*Now, verify if the father should be refined with uniform pattern (smoother)*/
     220                this->smooth_frequency=10000000;
     221                if(siblings.size()==3 || this->step%this->smooth_frequency==0){//it keeps the mesh with uniform elements
     222                        /*Father has uniform subelements now*/
     223                        TPZVec<TPZGeoEl *> sons;
     224                        father->Divide(sons);
     225                        this->smooth_frequency=this->step;
     226                }else{
     227                        specialfatherindex.push_back(father->Index());
     228                }
     229                if(this->specialelementsindex[i]!=-1) _error_("special element "<<i<<" was not deleted!\n");   
     230        }
     231        this->currentmesh->BuildConnectivity();
     232       
    211233        if(amr_verbose) _printf_("\t\tuniform refinement...\n");
     234        /*Deal with uniform elemnts*/
    212235        for(int i=0;i<this->sid2index.size();i++){
     236                if(this->sid2index[i]==-1) continue;
     237                /*Get element and verify*/
    213238                TPZGeoEl* geoel=this->currentmesh->Element(this->sid2index[i]);
    214                 if(geoel->HasSubElement()) _error_("Impossible to refine: geoel (index) "<<this->sid2index[i]<<" has subelements!\n");
    215                 if(geoel->MaterialId()!=this->GetElemMaterialID()) _error_("Impossible to refine: geoel->MaterialId is not GetElemMaterialID!\n");
    216                 /*Refine*/
    217                 if(thicknesserror[i]>mean_Herror){
     239                if(geoel->HasSubElement()) _error_("element (sid) "<<i<<" has "<<geoel->NSubElements()<<" subelements!\n");
     240                if(geoel->MaterialId()!=this->GetElemMaterialID()) _error_("geoel->MaterialId is not GetElemMaterialID!\n");
     241
     242                /*Refine process*/
     243                if(thicknesserror[i]>mean_Herror)
     244                {       
     245                        int count=0;
     246                        TPZGeoEl* father=geoel->Father();
     247                        if(father){
     248                                for(int j=3;j<6;j++){
     249                                        index=father->Neighbour(j).Element()->Index();
     250                                        for(int k=0;k<specialfatherindex.size();k++) if(specialfatherindex[k]==index) count++;
     251                                }
     252                        }
    218253                        TPZVec<TPZGeoEl *> sons;
    219                         if(geoel->Level()<this->levelmax) geoel->Divide(sons);
     254                        if(geoel->Level()<this->levelmax && count==0) geoel->Divide(sons);
    220255                }
    221                 else if(geoel->Level()>0){ /*try to unrefine*/
    222                         TPZVec<TPZGeoEl *> sons;
    223                         geoel->Father()->GetHigherSubElements(sons);
    224                         group_error=0;
    225                         for(int j=0;j<sons.size();j++){
    226                                 sons[j]->Index();
     256                else if(geoel->Level()>0)
     257                {/*Unrefine process*/
     258                       
     259                        /*Get siblings and verify*/
     260                        TPZVec<TPZGeoEl *> siblings;
     261                        geoel->Father()->GetHigherSubElements(siblings);
     262                        //if(siblings.size()<4) _error_("Impossible to refine: geoel (index) "<<this->sid2index[i]<<" has less than 3 siblings!\n");   
     263                        if(siblings.size()>4) continue;//Father has more then 4 sons, this group should not be unrefined.
     264                       
     265                        /*Compute the error of the group*/
     266                        group_Herror=0;
     267                        for(int j=0;j<siblings.size();j++){
     268                                index           = siblings[j]->Index();
     269                                sid             = this->index2sid[index];
     270                                if(sid==-1) continue;
     271                                group_Herror+=thicknesserror[sid];
    227272                        }
    228                 }
    229         }
     273                        /*Verify if this group should be unrefined*/
     274                        if(group_Herror>0 && group_Herror<0*mean_Herror){ //itapopo
     275                                /*Reset subelements in the father*/
     276                                this->currentmesh->Element(geoel->Father()->Index())->ResetSubElements();
     277                                /*Delete the elements and set their indexes in the index2sid and sid2index*/
     278                                for (int j=0;j<siblings.size();j++){
     279                                        index   = siblings[j]->Index();
     280                                        sid     = this->index2sid[index];
     281                                        this->index2sid[index]=-1;
     282                                        if(sid!=-1) this->sid2index[sid]=-1;
     283                                        this->currentmesh->DeleteElement(siblings[j],siblings[j]->Index());
     284                                }//for j
     285                        }//if
     286                }/*Unrefine process*/
     287        }//for i
    230288        this->currentmesh->BuildConnectivity();
    231289       
    232290        if(amr_verbose) _printf_("\t\trefine to avoid hanging nodes...\n");
    233291        this->RefineMeshToAvoidHangingNodes(this->currentmesh);
    234         this->currentmesh->BuildConnectivity();
    235292       
    236293                //nohangingnodesmesh = this->CreateRefPatternMesh(newmesh); itapopo tentar otimizar
    237        
     294
    238295        if(amr_verbose) _printf_("\trefinement process done!\n");
    239296}
     
    257314void AdaptiveMeshRefinement::RefineMeshToAvoidHangingNodes(TPZGeoMesh *gmesh){/*{{{*/
    258315   
    259         /*Refine elements to avoid hanging nodes: non-uniform refinement*/
     316        /*Now, insert special elements to avoid hanging nodes*/
     317        this->specialelementsindex.clear();
    260318        const int NElem = gmesh->NElements();
    261319        for(int i=0;i<NElem;i++){
     
    268326                TPZAutoPointer<TPZRefPattern> refp=TPZRefPatternTools::PerfectMatchRefPattern(geoel);
    269327                if(refp){
     328                        /*Non-uniform refinement*/
    270329                        TPZVec<TPZGeoEl *> Sons;
    271330                        geoel->SetRefPattern(refp);
    272331                        geoel->Divide(Sons);
    273       }
    274         }
    275    gmesh->BuildConnectivity();
    276    
     332                        /*Keep the index of the special elements*/
     333                        for(int j=0;j<Sons.size();j++) this->specialelementsindex.push_back(Sons[j]->Index());
     334                }
     335        }
     336        gmesh->BuildConnectivity();
    277337}
    278338/*}}}*/
     
    281341        /* IMPORTANT! pelements are in Matlab indexing
    282342           NEOPZ works only in C indexing.
    283                 This method cleans up and updated the this->sid2index 
    284                 and fills in it with the new mesh.
     343                This method cleans up and updated the this->sid2index
     344                and this->index2sid and fills in it with the new mesh.
    285345                Avoid to call this method before Refinement Process.*/
    286346
     
    295355        TPZGeoEl* geoel                 = NULL;
    296356        long* vertex_index2sid  = xNew<long>(gmesh->NNodes());
     357        this->index2sid.clear(); this->index2sid.resize(gmesh->NElements());
    297358        this->sid2index.clear();
    298359       
     
    307368        /*Fill in the vertex_index2sid vector with non usual index value*/
    308369        for(int i=0;i<gmesh->NNodes();i++) vertex_index2sid[i]=-1;
     370       
     371        /*Fill in the this->index2sid vector with non usual index value*/
     372        for(int i=0;i<gmesh->NElements();i++) this->index2sid[i]=-1;
    309373       
    310374        /*Get elements without sons and fill in the vertex_index2sid with used vertices (indexes) */
     
    316380                if(geoel->MaterialId() != this->GetElemMaterialID()) continue;
    317381                this->sid2index.push_back(i);//keep the element index
     382                this->index2sid[i]=this->sid2index.size()-1;//keep the element sid
    318383                for(int j=0;j<this->elementswidth;j++){
    319384        nodeindex=geoel->NodeIndex(j);
     
    347412                        newelements[i*this->elementswidth+j]=(int)sid+1;//C to Matlab indexing
    348413                }
    349         }
    350  
     414                /*Verify the Jacobian determinant. If detJ<0, swap the 2 first postions:
     415                  a -> b
     416                  b -> a */
     417                double detJ,xa,xb,xc,ya,yb,yc;
     418                int a,b,c;
     419
     420                a=newelements[i*this->elementswidth+0]-1;
     421                b=newelements[i*this->elementswidth+1]-1;
     422                c=newelements[i*this->elementswidth+2]-1;
     423
     424                xa=newmeshX[a]; ya=newmeshY[a];
     425                xb=newmeshX[b]; yb=newmeshY[b];
     426                xc=newmeshX[c]; yc=newmeshY[c];
     427
     428                detJ=(xb-xa)*(yc-ya)-(xc-xa)*(yb-ya);
     429       
     430                /*verify and swap, if necessary*/
     431                if(detJ<0) {
     432                        newelements[i*this->elementswidth+0]=b+1;//a->b
     433                        newelements[i*this->elementswidth+1]=a+1;//b->a
     434                }
     435        }
     436
    351437        /*Setting outputs*/
    352438        nvertices       = nconformvertices;
     
    358444        /*Cleanup*/
    359445        xDelete<long>(vertex_index2sid);
    360 
    361446}
    362447/*}}}*/
Note: See TracChangeset for help on using the changeset viewer.