albertaextra.hh

00001 /****************************************************************************/
00002 /*  Header--File for extra Albert Functions                                 */
00003 /****************************************************************************/
00004 #ifndef DUNE_ALBERTAEXTRA_HH
00005 #define DUNE_ALBERTAEXTRA_HH
00006 
00007 #include <algorithm>
00008 
00009 #ifdef __ALBERTApp__
00010 namespace Albert { 
00011 #endif
00012 
00013 #define ALBERTA_ERROR          ALBERTA print_error_funcname(funcName, __FILE__, __LINE__),\
00014                         ALBERTA print_error_msg
00015 #define ALBERTA_ERROR_EXIT     ALBERTA print_error_funcname(funcName, __FILE__, __LINE__),\
00016                         ALBERTA print_error_msg_exit
00017 
00018 #define ALBERTA_TEST_EXIT(test) if ((test));else ALBERTA_ERROR_EXIT
00019 
00020 #define getDofVec( vec, drv ) \
00021               (assert(drv != 0); (vec = (drv)->vec); assert(vec != 0));
00022 
00025 inline void computeNeigh(const MACRO_EL *mel, EL_INFO *elinfo, int neigh)
00026 {
00027   // set right neighbour element 
00028   elinfo->neigh[neigh]      = mel->neigh[neigh]->el;
00029   // get vertex of opposite coord 
00030   int oppvx = mel->opp_vertex[neigh];
00031   elinfo->opp_vertex[neigh] = oppvx;
00032  
00033   // copy to opp_coord 
00034   REAL_D *coord  = elinfo->opp_coord;
00035   const REAL * const * neighcoord  = mel->neigh[neigh]->coord;
00036   std::memcpy(coord[neigh],neighcoord[oppvx],sizeof(REAL_D));
00037 }
00038 
00040 inline void fillMacroInfo(TRAVERSE_STACK *stack, 
00041     const MACRO_EL *mel, EL_INFO *elinfo, int level)
00042 {
00043   /* Alberta version */
00044   fill_macro_info(stack->traverse_mesh,mel,elinfo);
00045 
00046 #if DIM == 2
00047   // only works for dim 2 at the moment 
00048   // because there we have a different fill_elinfo method 
00049   // quick solution, the method fill_macro_info has to be rewritten
00050   // not now, dont have the time 
00051   if(level == elinfo->level)
00052   {
00053     for(int i=0 ;i<N_NEIGH; i++)
00054     {
00055       if(mel->neigh[i])
00056       {
00057         computeNeigh(mel,elinfo,i);
00058       }
00059       else 
00060       {
00061         elinfo->neigh[i] = 0;
00062         elinfo->opp_vertex[i] = 0;
00063       } 
00064     }
00065   }
00066 #endif
00067 }
00068 
00069 
00070 // provides the element number generation and management 
00071 #include "agelementindex.cc"                        
00072 
00073 // This three function are used by albertgrid.hh ~.cc
00074 // but not defined in the regular albert.h
00075 //extern void free_leaf_data(void *leaf_data, MESH *mesh);
00076 //extern void free_dof(DOF *dof, MESH *mesh, int position);
00077 
00078 inline void enlargeTraverseStack(TRAVERSE_STACK *stack);
00079 inline static TRAVERSE_STACK *getTraverseStack(void);
00080 inline static TRAVERSE_STACK *freeTraverseStack(TRAVERSE_STACK *stack);
00081 inline void printTraverseStack(const TRAVERSE_STACK *stack);
00082 
00087 class ManageTravStack
00088 {
00090   TRAVERSE_STACK * stack_;
00091 
00093   mutable int *refCount_;
00094 
00095   mutable bool owner_;
00096 
00097 public:
00099   ManageTravStack() : stack_ (0) , refCount_ (0) , owner_(false) {}
00100  
00102   ManageTravStack(const ManageTravStack & copy)
00103   {
00104     stack_ = 0;
00105     refCount_ = 0;
00106     if(copy.stackExists())
00107     {
00108       stack_ = copy.stack_; 
00109       refCount_ = copy.refCount_;
00110       ++(*refCount_); 
00111       copy.owner_ = false;
00112       owner_ = true;
00113     }
00114   }
00115  
00118   void create ()
00119   {
00120     // remove existing stack, does nothing if no stack exists 
00121     remove();
00122     
00123     assert( stack_ == 0 );
00124     assert( refCount_ ==  0 );
00125     stack_ = getTraverseStack();
00126     refCount_ = new int (1);
00127     owner_ = true;
00128   }
00129 
00131   ~ManageTravStack()
00132   {
00133     remove();
00134   }
00135 
00136   bool stackExists() const 
00137   {
00138     return stack_ != 0;
00139   }
00140 
00142   TRAVERSE_STACK * getStack() const 
00143   {
00144     // if this assertion is thrown then either the stack = 0
00145     // or we want to uese the pointer but are not the owner
00146     assert( stack_ ); 
00147     assert( (!owner_) ? (std::cerr << "\nERROR:The feature of copying iterators is not supported by AlbertaGrid at the moment! \n\n", 0) : 1);
00148     return stack_;  
00149   }
00150 
00151 private:  
00153   ManageTravStack & operator = (const ManageTravStack & copy)
00154   {
00155     remove();  
00156     // do not use this method 
00157     if(copy.stack_ != 0)
00158     {
00159       stack_ = copy.stack_; 
00160       refCount_ = copy.refCount_;
00161       ++(*refCount_); 
00162       copy.owner_ = false;
00163       owner_ = true;
00164     }
00165     assert(false);
00166     return (*this);
00167   }
00168 
00169   void remove() 
00170   {
00171     if(refCount_ && stack_)
00172     {
00173       (*refCount_)--; 
00174       if((*refCount_) <= 0)
00175       {
00176         // in free_traverse_stack stack != 0 is checked
00177         if(stack_) 
00178         {
00179           stack_ = freeTraverseStack(stack_);
00180           owner_ = false;
00181         }
00182         if(refCount_) 
00183         {
00184           delete refCount_; 
00185           refCount_ = 0;   
00186         }
00187       }
00188     }
00189     stack_ = 0;
00190     refCount_ = 0;
00191   }
00192 };
00193 
00194 
00195 //***********************************************************
00196 // Traverse Stacks 
00197 //***********************************************************
00198 static inline void initTraverseStack(TRAVERSE_STACK *stack);
00199 static inline void resetTraverseStack(TRAVERSE_STACK *stack);
00200 
00201 inline static TRAVERSE_STACK *getTraverseStack(void)
00202 {
00203   TRAVERSE_STACK * stack = get_traverse_stack();
00204   
00205   //TRAVERSE_STACK * stack = new TRAVERSE_STACK(); 
00206   //initTraverseStack(stack);
00207 
00208   assert( stack );
00209   // if we use copyTraverseStack we should only create stacks with 
00210   // stack_size > 0 otherwise we get errors in TreeIterator 
00211   if(stack->stack_size <= 0) enlargeTraverseStack( stack ); 
00212   return stack; 
00213 }
00214 
00215 inline static TRAVERSE_STACK *freeTraverseStack(TRAVERSE_STACK *stack)
00216 {
00217   // reset stack, i.e set pointer to mesh to 0 ... 
00218   resetTraverseStack(stack);
00219   free_traverse_stack(stack);
00220   //delete stack;
00221   return 0;
00222 }
00223 
00224 inline void copyTraverseStack( TRAVERSE_STACK* stack, const TRAVERSE_STACK* org )
00225 {
00226   const int & used = stack->stack_size;
00227   // we have problems to copy stack of length 0 
00228   assert( used > 0 );
00229   
00230   if(stack->elinfo_stack) MEM_FREE(stack->elinfo_stack,used, EL_INFO);
00231   if(stack->info_stack)   MEM_FREE(stack->info_stack,used, U_CHAR );
00232   if(stack->save_elinfo_stack) MEM_FREE(stack->save_elinfo_stack,used,EL_INFO );
00233   if(stack->save_info_stack) MEM_FREE(stack->save_info_stack,used,U_CHAR);
00234  
00235   // NOTE: at this point also the used value changes
00236   // because stack->stack_size is changed 
00237   memcpy( stack, org, sizeof(TRAVERSE_STACK));
00238 
00239   stack->elinfo_stack = 0;
00240   stack->elinfo_stack = MEM_ALLOC(used, EL_INFO);
00241 
00242   // here we have to copy all EL_INFOs seperately, the normal way does not
00243   // work, unfortunately 
00244   if (used > 0)
00245   {
00246     for (int i=0; i<used; i++)
00247     {
00248       memcpy(&(stack->elinfo_stack[i]),&(org->elinfo_stack[i]),sizeof(EL_INFO));
00249     }
00250   }
00251 
00252   assert( used == org->stack_size );
00253 
00254   // the pointer have to be created new 
00255   stack->info_stack        = 0;
00256   stack->info_stack        = MEM_ALLOC(used, U_CHAR);
00257   stack->save_elinfo_stack = 0;
00258   stack->save_elinfo_stack = MEM_ALLOC(used, EL_INFO);
00259   stack->save_info_stack   = 0;
00260   stack->save_info_stack   = MEM_ALLOC(used, U_CHAR);
00261   
00262   memcpy(stack->elinfo_stack     ,org->elinfo_stack,     used * sizeof(EL_INFO));
00263   memcpy(stack->info_stack       ,org->info_stack,       used * sizeof(U_CHAR));
00264   memcpy(stack->save_elinfo_stack,org->save_elinfo_stack,used * sizeof(EL_INFO));
00265   memcpy(stack->save_info_stack  ,org->save_info_stack,  used * sizeof(U_CHAR)); 
00266 
00267   /*
00268   std::cout << "Print original\n";
00269   printTraverseStack(org);
00270   std::cout << "Print copy \n";
00271   printTraverseStack(stack);
00272   */
00273   return;
00274 }
00275 
00276 static inline void resetTraverseStack(TRAVERSE_STACK *stack)
00277 {
00278   stack->traverse_mesh = 0;
00279   stack->traverse_level = 0;
00280   stack->traverse_mel = 0;
00281   stack->stack_used = 0;
00282   stack->save_stack_used = 0;
00283   stack->el_count = 0;
00284   return;
00285 }
00286 
00287 static inline void initTraverseStack(TRAVERSE_STACK *stack)
00288 {
00289   // integers and pointers 
00290   stack->traverse_mesh = 0;
00291   stack->traverse_level = 0;
00292   stack->traverse_mel = 0;
00293   stack->el_count = 0;
00294   stack->stack_used = 0;
00295   stack->save_stack_used = 0;
00296   
00297   // pointers to stacks and sizes 
00298   stack->elinfo_stack = 0;
00299   stack->stack_size = 0;
00300   stack->info_stack = 0;
00301   stack->save_elinfo_stack = 0;
00302   stack->save_info_stack = 0;
00303 
00304   // pointer to next stack 
00305   stack->next = 0;
00306   return;
00307 }
00308 
00309 inline void enlargeTraverseStack(TRAVERSE_STACK *stack)
00310 {
00311   int     i;
00312   int     new_stack_size = stack->stack_size + 10;
00313  
00314   stack->elinfo_stack = MEM_REALLOC(stack->elinfo_stack, stack->stack_size,
00315               new_stack_size, EL_INFO);
00316 
00317   if (stack->stack_size > 0)
00318     for (i=stack->stack_size; i<new_stack_size; i++)
00319       stack->elinfo_stack[i].fill_flag = stack->elinfo_stack[0].fill_flag;
00320 
00321   stack->info_stack = MEM_REALLOC(stack->info_stack, stack->stack_size,
00322           new_stack_size, U_CHAR);
00323   stack->save_elinfo_stack = MEM_REALLOC(stack->save_elinfo_stack,
00324            stack->stack_size,
00325            new_stack_size, EL_INFO);
00326   stack->save_info_stack   = MEM_REALLOC(stack->save_info_stack,
00327            stack->stack_size,
00328            new_stack_size, U_CHAR);
00329 
00330   stack->stack_size = new_stack_size;
00331 }
00332 
00333 inline void printTraverseStack(const TRAVERSE_STACK *stack)
00334 {
00335   FUNCNAME("printTraverseStack");
00336   MSG("****************************************************\n");
00337   MSG("current stack %8X | size %d \n", stack,stack->stack_size); 
00338   MSG("traverse_level %d \n",stack->traverse_level);
00339   MSG("traverse_mesh  %8X \n",stack->traverse_mesh);
00340   MSG("elinfo_stack      = %8X\n",stack->elinfo_stack);
00341   MSG("info_stack        = %8X\n",stack->info_stack);
00342   MSG("save_elinfo_stack = %8X\n",stack->save_elinfo_stack);
00343   MSG("save_info_stack   = %8X\n\n",stack->save_info_stack);
00344   
00345   MSG("stack_used        = %d\n",stack->stack_used);
00346   MSG("save_stack_used   = %d\n",stack->save_stack_used);
00347 
00348   MSG("Current elements :\n"); 
00349   for(int i=0; i<stack->stack_used+1; ++i) 
00350   {
00351     //int no = stack->elinfo_stack[i].el->dof[6][0];
00352     MSG("have element %p \n",stack->elinfo_stack[i].el);
00353   }
00354   
00355   MSG("****************************************************\n");
00356 }
00357 
00358 inline void printElInfo(const EL_INFO *elf)
00359 {
00360   FUNCNAME("printElInfo");
00361  
00362   MSG("Element %d | level %d  | ",INDEX(elf->el),elf->level);
00363   printf("Neighs: ");
00364   for(int i=0; i<N_VERTICES; i++)
00365   {
00366     ALBERTA EL* el = elf->neigh[i];
00367     printf(" %p |",el);
00368   }
00369   printf("\n");
00370 
00371 
00372   for(int i=0; i<N_VERTICES; i++)
00373     printf("%d %f %f \n",i,elf->coord[i][0],elf->coord[i][1]);
00374 
00375   
00376   printf("\n******************************************\n");
00377   
00378 }
00379 
00380 
00381 //****************************************************************
00382 //  
00383 //  Wrapper for ALBERTA refine and coarsen routines. 
00384 //  Calling direct refine in the grid.refine() method leads to 
00385 //  infinite loop. Donno wy? 
00386 //  This wrappers solved the problem. 
00387 //
00388 //****************************************************************
00389 
00390 // wrapper for Albert refine routine 
00391 inline static U_CHAR AlbertRefine ( MESH * mesh )
00392 {
00393   return refine ( mesh );
00394 }
00395 
00396 // wrapper for Albert coarsen routine 
00397 inline static U_CHAR AlbertCoarsen ( MESH * mesh )
00398 {
00399   U_CHAR flag = coarsen ( mesh );
00400   // is mesh was really coarsend, then make dof_compress 
00401   if(flag == MESH_COARSENED) dof_compress ( mesh );
00402   return flag;
00403 }
00404 
00405 //*********************************************************************
00406 //
00407 //  Help Routines for the ALBERTA Mesh 
00408 //
00409 //*********************************************************************
00410 namespace AlbertHelp
00411 {
00412 
00413 template <int mydim, int cdim>
00414 inline void makeEmptyElInfo(EL_INFO * elInfo)
00415 {
00416   elInfo->mesh = 0;
00417   elInfo->el = 0;
00418   elInfo->parent = 0;
00419   elInfo->macro_el = 0;
00420   elInfo->level = 0;
00421 #if DIM > 2
00422   elInfo->orientation = 0;
00423   elInfo->el_type = 0;
00424 #endif        
00425               
00426   for(int i =0; i<mydim+1; i++)
00427   {
00428     for(int j =0; j< cdim; j++)
00429     {
00430       elInfo->coord[i][j] = 0.0;
00431       elInfo->opp_coord[i][j] = 0.0;
00432     }
00433     elInfo->bound[i] = 0;
00434   }
00435 }
00436 
00437 static EL_INFO * getFatherInfo(TRAVERSE_STACK * stack, EL_INFO * elInfo, int level)
00438 {
00439   //assert( level == elInfo->level );
00440   EL_INFO * fatherInfo = 0;
00441 
00442   //std::cout << elInfo->el << " element \n";
00443 
00444   // if this level > 0 return father = elInfoStack -1, 
00445   // else return father = this 
00446   assert(stack != 0);
00447 
00448   //std::cout << "get father of level "<< level << "\n";
00449 
00450   if(level > 0)
00451   {
00452     fatherInfo = stack->elinfo_stack + level;
00453     //std::cout << fatherInfo->el << " father \n";
00454     //std::cout << fatherInfo->el->child[0] << " ch 0 | ch 1 " << fatherInfo->el->child[1] << "\n";
00455   }
00456   else 
00457   {
00458     assert( (true) ? (printf("No Father for macro element, return macro element\n"),1) : 1);
00459     return elInfo;
00460   } 
00461   return fatherInfo;
00462 }
00463 
00464 //**************************************************************************
00465 //  calc Maxlevel of AlbertGrid and remember on wich level an element lives
00466 //**************************************************************************
00467 
00468 static int Albert_MaxLevel_help=-1;
00469 
00470 // function for mesh_traverse, is called on every element 
00471 inline static void calcmxl (const EL_INFO * elf)
00472 {
00473   int level = elf->level;
00474   if(Albert_MaxLevel_help < level) Albert_MaxLevel_help = level;
00475 }
00476 
00477 // remember on which level an element realy lives 
00478 inline int calcMaxLevel ( MESH * mesh , DOF_INT_VEC * levelVec ) 
00479 {
00480   Albert_MaxLevel_help = -1;
00481 
00482   // see ALBERTA Doc page 72, traverse over all hierarchical elements 
00483   mesh_traverse(mesh,-1, CALL_LEAF_EL|FILL_NOTHING, calcmxl);
00484 
00485   // check if ok 
00486   assert(Albert_MaxLevel_help != -1);
00487   return Albert_MaxLevel_help;
00488 }
00489 
00490 
00491 
00492 //**************************************************************************
00493 inline static void printNeighbour (const EL_INFO * elf)
00494 {
00495   int i;
00496   printf("%d EL \n",INDEX(elf->el));
00497   for(i=0; i<3; i++)
00498     if(elf->neigh[i])
00499       printf("%d Neigh \n",INDEX(elf->neigh[i]));
00500     else printf("%d Neigh \n",-1);
00501   printf("----------------------------------\n");
00502 }
00503 
00504 //*********************************************************************
00505 
00506 static int AlbertaLeafDataHelp_processor = -1;
00507 // Leaf Data for Albert, only the leaf elements have this data set 
00508 template <int cdim, int vertices> 
00509 struct AlbertLeafData
00510 {
00511 #ifdef LEAFDATACOORDS
00512   typedef Dune::FieldMatrix<double,vertices,cdim> CoordinateMatrixType;
00513   typedef Dune::FieldVector<double,cdim> CoordinateVectorType;
00514 #endif
00515   // type of stored data 
00516   typedef struct {
00517 #ifdef LEAFDATACOORDS
00518     CoordinateMatrixType coord;
00519 #endif
00520     double determinant; 
00521     int processor;
00522   } Data;
00523   
00524   // keep element numbers 
00525   inline static void AlbertLeafRefine(EL *parent, EL *child[2]) 
00526   {
00527     Data * ldata;
00528     int i, processor=-1;
00529 
00530     ldata = (Data *) parent->child[1];
00531     assert(ldata != 0);
00532 
00533     //std::cout << "Leaf refine for el = " << parent << "\n";
00534 
00535     double childDet = 0.5 * ldata->determinant; 
00536     processor = ldata->processor;
00537 
00538     /* bisection ==> 2 children */
00539     for(i=0; i<2; i++)
00540     {
00541       Data *ldataChi = (Data *) child[i]->child[1];
00542       assert(ldataChi != 0);
00543       ldataChi->determinant = childDet;
00544       ldataChi->processor = processor;
00545 
00546 #ifdef LEAFDATACOORDS
00547       // calculate the coordinates 
00548       {
00549         const CoordinateMatrixType &oldCoord = ldata->coord; 
00550         CoordinateMatrixType &coord = ldataChi->coord; 
00551         for (int j = 0; j < cdim; ++j)
00552         {
00553           coord[2][j] = 0.5 * (oldCoord[0][j] + oldCoord[1][j]);
00554           coord[i  ][j] = oldCoord[2][j];
00555           coord[1-i][j] = oldCoord[i][j];
00556         }
00557     //    std::cout << coord[0] << " " << coord[1] << " " << coord[2] << "\n";
00558       }
00559 #endif
00560     }
00561   }
00562 
00563   inline static void AlbertLeafCoarsen(EL *parent, EL *child[2])
00564   {
00565     Data *ldata;
00566     int i;
00567 
00568     ldata = (Data *) parent->child[1];
00569     assert(ldata != 0);
00570     ldata->processor = -1;
00571     double & det = ldata->determinant;
00572     det = 0.0;
00573 
00574     //std::cout << "Leaf coarsen for el = " << parent << "\n";
00575     
00576     /* bisection ==> 2 children */
00577     for(i=0; i<2; i++)
00578     {
00579       Data *ldataChi = (Data *) child[i]->child[1];
00580       assert(ldataChi != 0);
00581       det += ldataChi->determinant;
00582       if(ldataChi->processor >= 0) 
00583         ldata->processor = ldataChi->processor;
00584     }
00585   }
00586 
00587   // we dont need Leaf Data 
00588   inline static void initLeafData(LEAF_DATA_INFO * linfo)
00589   {
00590     linfo->leaf_data_size = sizeof(Data);
00591     linfo->refine_leaf_data  = &AlbertLeafRefine;
00592     linfo->coarsen_leaf_data = &AlbertLeafCoarsen;
00593     return;
00594   }
00595 
00596   // function for mesh_traverse, is called on every element 
00597   inline static void setLeafData(const EL_INFO * elf)
00598   {
00599     assert( elf->el->child[0] == 0 );
00600     Data *ldata = (Data *) elf->el->child[1];
00601     assert(ldata != 0);
00602 
00603 #ifdef LEAFDATACOORDS
00604     for(int i=0; i<vertices; ++i) 
00605     {
00606       CoordinateVectorType & c = ldata->coord[i];
00607       const ALBERTA REAL_D & coord = elf->coord[i];
00608       for(int j=0; j<cdim; ++j) c[j] = coord[j];
00609 //      std::cout << c << " coord \n";
00610     }
00611 #endif
00612 
00613     ldata->determinant = ALBERTA el_det(elf);
00614     ldata->processor   = AlbertaLeafDataHelp_processor;
00615   }
00616 
00617   // remember on which level an element realy lives 
00618   inline static void initLeafDataValues( MESH * mesh, int proc )
00619   {
00620     AlbertaLeafDataHelp_processor = proc;
00621     
00622     // see ALBERTA Doc page 72, traverse over all hierarchical elements 
00623     ALBERTA mesh_traverse(mesh,-1, CALL_LEAF_EL|FILL_COORDS,setLeafData);
00624 
00625     AlbertaLeafDataHelp_processor = -1;
00626   }
00627 
00628 }; // end of AlbertLeafData
00629 
00630 // struct holding the needed DOF_INT_VEC for AlbertGrid 
00631 typedef struct dofvec_stack DOFVEC_STACK;
00632 struct dofvec_stack 
00633 {
00634   // storage of unique element numbers 
00635   DOF_INT_VEC * elNumbers[numOfElNumVec];
00636   // contains information about refine status of element 
00637   DOF_INT_VEC * elNewCheck;
00638   // stores the processor number of proc where element is master 
00639   DOF_INT_VEC * owner;
00640 
00641 #ifndef CALC_COORD
00642   // vector that stores the coordinates 
00643   DOF_REAL_D_VEC * coords;
00644 #endif
00645 };
00646 
00647 static DOF_INT_VEC * elNumbers[numOfElNumVec];
00648 static DOF_INT_VEC * elNewCheck = 0;
00649 static DOF_INT_VEC * elOwner    = 0;
00650 #ifndef CALC_COORD
00651 static DOF_REAL_D_VEC * coordVec = 0; 
00652 #endif
00653 
00654 // return pointer to created elNumbers Vector to mesh 
00655 inline DOF_INT_VEC * getElNumbers(int i) 
00656 { 
00657   int * vec=0;
00658   GET_DOF_VEC(vec,elNumbers[i]);
00659   FOR_ALL_DOFS(elNumbers[i]->fe_space->admin, vec[dof] = getElementIndexForCodim(i) );
00660   return elNumbers[i];
00661 }
00662 
00663 // return pointer to created elNumbers Vector to mesh 
00664 inline static int calcMaxIndex(DOF_INT_VEC * drv) 
00665 { 
00666   int maxindex = 0;
00667   int * vec=0;
00668   GET_DOF_VEC(vec,drv);
00669   FOR_ALL_DOFS(drv->fe_space->admin, if(vec[dof] > maxindex) maxindex = vec[dof] );
00670   // we return +1 because this means a size 
00671   return maxindex+1;
00672 }
00673 
00674 // return pointer to created elNewCheck Vector to mesh 
00675 inline DOF_INT_VEC * getElNewCheck() 
00676 { 
00677   int * vec=0;
00678   GET_DOF_VEC(vec,elNewCheck);
00679   FOR_ALL_DOFS(elNewCheck->fe_space->admin, vec[dof] = 0 );
00680   return elNewCheck;
00681 }
00682 
00683 // return pointer to created elNewCheck Vector to mesh 
00684 inline DOF_INT_VEC * getOwner() 
00685 { 
00686   int * vec=0;
00687   GET_DOF_VEC(vec,elOwner);
00688   FOR_ALL_DOFS(elOwner->fe_space->admin, vec[dof] = 0 );
00689   return elOwner;
00690 }
00691 
00692 #ifndef CALC_COORD
00693 template <int dimworld>
00694 inline static void setLocalCoords(const EL_INFO * elf) 
00695 {
00696   const EL * element = elf->el; 
00697   assert(element);
00698   const DOF_ADMIN  * admin = coordVec->fe_space->admin;
00699   REAL_D * vec = 0;
00700   const int nv = admin->n0_dof[VERTEX];
00701 
00702   GET_DOF_VEC(vec,coordVec);
00703   assert(vec);
00704   
00705   for(int i=0; i<N_VERTICES; ++i) 
00706   {
00707     int dof = element->dof[i][nv];
00708     REAL_D & vecCoord = vec[dof];
00709     const REAL_D & coord = elf->coord[i];
00710     for(int j=0; j<dimworld; ++j) 
00711     {
00712       vecCoord[j] = coord[j];
00713     }
00714   }
00715 }
00716 
00717 // return pointer to created elNewCheck Vector to mesh 
00718 template <int dimworld> 
00719 inline DOF_REAL_D_VEC * getCoordVec() 
00720 { 
00721   MESH * mesh = coordVec->fe_space->admin->mesh;
00722   assert(mesh);
00723   mesh_traverse(mesh,-1, CALL_EVERY_EL_PREORDER|FILL_COORDS,& setLocalCoords<dimworld>);
00724 
00725   /*
00726   REAL_D * vec = 0;
00727   GET_DOF_VEC(vec,coordVec);
00728   FOR_ALL_DOFS(coordVec->fe_space->admin, 
00729       std::cout << "vec["<<dof<<"] = {";
00730       for(int i=0; i<dimworld; ++i) 
00731         std::cout << vec[dof][i] << ",";
00732       std::cout << "}\n";  
00733   );
00734   */
00735   
00736   return coordVec;
00737 }
00738 #endif
00739 
00740 template <int dimworld> 
00741 inline void getDofVecs(DOFVEC_STACK * dofvecs)
00742 {
00743   for(int i=0;i<numOfElNumVec; i++) 
00744   {
00745     dofvecs->elNumbers[i]  = getElNumbers(i); 
00746     elNumbers[i]  = 0;
00747   }
00748 
00749   dofvecs->elNewCheck   = getElNewCheck();  elNewCheck = 0;
00750   dofvecs->owner        = getOwner();       elOwner    = 0;
00751 #ifndef CALC_COORD
00752   dofvecs->coords       = getCoordVec<dimworld> ();    coordVec   = 0;
00753 #endif
00754 }
00755 
00756 struct MeshCallBack 
00757 {
00758   template <class HandlerImp>
00759   struct Refinement 
00760   {
00761     static void apply(void * handler, EL * el)
00762     {
00763       assert( handler );
00764       ((HandlerImp *) handler)->postRefinement(el);
00765     }
00766   };
00767 
00768   template <class HandlerImp>
00769   struct Coarsening 
00770   {
00771     static void apply(void * handler, EL * el)
00772     {
00773       assert( handler );
00774       ((HandlerImp *) handler)->preCoarsening(el);
00775     }
00776   };
00777 
00778   typedef void callBackPointer_t(void * , EL * );
00779   
00780   // pointer to actual mesh, for checking only 
00781   MESH * mesh_; 
00782   // pointer to data handler 
00783   void * dataHandler_; 
00784   // method to cast back and call methods of data handler 
00785   callBackPointer_t * postRefinement_;
00786   callBackPointer_t * preCoarsening_;
00787 
00788   void reset () 
00789   {
00790     mesh_           = 0; 
00791     dataHandler_    = 0;
00792     postRefinement_ = 0;
00793     preCoarsening_  = 0;
00794   }
00795 
00796   const MESH * lockMesh () const { return mesh_; }
00797   const void * dataHandler () const { return dataHandler_; }
00798 
00799   template <class HandlerImp>
00800   void setPointers(MESH * mesh, HandlerImp & handler) 
00801   {
00802     mesh_ = mesh; // set mesh pointer for checking 
00803     dataHandler_ = (void *) &handler; // set pointer of data handler 
00804 
00805     postRefinement_ = & Refinement<HandlerImp>::apply; 
00806     preCoarsening_  = & Coarsening<HandlerImp>::apply;
00807   }
00808 
00809   void postRefinement( EL * el ) 
00810   {
00811     assert( preCoarsening_ != 0 );
00812     postRefinement_(dataHandler_,el);
00813   }
00814   void preCoarsening( EL * el ) 
00815   {
00816     assert( preCoarsening_ != 0 );
00817     preCoarsening_(dataHandler_,el);
00818   }
00819   
00820 private:
00821   MeshCallBack () 
00822     : mesh_(0), dataHandler_(0), postRefinement_(0), preCoarsening_(0) {}
00823 public:  
00824   static MeshCallBack & instance() 
00825   {
00826     static MeshCallBack inst;
00827     return inst; 
00828   }
00829 };
00830 
00831 #ifndef CALC_COORD
00832 // set entry for new elements to 1 
00833 template <int dim>
00834 inline static void refineCoordsAndRefineCallBack ( DOF_REAL_D_VEC * drv , RC_LIST_EL *list, int ref)
00835 {
00836   static MeshCallBack & callBack = MeshCallBack::instance();
00837   
00838   const int nv = drv->fe_space->admin->n0_dof[VERTEX];
00839   REAL_D* vec = 0; 
00840   GET_DOF_VEC(vec,drv);
00841   assert(ref > 0);
00842 
00843   const EL * el = list->el;
00844   
00845   // refinement edge is alwyas between vertex 0 and 1 
00846   const int dof0 = el->dof[0][nv];
00847   const int dof1 = el->dof[1][nv];
00848 
00849   assert( el->child[0] );
00850   // new dof has local number dim 
00851   const int dofnew = el->child[0]->dof[dim][nv]; 
00852 
00853   // get coordinates 
00854   const REAL_D & oldCoordZero = vec[dof0]; 
00855   const REAL_D & oldCoordOne  = vec[dof1]; 
00856   REAL_D & newCoord = vec[dofnew]; 
00857  
00858   // new coordinate is average between old on same edge
00859   // see ALBERTA docu page 159, where this method is described
00860   // as real_refine_inter
00861   for(int j=0; j<dim; ++j) 
00862     newCoord[j] = 0.5*(oldCoordZero[j] + oldCoordOne[j]);
00863   
00864   if(callBack.dataHandler())
00865   {
00866     // make sure that mesh is the same as in MeshCallBack 
00867     assert( drv->fe_space->admin->mesh == callBack.lockMesh() );
00868     for(int i=0; i<ref; ++i)
00869     {
00870       EL * elem = list[i].el;
00871 
00872       //std::cout << "call refine for element " << elem << "\n";
00873       callBack.postRefinement(elem);
00874     }
00875   } 
00876 }
00877 
00878 inline static void 
00879 coarseCallBack ( DOF_REAL_D_VEC * drv , RC_LIST_EL *list, int ref)
00880 {
00881   static MeshCallBack & callBack = MeshCallBack::instance();
00882   
00883   if(callBack.dataHandler())
00884   {
00885     assert( drv->fe_space->admin->mesh == callBack.lockMesh() );
00886     assert(ref > 0);
00887     for(int i=0; i<ref; ++i)
00888     {
00889       EL * el = list[i].el;
00890       //std::cout << "call coarse for element " << el << "\n";
00891       callBack.preCoarsening(el);
00892     }
00893   }
00894 }
00895 #endif
00896 
00897 // set entry for new elements to 1 
00898 inline static void refineElNewCheck ( DOF_INT_VEC * drv , RC_LIST_EL *list, int ref)
00899 {
00900   const DOF_ADMIN * admin = drv->fe_space->admin;
00901   const int nv = admin->n0_dof[CENTER];
00902   const int k  = admin->mesh->node[CENTER];   
00903   int *vec = 0; 
00904 
00905   GET_DOF_VEC(vec,drv);
00906   assert(ref > 0);
00907 
00908   for(int i=0; i<ref; i++)
00909   {
00910     const EL * el = list[i].el;
00911     //std::cout << "refine elNewCheck for el = " << el << "\n";
00912     
00913     // get level of father which is the absolute value 
00914     // if value is < 0 then this just means that element 
00915     // was refined 
00916     int level = std::abs( vec[el->dof[k][nv]] ) + 1; 
00917     for(int ch=0; ch<2; ch++)
00918     {
00919       // set new to negative level of the element 
00920       // which then can be used to check whether an element is new on not
00921       // also this vector stores the level of the element which is needed
00922       // for the face iterator
00923       vec[el->child[ch]->dof[k][nv]] = -level; 
00924     }
00925   } 
00926 }
00927 
00928 // set entry for new elements to 1 
00929 inline static void refineElOwner( DOF_INT_VEC * drv , RC_LIST_EL *list, int ref)
00930 {
00931   const DOF_ADMIN * admin = drv->fe_space->admin;
00932   const int nv = admin->n0_dof[CENTER];
00933   const int k  = admin->mesh->node[CENTER];   
00934 
00935   int *vec = 0; 
00936   int val = -1;
00937 
00938   GET_DOF_VEC(vec,drv);
00939 
00940   assert(ref > 0);
00941 
00942   for(int i=0; i<ref; ++i)
00943   {
00944     const EL * el = list[i].el;
00945 
00946     val = vec[el->dof[k][nv]];
00947     // in case of ghosts 
00948     for(int ch=0; ch<2; ++ch)
00949     {
00950       // set processor 
00951       vec[el->child[ch]->dof[k][nv]] = val; 
00952     }
00953   } 
00954 }
00955 
00956 // clear Dof Vec 
00957 inline static void clearDofVec ( DOF_INT_VEC * drv ) 
00958 {
00959   int * vec=0;
00960   GET_DOF_VEC(vec,drv);
00961   FOR_ALL_DOFS(drv->fe_space->admin, vec[dof] = 0 );
00962 }
00963 
00964 // calculate max absolute value of given vector  
00965 inline int calcMaxAbsoluteValueOfVector ( const DOF_INT_VEC * drv ) 
00966 {
00967   const int * vec = 0;
00968   int maxi = 0;
00969   GET_DOF_VEC(vec,drv);
00970   FOR_ALL_DOFS(drv->fe_space->admin, maxi = std::max( maxi , std::abs(vec[dof]) ) );
00971   return maxi;
00972 }
00973 
00974 // set all values of vector to its positive value  
00975 inline static void set2positive ( DOF_INT_VEC * drv ) 
00976 {
00977   int * vec=0;
00978   GET_DOF_VEC(vec,drv);
00979   FOR_ALL_DOFS(drv->fe_space->admin, vec[dof] = std::abs( vec[dof] ) );
00980 }
00981 
00982 // clear Dof Vec 
00983 inline static void setDofVec ( DOF_INT_VEC * drv , int val ) 
00984 {
00985   int * vec=0;
00986   GET_DOF_VEC(vec,drv);
00987   FOR_ALL_DOFS(drv->fe_space->admin, vec[dof] = val );
00988 }
00989 
00990 // clear Dof Vec 
00991 inline static void copyOwner ( DOF_INT_VEC * drv , int * ownvec ) 
00992 {
00993   int * vec=0;
00994   GET_DOF_VEC(vec,drv);
00995   FOR_ALL_DOFS(drv->fe_space->admin, vec[dof] = ownvec[dof] );
00996 }
00997 
00998 
00999 #define PROCRESTORE 66666666
01000 
01001 // save processor number in owner vec
01002 // to the value at the position with the processor number 
01003 // the significant value PROCRESTORE is added or if the value is smaller 
01004 // then zero substracted. 
01005 inline static int saveMyProcNum ( DOF_INT_VEC * drv , const int myProc, 
01006       int & entry) 
01007 {
01008   int * vec=0;
01009   int spot = -1;
01010   GET_DOF_VEC(vec,drv);
01011   FOR_ALL_DOFS(drv->fe_space->admin, 
01012       if(dof == myProc) 
01013       {
01014         spot = dof;
01015         entry = vec[dof];
01016         if(vec[dof] >= 0) 
01017           vec[dof] += PROCRESTORE;
01018         else 
01019           vec[dof] -= PROCRESTORE;
01020       }
01021   );
01022   return spot;
01023 }
01024 
01025 // restore processor number for owner vec  
01026 inline static int restoreMyProcNum ( DOF_INT_VEC * drv) 
01027 {
01028   int myProc = -1; 
01029   int * vec=0;
01030   
01031   GET_DOF_VEC(vec,drv);
01032   FOR_ALL_DOFS(drv->fe_space->admin,
01033       if(vec[dof] >= PROCRESTORE)
01034       {
01035         vec[dof] -= PROCRESTORE;
01036         myProc = dof;
01037       }
01038       else if (vec[dof] <= -PROCRESTORE)
01039       {
01040         vec[dof] += PROCRESTORE;
01041         myProc = dof;  
01042       }
01043   );
01044 
01045   return myProc;
01046 }
01047 
01048 inline DOF_INT_VEC * getDofNewCheck(const FE_SPACE * espace, 
01049                                     const char * name)
01050 {
01051   DOF_INT_VEC * drv = get_dof_int_vec(name,espace);
01052   int * vec=0;
01053   drv->refine_interpol = &refineElNewCheck;
01054   drv->coarse_restrict = 0;
01055   GET_DOF_VEC(vec,drv);
01056   FOR_ALL_DOFS(drv->fe_space->admin, vec[dof] = 0 );
01057   return drv;
01058 }
01059 
01060 // setup of DOF_INT_VEC for reading 
01061 template <int dimworld> 
01062 inline void makeTheRest(DOFVEC_STACK * dofvecs) 
01063 {
01064   dofvecs->elNewCheck = getDofNewCheck(dofvecs->elNumbers[0]->fe_space,"el_new_check");
01065   // if owner vec not has been read 
01066   if(!dofvecs->owner) dofvecs->owner = getDofNewCheck(dofvecs->elNumbers[0]->fe_space,"el_owner");
01067   dofvecs->owner->refine_interpol = &refineElOwner;
01068  
01069 #ifndef CALC_COORD 
01070   {
01071     MESH * mesh = dofvecs->elNumbers[0]->fe_space->admin->mesh; 
01072     assert( mesh );
01073  
01074     enum { dim = dimworld };
01075     int vdof[dim+1]; // add at each vertex one dof for vertex numbering
01076 
01077     for(int i=0; i<dim+1; i++)
01078     {
01079       vdof[i] = 0;
01080     }
01081     vdof[0] = 1; 
01082 
01083     const FE_SPACE * vSpace = get_fe_space(mesh, "vertex_dofs", vdof, 0);
01084     
01085     // coords should not exist at this point 
01086     assert( !dofvecs->coords );
01087   
01088     coordVec = get_dof_real_d_vec("coordinates",vSpace);
01089     coordVec->refine_interpol = &refineCoordsAndRefineCallBack<dimworld>;
01090     coordVec->coarse_restrict = &coarseCallBack; // coords don't need to be coarsened
01091         
01092     dofvecs->coords = getCoordVec<dimworld> ();    
01093     coordVec = 0;
01094   }
01095 #endif
01096 }
01097 
01098 // initialize dofAdmin for vertex and element numbering 
01099 // and a given dim 
01100 // --initDofAdmin 
01101 template <int dim>
01102 static inline void initDofAdmin(MESH *mesh)
01103 {
01104   int edof[dim+1]; // add one dof at element for element numbering
01105   int vdof[dim+1]; // add at each vertex one dof for vertex numbering
01106   int fdof[dim+1]; // add at each face one dof for face numbering
01107   int edgedof[dim+1]; // add at each edge one dof for edge numbering
01108 
01109   for(int i=0; i<dim+1; i++)
01110   {
01111     vdof[i] = 0; fdof[i]    = 0;
01112     edof[i] = 0; edgedof[i] = 0;
01113   }
01114   
01115   vdof[0] = 1; 
01116 
01117   if(dim == 3) edgedof[1] = 1; // edge dof only in 3d 
01118   
01119   fdof[dim-1] = 1; // means edges in 2d and faces in 3d
01120   edof[dim] = 1;
01121 
01122   {
01123     // !! NOTE: 
01124     // the order in which the refine routines are called is jsut turned
01125     // arround, which mean that actual the coordinates are refined at last
01126     // and therefore the element call back is done in this function 
01127 #ifndef CALC_COORD
01128     const FE_SPACE * vSpace =
01129 #endif      
01130       get_fe_space(mesh, "vertex_dofs", vdof, 0);
01131     
01132 #ifndef CALC_COORD
01133     coordVec = get_dof_real_d_vec("coordinates",vSpace);
01134     coordVec->refine_interpol = &refineCoordsAndRefineCallBack<dim>;
01135     coordVec->coarse_restrict = &coarseCallBack; // coords don't need to be coarsened
01136 #endif
01137   }
01138 
01139   //**********************************************************************
01140   // all the element vectors 
01141   //**********************************************************************
01142   // space for center dofs , i.e. element numbers 
01143   const FE_SPACE * elemSpace = get_fe_space(mesh, "center_dofs", edof, 0);
01144  
01145   // the first entry is called at last for refinement and coarsening 
01146   // the methods for the adaptation call back are put to elNewCheck
01147   // refine and coarsening procedures 
01148   elNewCheck = get_dof_int_vec("el_new_check",elemSpace);
01149   elNewCheck->refine_interpol = &refineElNewCheck;
01150   elNewCheck->coarse_restrict = 0;
01151   
01152   // the element numbers, ie. codim = 0 
01153   elNumbers[0] = get_dof_int_vec("element_numbers",elemSpace);
01154   elNumbers[0]->refine_interpol = &RefineNumbering<dim,0>::refineNumbers;
01155   elNumbers[0]->coarse_restrict = &RefineNumbering<dim,0>::coarseNumbers;
01156 
01157   elOwner = get_dof_int_vec("el_owner",elemSpace);
01158   elOwner->refine_interpol = &refineElOwner;
01159   elOwner->coarse_restrict = 0;//&coarseCallBack;
01160 
01161   //**********************************************************************
01162 
01163   {
01164     // the face number space , i.e. codim == 1
01165     const FE_SPACE * fSpace = get_fe_space(mesh, "face_dofs", fdof, 0);
01166 
01167     // the face numbers, i.e. codim = 1 
01168     elNumbers[1] = get_dof_int_vec("face_numbers",fSpace);
01169     elNumbers[1]->refine_interpol = &RefineNumbering<dim,1>::refineNumbers;
01170     elNumbers[1]->coarse_restrict = &RefineNumbering<dim,1>::coarseNumbers;
01171   }
01172  
01173   if(dim == 3)
01174   {
01175     // the edge number space , i.e. codim == 2
01176     const FE_SPACE * eSpace = get_fe_space(mesh, "edge_dofs", edgedof, 0);
01177 
01178     // the edge numbers, i.e. codim = 2 
01179     elNumbers[2] = get_dof_int_vec("edge_numbers",eSpace);
01180     elNumbers[2]->refine_interpol = &RefineNumbering<dim,2>::refineNumbers;
01181     elNumbers[2]->coarse_restrict = &RefineNumbering<dim,2>::coarseNumbers;
01182   }
01183 
01184   return;
01185 }
01186 
01187 static std::stack < BOUNDARY * > * Alberta_tmpBndStack = 0;
01188 
01189 inline static void initBndStack( std::stack < BOUNDARY * > * bndStack )
01190 {
01191   Alberta_tmpBndStack = bndStack;
01192 }
01193 inline static void removeBndStack ()
01194 {
01195   Alberta_tmpBndStack = 0;
01196 }
01197 
01198 // initialize boundary for mesh 
01199 inline const BOUNDARY *initBoundary(MESH * Spmesh, int bound)
01200 {
01201   BOUNDARY *b = (BOUNDARY *) new BOUNDARY ();
01202   assert(b != 0);
01203 
01204   assert(Alberta_tmpBndStack);
01205   Alberta_tmpBndStack->push( b );
01206 
01207   // bound is of type signed char which goes from -127 to 128 
01208   if((bound < -127) && (bound > 128))
01209   {
01210     std::cerr << "Got boundary id = " << bound << "\n";
01211     std::cerr << "Wrong boundary id: range is only from -127 to 128 !\n";
01212     std::cerr << "Correct your macro grid file!\n";
01213     abort();
01214   }
01215 
01216   b->param_bound = 0;
01217   b->bound = bound;
01218 
01219   return b;
01220 }
01221 
01222 //*******************************************************************
01223 //*******************************************************************
01224 //*******************************************************************
01225 //
01226 //  functions for making the partition on one processor 
01227 //
01228 //*******************************************************************
01229 //*******************************************************************
01230 //*******************************************************************
01231 
01232 struct Albert_Restore_Mesh {
01233 
01234   MESH * mesh;
01235   MACRO_EL ** mels;
01236   int  n_macro_el;
01237   int n_elements; 
01238   int n_hier_elements;
01239   int n_vertices;
01240 };  
01241 
01242 typedef struct Albert_Restore_Mesh ALBERTA_RESTORE_MESH;
01243 
01244 
01245 static ALBERTA_RESTORE_MESH ag_restore = { 0 , 0 ,-1 ,-1 ,-1 ,-1};
01246 
01247 // backu the mesh before removing some macro elements 
01248 inline static void storeMacroElements(MESH * mesh)
01249 {
01250   // if other mesh was stored before, then restore was forget 
01251   assert(ag_restore.mesh == 0);
01252   int length = mesh->n_macro_el;
01253   MACRO_EL ** mel = (MACRO_EL **) std::malloc(length * sizeof(MACRO_EL *));
01254   assert(mel != 0);
01255 
01256   int no=0;
01257   for(MACRO_EL * el = mesh->first_macro_el; el; el = el->next)
01258   {
01259     mel[no] = el;
01260     no++;
01261   }
01262 
01263   assert(no == length); 
01264   
01265   ag_restore.mesh = mesh;
01266   ag_restore.mels = mel;
01267   ag_restore.n_macro_el = mesh->n_macro_el;
01268   ag_restore.n_elements = mesh->n_elements;
01269   ag_restore.n_hier_elements = mesh->n_hier_elements;
01270   ag_restore.n_vertices = mesh->n_vertices;
01271 }
01272 
01273 // restore the mesh, that ALBERTA can free it normaly 
01274 inline static void resetMacroElements(MESH * mesh)
01275 {
01276   // if not the same mesh to restore ==> break
01277   assert(ag_restore.mesh == mesh);
01278   int length = ag_restore.n_macro_el;
01279   MACRO_EL **mel = ag_restore.mels;
01280   assert(mel != 0);
01281   
01282   mesh->first_macro_el = mel[0];
01283   mel[0]->last = 0;
01284 
01285   for(int i=1; i<length; i++)
01286   {
01287     mel[i-1]->next = mel[i];
01288     (mel[i])->last = mel[i-1];
01289   }
01290 
01291   mel[length-1]->next = 0;
01292 
01293   mesh->n_macro_el = ag_restore.n_macro_el;
01294   mesh->n_elements = ag_restore.n_elements;
01295   mesh->n_hier_elements = ag_restore.n_hier_elements;
01296   mesh->n_vertices = ag_restore.n_vertices;
01297   
01298   ag_restore.mesh = 0;
01299   std::free(ag_restore.mels); ag_restore.mels = 0;
01300   ag_restore.n_macro_el = -1;
01301   ag_restore.n_elements = -1;
01302   ag_restore.n_hier_elements = -1;
01303   ag_restore.n_vertices = -1;
01304 }
01305 
01306 // mark elements that not belong to my processor 
01307 inline void partitioning ( MACRO_EL * mel, int proc, int mynumber  )
01308 {
01309   if(proc == mynumber)
01310   {
01311     mel->el->mark = 0;
01312   }
01313   else 
01314   {
01315     mel->el->mark = 1;
01316   }
01317 }
01318 
01319 // unmark neighbours of not interior elements  
01320 inline void ghosts ( MACRO_EL * mel )
01321 {
01322   if(mel->el->mark == 0)
01323   {
01324     for(int i=0; i<N_NEIGH; i++)
01325     {
01326       if(mel->neigh[i])
01327       {
01328         if(mel->neigh[i]->el->mark != 0)
01329         {
01330           mel->neigh[i]->el->mark = -1;
01331         }
01332       }
01333     }
01334   }
01335 }
01336 
01337 // reset mark 
01338 inline void afterGhosts ( MACRO_EL * mel )
01339 {
01340   if(mel->el->mark < 0)
01341   {
01342     mel->el->mark = 0;
01343   }
01344 }
01345 
01346 // remove macro elements that not belong to this processor or that are not ghost  
01347 inline void removeMacroEls ( MESH * mesh , int proc , int * ownvec )
01348 {
01349   MACRO_EL *mel = 0;
01350   
01351   int length = mesh->n_macro_el;
01352   int * dofNum = (int *) std::malloc(mesh->n_vertices * sizeof(int));
01353   int * dofHier = (int *) std::malloc(mesh->n_vertices*sizeof(int));
01354   assert(dofNum  != 0);
01355   assert(dofHier != 0);
01356 
01357   dof_compress(mesh);
01358   
01359   for(int i=0; i<mesh->n_vertices; i++) dofNum[i] = -1;
01360   for(int i=0; i<mesh->n_vertices; i++) dofHier[i] = -1;
01361 
01362   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01363   {
01364     partitioning( mel , proc, ownvec[mel->index] );
01365   }
01366  
01367   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01368   {
01369     ghosts ( mel );
01370   }
01371   
01372   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01373   {
01374     afterGhosts ( mel );
01375   }
01376 
01377   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01378   {
01379     if(mel->el->mark == 1)
01380     {
01381       for(int i=0; i<N_NEIGH; i++)
01382       {
01383         MACRO_EL * neigh = mel->neigh[i];
01384         if(neigh)
01385         {
01386           for(int k=0; k<N_NEIGH; k++)
01387           {
01388             if(neigh->neigh[k] == mel)
01389               neigh->neigh[k] = 0;
01390           } 
01391         }
01392       }
01393     }
01394   }
01395 
01396   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01397   {
01398     // mark all dof that remain on mesh
01399     if(mel->el->mark != 1)
01400     {
01401       EL * myEl = mel->el;
01402       for(int l=0; l<N_VERTICES; l++)
01403       {
01404         dofNum[myEl->dof[l][0]] = 1; 
01405       }
01406     }
01407   }
01408 
01409   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01410   {
01411     // mark all dof that remain on mesh
01412     if(mel->el->mark == 1)
01413     {
01414       EL * myEl = mel->el;
01415       for(int l=0; l<N_VERTICES; l++)
01416       {
01417         int dof = myEl->dof[l][0];
01418         if(dofNum[dof] == -1)
01419         {
01420           dofHier[dof] = mel->index; 
01421         }
01422       }
01423     }
01424   }
01425 
01426   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01427   {
01428     if(mel->el->mark == 1)
01429     {
01430       DOF * dofs[N_VERTICES];
01431       EL *myEl = mel->el;
01432       for(int k=0; k<N_VERTICES; k++)
01433       {
01434         dofs[k] = myEl->dof[k];
01435       }
01436       assert(myEl != 0);
01437 
01438       for(int k=0; k<N_VERTICES; k++)
01439       {
01440         if((dofNum[dofs[k][0]] == -1) && (dofHier[dofs[k][0]] == mel->index ) )
01441         {
01442           int dof = dofs[k][0];
01443           dofNum[dof] = 1;
01444           mesh->n_vertices--;
01445         }
01446       }
01447     }
01448   }
01449 
01450   // remove the macro elements 
01451   mel = mesh->first_macro_el;
01452   while(mel)
01453   {
01454     if(mel->el->mark == 1)
01455     {
01456       if(mel->last)
01457       {
01458         mel->last->next = mel->next;
01459       }
01460       else 
01461       {
01462         // if no last exists that means we have the first and change the
01463         // first macro el of the mesh 
01464         mesh->first_macro_el = mel->next;
01465       }
01466       
01467       if(mel->next)
01468       { 
01469         mel->next->last = mel->last;
01470       }
01471       
01472       mesh->n_hier_elements--;
01473       mesh->n_elements--;
01474       mesh->n_macro_el--;
01475      
01476     }
01477     mel = mel->next;
01478   }
01479  
01480   dof_compress(mesh);  
01481 
01482   // remember old owner 
01483   int * fakeMem = (int *) std::malloc(length * sizeof(int));
01484   std::memcpy(fakeMem,ownvec,length * sizeof(int));
01485   for(int i=0;i<length; i++) ownvec[i] = -1;
01486   int no = 0; 
01487   for(mel = mesh->first_macro_el; mel; mel = mel->next)
01488   {
01489     ownvec[no] = fakeMem[mel->index];  
01490     no++;
01491   }
01492 
01493   // free memory 
01494   if(fakeMem) std::free(fakeMem); fakeMem = 0;
01495   if(dofNum)  std::free(dofNum);  dofNum  = 0;
01496   if(dofHier) std::free(dofHier); dofHier = 0;
01497 }
01498 
01499 inline void printMacroData(MACRO_DATA * mdata)
01500 {
01501   FUNCNAME("printMacroData");
01502   MSG("noe %d , nvx %d \n",mdata->n_macro_elements,mdata->n_total_vertices);
01503   for(int i=0; i<mdata->n_total_vertices; i++)
01504     MSG("coords [%f | %f ]\n",mdata->coords[i][0],mdata->coords[i][1]);
01505  
01506   for(int i=0; i<mdata->n_macro_elements; i++)
01507     MSG("bound [%d | %d | %d ]\n",mdata->boundary[i][0],mdata->boundary[i][1],mdata->boundary[i][2]);
01508 
01509 
01510 }
01511 
01512 // function for mesh_traverse, is called on every element 
01513 inline static void setElOwner(const EL_INFO * elf)
01514 {
01515   const DOF_ADMIN * admin = elOwner->fe_space->admin;
01516   const int nv = admin->n0_dof[CENTER];
01517   const int k  = admin->mesh->node[CENTER];   
01518   int *vec = 0; 
01519   EL * el   = elf->el;
01520   EL * papi = elf->parent;
01521   
01522   if(elf->level <= 0) return;
01523 
01524   assert(el && papi);
01525   GET_DOF_VEC(vec,elOwner);
01526 
01527   int papiProc = vec[papi->dof[k][nv]];
01528   vec[el->dof[k][nv]] = papiProc;
01529   return ;
01530 }
01531 
01532 // remember on which level an element realy lives 
01533 inline void setElOwnerNew( MESH * mesh, DOF_INT_VEC * elOwn )
01534 {
01535   elOwner = elOwn;
01536   assert(elOwner != 0);
01537   // see ALBERTA Doc page 72, traverse over all hierarchical elements 
01538   mesh_traverse(mesh,-1, CALL_EVERY_EL_PREORDER|FILL_NEIGH,setElOwner);
01539   elOwner = 0;
01540   return ;
01541 }
01542 
01543 // function for mesh_traverse, is called on every element 
01544 inline static void storeLevelOfElement(const EL_INFO * elf)
01545 {
01546   const DOF_ADMIN * admin = elNewCheck->fe_space->admin;
01547   const int nv = admin->n0_dof[CENTER];
01548   const int k  = admin->mesh->node[CENTER];   
01549   int *vec = 0; 
01550   const EL * el   = elf->el;
01551   
01552   int level = elf->level;
01553   if( level <= 0 ) return;
01554 
01555   assert(el);
01556   GET_DOF_VEC(vec,elNewCheck);
01557 
01558   vec[el->dof[k][nv]] = level;
01559   return ;
01560 }
01561 
01562 // remember on which level an element realy lives 
01563 inline void restoreElNewCheck( MESH * mesh, DOF_INT_VEC * elNChk )
01564 {
01565   elNewCheck = elNChk;
01566   assert(elNewCheck != 0);
01567   
01568   // see ALBERTA Doc page 72, traverse over all hierarchical elements 
01569   mesh_traverse(mesh,-1,CALL_EVERY_EL_PREORDER|FILL_NEIGH,storeLevelOfElement);
01570   elNewCheck = 0;
01571   return ;
01572 }
01573 
01574 } // end namespace AlbertHelp 
01575 
01576 #ifdef __ALBERTApp__
01577 } // end namespace Albert  
01578 #endif
01579 
01580 #endif  /* !_ALBERTAEXTRA_H_ */

Generated on 9 Apr 2008 with Doxygen (ver 1.5.2) [logfile].