00001
00014 #ifndef PARFUM_ITERATORS_H
00015 #define PARFUM_ITERATORS_H
00016
00017 #include <ParFUM.h>
00018 #include <ParFUM_internals.h>
00019
00020 #include "ParFUM_Iterators_Types.h"
00021 #include "ParFUM_Iterators_CUDA.h"
00022
00023
00025 #define ATT_ELEM_ID (FEM_DATA+0)
00026 #define ATT_ELEM_N2E_CONN (FEM_DATA+1)
00027 #define ATT_ELEM_DATA (FEM_DATA+2)
00028
00029 #define ATT_NODE_ID (FEM_DATA+0)
00030 #define ATT_NODE_COORD (FEM_DATA+1)
00031 #define ATT_NODE_DATA (FEM_DATA+2)
00032
00033
00035 class MeshModel{
00036 public:
00037 FEM_Mesh *mesh;
00038 void *mAtt;
00039 AllocTable2d<unsigned char> *ElemData_T;
00040 AllocTable2d<unsigned char> *GhostElemData_T;
00041 AllocTable2d<unsigned char> *NodeData_T;
00042 AllocTable2d<unsigned char> *GhostNodeData_T;
00043 AllocTable2d<int> *ElemConn_T;
00044 AllocTable2d<FP_TYPE_LOW> *coord_T;
00045 AllocTable2d<int> *node_id_T;
00046 AllocTable2d<int> *elem_id_T;
00047 AllocTable2d<int> *n2eConn_T;
00048
00049
00050 CkHashtableT<CkHashtableAdaptorT<int>, int>* nodeIDHash;
00051 CkHashtableT<CkHashtableAdaptorT<int>, int>* elemIDHash;
00052
00053 unsigned node_attr_size;
00054 unsigned elem_attr_size;
00055 unsigned model_attr_size;
00056
00058 unsigned num_local_elem;
00060 unsigned num_local_node;
00062 MeshDevice target_device;
00063
00064 #ifdef CUDA
00065 bool allocatedForCUDADevice;
00066 MeshModelDevice device_model;
00067 #endif
00068 MeshModel(){
00069 nodeIDHash = NULL;
00070 elemIDHash = NULL;
00071 #ifdef CUDA
00072 allocatedForCUDADevice = false;
00073 #endif
00074 }
00075
00076
00077 void print(){
00078 CkPrintf("MeshModel::print() on pe %d\n", CkMyPe());
00079 CkPrintf("mesh=%p\n", mesh);
00080 CkPrintf("mAtt=%p\n", mAtt);
00081 CkPrintf("ElemData_T = %p\n", ElemData_T );
00082 CkPrintf("GhostElemData_T = %p\n", GhostElemData_T);
00083 CkPrintf("NodeData_T = %p\n", NodeData_T);
00084 CkPrintf("GhostNodeData_T = %p\n", GhostNodeData_T);
00085 CkPrintf("ElemConn_T = %p\n", ElemConn_T);
00086 CkPrintf("coord_T = %p\n", coord_T);
00087 CkPrintf("node_id_T = %p\n", node_id_T);
00088 CkPrintf("elem_id_T = %p\n", elem_id_T);
00089 CkPrintf("n2eConn_T = %p\n", n2eConn_T);
00090
00091 CkPrintf("nodeIDHash = %p\n", nodeIDHash);
00092 CkPrintf("elemIDHash = %p\n", elemIDHash);
00093
00094 CkPrintf("node_attr_size = %d\n", node_attr_size);
00095 CkPrintf("elem_attr_size = %d\n", elem_attr_size);
00096 CkPrintf("model_attr_size = %d\n", model_attr_size);
00097 CkPrintf("num_local_elem = %d\n", num_local_elem);
00098 CkPrintf("num_local_node = %d\n", num_local_node);
00099 CkPrintf("target_device = %d\n", target_device);
00100
00101 }
00102
00103 };
00104
00105
00106
00107
00108 #ifdef CUDA
00109 void allocateModelForCUDADevice(MeshModel* model);
00110 void deallocateModelForCUDADevice(MeshModel* model);
00111 #endif
00112
00113
00114
00116 class MeshNodeItr{
00117 public:
00119 int parfum_index;
00121 MeshModel *model;
00122 };
00123
00125 class MeshElemItr{
00126 public:
00127 int parfum_index;
00128 int type;
00129 MeshModel *model;
00130 bool done;
00131 };
00132
00134 class MeshNodeElemItr{
00135 public:
00137 int current_index;
00139 int numAdjElem;
00140
00141 MeshModel *model;
00142
00144 long node;
00145 };
00146
00147
00157 class MeshFacetItr{
00158 public:
00159 MeshModel *model;
00160 MeshElemItr *elemItr;
00161 int whichFacet;
00162 };
00163
00167 int lib_FP_Type_Size();
00168
00169
00170
00174 void mesh_set_device(MeshModel* m, MeshDevice d);
00175
00179 MeshDevice mesh_target_device(MeshModel* m);
00180
00186 MeshModel* meshModel_Create_Init();
00187
00188
00190 void meshModel_Create_Driver(MeshDevice target_device,
00191 int elem_attr_sz, int node_attr_sz, int model_attr_sz, void* mAtt, MeshModel &model);
00192
00194 void meshModel_Destroy(MeshModel* m);
00195
00197 MeshNode meshModel_InsertNode(MeshModel*, float x, float y, float z);
00198 MeshNode meshModel_InsertNode(MeshModel*, double x, double y, double z);
00199
00200 void meshModel_SuggestInitialSize(MeshModel* m, unsigned numNodes, unsigned numElements);
00201
00202
00204 void meshNode_SetId(MeshModel*, MeshNode, EntityID id);
00205
00207 void meshNode_SetAttrib(MeshModel*, MeshNode, void*);
00208
00210 MeshElement meshModel_InsertElem(MeshModel*, MeshElementType, MeshNode*);
00211
00213 void meshElement_SetId(MeshModel*, MeshElement, EntityID id);
00214
00216 int meshElement_GetId (MeshModel* m, MeshElement e);
00217
00219 void meshElement_SetAttrib(MeshModel*, MeshElement, void*);
00220
00222 MeshNode meshModel_GetNodeAtId(MeshModel*,EntityID);
00223
00225 void* meshNode_GetAttrib(MeshModel*, MeshNode);
00226
00228 void* meshElement_GetAttrib(MeshModel*, MeshElement);
00229
00231 MeshNode meshElement_GetNode(MeshModel*,MeshElement,int idx);
00232
00234
00235 #ifdef INLINE_GETELEMATID
00236 inline MeshElement meshModel_GetElemAtId(MeshModel*m,EntityID id)
00237 {
00238 MeshElement e;
00239 e.id = m->elemIDHash->get(id)-1;
00240 e.type = MESH_ELEMENT_TET4;
00241
00242 if (e.id != -1) return e;
00243
00244 AllocTable2d<int>* ghostElem_id_T = &((FEM_DataAttribute*)m->mesh->
00245 elem[MESH_ELEMENT_TET4].getGhost()->lookup(ATT_ELEM_ID,""))->getInt();
00246
00247 if(ghostElem_id_T != NULL) {
00248 for(int i=0; i<ghostElem_id_T->size(); ++i) {
00249 if((*ghostElem_id_T)(i,0)==id){
00250 e.id = FEM_To_ghost_index(i);
00251 e.type = MESH_ELEMENT_TET4;
00252 return e;
00253 }
00254 }
00255 }
00256
00257 e.id = -1;
00258 e.type = MESH_ELEMENT_TET4;
00259
00260 return e;
00261 }
00262
00263 #else
00264 MeshElement meshModel_GetElemAtId(MeshModel*,EntityID);
00265 #endif
00266
00267
00268 int meshNode_GetId(MeshModel* m, MeshNode n);
00269
00270 int meshModel_GetNNodes(MeshModel *model);
00271
00272 int meshElement_GetNNodes(MeshModel* model, MeshElement elem);
00273 bool meshElement_IsCohesive(MeshModel* m, MeshElement e);
00274
00275 void meshNode_GetPosition(MeshModel*model, MeshNode node,float*x,float*y,float*z);
00276 void meshNode_GetPosition(MeshModel*model, MeshNode node,double*x,double*y,double*z);
00277
00278
00279 void mesh_retrieve_elem_data(MeshModel* m);
00280 void mesh_retrieve_node_data(MeshModel* m);
00281 void mesh_put_elem_data(MeshModel* m);
00282 void mesh_put_node_data(MeshModel* m);
00283
00284 void mesh_retrieve_data(MeshModel* m);
00285 void mesh_put_data(MeshModel* m);
00286
00287
00288 int meshFacet_GetNNodes (MeshModel* m, MeshFacet f);
00289 MeshNode meshFacet_GetNode (MeshModel* m, MeshFacet f, int i);
00290 MeshElement meshFacet_GetElem (MeshModel* m, MeshFacet f, int i);
00291
00292 bool meshElement_IsValid(MeshModel* m, MeshElement e);
00293
00294 bool meshVertex_IsBoundary (MeshModel* m, MeshVertex v);
00295
00296 MeshVertex meshNode_GetVertex (MeshModel* m, MeshNode n);
00297
00298 MeshElement meshModel_InsertCohesiveAtFacet (MeshModel* m, int ElemType, MeshFacet f);
00299
00300
00301
00302
00303
00304
00305 bool haveConfigurableCPUGPUMap();
00306 bool isPartitionCPU(int partition);
00307 bool isPartitionGPU(int partition);
00308 int configurableCPUGPUMapNumNodes();
00309
00310
00311
00312 #ifndef INLINE_ITERATORS
00313
00314
00316 MeshNodeItr* meshModel_CreateNodeItr(MeshModel*);
00317
00319 void meshNodeItr_Destroy(MeshNodeItr*);
00320
00322 void meshNodeItr_Begin(MeshNodeItr*);
00323
00325 bool meshNodeItr_IsValid(MeshNodeItr*);
00326
00328 void meshNodeItr_Next(MeshNodeItr*);
00329
00331 MeshNode meshNodeItr_GetCurr(MeshNodeItr*);
00332
00334 int meshModel_GetNElem (MeshModel* m);
00335
00337 MeshElemItr* meshModel_CreateElemItr(MeshModel*);
00338
00340 void meshElemItr_Destroy(MeshElemItr*);
00341
00343 void meshElemItr_Begin(MeshElemItr*);
00344
00346 bool meshElemItr_IsValid(MeshElemItr*);
00347
00349 void meshElemItr_Next(MeshElemItr*);
00350
00352 MeshElement meshElemItr_GetCurr(MeshElemItr*);
00353
00355 void meshModel_TestIterators(MeshModel*m);
00356
00357 MeshNodeElemItr* meshModel_CreateNodeElemItr (MeshModel* m, MeshNode n);
00358 bool meshNodeElemItr_IsValid (MeshNodeElemItr* neitr);
00359 void meshNodeElemItr_Next (MeshNodeElemItr* neitr);
00360 MeshElement meshNodeElemItr_GetCurr (MeshNodeElemItr* neitr);
00361 void meshNodeElemItr_Destroy (MeshNodeElemItr* neitr);
00362
00363 MeshFacetItr* meshModel_CreateFacetItr (MeshModel* m);
00364 void meshFacetItr_Begin(MeshFacetItr* itr);
00365 bool meshFacetItr_IsValid(MeshFacetItr* itr);
00366 void meshFacetItr_Next(MeshFacetItr* itr);
00367 MeshFacet meshFacetItr_GetCurr (MeshFacetItr* itr);
00368 void meshFacetItr_Destroy (MeshFacetItr* itr);
00369
00370 #else
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 inline MeshNodeItr* meshModel_CreateNodeItr(MeshModel* model){
00383 MeshNodeItr *itr = new MeshNodeItr;
00384 itr->model = model;
00385 return itr;
00386 }
00387
00388 inline void meshNodeItr_Destroy(MeshNodeItr* itr){
00389 delete itr;
00390 }
00391
00392 inline void meshNodeItr_Begin(MeshNodeItr* itr){
00393 if(itr->model->mesh->node.ghost != NULL){
00394 itr->parfum_index = FEM_To_ghost_index(itr->model->mesh->node.ghost->size());
00395 }
00396 else{
00397 itr->parfum_index = 0;
00398 }
00399
00400
00401 while((!itr->model->mesh->node.is_valid_any_idx(itr->parfum_index)) &&
00402 (itr->parfum_index < itr->model->mesh->node.size()))
00403 itr->parfum_index++;
00404
00405 if(itr->parfum_index==itr->model->mesh->node.size()){
00406 itr->parfum_index = itr->model->mesh->node.size()+1000;
00407 }
00408
00409 #ifdef ITERATOR_PRINT
00410 CkPrintf("Initializing Node Iterator to %d\n", itr->parfum_index);
00411 #endif
00412 }
00413
00414 inline bool meshNodeItr_IsValid(MeshNodeItr*itr){
00415 return itr->model->mesh->node.is_valid_any_idx(itr->parfum_index);
00416 }
00417
00418 inline void meshNodeItr_Next(MeshNodeItr* itr){
00419 CkAssert(meshNodeItr_IsValid(itr));
00420
00421
00422 itr->parfum_index++;
00423
00424 while((!itr->model->mesh->node.is_valid_any_idx(itr->parfum_index)) &&
00425 (itr->parfum_index < itr->model->mesh->node.size()))
00426 itr->parfum_index++;
00427
00428 if(itr->parfum_index==itr->model->mesh->node.size()){
00429 itr->parfum_index = itr->model->mesh->node.size()+1000;
00430 }
00431
00432 #ifdef ITERATOR_PRINT
00433 CkPrintf("Advancing Node Iterator to %d\n", itr->parfum_index);
00434 #endif
00435 }
00436
00437
00438 inline MeshNode meshNodeItr_GetCurr(MeshNodeItr*itr){
00439 CkAssert(meshNodeItr_IsValid(itr));
00440 return itr->parfum_index;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 inline MeshElemItr* meshModel_CreateElemItr(MeshModel* model){
00452 MeshElemItr *itr = new MeshElemItr;
00453 itr->model = model;
00454 itr->type = MESH_ELEMENT_TET4;
00455 return itr;
00456 }
00457
00458 inline void meshElemItr_Destroy(MeshElemItr* itr){
00459 delete itr;
00460 }
00461
00462 inline void meshElemItr_Begin(MeshElemItr* itr){
00463 itr->done = false;
00464
00465 if(itr->model->mesh->elem[itr->type].ghost != NULL){
00466 itr->parfum_index = FEM_To_ghost_index(itr->model->mesh->elem[itr->type].ghost->size());
00467 }
00468 else{
00469 itr->parfum_index = 0;
00470 }
00471
00472
00473 while((!itr->model->mesh->elem[itr->type].is_valid_any_idx(itr->parfum_index)) &&
00474 (itr->parfum_index < itr->model->mesh->elem[itr->type].size()))
00475 itr->parfum_index++;
00476
00477 if(itr->parfum_index==itr->model->mesh->elem[itr->type].size()){
00478 itr->done = true;
00479 }
00480
00481 #ifdef ITERATOR_PRINT
00482 CkPrintf("Initializing elem[itr->type] Iterator to %d\n", itr->parfum_index);
00483 #endif
00484
00485 }
00486
00487 inline bool meshElemItr_IsValid(MeshElemItr*itr){
00488 return ! itr->done;
00489 }
00490
00491 inline void meshElemItr_Next(MeshElemItr* itr){
00492 CkAssert(meshElemItr_IsValid(itr));
00493
00494
00495 itr->parfum_index++;
00496
00497 while((!itr->model->mesh->elem[MESH_ELEMENT_TET4].is_valid_any_idx(itr->parfum_index)) &&
00498 (itr->parfum_index < itr->model->mesh->elem[MESH_ELEMENT_TET4].size())) {
00499 itr->parfum_index++;
00500 }
00501
00502
00503 if(itr->parfum_index==itr->model->mesh->elem[MESH_ELEMENT_TET4].size()) {
00504 itr->done = true;
00505 }
00506
00507 #ifdef ITERATOR_PRINT
00508 CkPrintf("Advancing Elem Iterator to %d\n", itr->parfum_index);
00509 #endif
00510 }
00511
00512
00513 inline MeshElement meshElemItr_GetCurr(MeshElemItr*itr){
00514 CkAssert(meshElemItr_IsValid(itr));
00515 MeshElement e;
00516 e.id = itr->parfum_index;
00517 e.type = itr->type;
00518 return e;
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 inline MeshNodeElemItr* meshModel_CreateNodeElemItr (MeshModel* model, MeshNode n){
00531 MeshNodeElemItr *itr = new MeshNodeElemItr;
00532
00533 itr->model = model;
00534 itr->node = n;
00535 itr->current_index=0;
00536
00537 if( itr->model->mesh->node.is_valid_any_idx(n) ){
00538 itr->numAdjElem = model->mesh->n2e_getLength(n);
00539 } else {
00540 itr->numAdjElem = -1;
00541 }
00542
00543 return itr;
00544 }
00545
00546
00547 inline bool meshNodeElemItr_IsValid (MeshNodeElemItr* itr){
00548 return (itr->current_index < itr->numAdjElem);
00549 }
00550
00551 inline void meshNodeElemItr_Next (MeshNodeElemItr* itr){
00552 itr->current_index ++;
00553 }
00554
00555
00556 inline MeshElement meshNodeElemItr_GetCurr (MeshNodeElemItr* itr){
00557 CkAssert(meshNodeElemItr_IsValid(itr));
00558 MeshElement e;
00559
00560 ElemID elem = itr->model->mesh->n2e_getElem(itr->node, itr->current_index);
00561 e.id = elem.getSignedId();
00562 e.type = elem.getUnsignedType();
00563 return e;
00564 }
00565
00566
00567 inline void meshNodeElemItr_Destroy (MeshNodeElemItr* itr){
00568 delete itr;
00569 }
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 inline MeshFacetItr* meshModel_CreateFacetItr (MeshModel* m){
00582 MeshFacetItr* itr = new MeshFacetItr();
00583 itr->model = m;
00584 return itr;
00585 }
00586
00587
00589 inline void meshFacetItr_Next(MeshFacetItr* itr){
00590 bool found = false;
00591
00592
00593 while( !found && meshElemItr_IsValid(itr->elemItr) ){
00594
00595 itr->whichFacet++;
00596 if(itr->whichFacet > 3){
00597 meshElemItr_Next(itr->elemItr);
00598 itr->whichFacet=0;
00599 }
00600
00601 if( ! meshElemItr_IsValid(itr->elemItr) ){
00602 break;
00603 }
00604
00605 MeshElement currElem = meshElemItr_GetCurr(itr->elemItr);
00606 ElemID e = itr->model->mesh->e2e_getElem(currElem.id, itr->whichFacet, currElem.type);
00607
00608 if (e < currElem) {
00609 found = true;
00610
00611 }
00612
00613 }
00614
00615 }
00616
00617
00618 inline void meshFacetItr_Begin(MeshFacetItr* itr){
00619 itr->elemItr = meshModel_CreateElemItr(itr->model);
00620 meshElemItr_Begin(itr->elemItr);
00621 itr->whichFacet = 0;
00622
00623
00624
00625
00626
00627 MeshElement currElem = meshElemItr_GetCurr(itr->elemItr);
00628 ElemID e = itr->model->mesh->e2e_getElem(currElem.id, itr->whichFacet, currElem.type);
00629 if (e < currElem) {
00630
00631 } else {
00632 meshFacetItr_Next(itr);
00633 }
00634
00635 }
00636
00637 inline bool meshFacetItr_IsValid(MeshFacetItr* itr){
00638 return meshElemItr_IsValid(itr->elemItr);
00639 }
00640
00641 inline MeshFacet meshFacetItr_GetCurr (MeshFacetItr* itr){
00642 MeshFacet f;
00643
00644 MeshElement el = meshElemItr_GetCurr(itr->elemItr);
00645 f.elem[0] = el;
00646
00647 int p1 = el.id;
00648 int p2 = itr->whichFacet;
00649 int p3 = el.type;
00650
00651 MeshElement e = itr->model->mesh->e2e_getElem(p1,p2, p3);
00652
00653 f.elem[1] = e;
00654
00655
00656
00657
00658 if(itr->whichFacet==0){
00659 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[0];
00660 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[1];
00661 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[3];
00662 }
00663
00664 else if(itr->whichFacet==1){
00665 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[0];
00666 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[2];
00667 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[1];
00668 }
00669
00670 else if(itr->whichFacet==2){
00671 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[1];
00672 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[2];
00673 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[3];
00674 }
00675
00676 else if(itr->whichFacet==3){
00677 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[0];
00678 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[3];
00679 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[2];
00680 }
00681
00682 return f;
00683 }
00684
00685
00686 inline void meshFacetItr_Destroy (MeshFacetItr* itr){
00687 delete itr;
00688 }
00689
00690
00691 #endif
00692
00693
00694
00695
00696 void setTableReferences(MeshModel* model, bool recomputeHash=false);
00697
00698
00699 #endif