00001
00005 #include "bulk_adapt_ops.h"
00006 #include "import.h"
00007
00008 #define BULK_DEBUG(x) x
00009
00011 BulkAdapt::BulkAdapt(int meshid,FEM_Mesh *mPtr, int partID,
00012 CProxy_ParFUMShadowArray sa_proxy)
00013 {
00014 meshID = meshid;
00015 meshPtr = mPtr;
00016 partitionID = partID;
00017 shadowProxy = sa_proxy;
00018 localShadow = meshPtr->parfumSA;
00019 for (int i=0; i<10; i++) { freeTable[i] = 1; }
00020 firstFree = 0;
00021 }
00022
00024 BulkAdapt::~BulkAdapt()
00025 {
00026 }
00027
00029 void BulkAdapt::pup(PUP::er &p)
00030 {
00031
00032
00033
00034 }
00035
00036
00037
00038
00040
00045 bool BulkAdapt::edge_bisect(int elemID, int elemType, int edgeID, int dim, RegionID lockRegionID)
00046 {
00047 if (dim == 2) {
00048 return edge_bisect_2D(elemID, elemType, edgeID);
00049 }
00050 else if (dim == 3) {
00051 return edge_bisect_3D(elemID, elemType, edgeID, lockRegionID);
00052 }
00053 else return false;
00054 }
00055
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 bool BulkAdapt::edge_bisect_2D(int elemID, int elemType, int edgeID)
00073 {
00074
00075
00076 adaptAdj elemsToLock[2];
00077 adaptAdj startElem(partitionID, elemID, elemType);
00078 adaptAdj nbrElem = *getAdaptAdj(meshID, elemID, elemType, edgeID);
00079
00080 elemsToLock[0] = startElem;
00081 elemsToLock[1] = nbrElem;
00082 RegionID lockRegionID;
00083 if (localShadow->lockRegion(2, elemsToLock, &lockRegionID,0.0)) {
00084
00085 }
00086 else {
00087
00088 return false;
00089 }
00090
00091
00092 int node1idx, node2idx, newNodeID;
00093 adaptAdj splitElem;
00094
00095 one_side_split_2D(startElem, splitElem, edgeID, &node1idx, &node2idx, &newNodeID, true);
00096
00097 if ((nbrElem.partID > -1) && (nbrElem.partID == partitionID)) {
00098
00099 FEM_Elem &elem = meshPtr->elem[elemType];
00100 int *nbrConn = elem.connFor(nbrElem.localID);
00101 int relNode1 = getRelNode(node1idx, nbrConn, 3);
00102 int relNode2 = getRelNode(node2idx, nbrConn, 3);
00103 int nbrEdgeID = getEdgeID(relNode1, relNode2, 3, 2);
00104
00105 int nbrNode1, nbrNode2;
00106 adaptAdj nbrSplitElem;
00107
00108 one_side_split_2D(nbrElem, nbrSplitElem, nbrEdgeID, &nbrNode1, &nbrNode2, &newNodeID, false);
00109
00110
00111 adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0);
00112 adaptAdj *nbrSplitElemAdaptAdj = getAdaptAdj(meshID, nbrSplitElem.localID, nbrSplitElem.elemType, 0);
00113 nbrSplitElemAdaptAdj[nbrEdgeID] = splitElem;
00114
00115
00116 splitElemAdaptAdj[edgeID] = nbrSplitElem;
00117
00118 }
00119 else if (nbrElem.partID == -1) {
00120 adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0);
00121 splitElemAdaptAdj[edgeID] = adaptAdj(-1, -1, 0);
00122
00123 }
00124 else {
00125 int chunks[1] = {nbrElem.partID};
00126 make_node_shared(newNodeID, 1, &chunks[0]);
00127 int new_idxl, n1_idxl, n2_idxl;
00128 new_idxl = get_idxl_for_node(newNodeID, nbrElem.partID);
00129 n1_idxl = get_idxl_for_node(node1idx, nbrElem.partID);
00130 n2_idxl = get_idxl_for_node(node2idx, nbrElem.partID);
00131
00132
00133
00134
00135 adaptAdjMsg *am = shadowProxy[nbrElem.partID].remote_bulk_edge_bisect_2D(nbrElem, splitElem, new_idxl, n1_idxl, n2_idxl, partitionID);
00136
00137 adaptAdj nbrSplitElem = am->elem;
00138
00139 adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0);
00140 splitElemAdaptAdj[edgeID] = nbrSplitElem;
00141
00142 }
00143
00144
00145 localShadow->unlockRegion(lockRegionID);
00146 getAndDumpAdaptAdjacencies(meshID, meshPtr->nElems(), elemType, partitionID);
00147 return true;
00148 }
00149
00150 void BulkAdapt::dumpConn()
00151 {
00152 FEM_Elem &elem = meshPtr->elem[0];
00153 int nelems=FEM_Mesh_get_length(meshID, FEM_ELEM+0);
00154 for (int i=0; i<nelems; i++) {
00155 int *conn = elem.connFor(i);
00156 CkPrintf("[%d] %d: %d %d %d %d\n", partitionID, i, conn[0], conn[1], conn[2], conn[3]);
00157 }
00158 }
00159
00160 adaptAdj BulkAdapt::remote_edge_bisect_2D(adaptAdj nbrElem, adaptAdj splitElem, int new_idxl, int n1_idxl, int n2_idxl, int remotePartID)
00161 {
00162 int node1idx, node2idx, newNodeID;
00163 node1idx = get_node_from_idxl(n1_idxl, remotePartID);
00164 node2idx = get_node_from_idxl(n2_idxl, remotePartID);
00165
00166 FEM_Elem &elem = meshPtr->elem[nbrElem.elemType];
00167 int *nbrConn = elem.connFor(nbrElem.localID);
00168 int relNode1 = getRelNode(node1idx, nbrConn, 3);
00169 int relNode2 = getRelNode(node2idx, nbrConn, 3);
00170 int nbrEdgeID = getEdgeID(relNode1, relNode2, 3, 2);
00171
00172 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00173 double *node1coords = (coord->getDouble()).getRow(node1idx);
00174 double *node2coords = (coord->getDouble()).getRow(node2idx);
00175 double bisectCoords[2];
00176 midpoint(node1coords, node2coords, 2, &bisectCoords[0]);
00177 newNodeID = add_node(2, &bisectCoords[0]);
00178 int chunks[2] = {nbrElem.partID, remotePartID};
00179 make_node_shared(newNodeID, 2, chunks);
00180 int local_new_idxl = get_idxl_for_node(newNodeID, remotePartID);
00181 if (new_idxl != local_new_idxl)
00182 printf("ERROR: Partition %d added shared node at different idxl index %d than other copy at %d on partition %d!",
00183 nbrElem.partID, local_new_idxl, new_idxl, remotePartID);
00184
00185 int nbrNode1, nbrNode2;
00186 adaptAdj nbrSplitElem;
00187
00188 one_side_split_2D(nbrElem, nbrSplitElem, nbrEdgeID, &nbrNode1, &nbrNode2, &newNodeID, false);
00189
00190 adaptAdj *nbrSplitElemAdaptAdj = getAdaptAdj(meshPtr, nbrSplitElem.localID, nbrSplitElem.elemType, 0);
00191 nbrSplitElemAdaptAdj[nbrEdgeID] = splitElem;
00192
00193
00194 return nbrSplitElem;
00195 }
00196
00197 int BulkAdapt::lock_3D_region(int elemID, int elemType, int edgeID, double prio, RegionID *lockRegionID)
00198 {
00199 int numElemsToLock=0, success=-1;
00200 adaptAdj *elemsToLock;
00201 adaptAdj startElem(partitionID, elemID, elemType);
00202
00203 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::lock_3D_region acquiring list of elements to build locked region.\n",
00204 partitionID));
00205 get_elemsToLock(startElem, &elemsToLock, edgeID, &numElemsToLock);
00206
00207 success = localShadow->lockRegion(numElemsToLock, elemsToLock, lockRegionID, prio);
00208 free(elemsToLock);
00209 if (success==2) {
00210 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::lock_3D_region: Lock (%d,%d,%6.4f) obtained.\n", partitionID,
00211 lockRegionID->chunkID, lockRegionID->localID, lockRegionID->prio));
00212 }
00213 else if (success==1) {
00214 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::lock_3D_region: Lock (%d,%d,%6.4f) pending.\n", partitionID,
00215 lockRegionID->chunkID, lockRegionID->localID, lockRegionID->prio));
00216 }
00217 else if (success==0) {
00218 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::edge_bisect_3D: Lock (%d,%d,%6.4f) not obtained.\n", partitionID,
00219 lockRegionID->chunkID, lockRegionID->localID, lockRegionID->prio));
00220 }
00221 else {
00222 CkPrintf("Lock status=%d\n", success);
00223 CkAbort("Invalid lock return status!\n");
00224 }
00225 return success;
00226 }
00227
00228 void BulkAdapt::unlock_3D_region(RegionID lockRegionID)
00229 {
00230 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::unlock_3D_region: Unlocking lock (%d,%d,%6.4f).\n", partitionID,
00231 lockRegionID.chunkID, lockRegionID.localID, lockRegionID.prio));
00232 localShadow->unlockRegion(lockRegionID);
00233 }
00234
00235 void BulkAdapt::unpend_3D_region(RegionID lockRegionID)
00236 {
00237 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::unpend_3D_region: Unlocking lock (%d,%d,%6.4f).\n", partitionID,
00238 lockRegionID.chunkID, lockRegionID.localID, lockRegionID.prio));
00239 localShadow->unpendRegion(lockRegionID);
00240 }
00241
00242
00244 bool BulkAdapt::edge_bisect_3D(int elemID, int elemType, int edgeID, RegionID lockRegionID)
00245 {
00246
00247 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::edge_bisect_3D starts at elemID %d \n",partitionID,elemID));
00248
00249
00250
00251 int numElemsToLock=0;
00252 adaptAdj *elemsToLock;
00253 adaptAdj startElem(partitionID, elemID, elemType);
00254
00255 CkAssert(lockRegionID == localShadow->holdingLock);
00256
00257 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::edge_bisect_3D acquiring list of elements surrounding edge.\n",
00258 partitionID));
00259 get_elemsToLock(startElem, &elemsToLock, edgeID, &numElemsToLock);
00260
00261
00262 int localNodes[3], localRelNodes[2];
00263 double nodeCoords[9];
00264 FEM_Elem &elems = meshPtr->elem[elemType];
00265 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00266 int *conn = elems.connFor(elemID);
00267
00268
00269 getRelNodes(edgeID, 4, &(localRelNodes[0]), &(localRelNodes[1]));
00270 localNodes[0] = conn[localRelNodes[0]];
00271 localNodes[1] = conn[localRelNodes[1]];
00272 double *n0co = (coord->getDouble()).getRow(localNodes[0]);
00273 double *n1co = (coord->getDouble()).getRow(localNodes[1]);
00274 nodeCoords[0] = n0co[0];
00275 nodeCoords[1] = n0co[1];
00276 nodeCoords[2] = n0co[2];
00277 nodeCoords[3] = n1co[0];
00278 nodeCoords[4] = n1co[1];
00279 nodeCoords[5] = n1co[2];
00280
00281
00282 midpoint(&(nodeCoords[0]), &(nodeCoords[3]), 3, &(nodeCoords[6]));
00283 localNodes[2] = add_node(3, &(nodeCoords[6]));
00284 int *chunks = (int *)malloc(numElemsToLock*sizeof(int));
00285 int numParts=0;
00286
00287 for (int i=0; i<numElemsToLock; i++) {
00288 chunks[i] = -1;
00289 int j;
00290 for (j=0; j<numParts; j++) {
00291 if (chunks[j] == elemsToLock[i].partID) {
00292 break;
00293 }
00294 }
00295 chunks[j] = elemsToLock[i].partID;
00296 if (j==numParts) numParts++;
00297 }
00298
00299 if (numParts > 1)
00300 make_node_shared(localNodes[2], numParts, &chunks[0]);
00301
00302 free(chunks);
00303
00304
00305 int numRemote=0;
00306 int tableID = getTableID();
00307 elemPairs[tableID] = (adaptAdj *)malloc(2*numElemsToLock*sizeof(adaptAdj));
00308
00309 for (int i=0; i<numElemsToLock; i++) {
00310 if (elemsToLock[i].partID != partitionID) {
00311 elemPairs[tableID][2*i] = elemsToLock[i];
00312 numRemote++;
00313 shadowProxy[elemsToLock[i].partID].
00314 handle_split_3D(partitionID, i, tableID, elemsToLock[i], lockRegionID,
00315 get_idxl_for_node(localNodes[0], elemsToLock[i].partID),
00316 get_idxl_for_node(localNodes[1], elemsToLock[i].partID),
00317 get_idxl_for_node(localNodes[2], elemsToLock[i].partID));
00318 }
00319 }
00320
00321 for (int i=0; i<numElemsToLock; i++) {
00322 if (elemsToLock[i].partID == partitionID) {
00323 elemPairs[tableID][2*i] = elemsToLock[i];
00324 adaptAdj *splitElem = local_split_3D(elemsToLock[i], localNodes[0],
00325 localNodes[1], localNodes[2]);
00326 elemPairs[tableID][2*i+1] = (*splitElem);
00327 delete splitElem;
00328 }
00329 }
00330
00331 if (numRemote > 0) {
00332 localShadow->recv_splits(tableID, numRemote);
00333 }
00334
00335
00336
00337 for (int i=0; i<numElemsToLock; i++) {
00338 if (elemsToLock[i].partID != partitionID) {
00339 shadowProxy[elemsToLock[i].partID].
00340 update_asterisk_3D(partitionID, i, elemsToLock[i], numElemsToLock,
00341 elemPairs[tableID], lockRegionID,
00342 get_idxl_for_node(localNodes[0], elemsToLock[i].partID),
00343 get_idxl_for_node(localNodes[1], elemsToLock[i].partID),
00344 get_idxl_for_node(localNodes[2], elemsToLock[i].partID));
00345 }
00346 }
00347 for (int i=0; i<numElemsToLock; i++) {
00348 if (elemsToLock[i].partID == partitionID) {
00349 local_update_asterisk_3D(i, elemsToLock[i], numElemsToLock, elemPairs[tableID],
00350 localNodes[0], localNodes[1], localNodes[2]);
00351 }
00352 }
00353
00354
00355 freeTableID(tableID);
00356 free(elemsToLock);
00357
00358
00359
00360
00361 BULK_DEBUG(CkPrintf("[%d] BulkAdapt::edge_bisect_3D of elem %d successful.\n",partitionID, elemID));
00362 return true;
00363 }
00364
00366
00371 int BulkAdapt::edge_flip(int elemID, int edgeID)
00372 {
00373 CkPrintf("BulkAdapt::edge_flip not yet implemented.\n");
00374 return 0;
00375 }
00376
00378
00383 int BulkAdapt::flip_23(int elemID, int faceID)
00384 {
00385 CkPrintf("BulkAdapt::flip_23 not yet implemented.\n");
00386 return 0;
00387 }
00388
00390
00395 int BulkAdapt::flip_32(int elemID, int edgeID)
00396 {
00397 CkPrintf("BulkAdapt::flip_32 not yet implemented.\n");
00398 return 0;
00399 }
00400
00402
00407 int BulkAdapt::edge_collapse(int elemID, int edgeID)
00408 {
00409 CkPrintf("BulkAdapt::edge_collapse not yet implemented.\n");
00410 return 0;
00411 }
00412
00413 void BulkAdapt::one_side_split_2D(adaptAdj &startElem, adaptAdj &splitElem,
00414 int edgeID, int *node1idx, int *node2idx,
00415 int *newNodeID, bool startSide)
00416 {
00417
00418 FEM_Elem &elem = meshPtr->elem[startElem.elemType];
00419 int *startConn = elem.connFor(startElem.localID);
00420
00421 int relNode1 = edgeID, relNode2 = (edgeID+1)%3;
00422 if (!startSide) {
00423 relNode1 = (edgeID+1)%3;
00424 relNode2 = edgeID;
00425 }
00426 *node1idx = startConn[relNode1];
00427 *node2idx = startConn[relNode2];
00428
00429
00430
00431
00432 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00433 double *node1coords = (coord->getDouble()).getRow(*node1idx);
00434 double *node2coords = (coord->getDouble()).getRow(*node2idx);
00435 double bisectCoords[2];
00436 midpoint(node1coords, node2coords, 2, &bisectCoords[0]);
00437
00438 int bisectNode;
00439 if (startSide) {
00440 bisectNode = add_node(2, &bisectCoords[0]);
00441 *newNodeID = bisectNode;
00442 }
00443 else {
00444
00445 bisectNode = *newNodeID;
00446 }
00447
00448 int splitConn[3];
00449 memcpy(&splitConn[0], startConn, 3*sizeof(int));
00450
00451 startConn[relNode2] = bisectNode;
00452
00453
00454 splitConn[relNode1] = bisectNode;
00455
00456 int splitElemID = add_element(startElem.elemType, 3, &splitConn[0], elem.getMeshSizing(startElem.localID));
00457
00458
00459 splitElem = adaptAdj(partitionID, splitElemID, startElem.elemType);
00460 adaptAdj *startElemAdaptAdj = getAdaptAdj(meshPtr, startElem.localID, startElem.elemType, 0);
00461 adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshPtr, splitElem.localID, startElem.elemType, 0);
00462 memcpy(splitElemAdaptAdj, startElemAdaptAdj, 3*sizeof(adaptAdj));
00463 adaptAdj startElemNbr;
00464 if (startSide) {
00465
00466 startElemNbr = startElemAdaptAdj[(edgeID+1)%3];
00467 startElemAdaptAdj[(edgeID+1)%3] = splitElem;
00468
00469 splitElemAdaptAdj[(edgeID+2)%3] = startElem;
00470
00471
00472 }
00473 else {
00474
00475 startElemNbr = startElemAdaptAdj[(edgeID+2)%3];
00476 startElemAdaptAdj[(edgeID+2)%3] = splitElem;
00477
00478 splitElemAdaptAdj[(edgeID+1)%3] = startElem;
00479
00480
00481 }
00482 if (startElemNbr.partID == startElem.partID) {
00483 replaceAdaptAdj(meshPtr, startElemNbr, startElem, splitElem);
00484
00485 }
00486 else if (startElemNbr.partID != -1) {
00487
00488 shadowProxy[startElemNbr.partID].remote_adaptAdj_replace(startElemNbr, startElem, splitElem);
00489 }
00490
00491 CkPrintf("WARNING: Data transfer not yet implemented.\n");
00492 }
00493
00494
00495
00496
00497
00498
00499 void BulkAdapt::remote_adaptAdj_replace(adaptAdj elem, adaptAdj oldElem, adaptAdj newElem)
00500 {
00501 replaceAdaptAdj(meshPtr, elem, oldElem, newElem);
00502 }
00503
00504 void BulkAdapt::remote_edgeAdj_replace(int remotePartID, adaptAdj elem, adaptAdj oldElem, adaptAdj newElem, int n1_idxl, int n2_idxl)
00505 {
00506 int n1 = get_node_from_idxl(n1_idxl, remotePartID),
00507 n2 = get_node_from_idxl(n2_idxl, remotePartID);
00508
00509 int relNodes[4];
00510 FEM_Elem &elems = meshPtr->elem[elem.elemType];
00511 int *conn = elems.connFor(elem.localID);
00512 fillNodes(relNodes, n1, n2, conn);
00513
00514 int edgeID = getEdgeID(relNodes[0], relNodes[1], 4, 3);
00515
00516 replaceAdaptAdjOnEdge(meshPtr, elem, oldElem, newElem, edgeID);
00517 }
00518
00519 void BulkAdapt::remote_edgeAdj_add(int remotePartID, adaptAdj adj, adaptAdj splitElem, int n1_idxl, int n2_idxl)
00520 {
00521 int n1 = get_node_from_idxl(n1_idxl, remotePartID),
00522 n2 = get_node_from_idxl(n2_idxl, remotePartID);
00523
00524 int relNodes[4];
00525 FEM_Elem &elems = meshPtr->elem[adj.elemType];
00526 int *conn = elems.connFor(adj.localID);
00527 fillNodes(relNodes, n1, n2, conn);
00528
00529 int edgeID = getEdgeID(relNodes[0], relNodes[1], 4, 3);
00530
00531 addToAdaptAdj(meshPtr, adj, edgeID, splitElem);
00532 }
00533
00534 void BulkAdapt::handle_split_3D(int remotePartID, int pos, int tableID, adaptAdj elem,
00535 RegionID lockRegionID, int n1_idxl, int n2_idxl, int n5_idxl)
00536 {
00537 int n1 = get_node_from_idxl(n1_idxl, remotePartID),
00538 n2 = get_node_from_idxl(n2_idxl, remotePartID),
00539 n5;
00540
00541 if (is_node_in_idxl(n5_idxl, remotePartID)) {
00542 n5 = get_node_from_idxl(n5_idxl, remotePartID);
00543 }
00544 else {
00545 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00546 double *n0co = (coord->getDouble()).getRow(n1);
00547 double *n1co = (coord->getDouble()).getRow(n2);
00548 double nodeCoords[9];
00549 nodeCoords[0] = n0co[0];
00550 nodeCoords[1] = n0co[1];
00551 nodeCoords[2] = n0co[2];
00552 nodeCoords[3] = n1co[0];
00553 nodeCoords[4] = n1co[1];
00554 nodeCoords[5] = n1co[2];
00555 midpoint(&(nodeCoords[0]), &(nodeCoords[3]), 3, &(nodeCoords[6]));
00556 n5 = add_node(3, &(nodeCoords[6]));
00557
00558
00559 int relNodes[4];
00560 FEM_Elem &elems = meshPtr->elem[elem.elemType];
00561 int *conn = elems.connFor(elem.localID);
00562
00563 fillNodes(relNodes, n1, n2, conn);
00564
00565 int edgeID = getEdgeID(relNodes[0], relNodes[1], 4, 3);
00566
00567
00568 int numElemsToLock = 0;
00569 adaptAdj *elemsToLock;
00570 get_elemsToLock(elem, &elemsToLock, edgeID, &numElemsToLock);
00571
00572
00573 int *chunks = (int *)malloc(numElemsToLock*sizeof(int));
00574 int numParts=0;
00575 for (int i=0; i<numElemsToLock; i++) {
00576 chunks[i] = -1;
00577 int j;
00578 for (j=0; j<numParts; j++) {
00579 if (chunks[j] == elemsToLock[i].partID) {
00580 break;
00581 }
00582 }
00583 chunks[j] = elemsToLock[i].partID;
00584 if (j==numParts) numParts++;
00585 }
00586
00587 if (numParts > 1)
00588 make_node_shared(n5, numParts, &chunks[0]);
00589
00590 free(chunks);
00591 free(elemsToLock);
00592 }
00593
00594 adaptAdj *splitElem = local_split_3D(elem, n1, n2, n5);
00595 shadowProxy[remotePartID].recv_split_3D(pos, tableID, elem, *splitElem);
00596 delete splitElem;
00597 }
00598
00599 void BulkAdapt::recv_split_3D(int pos, int tableID, adaptAdj elem,
00600 adaptAdj splitElem)
00601 {
00602 assert(elemPairs[tableID][2*pos] == elem);
00603 elemPairs[tableID][2*pos+1] = splitElem;
00604 numGathered[tableID]++;
00605 }
00606
00607 bool BulkAdapt::all_splits_received(int tableID, int expectedSplits)
00608 {
00609 return (expectedSplits == numGathered[tableID]);
00610 }
00611
00612 void BulkAdapt::update_asterisk_3D(int remotePartID, int i, adaptAdj elem,
00613 int numElemPairs, adaptAdj *elemPairs, RegionID lockRegionID,
00614 int n1_idxl, int n2_idxl, int n5_idxl)
00615 {
00616 CkAssert(remotePartID != elem.partID);
00617 int n1 = get_node_from_idxl(n1_idxl, remotePartID),
00618 n2 = get_node_from_idxl(n2_idxl, remotePartID),
00619 n5 = get_node_from_idxl(n5_idxl, remotePartID);
00620
00621
00622 local_update_asterisk_3D(i, elem, numElemPairs, elemPairs, n1, n2, n5);
00623 }
00624
00625
00626
00627
00632 int BulkAdapt::add_element(int elemType,int nodesPerElem,int *conn, double sizing){
00633
00634
00635 localShadow->setRunningTCharm();
00636 FEM_Elem &elem = meshPtr->elem[elemType];
00637 int newElem = elem.get_next_invalid();
00638 elem.connIs(newElem,conn);
00639 elem.setMeshSizing(newElem, sizing);
00640
00641 int nAdj;
00642 adaptAdj* adaptAdjacencies = lookupAdaptAdjacencies(
00643 meshPtr, elemType, &nAdj);
00644 for (int a = 0; a<nAdj; ++a) {
00645
00646 adaptAdjacencies[newElem*nAdj + a].partID = -1;
00647 adaptAdjacencies[newElem*nAdj + a].localID = -1;
00648 adaptAdjacencies[newElem*nAdj + a].elemType = elemType;
00649 }
00650 CkVec<adaptAdj>** adaptEdgeAdjacencies =
00651 lookupEdgeAdaptAdjacencies(meshPtr,elemType,&nAdj);
00652 for (int a=0; a<nAdj; ++a) {
00653 adaptEdgeAdjacencies[newElem*nAdj + a] = new CkVec<adaptAdj>;
00654 }
00655 return newElem;
00656 }
00657
00659 void BulkAdapt::update_element_conn(int elemType,int elemID,int nodesPerElem,int *conn){
00660 FEM_Elem &elem = meshPtr->elem[elemType];
00661 elem.connIs(elemID,conn);
00662 }
00663
00664 bool BulkAdapt::isLongest(int elem, int elemType, double len) {
00665 FEM_Elem &elems = meshPtr->elem[elemType];
00666 int *conn = elems.connFor(elem);
00667 if ((len < length(conn[0], conn[1], 3)) || (len < length(conn[0], conn[2], 3)) || (len < length(conn[0], conn[3], 3)) || (len < length(conn[1], conn[2], 3)) || (len < length(conn[1], conn[3], 3)) || (len < length(conn[2], conn[3], 3))) {
00668 return false;
00669 }
00670 return true;
00671 }
00672
00673
00674
00680 int BulkAdapt::add_node(int dim,double *coords){
00681
00682
00683 localShadow->setRunningTCharm();
00684 int newNode = meshPtr->node.get_next_invalid();
00685 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00686 (coord->getDouble()).setRow(newNode,coords);
00687 AllocTable2d<int> &lockTable = ((FEM_DataAttribute *)(meshPtr->node.lookup(FEM_ADAPT_LOCK,"lockRegion")))->getInt();
00688
00689 lockTable[newNode][0] = -1;
00690 lockTable[newNode][1] = -1;
00691 return newNode;
00692 }
00693
00694
00695 double BulkAdapt::length(int n1, int n2, int dim) {
00696 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00697 double *coordsn1 = (coord->getDouble()).getRow(n1);
00698 double *coordsn2 = (coord->getDouble()).getRow(n2);
00699 return length(coordsn1, coordsn2, dim);
00700 }
00701
00702 double BulkAdapt::length(double *n1, double *n2, int dim) {
00703 double d, ds_sum=0.0;
00704 for (int i=0; i<dim; i++) {
00705 if(n1[i]<-1.0 || n2[i]<-1.0) return -2.0;
00706 d = n1[i] - n2[i];
00707 ds_sum += d*d;
00708 }
00709 return (sqrt(ds_sum));
00710 }
00711
00712
00713
00716 void BulkAdapt::update_node_coord(int nodeID,int dim,double *coords){
00717 FEM_DataAttribute *coord = meshPtr->node.getCoord();
00718 (coord->getDouble()).setRow(nodeID,coords);
00719 }
00720
00721 void BulkAdapt::make_node_shared(int nodeID,int numSharedChunks,int *sharedChunks){
00722 for(int i=0;i<numSharedChunks;i++){
00723 IDXL_List &sharedList = meshPtr->node.shared.addList(sharedChunks[i]);
00724 sharedList.push_back(nodeID);
00725 }
00726 meshPtr->node.shared.flushMap();
00727 }
00728
00729 int BulkAdapt::get_idxl_for_node(int nodeID, int partID)
00730 {
00731 IDXL_List *list = meshPtr->node.shared.getIdxlListN(partID);
00732 CkAssert(list!=NULL);
00733 for (int i=0; i<list->size(); i++) {
00734 if ((*list)[i] == nodeID) {
00735 return i;
00736 }
00737 }
00738 CkAssert(0);
00739 return -1;
00740 }
00741
00742 int BulkAdapt::get_node_from_idxl(int node_idxl, int partID)
00743 {
00744 IDXL_List *list = meshPtr->node.shared.getIdxlListN(partID);
00745 CkAssert(list!=NULL);
00746 CkAssert(list->size()>node_idxl);
00747 return (*list)[node_idxl];
00748 }
00749
00750 bool BulkAdapt::is_node_in_idxl(int node_idxl, int partID)
00751 {
00752 IDXL_List *list = meshPtr->node.shared.getIdxlListN(partID);
00753 return(list->size()>node_idxl);
00754 }
00755
00756 void BulkAdapt::get_elemsToLock(adaptAdj startElem, adaptAdj **elemsToLock, int edgeID, int *count)
00757 {
00758 CkVec<adaptAdj>* nbrElems;
00759
00760
00761
00762 nbrElems = getEdgeAdaptAdj(meshID, startElem.localID, startElem.elemType,
00763 edgeID);
00764
00765 (*count) = nbrElems->size();
00766 (*elemsToLock) = (adaptAdj *)malloc((*count + 1) * sizeof(adaptAdj));
00767
00768 for (int i=0; i<*count; i++) {
00769 (*elemsToLock)[i] = (*nbrElems)[i];
00770 }
00771
00772 (*elemsToLock)[*count] = startElem;
00773 (*count)++;
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 }
00784
00785
00786
00787 void midpoint(double *n1, double *n2, int dim, double *result) {
00788 for(int i=0;i<dim;i++){
00789 result[i] = (n1[i]+n2[i])/2.0;
00790 }
00791 }
00792
00793 int getRelNode(int nodeIdx, int *conn, int nodesPerElem) {
00794 for(int i=0;i<nodesPerElem;i++){
00795 if(conn[i] == nodeIdx){
00796 return i;
00797 }
00798 }
00799 CkAbort("Could not find node in given connectivity");
00800 return -1;
00801 }
00802
00803
00804 void getRelNodes(int edgeID, int nodesPerElem, int *r1, int *r2)
00805 {
00806 if (nodesPerElem == 3) {
00807 (*r1) = edgeID;
00808 (*r2) = (edgeID + 1) % 3;
00809 }
00810 else if (nodesPerElem == 4) {
00811 if (edgeID < 3) {
00812 (*r1) = 0;
00813 (*r2) = edgeID+1;
00814 }
00815 else if (edgeID < 5) {
00816 (*r1) = 1;
00817 (*r2) = edgeID-1;
00818 }
00819 else {
00820 (*r1) = 2;
00821 (*r2) = 3;
00822 }
00823 }
00824 }
00825
00826 int getEdgeID(int node1, int node2, int nodesPerElem, int dim) {
00827 switch(dim){
00828 case 2: {
00829 switch(nodesPerElem){
00830 case 3:
00831 {
00832 static int edgeFromNode[3][3]={{-1,0,2},{0,-1,1},{2,1,-1}};
00833 return edgeFromNode[node1][node2];
00834 }
00835 break;
00836 default:
00837 CkAbort("This shape is not yet implemented");
00838 };
00839 break;
00840 }
00841 case 3: {
00842 switch(nodesPerElem){
00843 case 4:
00844 {
00845 static int edgeFromNode[4][4]={{-1,0,1,2},{0,-1,3,4},{1,3,-1,5},{2,4,5,-1}};
00846 return edgeFromNode[node1][node2];
00847 }
00848 break;
00849 default:
00850 CkAbort("This shape is not yet implemented");
00851 };
00852 break;
00853 }
00854 default:
00855 CkAbort("This dimension not yet implemented");
00856 };
00857 return -1;
00858 }
00859
00860
00861 int getFaceID(int node1, int node2, int node3, int nodesPerElem)
00862 {
00863 switch(nodesPerElem){
00864 case 4: {
00865 static int faceFromNode[4][4][4]=
00866 {{{-1,-1,-1,-1}, {-1,-1, 0, 1}, {-1, 0,-1, 2}, {-1, 1, 2,-1}},
00867 {{-1,-1, 0, 1}, {-1,-1,-1,-1}, {0,-1,-1, 3}, {1,-1, 3,-1}},
00868 {{-1, 0,-1, 2}, {0,-1,-1, 3}, {-1,-1,-1,-1}, {2, 3,-1,-1}},
00869 {{-1, 1, 2,-1}, {1,-1, 3,-1}, {2, 3,-1,-1}, {-1,-1,-1,-1}}};
00870 return faceFromNode[node1][node2][node3];
00871 break;
00872 }
00873 default:
00874 CkAbort("This shape is not yet implemented");
00875 };
00876 return -1;
00877 }
00878
00879 void fillNodes(int *relNode, int *nodeIDs, int *conn)
00880 {
00881 if ((relNode[0] != 0) && (relNode[1] != 0))
00882 relNode[2] = 0;
00883 else if ((relNode[0] != 1) && (relNode[1] != 1))
00884 relNode[2] = 1;
00885 else relNode[2] = 2;
00886 relNode[3] = 6 - relNode[0] - relNode[1] - relNode[2];
00887 nodeIDs[2] = conn[relNode[2]];
00888 nodeIDs[3] = conn[relNode[3]];
00889 }
00890
00891 void fillNodes(int *relNode, int n1, int n2, int *conn)
00892 {
00893
00894
00895
00896
00897
00898
00899
00900 for (int i=0; i<4; i++) {
00901 if (conn[i] == n1)
00902 relNode[0] = i;
00903 else if (conn[i] == n2)
00904 relNode[1] = i;
00905 }
00906 if ((relNode[0] != 0) && (relNode[1] != 0))
00907 relNode[2] = 0;
00908 else if ((relNode[0] != 1) && (relNode[1] != 1))
00909 relNode[2] = 1;
00910 else relNode[2] = 2;
00911 relNode[3] = 6 - relNode[0] - relNode[1] - relNode[2];
00912 }
00913
00915 adaptAdj *BulkAdapt::local_split_3D(adaptAdj elem, int n1, int n2, int n5)
00916 {
00917 CkPrintf("[%d] BEGIN local_split_3D\n", partitionID);
00918 int nElems = meshPtr->lookup(FEM_ELEM+elem.elemType,"BulkAdapt::local_split_3D")->size();
00919 int nNodes=meshPtr->lookup(FEM_NODE,"BulkAdapt::local_split_3D")->size();
00920 CkAssert(elem.localID < nElems);
00921 CkAssert((n1 < nNodes) && (n1 >= 0));
00922 CkAssert((n2 < nNodes) && (n2 >= 0));
00923 CkAssert((n5 < nNodes) && (n5 >= 0));
00924
00925
00926 FEM_Elem &elems = meshPtr->elem[elem.elemType];
00927 int *conn = elems.connFor(elem.localID);
00928
00929 int splitConn[4];
00930 memcpy(&splitConn[0], conn, 4*sizeof(int));
00931
00932 int rel_n1 = -1, rel_n2 = -1;
00933 for (int i=0; i<4; i++) {
00934 if (conn[i] == n1) rel_n1 = i;
00935 if (conn[i] == n2) rel_n2 = i;
00936 }
00937 CkAssert((rel_n1 != -1) && (rel_n2 != -1));
00938
00939 CkPrintf("[%d] elem %d conn was %d,%d,%d,%d\n", partitionID, elem.localID, conn[0], conn[1], conn[2], conn[3]);
00940 CkPrintf("[%d] old edge is %d,%d, inserting node %d in between\n", partitionID, n1, n2, n5);
00941 conn[rel_n2] = n5;
00942 CkPrintf("[%d] modifying elem %d to be %d,%d,%d,%d\n", partitionID, elem.localID, conn[0], conn[1], conn[2], conn[3]);
00943
00944 splitConn[rel_n1] = n5;
00945
00946 int splitElemID = add_element(elem.elemType, 4, &splitConn[0], elems.getMeshSizing(elem.localID));
00947 CkPrintf("[%d] Adding elem %d with conn %d,%d,%d,%d\n", partitionID, splitElemID, splitConn[0], splitConn[1], splitConn[2], splitConn[3]);
00948 adaptAdj *splitElem = new adaptAdj(partitionID, splitElemID, elem.elemType);
00949
00950 update_local_face_adj(elem, *splitElem, n1, n2, n5);
00951 update_local_edge_adj(elem, *splitElem, n1, n2, n5);
00952 CkPrintf("[%d] END local_split_3D\n", partitionID);
00953 return splitElem;
00954 }
00955
00956 void BulkAdapt::local_update_asterisk_3D(int i, adaptAdj elem, int numElemPairs,
00957 adaptAdj *elemPairs,
00958 int n1, int n2, int n5)
00959 {
00960 FEM_Elem &elems = meshPtr->elem[elem.elemType];
00961 int *conn = elems.connFor(elem.localID);
00962 int n3=-1, n4=-1;
00963 for (int i=0; i<4; i++) {
00964 if ((conn[i] != n1) && (conn[i] != n5) && (n3 == -1))
00965 n3 = conn[i];
00966 else if ((conn[i] != n1) && (conn[i] != n5))
00967 n4 = conn[i];
00968 }
00969
00970 int relNode[4];
00971 relNode[0] = getRelNode(n1, conn, 4);
00972 relNode[1] = getRelNode(n5, conn, 4);
00973 relNode[2] = getRelNode(n3, conn, 4);
00974 relNode[3] = getRelNode(n4, conn, 4);
00975 int face[4];
00976 face[0] = (relNode[0] + relNode[1] + relNode[2]) - 3;
00977 face[1] = (relNode[0] + relNode[1] + relNode[3]) - 3;
00978 face[2] = (relNode[0] + relNode[3] + relNode[2]) - 3;
00979 face[3] = (relNode[1] + relNode[3] + relNode[2]) - 3;
00980 adaptAdj neighbors[4];
00981 neighbors[0] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[0]);
00982 neighbors[1] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[1]);
00983 neighbors[2] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[2]);
00984 neighbors[3] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[3]);
00985
00986 adaptAdj splitElem = neighbors[3], nbr1 = neighbors[0], nbr2 = neighbors[1];
00987 adaptAdj nbr1split(-1,-1,0), nbr2split(-1,-1,0);
00988 int found=0;
00989 if (nbr1.localID != -1) found++;
00990 if (nbr2.localID != -1) found++;
00991 for (int i=0; i<numElemPairs; i++) {
00992 if (elemPairs[2*i] == nbr1) {
00993 nbr1split = elemPairs[2*i+1];
00994 found--;
00995 }
00996 else if (elemPairs[2*i] == nbr2) {
00997 nbr2split = elemPairs[2*i+1];
00998 found--;
00999 }
01000 if (found == 0) break;
01001 }
01002 int *splitConn = elems.connFor(splitElem.localID);
01003 int splitRelNode[4];
01004 splitRelNode[0] = getRelNode(n5, splitConn, 4);
01005 splitRelNode[1] = getRelNode(n2, splitConn, 4);
01006 splitRelNode[2] = getRelNode(n3, splitConn, 4);
01007 splitRelNode[3] = getRelNode(n4, splitConn, 4);
01008 int splitFace[4];
01009 splitFace[0] = (splitRelNode[0] + splitRelNode[1] + splitRelNode[2]) - 3;
01010 splitFace[1] = (splitRelNode[0] + splitRelNode[1] + splitRelNode[3]) - 3;
01011 splitFace[2] = (splitRelNode[0] + splitRelNode[3] + splitRelNode[2]) - 3;
01012 splitFace[3] = (splitRelNode[1] + splitRelNode[3] + splitRelNode[2]) - 3;
01013
01014
01015 replaceAdaptAdj(meshPtr, splitElem, nbr1, nbr1split);
01016 replaceAdaptAdj(meshPtr, splitElem, nbr2, nbr2split);
01017
01018
01019 int n3_n5, n4_n5;
01020
01021 int n5_n2, n5_n3, n5_n4, n2_n3, n2_n4;
01022
01023 n3_n5 = getEdgeID(relNode[2], relNode[1], 4, 3);
01024 n4_n5 = getEdgeID(relNode[3], relNode[1], 4, 3);
01025 n5_n2 = getEdgeID(splitRelNode[0], splitRelNode[1], 4, 3);
01026 n5_n3 = getEdgeID(splitRelNode[0], splitRelNode[2], 4, 3);
01027 n5_n4 = getEdgeID(splitRelNode[0], splitRelNode[3], 4, 3);
01028 n2_n3 = getEdgeID(splitRelNode[1], splitRelNode[2], 4, 3);
01029 n2_n4 = getEdgeID(splitRelNode[1], splitRelNode[3], 4, 3);
01030
01031 clearEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5);
01032 clearEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5);
01033 clearEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n2);
01034 clearEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3);
01035 clearEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4);
01036
01037 addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5, splitElem);
01038 if (nbr1.localID != -1) {
01039 addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5, nbr1);
01040 addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5, nbr1split);
01041 }
01042
01043 addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5, splitElem);
01044 if (nbr2.localID != -1) {
01045 addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5, nbr2);
01046 addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5, nbr2split);
01047 }
01048
01049 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3, elem);
01050 if (nbr1.localID != -1) {
01051 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3, nbr1);
01052 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3, nbr1split);
01053 }
01054
01055 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4, elem);
01056 if (nbr2.localID != -1) {
01057 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4, nbr2);
01058 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4, nbr2split);
01059 }
01060
01061 for (int i=0; i<numElemPairs; i++) {
01062 if (splitElem != elemPairs[2*i+1]) {
01063 addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n2,
01064 elemPairs[2*i+1]);
01065 }
01066 }
01067
01068 if(nbr1.localID != -1)
01069 replaceAdaptAdjOnEdge(meshPtr, splitElem, nbr1, nbr1split, n2_n3);
01070 if(nbr2.localID != -1)
01071 replaceAdaptAdjOnEdge(meshPtr, splitElem, nbr2, nbr2split, n2_n4);
01072 }
01073
01074
01076 void BulkAdapt::update_local_face_adj(adaptAdj elem, adaptAdj splitElem,
01077 int n1, int n2, int n5)
01078 {
01079
01080 CmiMemoryCheck();
01081 copyAdaptAdj(meshPtr, &elem, &splitElem);
01082
01083 FEM_Elem &elems = meshPtr->elem[elem.elemType];
01084 int *conn = elems.connFor(elem.localID);
01085 int n3=-1, n4=-1;
01086 for (int i=0; i<4; i++) {
01087 if ((conn[i] != n1) && (conn[i] != n5) && (n3 == -1))
01088 n3 = conn[i];
01089 else if ((conn[i] != n1) && (conn[i] != n5))
01090 n4 = conn[i];
01091 }
01092
01093 int relNode[4];
01094 relNode[0] = getRelNode(n1, conn, 4);
01095 relNode[1] = getRelNode(n5, conn, 4);
01096 relNode[2] = getRelNode(n3, conn, 4);
01097 relNode[3] = getRelNode(n4, conn, 4);
01098 int face[4];
01099 face[0] = (relNode[0] + relNode[1] + relNode[2]) - 3;
01100 face[1] = (relNode[0] + relNode[1] + relNode[3]) - 3;
01101 face[2] = (relNode[0] + relNode[3] + relNode[2]) - 3;
01102 face[3] = (relNode[1] + relNode[3] + relNode[2]) - 3;
01103 adaptAdj neighbors[4];
01104 neighbors[0] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[0]);
01105 neighbors[1] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[1]);
01106 neighbors[2] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[2]);
01107 neighbors[3] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[3]);
01108
01109
01110 setAdaptAdj(meshPtr, elem, face[3], splitElem);
01111
01112
01113 setAdaptAdj(meshPtr, splitElem, face[2], elem);
01114
01115
01116 if (neighbors[3].partID == elem.partID) {
01117 replaceAdaptAdj(meshPtr, neighbors[3], elem, splitElem);
01118 }
01119 else if (neighbors[3].partID != -1) {
01120 shadowProxy[neighbors[3].partID].remote_adaptAdj_replace(neighbors[3], elem, splitElem);
01121 }
01122 }
01123
01125 void BulkAdapt::update_local_edge_adj(adaptAdj elem, adaptAdj splitElem,
01126 int n1, int n2, int n5)
01127 {
01128 copyEdgeAdaptAdj(meshPtr, &elem, &splitElem);
01129
01130 CkVec<adaptAdj> *elemEdgeAdj[6];
01131 CkVec<adaptAdj> *splitElemEdgeAdj[6];
01132 for (int i=0; i<6; i++) {
01133 elemEdgeAdj[i] = getEdgeAdaptAdj(meshPtr, elem.localID, elem.elemType, i);
01134 splitElemEdgeAdj[i] = getEdgeAdaptAdj(meshPtr, splitElem.localID, splitElem.elemType, i);
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157 FEM_Elem &elems = meshPtr->elem[splitElem.elemType];
01158 int *conn = elems.connFor(splitElem.localID);
01159 int n3=-1, n4=-1;
01160 for (int i=0; i<4; i++) {
01161 if ((conn[i] != n5) && (conn[i] != n2) && (n3 == -1))
01162 n3 = conn[i];
01163 else if ((conn[i] != n5) && (conn[i] != n2))
01164 n4 = conn[i];
01165 }
01166
01167 int relNode[4];
01168 relNode[0] = getRelNode(n5, conn, 4);
01169 relNode[1] = getRelNode(n2, conn, 4);
01170 relNode[2] = getRelNode(n3, conn, 4);
01171 relNode[3] = getRelNode(n4, conn, 4);
01172
01173
01174 int n2_n3 = getEdgeID(relNode[1], relNode[2], 4, 3);
01175 int n2_n4 = getEdgeID(relNode[1], relNode[3], 4, 3);
01176 int n3_n4 = getEdgeID(relNode[2], relNode[3], 4, 3);
01177 int n3_n5 = getEdgeID(relNode[2], relNode[0], 4, 3);
01178 int n4_n5 = getEdgeID(relNode[3], relNode[0], 4, 3);
01179
01180
01181 int *elemConn = elems.connFor(elem.localID);
01182
01183 int elem_relNode[4];
01184 elem_relNode[0] = getRelNode(n1, elemConn, 4);
01185 elem_relNode[1] = getRelNode(n5, elemConn, 4);
01186 elem_relNode[2] = getRelNode(n3, elemConn, 4);
01187 elem_relNode[3] = getRelNode(n4, elemConn, 4);
01188
01189
01190 int elem_n3_n4 = getEdgeID(relNode[2], relNode[3], 4, 3);
01191 int elem_n3_n5 = getEdgeID(relNode[2], relNode[1], 4, 3);
01192 int elem_n4_n5 = getEdgeID(relNode[3], relNode[1], 4, 3);
01193
01194
01195 int face[4];
01196 face[0] = (elem_relNode[0] + elem_relNode[1] + elem_relNode[2]) - 3;
01197 face[1] = (elem_relNode[0] + elem_relNode[1] + elem_relNode[3]) - 3;
01198
01199 adaptAdj elem_neighbors[4];
01200 elem_neighbors[0] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[0]);
01201 elem_neighbors[1] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[1]);
01202
01203
01204
01205 for (int i=0; i<elemEdgeAdj[elem_n3_n5]->size(); i++) {
01206 adaptAdj adj = (*elemEdgeAdj[elem_n3_n5])[i];
01207 if ((adj != elem_neighbors[0]) && (adj != elem_neighbors[1])) {
01208 if (adj.partID == splitElem.partID) {
01209 int *adjConn = elems.connFor(adj.localID);
01210
01211 int r2, r3;
01212 r2 = getRelNode(n2, adjConn, 4);
01213 r3 = getRelNode(n3, adjConn, 4);
01214
01215 int edgeID = getEdgeID(r2, r3, 4, 3);
01216 replaceAdaptAdjOnEdge(meshPtr, adj, elem, splitElem, edgeID);
01217 }
01218 else if (adj.partID != -1) {
01219 int n2_idxl = get_idxl_for_node(n2, adj.partID);
01220 int n3_idxl = get_idxl_for_node(n3, adj.partID);
01221
01222 shadowProxy[adj.partID].remote_edgeAdj_replace(partitionID, adj, elem,
01223 splitElem, n2_idxl, n3_idxl);
01224 }
01225 }
01226 }
01227
01228
01229 for (int i=0; i<elemEdgeAdj[elem_n4_n5]->size(); i++) {
01230 adaptAdj adj = (*elemEdgeAdj[elem_n4_n5])[i];
01231 if ((adj != elem_neighbors[0]) && (adj != elem_neighbors[1])) {
01232 if (adj.partID == splitElem.partID) {
01233 int *adjConn = elems.connFor(adj.localID);
01234
01235 int r2, r4;
01236 r2 = getRelNode(n2, adjConn, 4);
01237 r4 = getRelNode(n4, adjConn, 4);
01238
01239 int edgeID = getEdgeID(r2, r4, 4, 3);
01240 replaceAdaptAdjOnEdge(meshPtr, adj, elem, splitElem, edgeID);
01241 }
01242 else if (adj.partID != -1) {
01243 int n2_idxl = get_idxl_for_node(n2, adj.partID);
01244 int n4_idxl = get_idxl_for_node(n4, adj.partID);
01245
01246 shadowProxy[adj.partID].remote_edgeAdj_replace(partitionID, adj, elem,
01247 splitElem, n2_idxl, n4_idxl);
01248 }
01249 }
01250 }
01251
01252
01253
01254
01255
01256
01257 for (int i=0; i<elemEdgeAdj[elem_n3_n4]->size(); i++) {
01258 adaptAdj adj = (*elemEdgeAdj[elem_n3_n4])[i];
01259 if (adj.partID == splitElem.partID) {
01260 int *adjConn = elems.connFor(adj.localID);
01261
01262 int r3, r4;
01263 r3 = getRelNode(n3, adjConn, 4);
01264 r4 = getRelNode(n4, adjConn, 4);
01265
01266 int edgeID = getEdgeID(r3, r4, 4, 3);
01267 addToAdaptAdj(meshPtr, adj, edgeID, splitElem);
01268 }
01269 else if (adj.partID != -1) {
01270 int n3_idxl = get_idxl_for_node(n3, adj.partID);
01271 int n4_idxl = get_idxl_for_node(n4, adj.partID);
01272 shadowProxy[adj.partID].remote_edgeAdj_add(partitionID, adj, splitElem,
01273 n3_idxl, n4_idxl);
01274 }
01275 }
01276 addToAdaptAdj(meshPtr, splitElem, n3_n4, elem);
01277 addToAdaptAdj(meshPtr, elem, elem_n3_n4, splitElem);
01278
01279 }
01280