00001
00002
00003
00004
00005
00006
00007 #include "ParFUM.h"
00008 #include "ParFUM_internals.h"
00009 using namespace std;
00010
00011 const int faceMap2d_tri[3][2] = {{0,1},{1,2},{2,0}};
00012 const int faceMap2d_quad[4][2] = {{0,1},{1,2},{2,3},{3,0}};
00013 const int faceMap3d_tet[4][3] = {{0,1,2},{0,3,1},{0,2,3},{1,3,2}};
00014 const int faceMap3d_hex[6][4] = {{0,1,2,3},{1,5,6,2},{2,6,7,3},{3,7,4,0},{0,4,5,1},{5,4,6,7}};
00015
00016 const int edgeMap3d_tet[6][2] = {{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
00017 const int edgeMap3d_hex[12][2] = {{0,1},{0,3},{0,4},{1,2},{1,5},{2,3},{2,6},{3,7},{4,5},{4,7},{5,6},{6,7}};
00018
00019 const int faceMap2d_cohquad[2][2] = {{0,1},{2,3}};
00020 const int faceMap3d_cohprism[2][3] = {{0,1,2},{3,4,5}};
00021
00022
00023 inline void addSharedNodeData(int node, const IDXL_Rec *sharedChunkList,
00024 adjNode *adaptAdjTable)
00025 {
00026 adaptAdjTable[node].numSharedPartitions = sharedChunkList->getShared();
00027 adaptAdjTable[node].sharedWithPartition =
00028 new int [sharedChunkList->getShared()];
00029 adaptAdjTable[node].sharedWithLocalIdx =
00030 new int [sharedChunkList->getShared()];
00031 for(int j=0; j<sharedChunkList->getShared(); j++){
00032 int sharedChunk = sharedChunkList->getChk(j);
00033 int sharedIdx = sharedChunkList->getIdx(j);
00034 adaptAdjTable[node].sharedWithPartition[j] = sharedChunk;
00035 adaptAdjTable[node].sharedWithLocalIdx[j] = sharedIdx;
00036 }
00037 }
00038
00039
00040 inline void addElementNodeSetData(
00041 const int elem,
00042 const int *conn,
00043 const int nodesPerElem,
00044 const int numFaces,
00045 const int numEdges,
00046 const int faceSize,
00047 const int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE],
00048 const int edgeMap[MAX_EDGES][2],
00049 adjNode *faceTable,
00050 adjNode* edgeTable)
00051 {
00052
00053 for (int j=0; j<numFaces; j++) {
00054 adjElem *e = new adjElem(faceSize);
00055 e->nodeSetID = j;
00056 for (int k=0; k<faceSize; k++) {
00057 e->nodeSet[k] = conn[elem * nodesPerElem + faceMap[j][k]];
00058 }
00059
00060 e->nodeSet.quickSort();
00061 int minNode = e->nodeSet[0];
00062 e->elemID = elem;
00063 e->next = faceTable[minNode].adjElemList->next;
00064 faceTable[minNode].adjElemList->next = e;
00065 faceTable[minNode].adjElemCount++;
00066
00067
00068
00069
00070 }
00071
00072
00073 if (edgeTable) {
00074 for (int j=0; j<numEdges; j++) {
00075 adjElem *e = new adjElem(2);
00076 e->nodeSetID = j;
00077 for (int k=0; k<2; k++) {
00078 e->nodeSet[k] = conn[elem * nodesPerElem + edgeMap[j][k]];
00079 }
00080
00081
00082 e->nodeSet.quickSort();
00083 int minNode = e->nodeSet[0];
00084 e->elemID = elem;
00085 e->next = edgeTable[minNode].adjElemList->next;
00086 edgeTable[minNode].adjElemList->next = e;
00087 edgeTable[minNode].adjElemCount++;
00088
00089
00090
00091
00092
00093 }
00094 }
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104 inline adjElem *searchAdjElemInList(adjElem *adjStart, int *searchForNodeSet,
00105 int nodeSetSize, int searchForElemID, int *found)
00106 {
00107 adjElem *rover = adjStart;
00108 *found = 0;
00109
00110 while (rover->next != NULL) {
00111 if (rover->next->elemID != searchForElemID) {
00112
00113 *found = 1;
00114
00115
00116 if (nodeSetSize != rover->next->nodeSet.size()) {
00117 *found = 0;
00118
00119 continue;
00120 }
00121 for (int j=0; j<nodeSetSize; j++) {
00122 if (rover->next->nodeSet[j] != searchForNodeSet[j]) {
00123
00124 *found = 0;
00125 break;
00126 }
00127 }
00128 }
00129 if (*found) {
00130
00131
00132
00133
00134 break;
00135 } else {
00136 rover = rover->next;
00137 }
00138 }
00139 return rover;
00140 }
00141
00142
00144 void CreateAdaptAdjacencies(int meshid, int elemType)
00145 {
00146
00147 int myRank,numChunks;
00148 int faceSize;
00149 int faceMapSize;
00150 int edgeMapSize;
00151
00152 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
00153 MPI_Comm_size(MPI_COMM_WORLD,&numChunks);
00154 FEM_Mesh* mesh = FEM_chunk::get("CreateAdaptAdjacencies")->lookup(
00155 meshid,"CreateAdaptAdjacencies");
00156 FEM_Elem* elem = (FEM_Elem *)mesh->lookup(
00157 FEM_ELEM+elemType,"CreateAdaptAdjacencies");
00158 FEM_Node* node = (FEM_Node *)mesh->lookup(
00159 FEM_NODE,"CreateAdaptAdjacencies");
00160
00161 const int numElems = elem->size();
00162 const int numNodes = node->size();
00163 const int nodesPerElem = (elem->getConn()).width();
00164 CkAssert(node->getCoord() != NULL);
00165 const int dim = (node->getCoord())->getWidth();
00166 CkAssert(dim == 2|| dim == 3);
00167
00168
00169
00170
00171
00172
00173
00174 int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE];
00175 int edgeMap[MAX_EDGES][2];
00176
00177 guessElementShape(dim, nodesPerElem,
00178 &faceSize, &faceMapSize, &edgeMapSize,
00179 faceMap, edgeMap);
00180 CkAssert(faceMapSize <= MAX_ADJELEMS);
00181 CkAssert(edgeMapSize <= MAX_EDGES);
00182 CkAssert(faceSize <= MAX_FACE_SIZE);
00183
00184
00185 FEM_DataAttribute* adaptAdjAttr = (FEM_DataAttribute*) elem->lookup(
00186 FEM_ADAPT_FACE_ADJ, "CreateAdaptAdjacencies");
00187 adaptAdjAttr->setWidth(faceMapSize*sizeof(adaptAdj));
00188 adaptAdj* adaptFaceAdjacencies =
00189 reinterpret_cast<adaptAdj*>((adaptAdjAttr->getChar()).getData());
00190
00191 FEM_DataAttribute* adaptAdjEdgeAttr = (FEM_DataAttribute*) elem->lookup(
00192 FEM_ADAPT_EDGE_ADJ, "CreateAdaptAdjacencies");
00193 adaptAdjEdgeAttr->setWidth(edgeMapSize*sizeof(CkVec<adaptAdj>*));
00194 CkVec<adaptAdj>** adaptEdgeAdjacencies = edgeMapSize == 0 ?
00195 NULL :
00196 reinterpret_cast<CkVec<adaptAdj>**>(
00197 (adaptAdjEdgeAttr->getChar()).getData());
00198
00199
00200 for (int i=0; i<numElems; i++) {
00201 for (int j=0; j<faceMapSize; ++j) {
00202 adaptFaceAdjacencies[i*faceMapSize + j].partID = -1;
00203 adaptFaceAdjacencies[i*faceMapSize + j].localID = -1;
00204 }
00205 if (adaptEdgeAdjacencies) {
00206 for (int j=0; j<edgeMapSize; ++j) {
00207 adaptEdgeAdjacencies[i*edgeMapSize + j] = new CkVec<adaptAdj>;
00208 assert(adaptEdgeAdjacencies[i*edgeMapSize + j] != NULL);
00209 }
00210 }
00211 }
00212
00213
00214
00215
00216
00217 adjNode *faceTable;
00218 adjNode *edgeTable;
00219 faceTable = new adjNode[numNodes];
00220 edgeTable = adaptEdgeAdjacencies ? new adjNode[numNodes] : NULL;
00221
00222
00223 for (int i=0; i<numNodes; i++) {
00224 if (node->is_valid(i)) {
00225 const IDXL_Rec *sharedChunkList = node->shared.getRec(i);
00226 if (sharedChunkList != NULL) {
00227 addSharedNodeData(i, sharedChunkList, faceTable);
00228 if (edgeTable)
00229 addSharedNodeData(i, sharedChunkList, edgeTable);
00230 } else {
00231 faceTable[i].sharedWithPartition = NULL;
00232 faceTable[i].sharedWithLocalIdx= NULL;
00233 if (edgeTable) {
00234 edgeTable[i].sharedWithPartition = NULL;
00235 edgeTable[i].sharedWithLocalIdx= NULL;
00236 }
00237 }
00238 } else {
00239 faceTable[i].sharedWithPartition = NULL;
00240 faceTable[i].sharedWithLocalIdx= NULL;
00241 if (edgeTable) {
00242 edgeTable[i].sharedWithPartition = NULL;
00243 edgeTable[i].sharedWithLocalIdx= NULL;
00244 }
00245 }
00246 }
00247
00248
00249 const int *conn = (elem->getConn()).getData();
00250 for (int i=0; i<numElems; i++) {
00251 if(elem->is_valid(i)){
00252 addElementNodeSetData(i, conn, nodesPerElem, faceMapSize,
00253 edgeMapSize, faceSize, faceMap, edgeMap, faceTable,
00254 edgeTable);
00255 }
00256 }
00257
00258 fillLocalAdaptAdjacencies(
00259 numNodes,
00260 node,
00261 faceTable,
00262 edgeTable,
00263 faceMapSize,
00264 edgeMapSize,
00265 adaptFaceAdjacencies,
00266 adaptEdgeAdjacencies,
00267 myRank,
00268 elemType);
00269
00270
00271
00272
00273
00274 MPI_Barrier(MPI_COMM_WORLD);
00275 MSA1DREQLIST *requestTable;
00276 if (myRank == 0) {
00277 requestTable = new MSA1DREQLIST(numChunks,numChunks);
00278 } else {
00279 requestTable = new MSA1DREQLIST;
00280 }
00281 MPI_Bcast_pup(*requestTable,0,MPI_COMM_WORLD);
00282 requestTable->enroll(numChunks);
00283 MSA1DREQLIST::Accum requestTableAcc = requestTable->getInitialAccum();
00284
00285 makeAdjacencyRequests(
00286 numNodes,
00287 node,
00288 faceTable,
00289 requestTableAcc,
00290 faceSize,
00291 myRank,
00292 elemType);
00293
00294 MSA1DREQLIST::Read reqTableRead = requestTableAcc.syncToRead();
00295
00296
00297 MSA1DREPLYLIST *replyTable;
00298 if (myRank == 0) {
00299 replyTable = new MSA1DREPLYLIST(numChunks,numChunks);
00300 } else {
00301 replyTable = new MSA1DREPLYLIST;
00302 }
00303 MPI_Bcast_pup(*replyTable,0,MPI_COMM_WORLD);
00304 replyTable->enroll(numChunks);
00305 MSA1DREPLYLIST::Accum replyAcc = replyTable->getInitialAccum();
00306
00307 replyAdjacencyRequests(
00308 reqTableRead.get(myRank).vec,
00309 replyAcc,
00310 node,
00311 faceTable,
00312 adaptFaceAdjacencies,
00313 adaptEdgeAdjacencies,
00314 faceSize,
00315 faceMapSize,
00316 myRank,
00317 elemType,
00318 false);
00319
00320 reqTableRead.syncDone();
00321 replyAcc.syncDone();
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 delete requestTable;
00339 delete replyTable;
00340
00341 if (adaptEdgeAdjacencies != NULL) {
00342 MSA1DREQLIST *edgeRequestTable;
00343 MSA1DREPLYLIST *edgeReplyTable;
00344
00345
00346 if (myRank == 0) {
00347 edgeRequestTable = new MSA1DREQLIST(numChunks,numChunks);
00348 } else {
00349 edgeRequestTable = new MSA1DREQLIST;
00350 }
00351 MPI_Bcast_pup(*edgeRequestTable,0,MPI_COMM_WORLD);
00352 edgeRequestTable->enroll(numChunks);
00353 MSA1DREQLIST::Accum edgeRequestTableAcc = requestTable->getInitialAccum();
00354
00355 makeAdjacencyRequests(
00356 numNodes,
00357 node,
00358 edgeTable,
00359 edgeRequestTableAcc,
00360 2,
00361 myRank,
00362 elemType);
00363
00364 MSA1DREQLIST::Read edgeReqRead = edgeRequestTableAcc.syncToRead();
00365
00366
00367 if (myRank == 0) {
00368 edgeReplyTable = new MSA1DREPLYLIST(numChunks,numChunks);
00369 } else {
00370 edgeReplyTable = new MSA1DREPLYLIST;
00371 }
00372 MPI_Bcast_pup(*edgeReplyTable,0,MPI_COMM_WORLD);
00373 edgeReplyTable->enroll(numChunks);
00374 MSA1DREPLYLIST::Accum edgeReplyAcc = edgeReplyTable->getInitialAccum();
00375
00376 replyAdjacencyRequests(
00377 edgeReqRead.get(myRank).vec,
00378 edgeReplyAcc,
00379 node,
00380 edgeTable,
00381 adaptFaceAdjacencies,
00382 adaptEdgeAdjacencies,
00383 2,
00384 edgeMapSize,
00385 myRank,
00386 elemType,
00387 true);
00388
00389 edgeReqRead.syncDone();
00390 edgeReplyAcc.syncDone();
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 delete edgeRequestTable;
00410 delete edgeReplyTable;
00411 }
00412
00413 for (int i=0; i<numNodes; ++i) {
00414 delete[] faceTable[i].sharedWithPartition;
00415 delete[] faceTable[i].sharedWithLocalIdx;
00416 adjElem* e = faceTable[i].adjElemList->next;
00417 adjElem* dummy;
00418 while (e != NULL) {
00419 dummy = e;
00420 e = e->next;
00421 delete dummy;
00422 }
00423
00424 if (edgeTable) {
00425 delete[] edgeTable[i].sharedWithPartition;
00426 delete[] edgeTable[i].sharedWithLocalIdx;
00427 e = edgeTable[i].adjElemList->next;
00428 while (e != NULL) {
00429 dummy = e;
00430 e = e->next;
00431 delete dummy;
00432 }
00433 }
00434 }
00435 delete[] faceTable;
00436 delete[] edgeTable;
00437
00438 }
00439
00440
00441 void fillLocalAdaptAdjacencies(
00442 const int numNodes,
00443 FEM_Node* node,
00444 adjNode* faceTable,
00445 adjNode* edgeTable,
00446 const int faceMapSize,
00447 const int edgeMapSize,
00448 adaptAdj* adaptFaceAdjacencies,
00449 CkVec<adaptAdj>** adaptEdgeAdjacencies,
00450 const int myRank,
00451 const int elemType)
00452 {
00453
00454 adjNode* adaptAdjTable = faceTable;
00455 for (int i=0; i<numNodes; i++) {
00456 if (!adaptAdjTable)
00457 break;
00458
00459
00460
00461 if (node->is_valid(i) && adaptAdjTable[i].adjElemList != NULL) {
00462
00463 adjElem *preTarget = adaptAdjTable[i].adjElemList;
00464 adjElem *target = adaptAdjTable[i].adjElemList->next;
00465 while (target != NULL) {
00466 int found = 0;
00467
00468
00469
00470
00471
00472
00473 adjElem *rover = searchAdjElemInList(preTarget,
00474 target->nodeSet.getVec(), target->nodeSet.size(),
00475 target->elemID, &found);
00476
00477 if (found) {
00478
00479
00480
00481
00482
00483
00484 adaptFaceAdjacencies[faceMapSize*target->elemID +
00485 target->nodeSetID] = adaptAdj(myRank, rover->next->elemID,
00486 elemType);
00487 adaptFaceAdjacencies[
00488 faceMapSize*rover->next->elemID +
00489 rover->next->nodeSetID] = adaptAdj(myRank, target->elemID,
00490 elemType);
00491
00492
00493 adjElem *tmp = rover->next;
00494 rover->next = rover->next->next;
00495 delete tmp;
00496 tmp = target;
00497 preTarget->next = target->next;
00498 target = target->next;
00499 delete tmp;
00500 } else {
00501
00502
00503
00504
00505
00506 preTarget = target;
00507 target = target->next;
00508 }
00509 }
00510 }
00511 }
00512
00513
00514 adaptAdjTable = edgeTable;
00515 for (int i=0; i<numNodes; i++) {
00516 if (!adaptAdjTable)
00517 break;
00518
00519
00520
00521 if (node->is_valid(i) && adaptAdjTable[i].adjElemList != NULL) {
00522 adjElem *preTarget = adaptAdjTable[i].adjElemList;
00523 adjElem *target = adaptAdjTable[i].adjElemList->next;
00524
00525
00526
00527
00528
00529
00530
00531 preTarget = adaptAdjTable[i].adjElemList;
00532 target = preTarget->next;
00533 while (target != NULL) {
00534
00535
00536
00537
00538 int found = 0;
00539
00540
00541
00542
00543
00544
00545 adjElem
00546 *rover =
00547 searchAdjElemInList(preTarget, target->nodeSet.getVec(), target->nodeSet.size(), target->elemID, &found);
00548
00549 while (found) {
00550
00551
00552
00553
00554
00555
00556
00557
00558 adaptEdgeAdjacencies[edgeMapSize*target->elemID +
00559 target->nodeSetID]->push_back(adaptAdj(myRank, rover->next->elemID, elemType));
00560
00561
00562
00563
00564
00565 rover
00566 = searchAdjElemInList(rover->next, target->nodeSet.getVec(), target->nodeSet.size(), target->elemID, &found);
00567 }
00568 target = target->next;
00569 }
00570 }
00571 }
00572 }
00573
00574
00575 void makeAdjacencyRequests(
00576 const int numNodes,
00577 FEM_Node *node,
00578 adjNode *adaptAdjTable,
00579 MSA1DREQLIST::Accum &requestTable,
00580 const int nodeSetSize,
00581 const int myRank,
00582 const int elemType)
00583 {
00584 for (int i=0; i<numNodes; i++) {
00585
00586 if(node->is_valid(i)){
00587 if (adaptAdjTable[i].adjElemList->next!=NULL) {
00588 adjElem *adjStart = adaptAdjTable[i].adjElemList->next;
00589 while (adjStart !=NULL) {
00590
00591 std::set<int> commonSharedChunks;
00592 for (int j=0; j<nodeSetSize; j++) {
00593
00594
00595
00596 int sharedNode = adjStart->nodeSet[j];
00597 adjNode *sharedNodeAdj = &adaptAdjTable[sharedNode];
00598 std::set<int> sharedChunks(
00599 sharedNodeAdj->sharedWithPartition,
00600 sharedNodeAdj->sharedWithPartition +
00601 sharedNodeAdj->numSharedPartitions);
00602 if(j == 0){
00603 commonSharedChunks = sharedChunks;
00604 }else{
00605 std::set<int> tmpIntersect;
00606 set_intersection(
00607 commonSharedChunks.begin(),
00608 commonSharedChunks.end(),
00609 sharedChunks.begin(),
00610 sharedChunks.end(),
00611 inserter(
00612 tmpIntersect,
00613 tmpIntersect.begin()));
00614 commonSharedChunks = tmpIntersect;
00615 }
00616 }
00617
00618
00619
00620 int numCommonSharedChunks = commonSharedChunks.size();
00621 if(numCommonSharedChunks > 0){
00622
00623
00624 adjRequest *adjRequestList =
00625 new adjRequest[numCommonSharedChunks];
00626
00627
00628
00629
00630
00631
00632
00633
00634 for(int j=0;j<nodeSetSize;j++){
00635 int sharedNode = adjStart->nodeSet[j];
00636 const IDXL_Rec *recSharedNode =
00637 node->shared.getRec(sharedNode);
00638 int countChunk=0;
00639 for(std::set<int>::iterator chunkIterator =
00640 commonSharedChunks.begin();
00641 chunkIterator != commonSharedChunks.end();
00642 chunkIterator++){
00643 int chunk = *chunkIterator;
00644 if(j == 0){
00645
00646
00647 adjRequestList[countChunk] =
00648 adjRequest(adjStart->elemID,
00649 myRank,
00650 adjStart->nodeSetID,
00651 elemType);
00652 }
00653
00654
00655
00656
00657 int sharedNodeIdx=-1;
00658 for(int k=0;k<recSharedNode->getShared();k++){
00659 if(recSharedNode->getChk(k) == chunk){
00660
00661 sharedNodeIdx =
00662 recSharedNode->getIdx(k);
00663 break;
00664 }
00665 }
00666 CkAssert(sharedNodeIdx != -1);
00667
00668
00669
00670 adjRequestList[countChunk].
00671 translatedNodeSet[j] = sharedNodeIdx;
00672 countChunk++;
00673 }
00674 }
00675
00676
00677
00678
00679
00680 int countChunk=0;
00681 for(std::set<int>::iterator chunkIterator =
00682 commonSharedChunks.begin();
00683 chunkIterator != commonSharedChunks.end();
00684 chunkIterator++){
00685 int chunk = *chunkIterator;
00686 #if 0
00687 printf("[%d] Sending to chunk %d request (%d,%d,%d,%d) \n",
00688 myRank, chunk,
00689 adjRequestList[countChunk].elemID,
00690 adjRequestList[countChunk].chunkID,
00691 adjRequestList[countChunk].elemType,
00692 adjRequestList[countChunk].nodeSetID);
00693 #endif
00694 requestTable(chunk) += adjRequestList[countChunk];
00695 countChunk++;
00696 }
00697 delete [] adjRequestList;
00698 }
00699 adjStart = adjStart->next;
00700 }
00701 }
00702 }
00703 }
00704 }
00705
00706
00707 void replyAdjacencyRequests(
00708 CkVec<adjRequest> *receivedRequestVec,
00709 MSA1DREPLYLIST::Accum &replyTable,
00710 FEM_Node* node,
00711 adjNode* adaptAdjTable,
00712 adaptAdj* adaptFaceAdjacencies,
00713 CkVec<adaptAdj>** adaptEdgeAdjacencies,
00714 const int nodeSetSize,
00715 const int numAdjElems,
00716 const int myRank,
00717 const int elemType,
00718 bool isEdgeRequest)
00719 {
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 for (int i=0;i<receivedRequestVec->length();i++) {
00732 adjRequest &receivedRequest = (*receivedRequestVec)[i];
00733 const IDXL_List &sharedNodeList =
00734 node->shared.getList(receivedRequest.chunkID);
00735 CkVec<int> sharedNodes(nodeSetSize);
00736
00737 for (int j=0;j<nodeSetSize;j++) {
00738 int sharedNode = sharedNodeList[
00739 receivedRequest.translatedNodeSet[j]];
00740 sharedNodes[j] = sharedNode;
00741 }
00742 sharedNodes.quickSort();
00743
00744
00745 adjNode *minNode = &adaptAdjTable[sharedNodes[0]];
00746 int found=0;
00747
00748 adjElem *rover = searchAdjElemInList(
00749 minNode->adjElemList,
00750 sharedNodes.getVec(),
00751 nodeSetSize,
00752 -1,
00753 &found);
00754
00755
00756
00757
00758
00759
00760
00761 if (found) {
00762
00763
00764
00765
00766 int matchingElemID = rover->next->elemID;
00767
00768 if (isEdgeRequest) {
00769
00770
00771 while (found) {
00772
00773
00774
00775
00776
00777 CkVec<adaptAdj>* matchingAdaptAdj = adaptEdgeAdjacencies[
00778 matchingElemID*numAdjElems + rover->next->nodeSetID];
00779 matchingAdaptAdj->push_back(adaptAdj(
00780 receivedRequest.chunkID,
00781 receivedRequest.elemID,
00782 receivedRequest.elemType));
00783
00784 rover = searchAdjElemInList(
00785 rover->next,
00786 sharedNodes.getVec(),
00787 nodeSetSize,
00788 -1,
00789 &found);
00790
00791 if (found) {
00792 matchingElemID = rover->next->elemID;
00793 }
00794 }
00795 } else {
00796 adaptAdj *matchingAdaptAdj = &adaptFaceAdjacencies[
00797 matchingElemID*numAdjElems + rover->next->nodeSetID];
00798 CkAssert(matchingAdaptAdj->localID == -1);
00799 matchingAdaptAdj->partID = receivedRequest.chunkID;
00800 matchingAdaptAdj->localID = receivedRequest.elemID;
00801 matchingAdaptAdj->elemType = receivedRequest.elemType;
00802
00803 adjElem *tmp = rover->next;
00804 rover->next = tmp->next;
00805 delete tmp;
00806 }
00807
00808
00809
00810 adjReply reply;
00811 reply.requestingElemID = receivedRequest.elemID;
00812 reply.requestingNodeSetID = receivedRequest.nodeSetID;
00813 reply.replyingElem.partID = myRank;
00814 reply.replyingElem.localID = matchingElemID;
00815 reply.replyingElem.elemType = elemType;
00816
00817 replyTable(receivedRequest.chunkID) += reply;
00818 } else {
00819
00820
00821 }
00822 }
00823 }
00824
00825
00826 inline void findNodeSet(
00827 int meshid,
00828 int elemType,
00829 int* faceSize,
00830 int* faceMapSize,
00831 int* edgeMapSize,
00832 int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE],
00833 int edgeMap[MAX_EDGES][2])
00834 {
00835 FEM_Mesh *mesh = FEM_chunk::get("GetAdaptAdj")->
00836 lookup(meshid,"GetAdaptAdj");
00837 FEM_Elem *elem = (FEM_Elem *)mesh->
00838 lookup(FEM_ELEM+elemType,"GetAdaptAdj");
00839 FEM_Node *node = (FEM_Node *)mesh->
00840 lookup(FEM_NODE,"GetAdaptAdj");
00841 const int nodesPer = (elem->getConn()).width();
00842 assert(node->getCoord()!= NULL);
00843
00844
00845
00846
00847 assert(nodesPer > 0);
00848 const int dim = (node->getCoord())->getWidth();
00849 assert(dim == 2|| dim == 3);
00850
00851 guessElementShape(dim, nodesPer,
00852 faceSize, faceMapSize, edgeMapSize,
00853 nodeSetMap, edgeMap);
00854 }
00855
00856 void getAndDumpAdaptAdjacencies(
00857 const int meshid,
00858 const int numElems,
00859 const int elemType,
00860 const int myRank)
00861 {
00862 int faceSize;
00863 int faceMapSize, edgeMapSize;
00864 int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
00865 int edgeMap[MAX_EDGES][2];
00866
00867 findNodeSet(meshid, elemType, &faceSize, &faceMapSize, &edgeMapSize,
00868 nodeSetMap, edgeMap);
00869
00870 for (int i=0; i<numElems; i++) {
00871 printf("[%d] %d :",myRank,i);
00872 for (int j=0; j<faceMapSize; j++) {
00873 adaptAdj *entry = getAdaptAdj(meshid, i, elemType, j);
00874 printf("(%d,%d,%d)", entry->partID, entry->localID, entry->elemType);
00875 }
00876 printf("\n");
00877 }
00878
00879 if (edgeMapSize == 0) return;
00880 for (int i=0; i<numElems; i++) {
00881 printf("[%d] %d :", myRank, i);
00882 for (int j=0; j<edgeMapSize; j++) {
00883 CkVec<adaptAdj>* entry = getEdgeAdaptAdj(meshid, i, elemType, j);
00884 for (int k=0; k<entry->size(); ++k) {
00885 printf("(%d,%d,%d)", (*entry)[k].partID, (*entry)[k].localID,
00886 (*entry)[k].elemType);
00887 }
00888 if (j < (edgeMapSize-1)) printf(" | ");
00889 }
00890 printf("\n");
00891 }
00892 }
00893
00894
00895 adaptAdj* lookupAdaptAdjacencies(
00896 const FEM_Mesh* const mesh,
00897 const int elemType,
00898 int* numAdjacencies)
00899 {
00900 FEM_Elem *elem = (FEM_Elem*)mesh->lookup(
00901 FEM_ELEM+elemType, "lookupAdaptAdjacencies");
00902
00903 FEM_DataAttribute* adaptAttr = (FEM_DataAttribute*)elem->lookup(
00904 FEM_ADAPT_FACE_ADJ, "lookupAdaptAdjacencies");
00905 *numAdjacencies = adaptAttr->getWidth()/sizeof(adaptAdj);
00906 AllocTable2d<unsigned char> &table = adaptAttr->getChar();
00907
00908 return (adaptAdj*)(adaptAttr->getChar().getData());
00909 }
00910
00911 adaptAdj* lookupAdaptAdjacencies(
00912 const int meshid,
00913 const int elemType,
00914 int* numAdjacencies)
00915 {
00916 FEM_Mesh* mesh = FEM_chunk::get("lookupAdaptAdjacencies")->lookup(
00917 meshid, "lookupAdaptAdjacencies");
00918 return lookupAdaptAdjacencies(mesh, elemType, numAdjacencies);
00919 }
00920
00921 CkVec<adaptAdj>** lookupEdgeAdaptAdjacencies(
00922 const FEM_Mesh* const mesh,
00923 const int elemType,
00924 int* numAdjacencies)
00925 {
00926 FEM_Elem *elem = (FEM_Elem*)mesh->lookup(
00927 FEM_ELEM+elemType,"lookupAdaptAdjacencies");
00928 FEM_DataAttribute* adaptAdjAttr = (FEM_DataAttribute*)elem->lookup(
00929 FEM_ADAPT_EDGE_ADJ, "CreateAdaptAdjacencies");
00930 *numAdjacencies = adaptAdjAttr->getWidth()/sizeof(CkVec<adaptAdj>**);
00931 CkVec<adaptAdj>** adaptAdjacencies =
00932 reinterpret_cast<CkVec<adaptAdj>**>((adaptAdjAttr->getChar()).getData());
00933 return adaptAdjacencies;
00934 }
00935
00936 CkVec<adaptAdj>** lookupEdgeAdaptAdjacencies(
00937 const int meshID,
00938 const int elemType,
00939 int* numAdjacencies)
00940 {
00941 FEM_Mesh *mesh = FEM_chunk::get("lookupAdaptAdjacencies")->
00942 lookup(meshID,"lookupAdaptAdjacencies");
00943 return lookupEdgeAdaptAdjacencies(mesh, elemType, numAdjacencies);
00944 }
00945
00947 adaptAdj* getAdaptAdj(
00948 const int meshID,
00949 const int localID,
00950 const int elemType,
00951 const int faceID)
00952 {
00953 int numAdjacencies;
00954 adaptAdj* adaptAdjacencies =
00955 lookupAdaptAdjacencies(meshID, elemType, &numAdjacencies);
00956 return &(adaptAdjacencies[localID*numAdjacencies+faceID]);
00957 }
00958
00959 adaptAdj* getAdaptAdj(
00960 const FEM_Mesh* const meshPtr,
00961 const int localID,
00962 const int elemType,
00963 const int faceID)
00964 {
00965 int numAdjacencies;
00966 adaptAdj* adaptAdjacencies =
00967 lookupAdaptAdjacencies(meshPtr, elemType, &numAdjacencies);
00968 return &(adaptAdjacencies[localID*numAdjacencies+faceID]);
00969 }
00970
00971 CkVec<adaptAdj>* getEdgeAdaptAdj(
00972 const int meshID,
00973 const int localID,
00974 const int elemType,
00975 const int edgeID)
00976 {
00977 int numAdjacencies;
00978 CkVec<adaptAdj>** adaptAdjacencies =
00979 lookupEdgeAdaptAdjacencies(meshID, elemType, &numAdjacencies);
00980 return adaptAdjacencies[localID*numAdjacencies+edgeID];
00981 }
00982
00983 CkVec<adaptAdj>* getEdgeAdaptAdj(
00984 const FEM_Mesh* const meshPtr,
00985 const int localID,
00986 const int elemType,
00987 const int edgeID)
00988 {
00989 int numAdjacencies;
00990 CkVec<adaptAdj>** adaptAdjacencies =
00991 lookupEdgeAdaptAdjacencies(meshPtr, elemType, &numAdjacencies);
00992 return adaptAdjacencies[localID*numAdjacencies+edgeID];
00993 }
00994
00998 adaptAdj* getAdaptAdj(
00999 const int meshID,
01000 const int localID,
01001 const int elemType,
01002 const int* const vertexList)
01003 {
01004 int faceID = getElemFace(meshID, elemType, vertexList);
01005 return getAdaptAdj(meshID, localID, elemType, faceID);
01006 }
01007
01008 CkVec<adaptAdj>* getEdgeAdaptAdj(
01009 const int meshID,
01010 const int localID,
01011 const int elemType,
01012 const int* const vertexList)
01013 {
01014 int edgeID = getElemEdge(meshID, elemType, vertexList);
01015 return getEdgeAdaptAdj(meshID, localID, elemType, edgeID);
01016 }
01017
01018 adaptAdj* getFaceAdaptAdj(
01019 const int meshID,
01020 const int localID,
01021 const int elemType,
01022 const int* const vertexList)
01023 {
01024 return getAdaptAdj(meshID, localID, elemType, vertexList);
01025 }
01026
01027 adaptAdj* getFaceAdaptAdj(
01028 const int meshID,
01029 const int localID,
01030 const int elemType,
01031 const int faceID)
01032 {
01033 return getAdaptAdj(meshID, localID, elemType, faceID);
01034 }
01035
01036 adaptAdj* getFaceAdaptAdj(
01037 const FEM_Mesh* const meshPtr,
01038 const int localID,
01039 const int elemType,
01040 const int faceID)
01041 {
01042 return getAdaptAdj(meshPtr, localID, elemType, faceID);
01043 }
01044
01045
01047 void clearEdgeAdjacency(
01048 const FEM_Mesh* const meshPtr,
01049 const int localID,
01050 const int elemType,
01051 const int edgeID)
01052 {
01053 getEdgeAdaptAdj(meshPtr, localID, elemType, edgeID)->removeAll();
01054 }
01055
01056 void clearEdgeAdjacency(
01057 const int meshID,
01058 const int localID,
01059 const int elemType,
01060 const int edgeID)
01061 {
01062 FEM_Mesh *mesh = FEM_chunk::get("lookupAdaptAdjacencies")->
01063 lookup(meshID,"lookupAdaptAdjacencies");
01064 clearEdgeAdjacency(mesh, localID, elemType, edgeID);
01065 }
01066
01068 void addEdgeAdjacency(
01069 const FEM_Mesh* const meshPtr,
01070 const int localID,
01071 const int elemType,
01072 const int edgeID,
01073 const adaptAdj adj)
01074 {
01075 CkAssert(adj.localID != -1);
01076 getEdgeAdaptAdj(meshPtr, localID, elemType, edgeID)->push_back(adj);
01077 }
01078
01079 void addEdgeAdjacency(
01080 const int meshID,
01081 const int localID,
01082 const int elemType,
01083 const int edgeID,
01084 const adaptAdj adj)
01085 {
01086 CkAssert(adj.localID != -1);
01087 FEM_Mesh *mesh = FEM_chunk::get("lookupAdaptAdjacencies")->
01088 lookup(meshID,"lookupAdaptAdjacencies");
01089 addEdgeAdjacency(mesh, localID, elemType, edgeID, adj);
01090 }
01091
01094 int getElemFace(
01095 const int meshID,
01096 const int type,
01097 const int* vertexList)
01098 {
01099 int faceSize;
01100 int faceMapSize;
01101 int faceMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
01102 int edgeMapSize;
01103 int edgeMap[MAX_EDGES][2];
01104 findNodeSet(meshID, type, &faceSize, &faceMapSize, &edgeMapSize,
01105 faceMap, edgeMap);
01106
01107
01108 std::set<int> vertexSet(vertexList, vertexList+faceSize);
01109 for (int i=0; i<faceMapSize; i++) {
01110 std::set<int> aNodeSet(faceMap[i], faceMap[i]+faceSize);
01111 if (vertexSet == aNodeSet) return i;
01112 }
01113
01114
01115 CkAbort("ERROR: GetEdgeFace: vertexList is not a valid face./n");
01116 return -1;
01117 }
01118
01119 int getElemEdge(
01120 const int meshID,
01121 const int type,
01122 const int* vertexList)
01123 {
01124 int faceSize;
01125 int faceMapSize;
01126 int faceMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
01127 int edgeMapSize;
01128 int edgeMap[MAX_EDGES][2];
01129 findNodeSet(meshID, type, &faceSize, &faceMapSize, &edgeMapSize,
01130 faceMap, edgeMap);
01131
01132
01133 std::set<int> vertexSet(vertexList, vertexList+2);
01134 for (int i=0; i<edgeMapSize; i++) {
01135 std::set<int> aNodeSet(edgeMap[i], edgeMap[i]+2);
01136 if (vertexSet == aNodeSet) return i;
01137 }
01138
01139
01140 CkAbort("ERROR: GetEdgeFace: vertexList is not a valid edge./n");
01141 return -1;
01142 }
01143
01144
01145
01148 void setAdaptAdj(
01149 const int meshID,
01150 const adaptAdj elem,
01151 const int faceID,
01152 const adaptAdj nbr)
01153 {
01154 int numAdjacencies;
01155 adaptAdj *adaptAdjTable = lookupAdaptAdjacencies(meshID, elem.elemType,
01156 &numAdjacencies);
01157 adaptAdjTable[elem.localID*numAdjacencies + faceID] = nbr;
01158 }
01159
01160 void setAdaptAdj(
01161 const FEM_Mesh* meshPtr,
01162 const adaptAdj elem,
01163 const int faceID,
01164 const adaptAdj nbr)
01165 {
01166 int numAdjacencies;
01167 adaptAdj *adaptAdjTable = lookupAdaptAdjacencies(meshPtr, elem.elemType,
01168 &numAdjacencies);
01169 adaptAdjTable[elem.localID*numAdjacencies + faceID] = nbr;
01170 }
01171
01172 void addToAdaptAdj(
01173 const int meshid,
01174 const adaptAdj elem,
01175 const int edgeID,
01176 const adaptAdj nbr)
01177 {
01178 CkAssert(nbr.localID != -1);
01179 CkVec<adaptAdj>* adjVec = getEdgeAdaptAdj(meshid, elem.localID,
01180 elem.elemType, edgeID);
01181 adjVec->push_back(nbr);
01182 }
01183
01184 void addToAdaptAdj(
01185 const FEM_Mesh* meshPtr,
01186 const adaptAdj elem,
01187 const int edgeID,
01188 const adaptAdj nbr)
01189 {
01190 CkAssert(nbr.localID != -1);
01191 CkVec<adaptAdj>* adjVec = getEdgeAdaptAdj(meshPtr, elem.localID,
01192 elem.elemType, edgeID);
01193 adjVec->push_back(nbr);
01194 }
01195
01196 void removeFromAdaptAdj(
01197 const int meshid,
01198 const adaptAdj elem,
01199 const int edgeID,
01200 const adaptAdj nbr)
01201 {
01202 CkVec<adaptAdj>* adjVec = getEdgeAdaptAdj(meshid, elem.localID,
01203 elem.elemType, edgeID);
01204 for (int i=0; i<adjVec->size(); ++i) {
01205 if ((*adjVec)[i] == nbr) {
01206 adjVec->remove(i);
01207 return;
01208 }
01209 }
01210 CkAbort("removeFromAdaptAdj did not find the specified nbr");
01211 }
01212
01213
01214 void copyAdaptAdj(
01215 const int meshid,
01216 const adaptAdj* const srcElem,
01217 const adaptAdj* const destElem)
01218 {
01219 FEM_Mesh* meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(
01220 meshid,"ReplaceAdaptAdj");
01221 copyAdaptAdj(meshPtr, srcElem, destElem);
01222 }
01223
01224
01225 void copyAdaptAdj(
01226 const FEM_Mesh* const meshPtr,
01227 const adaptAdj* const srcElem,
01228 const adaptAdj* const destElem)
01229 {
01230 int numAdjacencies;
01231 adaptAdj* adaptAdjTable = lookupAdaptAdjacencies(meshPtr, srcElem->elemType,
01232 &numAdjacencies);
01233 memcpy(&adaptAdjTable[destElem->localID*numAdjacencies],
01234 &adaptAdjTable[srcElem->localID*numAdjacencies],
01235 numAdjacencies*sizeof(adaptAdj));
01236 }
01237
01238
01239 void copyEdgeAdaptAdj(
01240 const int meshid,
01241 const adaptAdj* const srcElem,
01242 const adaptAdj* const destElem)
01243 {
01244 FEM_Mesh* meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(
01245 meshid,"ReplaceAdaptAdj");
01246 copyEdgeAdaptAdj(meshPtr, srcElem, destElem);
01247 }
01248
01249
01250 void copyEdgeAdaptAdj(
01251 const FEM_Mesh* const meshPtr,
01252 const adaptAdj* const srcElem,
01253 const adaptAdj* const destElem)
01254 {
01255 int nAdj;
01256 CkVec<adaptAdj>** adaptAdjTable = lookupEdgeAdaptAdjacencies(meshPtr,
01257 srcElem->elemType, &nAdj);
01258
01259 CkVec<adaptAdj>** srcTable = &adaptAdjTable[srcElem->localID*nAdj];
01260 CkVec<adaptAdj>** dstTable = &adaptAdjTable[destElem->localID*nAdj];
01261 for (int i=0; i<nAdj; ++i)
01262 *dstTable[i] = *srcTable[i];
01263 }
01264
01265
01266
01270 void replaceAdaptAdj(
01271 const FEM_Mesh* const meshPtr,
01272 const adaptAdj elem,
01273 const adaptAdj originalNbr,
01274 const adaptAdj newNbr)
01275 {
01276 int numAdjacencies;
01277 adaptAdj *adaptAdjTable = lookupAdaptAdjacencies(meshPtr, elem.elemType,
01278 &numAdjacencies);
01279 for(int i=0;i<numAdjacencies;i++){
01280 if(adaptAdjTable[elem.localID*numAdjacencies+i] == originalNbr){
01281 adaptAdjTable[elem.localID*numAdjacencies+i] = newNbr;
01282 return;
01283 }
01284 }
01285 CkAbort("replaceAdaptAdj did not find the specified originalNbr");
01286 }
01287
01288
01289 void replaceAdaptAdj(
01290 const int meshID,
01291 const adaptAdj elem,
01292 const adaptAdj originalNbr,
01293 const adaptAdj newNbr)
01294 {
01295 FEM_Mesh* meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(
01296 meshID,"ReplaceAdaptAdj");
01297 replaceAdaptAdj(meshPtr, elem, originalNbr, newNbr);
01298 }
01299
01300
01301 void replaceAdaptAdjOnEdge(
01302 const FEM_Mesh* const meshPtr,
01303 const adaptAdj elem,
01304 const adaptAdj originalNbr,
01305 const adaptAdj newNbr,
01306 const int edgeID)
01307 {
01308 int numAdjacencies;
01309 CkAssert(newNbr.localID != -1);
01310 CkVec<adaptAdj>** adaptAdjTable = lookupEdgeAdaptAdjacencies(
01311 meshPtr, elem.elemType, &numAdjacencies);
01312 CkVec<adaptAdj>* innerTable =
01313 adaptAdjTable[elem.localID*numAdjacencies + edgeID];
01314 for (int n=0; n<innerTable->size(); ++n) {
01315 if((*innerTable)[n] == originalNbr){
01316 (*innerTable)[n] = newNbr;
01317 return;
01318 }
01319 }
01320 CkAbort("replaceAdaptAdjOnEdge did not find the specified originalNbr");
01321 }
01322
01323
01324 void replaceAdaptAdjOnEdge(
01325 const int meshID,
01326 const adaptAdj elem,
01327 const adaptAdj originalNbr,
01328 const adaptAdj newNbr,
01329 const int edgeID)
01330 {
01331 CkAssert(newNbr.localID != -1);
01332 FEM_Mesh* meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(
01333 meshID,"ReplaceAdaptAdj");
01334 replaceAdaptAdjOnEdge(meshPtr, elem, originalNbr, newNbr, edgeID);
01335 }
01336
01337
01338 #define copyNodeMap(numEntries,entrySize,map,srcMap) \
01339 do { \
01340 for (int i=0;i<numEntries;i++){ \
01341 for(int j=0;j<entrySize;j++){ \
01342 map[i][j] = srcMap[i][j]; \
01343 } \
01344 } \
01345 } while (0)
01346
01347
01348
01349
01350
01351 void guessElementShape(
01352 const int dim,
01353 const int nodesPerElem,
01354 int* faceSize,
01355 int *faceMapSize,
01356 int* edgeMapSize,
01357 int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE],
01358 int edgeMap[MAX_EDGES][2])
01359 {
01360 switch(dim){
01361 case 2:
01362 {
01363
01364 switch (nodesPerElem) {
01365 case 3:
01366
01367 *faceSize = 2;
01368 *faceMapSize = 3;
01369 *edgeMapSize = 0;
01370 copyNodeMap(3,2,faceMap,faceMap2d_tri);
01371 break;
01372 case 4:
01373
01374 *faceSize = 2;
01375 *faceMapSize = 4;
01376 *edgeMapSize = 0;
01377 copyNodeMap(4,2,faceMap,faceMap2d_quad);
01378 break;
01379 default:
01380 CkPrintf("Unknown element type\n");
01381 CkAssert(false);
01382 }
01383 }
01384 break;
01385 case 3:
01386 {
01387
01388 switch(nodesPerElem){
01389 case 4:
01390
01391 *faceSize = 3;
01392 *faceMapSize = 4;
01393 *edgeMapSize = 6;
01394 copyNodeMap(4,3,faceMap,faceMap3d_tet);
01395 copyNodeMap(6,2,edgeMap,edgeMap3d_tet);
01396 break;
01397 case 8:
01398
01399 *faceSize = 4;
01400 *faceMapSize = 6;
01401 *edgeMapSize = 12;
01402 copyNodeMap(6,4,faceMap,faceMap3d_hex);
01403 copyNodeMap(12,2,edgeMap,edgeMap3d_hex);
01404 break;
01405 default:
01406 CkPrintf("Unknown element type\n");
01407 CkAssert(false);
01408 }
01409 }
01410 break;
01411 default:
01412 CkPrintf("Unknown element type\n");
01413 CkAssert(false);
01414 }
01415 }
01416