00001
00002
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
00029 elinfo->neigh[neigh] = mel->neigh[neigh]->el;
00030
00031 int oppvx = mel->opp_vertex[neigh];
00032 elinfo->opp_vertex[neigh] = oppvx;
00033
00034
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
00045 fill_macro_info(stack->traverse_mesh,mel,elinfo);
00046
00047 #if DIM == 2
00048
00049
00050
00051
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
00072 #include "agelementindex.cc"
00073
00074
00075
00076
00077
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
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
00146
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
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
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
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
00207
00208
00209 assert( stack );
00210
00211
00212 if(stack->stack_size <= 0) enlargeTraverseStack( stack );
00213 return stack;
00214 }
00215
00216 inline static TRAVERSE_STACK *freeTraverseStack(TRAVERSE_STACK *stack)
00217 {
00218
00219 resetTraverseStack(stack);
00220 free_traverse_stack(stack);
00221
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
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
00237
00238 memcpy( stack, org, sizeof(TRAVERSE_STACK));
00239
00240 stack->elinfo_stack = 0;
00241 stack->elinfo_stack = MEM_ALLOC(used, EL_INFO);
00242
00243
00244
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
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
00270
00271
00272
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
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
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
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
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
00385
00386
00387
00388
00389
00390
00391
00392 inline static U_CHAR AlbertRefine ( MESH * mesh )
00393 {
00394 return refine ( mesh );
00395 }
00396
00397
00398 inline static U_CHAR AlbertCoarsen ( MESH * mesh )
00399 {
00400 U_CHAR flag = coarsen ( mesh );
00401
00402 if(flag == MESH_COARSENED) dof_compress ( mesh );
00403 return flag;
00404 }
00405
00406
00407
00408
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
00441 EL_INFO * fatherInfo = 0;
00442
00443
00444
00445
00446
00447 assert(stack != 0);
00448
00449
00450
00451 if(level > 0)
00452 {
00453 fatherInfo = stack->elinfo_stack + level;
00454
00455
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
00467
00468
00469 static int Albert_MaxLevel_help=-1;
00470
00471
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
00479 inline int calcMaxLevel ( MESH * mesh , DOF_INT_VEC * levelVec )
00480 {
00481 Albert_MaxLevel_help = -1;
00482
00483
00484 mesh_traverse(mesh,-1, CALL_LEAF_EL|FILL_NOTHING, calcmxl);
00485
00486
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
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
00517 typedef struct {
00518 #ifdef LEAFDATACOORDS
00519 CoordinateMatrixType coord;
00520 #endif
00521 double determinant;
00522 int processor;
00523 } Data;
00524
00525
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
00535
00536 double childDet = 0.5 * ldata->determinant;
00537 processor = ldata->processor;
00538
00539
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
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
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
00576
00577
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
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
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
00611 }
00612 #endif
00613
00614 ldata->determinant = ALBERTA el_det(elf);
00615 ldata->processor = AlbertaLeafDataHelp_processor;
00616 }
00617
00618
00619 inline static void initLeafDataValues( MESH * mesh, int proc )
00620 {
00621 AlbertaLeafDataHelp_processor = proc;
00622
00623
00624 ALBERTA mesh_traverse(mesh,-1, CALL_LEAF_EL|FILL_COORDS,setLeafData);
00625
00626 AlbertaLeafDataHelp_processor = -1;
00627 }
00628
00629 };
00630
00631
00632 typedef struct dofvec_stack DOFVEC_STACK;
00633 struct dofvec_stack
00634 {
00635
00636 DOF_INT_VEC * elNumbers[numOfElNumVec];
00637
00638 DOF_INT_VEC * elNewCheck;
00639
00640 DOF_INT_VEC * owner;
00641
00642 #ifndef CALC_COORD
00643
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
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
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
00672 return maxindex+1;
00673 }
00674
00675
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
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
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
00728
00729
00730
00731
00732
00733
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
00782 MESH * mesh_;
00783
00784 void * dataHandler_;
00785
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;
00804 dataHandler_ = (void *) &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
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
00847 const int dof0 = el->dof[0][nv];
00848 const int dof1 = el->dof[1][nv];
00849
00850 assert( el->child[0] );
00851
00852 const int dofnew = el->child[0]->dof[dim][nv];
00853
00854
00855 const REAL_D & oldCoordZero = vec[dof0];
00856 const REAL_D & oldCoordOne = vec[dof1];
00857 REAL_D & newCoord = vec[dofnew];
00858
00859
00860
00861
00862 for(int j=0; j<dim; ++j)
00863 newCoord[j] = 0.5*(oldCoordZero[j] + oldCoordOne[j]);
00864
00865 if(callBack.dataHandler())
00866 {
00867
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
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
00892 callBack.preCoarsening(el);
00893 }
00894 }
00895 }
00896 #endif
00897
00898
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
00913
00914
00915
00916
00917 int level = std::abs( vec[el->dof[k][nv]] ) + 1;
00918 for(int ch=0; ch<2; ch++)
00919 {
00920
00921
00922
00923
00924 vec[el->child[ch]->dof[k][nv]] = -level;
00925 }
00926 }
00927 }
00928
00929
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
00949 for(int ch=0; ch<2; ++ch)
00950 {
00951
00952 vec[el->child[ch]->dof[k][nv]] = val;
00953 }
00954 }
00955 }
00956
00957
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
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
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
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
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
01003
01004
01005
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
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
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
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];
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
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;
01092
01093 dofvecs->coords = getCoordVec<dimworld> ();
01094 coordVec = 0;
01095 }
01096 #endif
01097 }
01098
01099
01100
01101
01102 template <int dim>
01103 static inline void initDofAdmin(MESH *mesh)
01104 {
01105 int edof[dim+1];
01106 int vdof[dim+1];
01107 int fdof[dim+1];
01108 int edgedof[dim+1];
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;
01119
01120 fdof[dim-1] = 1;
01121 edof[dim] = 1;
01122
01123 {
01124
01125
01126
01127
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;
01137 #endif
01138 }
01139
01140
01141
01142
01143
01144 const FE_SPACE * elemSpace = get_fe_space(mesh, "center_dofs", edof, 0);
01145
01146
01147
01148
01149 elNewCheck = get_dof_int_vec("el_new_check",elemSpace);
01150 elNewCheck->refine_interpol = &refineElNewCheck;
01151 elNewCheck->coarse_restrict = 0;
01152
01153
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;
01161
01162
01163
01164 {
01165
01166 const FE_SPACE * fSpace = get_fe_space(mesh, "face_dofs", fdof, 0);
01167
01168
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
01177 const FE_SPACE * eSpace = get_fe_space(mesh, "edge_dofs", edgedof, 0);
01178
01179
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
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
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
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
01249 inline static void storeMacroElements(MESH * mesh)
01250 {
01251
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
01275 inline static void resetMacroElements(MESH * mesh)
01276 {
01277
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
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
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
01339 inline void afterGhosts ( MACRO_EL * mel )
01340 {
01341 if(mel->el->mark < 0)
01342 {
01343 mel->el->mark = 0;
01344 }
01345 }
01346
01347
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
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
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
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
01464
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
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
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
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
01534 inline void setElOwnerNew( MESH * mesh, DOF_INT_VEC * elOwn )
01535 {
01536 elOwner = elOwn;
01537 assert(elOwner != 0);
01538
01539 mesh_traverse(mesh,-1, CALL_EVERY_EL_PREORDER|FILL_NEIGH,setElOwner);
01540 elOwner = 0;
01541 return ;
01542 }
01543
01544
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
01564 inline void restoreElNewCheck( MESH * mesh, DOF_INT_VEC * elNChk )
01565 {
01566 elNewCheck = elNChk;
01567 assert(elNewCheck != 0);
01568
01569
01570 mesh_traverse(mesh,-1,CALL_EVERY_EL_PREORDER|FILL_NEIGH,storeLevelOfElement);
01571 elNewCheck = 0;
01572 return ;
01573 }
01574
01575 }
01576
01577 #ifdef __ALBERTApp__
01578 }
01579 #endif
01580
01581 #endif