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

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].