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