00001 #include "tri.h"
00002 #include "edge.h"
00003
00004 void edge::reset()
00005 {
00006 newNodeIdx = incidentNode = fixNode = -1;
00007 if (!(newEdgeRef == nullRef))
00008 C->theEdges[newEdgeRef.idx].reset();
00009 unsetPending(); waitingFor.reset(); newEdgeRef.reset();
00010 newNode.reset();
00011 }
00012
00013 int edge::isPending(elemRef e)
00014 {
00015 return (pending && (waitingFor == e));
00016 }
00017
00018 void edge::checkPending(elemRef e)
00019 {
00020 elemRef nullRef;
00021 if (pending && (waitingFor == e) && !(e == nullRef))
00022 mesh[e.cid].refineElement(e.idx, e.getArea());
00023 }
00024
00025 void edge::checkPending(elemRef e, elemRef ne)
00026 {
00027 elemRef nullRef;
00028 if (pending && (waitingFor == e) && !(e == nullRef)) {
00029 waitingFor = ne;
00030 mesh[ne.cid].refineElement(ne.idx, ne.getArea());
00031 }
00032 }
00033
00034 int edge::split(int *m, edgeRef *e_prime, int oIdx, int fIdx,
00035 elemRef requester, int *local, int *first, int *nullNbr)
00036 {
00037
00038
00039
00040
00041
00042 intMsg *im;
00043 elemRef nbr = getNot(requester), nullRef;
00044 nullRef.reset();
00045
00046 if (requester.cid != myRef.cid) {
00047 FEM_Node *theNodes = &(C->meshPtr->node);
00048 const FEM_Comm_List *sharedList = &(theNodes->shared.getList(requester.cid));
00049 oIdx = (*sharedList)[oIdx];
00050 fIdx = (*sharedList)[fIdx];
00051 }
00052 #ifdef TDEBUG3
00053 CkPrintf("TMRC2D: [%d] oIdx=%d fIdx=%d ", myRef.cid, oIdx, fIdx);
00054 CkPrintf("\ntheNodes[oIdx]="); C->theNodes[oIdx].dump();
00055 CkPrintf("\ntheNodes[fIdx]="); C->theNodes[fIdx].dump();
00056 CkPrintf("\n");
00057 CkPrintf("TMRC2D: [%d] node[0]=%d node[1]=%d ",myRef.cid,nodes[0],nodes[1]);
00058 CkPrintf("\ncoords of node[0]="); C->theNodes[nodes[0]].dump();
00059 CkPrintf("\ncoords of node[1]="); C->theNodes[nodes[1]].dump();
00060 CkPrintf("\n");
00061 CkAssert((oIdx == nodes[0]) || (oIdx == nodes[1]));
00062 CkAssert((fIdx == nodes[0]) || (fIdx == nodes[1]));
00063 #endif
00064 if (pending && (waitingFor == requester)) {
00065
00066 #ifdef TDEBUG1
00067 CkPrintf("TMRC2D: [%d] edge::split: ** PART 2! ** On edge=%d on chunk=%d, requester=(%d,%d) with nbr=(%d,%d)\n", myRef.cid, myRef.idx, myRef.cid, requester.cid, requester.idx, nbr.cid, nbr.idx);
00068 #endif
00069 *m = newNodeIdx;
00070 *e_prime = newEdgeRef;
00071 *first = 0;
00072 *local = 1;
00073 if (nbr.cid != requester.cid) {
00074 *local = 0;
00075 im = mesh[requester.cid].addNode(newNode, C->theNodes[nodes[0]].boundary,
00076 C->theNodes[nodes[1]].boundary, 1);
00077 *m = im->anInt;
00078 CkFreeMsg(im);
00079 #ifdef TDEBUG2
00080 CkPrintf("TMRC2D: [%d] New node (%f,%f) added at index %d on chunk %d\n", myRef.cid, newNode.X(), newNode.Y(), *m, myRef.cid);
00081 #endif
00082 }
00083 int nLoc = newNodeIdx;
00084 if (requester.cid == myRef.cid) {
00085 nLoc = *m;
00086 C->theEdges[newEdgeRef.idx].updateNode(newNodeIdx, nLoc);
00087 }
00088 if (oIdx == incidentNode) {
00089 if (nodes[0] == oIdx) {
00090 nodes[0] = nLoc;
00091 #ifdef TDEBUG2
00092 CkPrintf("TMRC2D: [%d] Edge %d node[0] updated to %d\n", myRef.cid,
00093 myRef.idx, nLoc);
00094 #endif
00095 }
00096 else if (nodes[1] == oIdx) {
00097 nodes[1] = nLoc;
00098 #ifdef TDEBUG2
00099 CkPrintf("TMRC2D: [%d] Edge %d node[1] updated to %d\n", myRef.cid,
00100 myRef.idx, nLoc);
00101 #endif
00102 }
00103 else CkAbort("ERROR: incident node not found on edge\n");
00104 return 1;
00105 }
00106 else {
00107 CkAssert(fIdx == incidentNode);
00108 if (nodes[0] == fIdx) {
00109 nodes[0] = nLoc;
00110 #ifdef TDEBUG2
00111 CkPrintf("TMRC2D: [%d] Edge %d node[0] updated to %d\n", myRef.cid,
00112 myRef.idx, nLoc);
00113 #endif
00114 }
00115 else if (nodes[1] == fIdx) {
00116 nodes[1] = nLoc;
00117 #ifdef TDEBUG2
00118 CkPrintf("TMRC2D: [%d] Edge %d node[1] updated to %d\n", myRef.cid,
00119 myRef.idx, nLoc);
00120 #endif
00121 }
00122 else CkAbort("ERROR: incident node not found on edge\n");
00123 return 0;
00124 }
00125 }
00126 else if (pending) {
00127 #ifdef TDEBUG1
00128 CkPrintf("TMRC2D: [%d] edge::split: ** Pending on (%d,%d)! ** On edge=%d on chunk=%d, requester=%d on chunk=%d\n", myRef.cid, waitingFor.cid, waitingFor.idx, myRef.idx, myRef.cid, requester.idx, requester.cid);
00129 #endif
00130 return -1;
00131 }
00132 else {
00133 #ifdef TDEBUG1
00134 CkPrintf("TMRC2D: [%d] edge::split: ** PART 1! ** On edge=%d on chunk=%d, requester==(%d,%d) with nbr=(%d,%d)\n", myRef.cid, myRef.idx, myRef.cid, requester.cid, requester.idx, nbr.cid, nbr.idx);
00135 #endif
00136 setPending();
00137 C->theNodes[oIdx].midpoint(C->theNodes[fIdx], newNode);
00138 im = mesh[requester.cid].addNode(newNode, C->theNodes[nodes[0]].boundary,
00139 C->theNodes[nodes[1]].boundary, (nbr.cid != -1));
00140 newNodeIdx = im->anInt;
00141 CkFreeMsg(im);
00142 #ifdef TDEBUG2
00143 CkPrintf("TMRC2D: [%d] New node (%f,%f) added at index %d on chunk %d\n", myRef.cid, newNode.X(), newNode.Y(), newNodeIdx, requester.cid);
00144 #endif
00145 newEdgeRef = C->addEdge(newNodeIdx, oIdx, boundary);
00146 #ifdef TDEBUG2
00147 CkPrintf("TMRC2D: [%d] New edge (%d,%d) added between nodes (%f,%f) and newNode\n", myRef.cid, newEdgeRef.cid, newEdgeRef.idx, C->theNodes[oIdx].X(), C->theNodes[oIdx].Y());
00148 #endif
00149 incidentNode = oIdx;
00150 fixNode = fIdx;
00151 *m = newNodeIdx;
00152 *e_prime = newEdgeRef;
00153 *first = 1;
00154 if ((nbr.cid == requester.cid) || (nbr.cid == -1)) *local = 1;
00155 else *local = 0;
00156 C->theEdges[newEdgeRef.idx].setPending();
00157 *nullNbr = 0;
00158 if (nbr == nullRef) *nullNbr = 1;
00159 if (nbr.cid != -1) {
00160 waitingFor = nbr;
00161 double nbrArea = nbr.getArea();
00162 mesh[nbr.cid].refineElement(nbr.idx, nbrArea);
00163 }
00164 else {
00165 if (nodes[0] == oIdx) {
00166 nodes[0] = newNodeIdx;
00167 #ifdef TDEBUG2
00168 CkPrintf("TMRC2D: [%d] Edge %d node[0] updated to %d\n", myRef.cid,
00169 myRef.idx, newNodeIdx);
00170 #endif
00171 }
00172 else if (nodes[1] == oIdx) {
00173 nodes[1] = newNodeIdx;
00174 #ifdef TDEBUG2
00175 CkPrintf("TMRC2D: [%d] Edge %d node[1] updated to %d\n", myRef.cid,
00176 myRef.idx, newNodeIdx);
00177 #endif
00178 }
00179 else CkAbort("ERROR: incident node not found on edge\n");
00180 }
00181 return 1;
00182 }
00183 }
00184
00185 void edge::collapse(elemRef requester, int kIdx, int dIdx, elemRef kNbr,
00186 elemRef dNbr, edgeRef kEdge, edgeRef dEdge, node newN,
00187 double frac)
00188 {
00189 int local, first, dIdxlShared, kIdxlShared;
00190 elemRef nbr = getNot(requester);
00191 FEM_Comm_Rec *dNodeRec, *kNodeRec;
00192
00193 translateSharedNodeIDs(&kIdx, &dIdx, requester);
00194
00195 local = 0;
00196 if ((nbr.cid == -1) || (nbr.cid == requester.cid)) local = 1;
00197 if (pending && (waitingFor == requester)) {
00198 #ifdef TDEBUG1
00199 CkPrintf("TMRC2D: [%d] edge::collapse: PART 2: On edge=%d on chunk=%d, requester=(%d,%d) with nbr=(%d,%d) dIdx=%d kIdx=%d dNbr=%d kNbr=%d dEdge=%d kEdge=%d\n", myRef.cid, myRef.idx, myRef.cid, requester.cid, requester.idx, nbr.cid, nbr.idx, dIdx, kIdx, dNbr.idx, kNbr.idx, dEdge.idx, kEdge.idx);
00200 #endif
00201 first = 0;
00202 if (dIdx == incidentNode) {
00203 localCollapse(kIdx, dIdx, &requester, &newNode, frac, &kNbr, &dNbr,
00204 &kEdge, &dEdge, local, first);
00205 updateCloud(kIdx, dIdx, newNode, &dIdxlShared, &kIdxlShared, &dNodeRec,
00206 &kNodeRec);
00207 unlockCloudRemoveEdge(dIdxlShared, kIdxlShared, dNodeRec, kNodeRec);
00208 }
00209 else {
00210 localCollapse(dIdx, kIdx, &requester, &newNode, frac, &dNbr, &kNbr,
00211 &dEdge, &kEdge, local, first);
00212 updateCloud(dIdx, kIdx, newNode, &dIdxlShared, &kIdxlShared, &dNodeRec,
00213 &kNodeRec);
00214 unlockCloudRemoveEdge(dIdxlShared, kIdxlShared, dNodeRec, kNodeRec);
00215 }
00216 }
00217 else if (pending) {
00218 #ifdef TDEBUG1
00219 CkPrintf("TMRC2D: [%d] edge::collapse: Pending on (%d,%d): On edge=%d on chunk=%d, requester=%d on chunk=%d\n", myRef.cid, waitingFor.cid, waitingFor.idx, myRef.idx, myRef.cid, requester.idx, requester.cid);
00220 #endif
00221 }
00222 else {
00223 first = 1;
00224 if (!buildLockingCloud(kIdx, dIdx, &requester, &nbr)) return;
00225 #ifdef TDEBUG1
00226 CkPrintf("TMRC2D: [%d] edge::collapse: PART 1: On edge=%d on chunk=%d, requester==(%d,%d) with nbr=(%d,%d) dIdx=%d kIdx=%d dNbr=%d kNbr=%d dEdge=%d kEdge=%d\n", myRef.cid, myRef.idx, myRef.cid, requester.cid, requester.idx, nbr.cid, nbr.idx, dIdx, kIdx, dNbr.idx, kNbr.idx, dEdge.idx, kEdge.idx);
00227 #endif
00228 setPending();
00229 incidentNode = dIdx; fixNode = kIdx;
00230 newNode = newN;
00231 localCollapse(kIdx, dIdx, &requester, &newNode, frac, &kNbr, &dNbr,
00232 &kEdge, &dEdge, local, first);
00233 if (nbr.cid > -1) {
00234 waitingFor = nbr;
00235 double nbrArea = nbr.getArea();
00236 CkPrintf("Calling coarsen on neighbor element[%d] with area=%1.10e\n",
00237 nbr.idx, 2.0*nbrArea);
00238 mesh[nbr.cid].coarsenElement(nbr.idx, 2.0*nbrArea);
00239 }
00240 else {
00241 updateCloud(kIdx, dIdx, newNode, &dIdxlShared, &kIdxlShared, &dNodeRec,
00242 &kNodeRec);
00243 unlockCloudRemoveEdge(dIdxlShared, kIdxlShared, dNodeRec, kNodeRec);
00244 }
00245 }
00246 }
00247
00248 int edge::flipPrevent(elemRef requester, int kIdx, int dIdx, elemRef kNbr,
00249 elemRef dNbr, edgeRef kEdge, edgeRef dEdge, node newN)
00250 {
00251 int i,j, lk, chunk, dIdxlShared, kIdxlShared;
00252 int *dIdxlChk, *dIdxlIdx, *kIdxlChk, *kIdxlIdx;
00253 boolMsg *ret;
00254
00255 length = (C->theNodes[kIdx]).distance(C->theNodes[dIdx]);
00256 FEM_Node *theNodes = &(C->meshPtr->node);
00257 FEM_Comm_Rec *dNodeRec=(FEM_Comm_Rec *)(theNodes->shared.getRec(dIdx));
00258 FEM_Comm_Rec *kNodeRec=(FEM_Comm_Rec *)(theNodes->shared.getRec(kIdx));
00259 intMsg *im;
00260 lk = C->lockLocalChunk(myRef.cid, myRef.idx, length);
00261 if (dNodeRec) dIdxlShared = dNodeRec->getShared();
00262 else dIdxlShared = 0;
00263 if (kNodeRec) kIdxlShared = kNodeRec->getShared();
00264 else kIdxlShared = 0;
00265 if (!(C->lockLocalChunk(myRef.cid, myRef.idx, length)))
00266 return -1;
00267 for (i=0; i<dIdxlShared; i++) {
00268 chunk = dNodeRec->getChk(i);
00269 im = mesh[chunk].lockChunk(myRef.cid, myRef.idx, length);
00270 if (im->anInt == 0) {
00271 CkFreeMsg(im);
00272 C->unlockLocalChunk(myRef.cid, myRef.idx);
00273 for (j=0; j<i; j++) {
00274 chunk = dNodeRec->getChk(j);
00275 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00276 }
00277 return -1;
00278 }
00279 }
00280 for (i=0; i<kIdxlShared; i++) {
00281 chunk = kNodeRec->getChk(i);
00282 im = mesh[chunk].lockChunk(myRef.cid, myRef.idx, length);
00283 if (im->anInt == 0) {
00284 CkFreeMsg(im);
00285 C->unlockLocalChunk(myRef.cid, myRef.idx);
00286 for (j=0; j<dIdxlShared; j++) {
00287 chunk = dNodeRec->getChk(j);
00288 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00289 }
00290 for (j=0; j<i; j++) {
00291 chunk = kNodeRec->getChk(j);
00292 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00293 }
00294 return -1;
00295 }
00296 }
00297 fixNode = kIdx;
00298 newNode = newN;
00299
00300 theNodes = &(C->meshPtr->node);
00301 dNodeRec=(FEM_Comm_Rec *)(theNodes->shared.getRec(dIdx));
00302 kNodeRec=(FEM_Comm_Rec *)(theNodes->shared.getRec(kIdx));
00303
00304 if (dNodeRec) dIdxlShared = dNodeRec->getShared();
00305 else dIdxlShared = 0;
00306 if (kNodeRec) kIdxlShared = kNodeRec->getShared();
00307 else kIdxlShared = 0;
00308 dIdxlChk = (int *)malloc((dIdxlShared+1)*sizeof(int));
00309 kIdxlChk = (int *)malloc((kIdxlShared+1)*sizeof(int));
00310 dIdxlIdx = (int *)malloc((dIdxlShared+1)*sizeof(int));
00311 kIdxlIdx = (int *)malloc((kIdxlShared+1)*sizeof(int));
00312 for (i=0; i<dIdxlShared; i++) {
00313 dIdxlIdx[i] = dNodeRec->getIdx(i);
00314 dIdxlChk[i] = dNodeRec->getChk(i);
00315 }
00316 dIdxlIdx[dIdxlShared] = dIdx;
00317 dIdxlChk[dIdxlShared] = myRef.cid;
00318 for (i=0; i<kIdxlShared; i++) {
00319 kIdxlIdx[i] = kNodeRec->getIdx(i);
00320 kIdxlChk[i] = kNodeRec->getChk(i);
00321 }
00322 kIdxlIdx[kIdxlShared] = kIdx;
00323 kIdxlChk[kIdxlShared] = myRef.cid;
00324 ret = C->flipPrevent(kIdx, dIdx, newNode, dIdxlShared, dIdxlChk, dIdxlIdx);
00325 for (i=0; i<dIdxlShared; i++) {
00326 chunk = dNodeRec->getChk(i);
00327 if (kNodeRec && ((j=existsOn(kNodeRec, chunk)) >= 0)) {
00328 ret = mesh[chunk].flipPrevent(kNodeRec->getIdx(j), dNodeRec->getIdx(i), newNode, dIdxlShared, dIdxlChk, dIdxlIdx);
00329 }
00330 else {
00331 ret = mesh[chunk].flipPrevent(-1, dNodeRec->getIdx(i), newNode, kIdxlShared, kIdxlChk, kIdxlIdx);
00332 }
00333 }
00334 for (i=0; i<kIdxlShared; i++) {
00335 chunk = kNodeRec->getChk(i);
00336 if (!dNodeRec || (existsOn(dNodeRec, chunk) == -1)) {
00337 ret = mesh[chunk].flipPrevent(kNodeRec->getIdx(i), -1, newNode, dIdxlShared, dIdxlChk, dIdxlIdx);
00338 }
00339 }
00340
00341 C->unlockLocalChunk(myRef.cid, myRef.idx);
00342 for (i=0; i<dIdxlShared; i++) {
00343 chunk = dNodeRec->getChk(i);
00344 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00345 }
00346 for (i=0; i<kIdxlShared; i++) {
00347 chunk = kNodeRec->getChk(i);
00348 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00349 }
00350 if(ret->aBool) return -1;
00351 return 1;
00352 }
00353
00354 void edge::translateSharedNodeIDs(int *kIdx, int *dIdx, elemRef req)
00355 {
00356 if (req.cid != myRef.cid) {
00357 FEM_Node *theNodes = &(C->meshPtr->node);
00358 const FEM_Comm_List *sharedList = &(theNodes->shared.getList(req.cid));
00359 (*kIdx) = (*sharedList)[(*kIdx)];
00360 (*dIdx) = (*sharedList)[(*dIdx)];
00361 }
00362 #ifdef TDEBUG3
00363 CkPrintf("TMRC2D: [%d] kIdx=%d dIdx=%d\n", myRef.cid, *kIdx, *dIdx);
00364 #endif
00365 }
00366
00367 void edge::unlockCloudRemoveEdge(int dIdxlShared, int kIdxlShared,
00368 FEM_Comm_Rec *dNodeRec, FEM_Comm_Rec *kNodeRec)
00369 {
00370 int chunk;
00371 C->unlockLocalChunk(myRef.cid, myRef.idx);
00372 for (int i=0; i<dIdxlShared; i++) {
00373 chunk = dNodeRec->getChk(i);
00374 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00375 }
00376 for (int i=0; i<kIdxlShared; i++) {
00377 chunk = kNodeRec->getChk(i);
00378 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00379 }
00380 #ifdef TDEBUG2
00381 CkPrintf("TMRC2D: [%d] ......removing edge %d on %d\n", myRef.cid,
00382 myRef.idx, myRef.cid);
00383 #endif
00384 C->removeEdge(myRef.idx);
00385 }
00386
00387 void edge::localCollapse(int kIdx, int dIdx, elemRef *req, node *newNode,
00388 double frac, elemRef *keepNbr, elemRef *delNbr,
00389 edgeRef *kEdge, edgeRef *dEdge, int local, int first)
00390 {
00391 int b = 0, flag;
00392
00393 if (delNbr->cid != -1) {
00394 CkPrintf("Telling delNbr %d to replace dEdge %d with kEdge %d\n",
00395 delNbr->idx, dEdge->idx, kEdge->idx);
00396 mesh[delNbr->cid].updateElementEdge(delNbr->idx, *dEdge, *kEdge);
00397 b = dEdge->getBoundary();
00398 }
00399
00400 CkPrintf("Telling keepEdge %d to replace requester %d with delNbr %d\n",
00401 kEdge->idx, req->idx, delNbr->idx);
00402 kEdge->update(*req, *delNbr, b);
00403
00404 dEdge->remove();
00405 if ((delNbr->cid == -1) && (keepNbr->cid == -1))
00406 kEdge->remove();
00407
00408 if (local && first) flag = LOCAL_FIRST;
00409 if (local && !first) flag = LOCAL_SECOND;
00410 if (!local && first) flag = BOUND_FIRST;
00411 if (!local && !first) flag = BOUND_SECOND;
00412 C->theClient->collapse(req->idx, kIdx, dIdx, newNode->X(), newNode->Y(),
00413 flag, b, frac);
00414 #ifdef TDEBUG1
00415 CkPrintf("TMRC2D: [%d] theClient->collapse(%d, %d, %d, %2.10f, %2.10f, (flag), %d, %1.1f\n", req->cid, req->idx, kIdx, dIdx, newNode->X(), newNode->Y(), b, frac);
00416 #endif
00417 }
00418
00419 int edge::buildLockingCloud(int kIdx, int dIdx, elemRef *req, elemRef *nbr)
00420 {
00421
00422 double length;
00423 int dIdxlShared, kIdxlShared, chunk;
00424 length = (C->theNodes[kIdx]).distance(C->theNodes[dIdx]);
00425 #ifdef TDEBUG2
00426 CkPrintf("TMRC2D: [%d] ......Building lock cloud... edge=%d requester=%d nbr=%d\n", myRef.cid, myRef.idx, req->idx, nbr->idx);
00427 #endif
00428 FEM_Node *theNodes = &(C->meshPtr->node);
00429 FEM_Comm_Rec *dNodeRec=(FEM_Comm_Rec *)(theNodes->shared.getRec(dIdx));
00430 FEM_Comm_Rec *kNodeRec=(FEM_Comm_Rec *)(theNodes->shared.getRec(kIdx));
00431 intMsg *im;
00432 if (dNodeRec) dIdxlShared = dNodeRec->getShared();
00433 else dIdxlShared = 0;
00434 if (kNodeRec) kIdxlShared = kNodeRec->getShared();
00435 else kIdxlShared = 0;
00436 if (!(C->lockLocalChunk(myRef.cid, myRef.idx, length)))
00437 return 0;
00438 for (int i=0; i<dIdxlShared; i++) {
00439 chunk = dNodeRec->getChk(i);
00440 im = mesh[chunk].lockChunk(myRef.cid, myRef.idx, length);
00441 if (im->anInt == 0) {
00442 CkFreeMsg(im);
00443 C->unlockLocalChunk(myRef.cid, myRef.idx);
00444 for (int j=0; j<i; j++) {
00445 chunk = dNodeRec->getChk(j);
00446 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00447 }
00448 return 0;
00449 }
00450 }
00451 for (int i=0; i<kIdxlShared; i++) {
00452 chunk = kNodeRec->getChk(i);
00453 im = mesh[chunk].lockChunk(myRef.cid, myRef.idx, length);
00454 if (im->anInt == 0) {
00455 CkFreeMsg(im);
00456 C->unlockLocalChunk(myRef.cid, myRef.idx);
00457 for (int j=0; j<dIdxlShared; j++) {
00458 chunk = dNodeRec->getChk(j);
00459 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00460 }
00461 for (int j=0; j<i; j++) {
00462 chunk = kNodeRec->getChk(j);
00463 mesh[chunk].unlockChunk(myRef.cid, myRef.idx);
00464 }
00465 return 0;
00466 }
00467 }
00468 #ifdef TDEBUG2
00469 CkPrintf("TMRC2D: [%d] ......edge::collapse: LOCKS obtained... On edge=%d on chunk=%d, requester==(%d,%d) with nbr=(%d,%d)\n", myRef.cid, myRef.idx, myRef.cid, req->cid, req->idx, nbr->cid, nbr->idx);
00470 #endif
00471 return 1;
00472 }
00473
00474 void edge::updateCloud(int kIdx, int dIdx, node newNode, int *dIdxl,int *kIdxl,
00475 FEM_Comm_Rec **dNodeRec, FEM_Comm_Rec **kNodeRec)
00476 {
00477 int chunk, j;
00478 int *dIdxlChk, *dIdxlIdx, *kIdxlChk, *kIdxlIdx;
00479
00480 FEM_Node *theNodes = &(C->meshPtr->node);
00481 (*dNodeRec) = (FEM_Comm_Rec *)(theNodes->shared.getRec(dIdx));
00482 (*kNodeRec) = (FEM_Comm_Rec *)(theNodes->shared.getRec(kIdx));
00483
00484 if ((*dNodeRec)) (*dIdxl) = (*dNodeRec)->getShared();
00485 else (*dIdxl) = 0;
00486 if ((*kNodeRec)) (*kIdxl) = (*kNodeRec)->getShared();
00487 else (*kIdxl) = 0;
00488 dIdxlChk = (int *)malloc(((*dIdxl)+1)*sizeof(int));
00489 kIdxlChk = (int *)malloc(((*kIdxl)+1)*sizeof(int));
00490 dIdxlIdx = (int *)malloc(((*dIdxl)+1)*sizeof(int));
00491 kIdxlIdx = (int *)malloc(((*kIdxl)+1)*sizeof(int));
00492 for (int i=0; i<(*dIdxl); i++) {
00493 dIdxlIdx[i] = (*dNodeRec)->getIdx(i);
00494 dIdxlChk[i] = (*dNodeRec)->getChk(i);
00495 }
00496 dIdxlIdx[(*dIdxl)] = dIdx;
00497 dIdxlChk[(*dIdxl)] = myRef.cid;
00498 for (int i=0; i<(*kIdxl); i++) {
00499 kIdxlIdx[i] = (*kNodeRec)->getIdx(i);
00500 kIdxlChk[i] = (*kNodeRec)->getChk(i);
00501 }
00502 kIdxlIdx[(*kIdxl)] = kIdx;
00503 kIdxlChk[(*kIdxl)] = myRef.cid;
00504 C->nodeReplaceDelete(kIdx, dIdx, newNode, (*dIdxl), dIdxlChk,
00505 dIdxlIdx);
00506 for (int i=0; i<(*dIdxl); i++) {
00507 chunk = (*dNodeRec)->getChk(i);
00508 if ((*kNodeRec) && ((j=existsOn((*kNodeRec), chunk)) >= 0)) {
00509 mesh[chunk].nodeReplaceDelete((*kNodeRec)->getIdx(j),
00510 (*dNodeRec)->getIdx(i), newNode,
00511 (*dIdxl), dIdxlChk, dIdxlIdx);
00512 }
00513 else {
00514 mesh[chunk].nodeReplaceDelete(-1, (*dNodeRec)->getIdx(i), newNode,
00515 (*kIdxl), kIdxlChk, kIdxlIdx);
00516 }
00517 }
00518 for (int i=0; i<(*kIdxl); i++) {
00519 chunk = (*kNodeRec)->getChk(i);
00520 if (!(*dNodeRec) || (existsOn((*dNodeRec), chunk) == -1)) {
00521 mesh[chunk].nodeReplaceDelete((*kNodeRec)->getIdx(i), -1, newNode,
00522 (*dIdxl), dIdxlChk, dIdxlIdx);
00523 }
00524 }
00525 }
00526
00527 void edge::sanityCheck(chunk *c, edgeRef shouldRef)
00528 {
00529 int nonNullElements=0;
00530 for (int i=0;i<2;i++) {
00531 if (!elements[i].isNull()) {
00532 elements[i].sanityCheck();
00533 nonNullElements++;
00534 }
00535 }
00536 if (nonNullElements == 0)
00537 CkPrintf("TMRC2D: WARNING: Dangling edge found!\n");
00538 }
00539
00540 void edge::sanityCheck(int node1, int node2, int eIdx)
00541 {
00542 CkAssert((node1 == nodes[0]) || (node1 == nodes[1]));
00543 CkAssert((node2 == nodes[0]) || (node2 == nodes[1]));
00544 CkAssert((elements[0].idx == eIdx) || (elements[1].idx == eIdx));
00545 }