00001
00014 #ifndef __PARFUM_TOPS___H
00015 #define __PARFUM_TOPS___H
00016
00017 #include <ParFUM.h>
00018 #include <ParFUM_internals.h>
00019
00020 #include "ParFUM_TOPS_Types.h"
00021 #include "ParFUM_TOPS_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 TopModel{
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 TopDevice target_device;
00063
00064 #ifdef CUDA
00065 TopModelDevice device_model;
00066 #endif
00067 TopModel(){
00068 nodeIDHash = NULL;
00069 elemIDHash = NULL;
00070 }
00071 };
00072
00073
00075 class TopNodeItr{
00076 public:
00078 int parfum_index;
00080 TopModel *model;
00081 };
00082
00084 class TopElemItr{
00085 public:
00086 int parfum_index;
00087 int type;
00088 TopModel *model;
00089 bool done;
00090 };
00091
00093 class TopNodeElemItr{
00094 public:
00096 int current_index;
00098 int numAdjElem;
00099
00100 TopModel *model;
00101
00103 long node;
00104 };
00105
00106
00116 class TopFacetItr{
00117 public:
00118 TopModel *model;
00119 TopElemItr *elemItr;
00120 int whichFacet;
00121 };
00122
00127 int tops_lib_FP_Type_Size();
00128
00129
00130
00134 void top_set_device(TopModel* m, TopDevice d);
00135
00139 TopDevice top_target_device(TopModel* m);
00140
00145
00146 TopModel* topModel_Create_Init();
00147
00148
00150 TopModel* topModel_Create_Driver(TopDevice target_device, int elem_attr_sz, int node_attr_sz, int model_attr_sz, void* mAtt);
00151
00153 void topModel_Destroy(TopModel* m);
00154
00156 TopNode topModel_InsertNode(TopModel*, float x, float y, float z);
00157 TopNode topModel_InsertNode(TopModel*, double x, double y, double z);
00158
00159 void topModel_SuggestInitialSize(TopModel* m, unsigned numNodes, unsigned numElements);
00160
00161
00163 void topNode_SetId(TopModel*, TopNode, TopID id);
00164
00166 void topNode_SetAttrib(TopModel*, TopNode, void*);
00167
00169 TopElement topModel_InsertElem(TopModel*, TopElemType, TopNode*);
00170
00172 void topElement_SetId(TopModel*, TopElement, TopID id);
00173
00175 int topElement_GetId (TopModel* m, TopElement e);
00176
00178 void topElement_SetAttrib(TopModel*, TopElement, void*);
00179
00181 TopNode topModel_GetNodeAtId(TopModel*,TopID);
00182
00184 void* topNode_GetAttrib(TopModel*, TopNode);
00185
00187 void* topElement_GetAttrib(TopModel*, TopElement);
00188
00190 TopNode topElement_GetNode(TopModel*,TopElement,int idx);
00191
00193
00194 #ifdef INLINE_GETELEMATID
00195 inline TopElement topModel_GetElemAtId(TopModel*m,TopID id)
00196 {
00197 TopElement e;
00198 e.id = m->elemIDHash->get(id)-1;
00199 e.type = TOP_ELEMENT_TET4;
00200
00201 if (e.id != -1) return e;
00202
00203 AllocTable2d<int>* ghostElem_id_T = &((FEM_DataAttribute*)m->mesh->
00204 elem[TOP_ELEMENT_TET4].getGhost()->lookup(ATT_ELEM_ID,""))->getInt();
00205
00206 if(ghostElem_id_T != NULL) {
00207 for(int i=0; i<ghostElem_id_T->size(); ++i) {
00208 if((*ghostElem_id_T)(i,0)==id){
00209 e.id = FEM_To_ghost_index(i);
00210 e.type = TOP_ELEMENT_TET4;
00211 return e;
00212 }
00213 }
00214 }
00215
00216 e.id = -1;
00217 e.type = TOP_ELEMENT_TET4;
00218
00219 return e;
00220 }
00221
00222 #else
00223 TopElement topModel_GetElemAtId(TopModel*,TopID);
00224 #endif
00225
00226
00227
00228
00229
00230
00231
00232
00233 int topNode_GetId(TopModel* m, TopNode n);
00234
00235 int topModel_GetNNodes(TopModel *model);
00236
00237 int topElement_GetNNodes(TopModel* model, TopElement elem);
00238 bool topElement_IsCohesive(TopModel* m, TopElement e);
00239
00240 void topNode_GetPosition(TopModel*model, TopNode node,float*x,float*y,float*z);
00241 void topNode_GetPosition(TopModel*model, TopNode node,double*x,double*y,double*z);
00242
00243
00244 void top_retrieve_elem_data(TopModel* m);
00245 void top_retrieve_node_data(TopModel* m);
00246 void top_put_elem_data(TopModel* m);
00247 void top_put_node_data(TopModel* m);
00248
00249 void top_retrieve_data(TopModel* m);
00250 void top_put_data(TopModel* m);
00251
00252
00253
00254
00255
00256
00257 int topFacet_GetNNodes (TopModel* m, TopFacet f);
00258 TopNode topFacet_GetNode (TopModel* m, TopFacet f, int i);
00259 TopElement topFacet_GetElem (TopModel* m, TopFacet f, int i);
00260
00261 bool topElement_IsValid(TopModel* m, TopElement e);
00262
00263 bool topVertex_IsBoundary (TopModel* m, TopVertex v);
00264
00265 TopVertex topNode_GetVertex (TopModel* m, TopNode n);
00266
00267 TopElement topModel_InsertCohesiveAtFacet (TopModel* m, int ElemType, TopFacet f);
00268
00269
00270
00271
00272
00273
00274 bool haveConfigurableCPUGPUMap();
00275 bool isPartitionCPU(int partition);
00276 bool isPartitionGPU(int partition);
00277 int configurableCPUGPUMapNumNodes();
00278
00279
00280
00281 #ifndef INLINE_ITERATORS
00282
00283
00285 TopNodeItr* topModel_CreateNodeItr(TopModel*);
00286
00288 void topNodeItr_Destroy(TopNodeItr*);
00289
00291 void topNodeItr_Begin(TopNodeItr*);
00292
00294 bool topNodeItr_IsValid(TopNodeItr*);
00295
00297 void topNodeItr_Next(TopNodeItr*);
00298
00300 TopNode topNodeItr_GetCurr(TopNodeItr*);
00301
00303 int topModel_GetNElem (TopModel* m);
00304
00306 TopElemItr* topModel_CreateElemItr(TopModel*);
00307
00309 void topElemItr_Destroy(TopElemItr*);
00310
00312 void topElemItr_Begin(TopElemItr*);
00313
00315 bool topElemItr_IsValid(TopElemItr*);
00316
00318 void topElemItr_Next(TopElemItr*);
00319
00321 TopElement topElemItr_GetCurr(TopElemItr*);
00322
00324 void topModel_TestIterators(TopModel*m);
00325
00326 TopNodeElemItr* topModel_CreateNodeElemItr (TopModel* m, TopNode n);
00327 bool topNodeElemItr_IsValid (TopNodeElemItr* neitr);
00328 void topNodeElemItr_Next (TopNodeElemItr* neitr);
00329 TopElement topNodeElemItr_GetCurr (TopNodeElemItr* neitr);
00330 void topNodeElemItr_Destroy (TopNodeElemItr* neitr);
00331
00332 TopFacetItr* topModel_CreateFacetItr (TopModel* m);
00333 void topFacetItr_Begin(TopFacetItr* itr);
00334 bool topFacetItr_IsValid(TopFacetItr* itr);
00335 void topFacetItr_Next(TopFacetItr* itr);
00336 TopFacet topFacetItr_GetCurr (TopFacetItr* itr);
00337 void topFacetItr_Destroy (TopFacetItr* itr);
00338
00339 #else
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 inline TopNodeItr* topModel_CreateNodeItr(TopModel* model){
00353 TopNodeItr *itr = new TopNodeItr;
00354 itr->model = model;
00355 return itr;
00356 }
00357
00358 inline void topNodeItr_Destroy(TopNodeItr* itr){
00359 delete itr;
00360 }
00361
00362 inline void topNodeItr_Begin(TopNodeItr* itr){
00363 if(itr->model->mesh->node.ghost != NULL){
00364 itr->parfum_index = FEM_To_ghost_index(itr->model->mesh->node.ghost->size());
00365 }
00366 else{
00367 itr->parfum_index = 0;
00368 }
00369
00370
00371 while((!itr->model->mesh->node.is_valid_any_idx(itr->parfum_index)) &&
00372 (itr->parfum_index < itr->model->mesh->node.size()))
00373 itr->parfum_index++;
00374
00375 if(itr->parfum_index==itr->model->mesh->node.size()){
00376 itr->parfum_index = itr->model->mesh->node.size()+1000;
00377 }
00378
00379 #ifdef PTOPS_ITERATOR_PRINT
00380 CkPrintf("Initializing Node Iterator to %d\n", itr->parfum_index);
00381 #endif
00382 }
00383
00384 inline bool topNodeItr_IsValid(TopNodeItr*itr){
00385 return itr->model->mesh->node.is_valid_any_idx(itr->parfum_index);
00386 }
00387
00388 inline void topNodeItr_Next(TopNodeItr* itr){
00389 CkAssert(topNodeItr_IsValid(itr));
00390
00391
00392 itr->parfum_index++;
00393
00394 while((!itr->model->mesh->node.is_valid_any_idx(itr->parfum_index)) &&
00395 (itr->parfum_index < itr->model->mesh->node.size()))
00396 itr->parfum_index++;
00397
00398 if(itr->parfum_index==itr->model->mesh->node.size()){
00399 itr->parfum_index = itr->model->mesh->node.size()+1000;
00400 }
00401
00402 #ifdef PTOPS_ITERATOR_PRINT
00403 CkPrintf("Advancing Node Iterator to %d\n", itr->parfum_index);
00404 #endif
00405 }
00406
00407
00408 inline TopNode topNodeItr_GetCurr(TopNodeItr*itr){
00409 CkAssert(topNodeItr_IsValid(itr));
00410 return itr->parfum_index;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 inline TopElemItr* topModel_CreateElemItr(TopModel* model){
00422 TopElemItr *itr = new TopElemItr;
00423 itr->model = model;
00424 itr->type = TOP_ELEMENT_TET4;
00425 return itr;
00426 }
00427
00428 inline void topElemItr_Destroy(TopElemItr* itr){
00429 delete itr;
00430 }
00431
00432 inline void topElemItr_Begin(TopElemItr* itr){
00433 itr->done = false;
00434
00435 if(itr->model->mesh->elem[itr->type].ghost != NULL){
00436 itr->parfum_index = FEM_To_ghost_index(itr->model->mesh->elem[itr->type].ghost->size());
00437 }
00438 else{
00439 itr->parfum_index = 0;
00440 }
00441
00442
00443 while((!itr->model->mesh->elem[itr->type].is_valid_any_idx(itr->parfum_index)) &&
00444 (itr->parfum_index < itr->model->mesh->elem[itr->type].size()))
00445 itr->parfum_index++;
00446
00447 if(itr->parfum_index==itr->model->mesh->elem[itr->type].size()){
00448 itr->done = true;
00449 }
00450
00451 #ifdef PTOPS_ITERATOR_PRINT
00452 CkPrintf("Initializing elem[itr->type] Iterator to %d\n", itr->parfum_index);
00453 #endif
00454
00455 }
00456
00457 inline bool topElemItr_IsValid(TopElemItr*itr){
00458 return ! itr->done;
00459 }
00460
00461 inline void topElemItr_Next(TopElemItr* itr){
00462 CkAssert(topElemItr_IsValid(itr));
00463
00464
00465 itr->parfum_index++;
00466
00467 while((!itr->model->mesh->elem[TOP_ELEMENT_TET4].is_valid_any_idx(itr->parfum_index)) &&
00468 (itr->parfum_index < itr->model->mesh->elem[TOP_ELEMENT_TET4].size()))
00469 itr->parfum_index++;
00470
00471
00472 if(itr->parfum_index==itr->model->mesh->elem[TOP_ELEMENT_TET4].size()){
00473 itr->done = true;
00474 }
00475
00476 #ifdef PTOPS_ITERATOR_PRINT
00477 CkPrintf("Advancing Elem Iterator to %d\n", itr->parfum_index);
00478 #endif
00479 }
00480
00481
00482 inline TopElement topElemItr_GetCurr(TopElemItr*itr){
00483 CkAssert(topElemItr_IsValid(itr));
00484 TopElement e;
00485 e.id = itr->parfum_index;
00486 e.type = itr->type;
00487 return e;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 inline TopNodeElemItr* topModel_CreateNodeElemItr (TopModel* model, TopNode n){
00500 TopNodeElemItr *itr = new TopNodeElemItr;
00501
00502 itr->model = model;
00503 itr->node = n;
00504 itr->current_index=0;
00505
00506 if( itr->model->mesh->node.is_valid_any_idx(n) ){
00507 itr->numAdjElem = model->mesh->n2e_getLength(n);
00508 } else {
00509 itr->numAdjElem = -1;
00510 }
00511
00512 return itr;
00513 }
00514
00515
00516 inline bool topNodeElemItr_IsValid (TopNodeElemItr* itr){
00517 return (itr->current_index < itr->numAdjElem);
00518 }
00519
00520 inline void topNodeElemItr_Next (TopNodeElemItr* itr){
00521 itr->current_index ++;
00522 }
00523
00524
00525 inline TopElement topNodeElemItr_GetCurr (TopNodeElemItr* itr){
00526 CkAssert(topNodeElemItr_IsValid(itr));
00527 TopElement e;
00528
00529 ElemID elem = itr->model->mesh->n2e_getElem(itr->node, itr->current_index);
00530 e.id = elem.getSignedId();
00531 e.type = elem.getUnsignedType();
00532 return e;
00533 }
00534
00535
00536 inline void topNodeElemItr_Destroy (TopNodeElemItr* itr){
00537 delete itr;
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 inline TopFacetItr* topModel_CreateFacetItr (TopModel* m){
00551 TopFacetItr* itr = new TopFacetItr();
00552 itr->model = m;
00553 return itr;
00554 }
00555
00556
00558 inline void topFacetItr_Next(TopFacetItr* itr){
00559 bool found = false;
00560
00561
00562 while( !found && topElemItr_IsValid(itr->elemItr) ){
00563
00564 itr->whichFacet++;
00565 if(itr->whichFacet > 3){
00566 topElemItr_Next(itr->elemItr);
00567 itr->whichFacet=0;
00568 }
00569
00570 if( ! topElemItr_IsValid(itr->elemItr) ){
00571 break;
00572 }
00573
00574 TopElement currElem = topElemItr_GetCurr(itr->elemItr);
00575 ElemID e = itr->model->mesh->e2e_getElem(currElem.id, itr->whichFacet, currElem.type);
00576
00577 if (e < currElem) {
00578 found = true;
00579
00580 }
00581
00582 }
00583
00584 }
00585
00586
00587 inline void topFacetItr_Begin(TopFacetItr* itr){
00588 itr->elemItr = topModel_CreateElemItr(itr->model);
00589 topElemItr_Begin(itr->elemItr);
00590 itr->whichFacet = 0;
00591
00592
00593
00594
00595
00596 TopElement currElem = topElemItr_GetCurr(itr->elemItr);
00597 ElemID e = itr->model->mesh->e2e_getElem(currElem.id, itr->whichFacet, currElem.type);
00598 if (e < currElem) {
00599
00600 } else {
00601 topFacetItr_Next(itr);
00602 }
00603
00604 }
00605
00606 inline bool topFacetItr_IsValid(TopFacetItr* itr){
00607 return topElemItr_IsValid(itr->elemItr);
00608 }
00609
00610
00611
00612
00613
00614 inline TopFacet topFacetItr_GetCurr (TopFacetItr* itr){
00615 TopFacet f;
00616
00617 TopElement el = topElemItr_GetCurr(itr->elemItr);
00618 f.elem[0] = el;
00619
00620 int p1 = el.id;
00621 int p2 = itr->whichFacet;
00622 int p3 = el.type;
00623
00624 TopElement e = itr->model->mesh->e2e_getElem(p1,p2, p3);
00625
00626 f.elem[1] = e;
00627
00628
00629
00630
00631 if(itr->whichFacet==0){
00632 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[0];
00633 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[1];
00634 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[3];
00635 }
00636
00637 else if(itr->whichFacet==1){
00638 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[0];
00639 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[2];
00640 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[1];
00641 }
00642
00643 else if(itr->whichFacet==2){
00644 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[1];
00645 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[2];
00646 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[3];
00647 }
00648
00649 else if(itr->whichFacet==3){
00650 f.node[0] = f.node[3] = itr->model->mesh->elem[el.type].connFor(el.id)[0];
00651 f.node[1] = f.node[4] = itr->model->mesh->elem[el.type].connFor(el.id)[3];
00652 f.node[2] = f.node[5] = itr->model->mesh->elem[el.type].connFor(el.id)[2];
00653 }
00654
00655 return f;
00656 }
00657
00658
00659 inline void topFacetItr_Destroy (TopFacetItr* itr){
00660 delete itr;
00661 }
00662
00663
00664 #endif
00665
00666
00667 #endif