00001
00002
00003
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include "tri.h"
00007
00008
00009 CProxy_chunk mesh;
00010 CtvDeclare(chunk *, _refineChunk);
00011
00012 void refineChunkInit(void) {
00013 CtvInitialize(chunk *, _refineChunk);
00014 }
00015
00016 static elemRef nullRef(-1,-1);
00017
00018
00019 void edgeRef::updateElement(chunk *C, elemRef oldval, elemRef newval)
00020 {
00021 if (cid == C->cid)
00022 C->theEdges[idx].updateElement(oldval, newval);
00023 else
00024 mesh[cid].updateElement(idx, oldval, newval);
00025 }
00026
00027 int edgeRef::lock(chunk *C)
00028 {
00029
00030 if (cid == C->cid) {
00031 if (C->theEdges[idx].locked())
00032 return 0;
00033 else {
00034 C->theEdges[idx].lock();
00035 return 1;
00036 }
00037 }
00038 else {
00039 intMsg *im2;
00040 int result;
00041 im2 = mesh[cid].lock(idx);
00042 result = im2->anInt;
00043 CkFreeMsg(im2);
00044 return result;
00045 }
00046 }
00047
00048 void edgeRef::unlock(chunk *C)
00049 {
00050 if (cid == C->cid)
00051 C->theEdges[idx].unlock();
00052 else
00053 mesh[cid].unlock(idx);
00054 }
00055
00056 int edgeRef::locked(chunk *C) const
00057 {
00058 if (cid == C->cid)
00059 return C->theEdges[idx].locked();
00060 else {
00061 intMsg *im2;
00062 int result;
00063 im2 = mesh[cid].locked(idx);
00064 result = im2->anInt;
00065 CkFreeMsg(im2);
00066 return result;
00067 }
00068 }
00069
00070
00071 double elemRef::getArea(chunk *C)
00072 {
00073 if (cid == C->cid)
00074 return C->theElements[idx].getArea();
00075 else {
00076 doubleMsg *dm;
00077 double result;
00078 dm = mesh[cid].getArea(idx);
00079 result = dm->aDouble;
00080 CkFreeMsg(dm);
00081 return result;
00082 }
00083 }
00084
00085 int elemRef::checkIfLongEdge(chunk *C, edgeRef e)
00086 {
00087 if (cid == C->cid)
00088 return C->theElements[idx].checkIfLongEdge(e);
00089 else {
00090 intMsg *im;
00091 int result;
00092 im = mesh[cid].checkElement(e, idx);
00093 result = im->anInt;
00094 CkFreeMsg(im);
00095 return result;
00096 }
00097 }
00098
00099 void elemRef::updateEdges(chunk *C, edgeRef e0, edgeRef e1,
00100 edgeRef e2)
00101 {
00102 if (cid == C->cid)
00103 C->theElements[idx].updateEdges(e0, e1, e2);
00104 else
00105 mesh[cid].updateEdges(idx, e0, e1, e2);
00106 }
00107
00108 void elemRef::setDependent(chunk *C, int anIdx, int aCid)
00109 {
00110 if (cid == C->cid) {
00111 C->theElements[idx].setDependent(aCid, anIdx);
00112 C->setModified();
00113 if (!C->isRefining()) {
00114 C->setRefining();
00115 mesh[cid].refiningElements();
00116 }
00117 }
00118 else
00119 mesh[cid].setDependent(objRef(aCid, anIdx), idx);
00120 }
00121
00122 void elemRef::unsetDependency(chunk *C)
00123 {
00124 if (cid == C->cid) {
00125 C->theElements[idx].unsetDependency();
00126 C->setModified();
00127 if (!C->isRefining()) {
00128 C->setRefining();
00129 mesh[cid].refiningElements();
00130 }
00131 }
00132 else
00133 mesh[cid].unsetDependency(idx);
00134 }
00135
00136 int elemRef::hasDependent(chunk *C)
00137 {
00138 if (cid == C->cid)
00139 return (C->theElements[idx].hasDependent());
00140 else {
00141 intMsg *im2;
00142 int result;
00143 im2 = mesh[cid].hasDependent(idx);
00144 result = im2->anInt;
00145 CkFreeMsg(im2);
00146 return result;
00147 }
00148 }
00149
00150 void elemRef::setTargetArea(chunk *C, double ta)
00151 {
00152 if (cid == C->cid)
00153 C->theElements[idx].setTargetArea(ta);
00154 else
00155 mesh[cid].setTargetArea(idx, ta);
00156 }
00157
00158
00159 void edge::init(int i, chunk *cPtr)
00160 {
00161 C = cPtr; myRef.init(C->cid,i); theLock = 0;
00162 }
00163
00164 void edge::init(elemRef *e, int i, chunk *cPtr)
00165 {
00166 elements[0] = e[0]; elements[1] = e[1];
00167 C = cPtr; myRef.init(C->cid,i); theLock = 0;
00168 }
00169
00170 void edge::updateElement(elemRef oldval, elemRef newval)
00171 {
00172 if (elements[0] == oldval)
00173 elements[0] = newval;
00174 else if (elements[1] == oldval)
00175 elements[1] = newval;
00176 else
00177 CkAbort("ERROR: edge::updateElement: no match for oldval\n");
00178 }
00179
00180
00181 element::element()
00182 {
00183 targetArea = currentArea = -1.0;
00184 specialRequest = pendingRequest = requestResponse = depend = 0;
00185 unsetDependent();
00186 specialRequester.init();
00187 newNode.init();
00188 otherNode.init();
00189 newLongEdgeRef.init();
00190 C = NULL;
00191 }
00192
00193 void element::init()
00194 {
00195 targetArea = currentArea = -1.0;
00196 specialRequest = pendingRequest = requestResponse = depend = 0;
00197 unsetDependent();
00198 }
00199
00200 void element::init(int *n, int index, chunk *chk)
00201 {
00202 for (int i=0; i<3; i++) {
00203 nodes[i] = n[i];
00204 edges[i].init();
00205 }
00206 C = chk;
00207 myRef.init(C->cid, index);
00208 targetArea = currentArea = -1.0;
00209 specialRequest = pendingRequest = requestResponse = depend = 0;
00210 unsetDependent();
00211 }
00212
00213 void element::init(int *n, edgeRef *e, int index, chunk *chk)
00214 {
00215 for (int i=0; i<3; i++) {
00216 nodes[i] = n[i];
00217 edges[i] = e[i];
00218 }
00219 C = chk;
00220 myRef.init(C->cid, index);
00221 targetArea = currentArea = -1.0;
00222 specialRequest = pendingRequest = requestResponse = depend = 0;
00223 unsetDependent();
00224 }
00225
00226 double element::getArea()
00227 {
00228 calculateArea();
00229 return currentArea;
00230 }
00231
00232 void element::calculateArea()
00233 {
00234
00235
00236
00237 node n[3];
00238 double s, perimeter, len[3];
00239
00240 for (int i=0; i<3; i++)
00241 n[i] = C->theNodes[nodes[i]];
00242
00243 len[0] = n[0].distance(n[1]);
00244 len[1] = n[1].distance(n[2]);
00245 len[2] = n[2].distance(n[0]);
00246
00247
00248 perimeter = len[0] + len[1] + len[2];
00249 s = perimeter / 2.0;
00250
00251 currentArea = sqrt(s * (s - len[0]) * (s - len[1]) * (s - len[2]));
00252 }
00253
00254 int element::findLongestEdge()
00255 {
00256 int i, longEdge;
00257 node n[3];
00258 double maxlen = 0.0, len[3];
00259
00260 for (i=0; i<3; i++)
00261 n[i] = C->theNodes[nodes[i]];
00262
00263 len[0] = n[0].distance(n[1]);
00264 len[1] = n[1].distance(n[2]);
00265 len[2] = n[2].distance(n[0]);
00266
00267 for (i=0; i<3; i++)
00268 if (len[i] > maxlen) {
00269 longEdge = i;
00270 maxlen = len[i];
00271 }
00272 return longEdge;
00273 }
00274
00275 elemRef element::getNeighbor(int e) const
00276 {
00277 if (edges[e].cid == myRef.cid) {
00278
00279 return C->theEdges[edges[e].idx].getNbrRef(myRef);
00280 }
00281 else {
00282 refMsg *result = mesh[edges[e].cid].getNeighbor(myRef, edges[e].idx);
00283 elemRef ret=*(elemRef *)&result->aRef;
00284 CkFreeMsg(result);
00285 return ret;
00286 }
00287 }
00288
00289 int element::checkNeighbor(int longEdge)
00290 {
00291 elemRef nbr = getNeighbor(longEdge);
00292
00293 if (nbr.idx == -1) {
00294 return -1;
00295 }
00296 else {
00297 int result;
00298 result = nbr.checkIfLongEdge(C, edges[longEdge]);
00299 return result;
00300 }
00301 }
00302
00303 int element::checkIfLongEdge(edgeRef e)
00304 {
00305 int longEdge = findLongestEdge();
00306 return (edges[longEdge] == e);
00307 }
00308
00309 void element::refine()
00310 {
00311 int longEdge, test;
00312
00313 longEdge = findLongestEdge();
00314
00315 if (requestResponse) {
00316
00317
00318 splitHelp(longEdge);
00319 return;
00320 }
00321 if (specialRequest) {
00322 if (getArea() < targetArea) {
00323 splitResponse(longEdge);
00324 return;
00325 }
00326 else {
00327 if ((myRef.idx > specialRequester.idx) ||
00328 ((myRef.idx == specialRequester.idx) && (myRef.cid > specialRequester.cid))) {
00329
00330 splitResponse(longEdge);
00331 return;
00332 }
00333 else
00334 specialRequest = pendingRequest = 0;
00335 }
00336 }
00337 if (pendingRequest)
00338 return;
00339
00340
00341 test = checkNeighbor(longEdge);
00342 if (test == -1)
00343 splitBorder(longEdge);
00344 else if (test == 1) {
00345 if (!edges[longEdge].locked(C))
00346 splitNeighbors(longEdge);
00347 }
00348 else
00349 refineNeighbor(longEdge);
00350 }
00351
00352 void element::splitBorder(int longEdge)
00353 {
00354 int opnode, othernode, modEdge, otherEdge;
00355 edgeRef modEdgeRef;
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 opnode = (longEdge + 2) % 3;
00372 othernode = longEdge;
00373 modEdge = opnode;
00374 otherEdge = (longEdge + 1) % 3;
00375 modEdgeRef = edges[modEdge];
00376
00377
00378 if (edges[modEdge].lock(C)) {
00379 if (edges[otherEdge].lock(C)) {
00380 splitBorderLocal(longEdge, opnode, othernode, modEdge);
00381 edges[otherEdge].unlock(C);
00382 }
00383 modEdgeRef.unlock(C);
00384 }
00385 }
00386
00387 void element::splitBorderLocal(int longEdge, int opnode, int othernode,
00388 int modEdge)
00389 {
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 int fixnode = 3 - opnode - othernode;
00409
00410 node m;
00411 C->theNodes[nodes[othernode]].midpoint(C->theNodes[nodes[fixnode]], &m);
00412
00413
00414 int mIdx = C->addNode(m);
00415 edgeRef newEdgeRef = C->addEdge();
00416 edgeRef newLongRef = C->addEdge();
00417 elemRef newElemRef;
00418 if (opnode == 0) {
00419 if (othernode == 1)
00420 newElemRef = C->addElement(nodes[0], nodes[1], mIdx, edges[modEdge],
00421 newLongRef, newEdgeRef);
00422 else
00423 newElemRef = C->addElement(nodes[0], mIdx, nodes[2], newEdgeRef,
00424 newLongRef, edges[modEdge]);
00425 }
00426 else if (opnode == 1) {
00427 if (othernode == 0)
00428 newElemRef = C->addElement(nodes[0], nodes[1], mIdx, edges[modEdge],
00429 newEdgeRef, newLongRef);
00430 else
00431 newElemRef = C->addElement(mIdx, nodes[1], nodes[2], newEdgeRef,
00432 edges[modEdge], newLongRef);
00433 }
00434 else {
00435 if (othernode == 0)
00436 newElemRef = C->addElement(nodes[0], mIdx, nodes[2], newLongRef,
00437 newEdgeRef, edges[modEdge]);
00438 else
00439 newElemRef = C->addElement(mIdx, nodes[1], nodes[2], newLongRef,
00440 edges[modEdge], newEdgeRef);
00441 }
00442
00443 edges[modEdge].updateElement(C, myRef, newElemRef);
00444 C->theEdges[newEdgeRef.idx].updateElement(nullRef, myRef);
00445 C->theEdges[newEdgeRef.idx].updateElement(nullRef, newElemRef);
00446 C->theEdges[newLongRef.idx].updateElement(nullRef, newElemRef);
00447
00448 nodes[othernode] = mIdx;
00449 edges[modEdge] = newEdgeRef;
00450 C->theElements[newElemRef.idx].setTargetArea(targetArea);
00451
00452
00453 if (C->theClient) C->theClient->split(myRef.idx, longEdge, othernode, 0.5,
00454 LOCAL_FIRST);
00455
00456 tellDepend();
00457
00458 calculateArea();
00459 C->theElements[newElemRef.idx].calculateArea();
00460 }
00461
00462 void element::splitNeighbors(int longEdge)
00463 {
00464 int opnode, othernode, modEdge, otherEdge;
00465 int nbrLongEdge, nbrOpnode, nbrOthernode, nbrModEdge, nbrOtherEdge;
00466 elemRef nbr = getNeighbor(longEdge);
00467 edgeRef modEdgeRef, nbrModEdgeRef;
00468
00469
00470 opnode = (longEdge + 2) % 3;
00471 othernode = longEdge;
00472 modEdge = opnode;
00473 otherEdge = (longEdge + 1) % 3;
00474
00475 if (nbr.cid == myRef.cid) {
00476
00477 nbrLongEdge = C->theElements[nbr.idx].findLongestEdge();
00478 nbrOpnode = (nbrLongEdge + 2) % 3;
00479 nbrOthernode = (nbrOpnode+1) % 3;
00480 nbrModEdge = nbrOpnode;
00481 nbrOtherEdge = (nbrLongEdge + 1) % 3;
00482 if (!(C->theElements[nbr.idx].nodes[nbrOthernode] == nodes[othernode])) {
00483 nbrOthernode = (nbrOpnode+2) % 3;
00484 nbrModEdge = nbrOthernode;
00485 nbrOtherEdge = (nbrLongEdge + 2) % 3;
00486 }
00487
00488 modEdgeRef = edges[modEdge];
00489 nbrModEdgeRef = C->theElements[nbr.idx].edges[nbrModEdge];
00490
00491
00492 if (edges[modEdge].lock(C)) {
00493 if (edges[otherEdge].lock(C)) {
00494 if (C->theElements[nbr.idx].edges[nbrModEdge].lock(C)) {
00495 if (C->theElements[nbr.idx].edges[nbrOtherEdge].lock(C)) {
00496
00497 splitNeighborsLocal(longEdge, opnode, othernode, modEdge,
00498 nbrLongEdge, nbrOpnode, nbrOthernode,
00499 nbrModEdge, nbr);
00500
00501 C->theElements[nbr.idx].edges[nbrOtherEdge].unlock(C);
00502 }
00503 nbrModEdgeRef.unlock(C);
00504 }
00505 edges[otherEdge].unlock(C);
00506 }
00507 modEdgeRef.unlock(C);
00508 }
00509 }
00510 else {
00511 pendingRequest = 1;
00512 mesh[nbr.cid].specialRequest(nbr.idx, myRef);
00513 }
00514 }
00515
00516 void element::splitNeighborsLocal(int longEdge, int opnode, int othernode,
00517 int modEdge, int nbrLongEdge, int nbrOpnode,
00518 int nbrOthernode, int nbrModEdge,
00519 const elemRef &nbr)
00520 {
00521
00522 int fixnode = 3 - opnode - othernode;
00523 node m;
00524 C->theNodes[nodes[othernode]].midpoint(C->theNodes[nodes[fixnode]], &m);
00525
00526
00527 int mIdx = C->addNode(m);
00528 edgeRef newEdgeRef = C->addEdge();
00529 edgeRef newLongRef = C->addEdge();
00530 edgeRef newNbrEdgeRef = C->addEdge();
00531 elemRef newElemRef;
00532 if (opnode == 0) {
00533 if (othernode == 1)
00534 newElemRef = C->addElement(nodes[0], nodes[1], mIdx, edges[modEdge],
00535 newLongRef, newEdgeRef);
00536 else
00537 newElemRef = C->addElement(nodes[0], mIdx, nodes[2], newEdgeRef,
00538 newLongRef, edges[modEdge]);
00539 }
00540 else if (opnode == 1) {
00541 if (othernode == 0)
00542 newElemRef = C->addElement(nodes[0], nodes[1], mIdx, edges[modEdge],
00543 newEdgeRef, newLongRef);
00544 else
00545 newElemRef = C->addElement(mIdx, nodes[1], nodes[2], newEdgeRef,
00546 edges[modEdge], newLongRef);
00547 }
00548 else {
00549 if (othernode == 0)
00550 newElemRef = C->addElement(nodes[0], mIdx, nodes[2], newLongRef,
00551 newEdgeRef, edges[modEdge]);
00552 else
00553 newElemRef = C->addElement(mIdx, nodes[1], nodes[2], newLongRef,
00554 edges[modEdge], newEdgeRef);
00555 }
00556 elemRef newNbrRef;
00557 if (nbrOpnode == 0) {
00558 if (nbrOthernode == 1)
00559 newNbrRef = C->addElement(C->theElements[nbr.idx].nodes[0],
00560 C->theElements[nbr.idx].nodes[1], mIdx,
00561 C->theElements[nbr.idx].edges[nbrModEdge],
00562 newLongRef, newNbrEdgeRef);
00563 else
00564 newNbrRef = C->addElement(C->theElements[nbr.idx].nodes[0], mIdx,
00565 C->theElements[nbr.idx].nodes[2],
00566 newNbrEdgeRef, newLongRef,
00567 C->theElements[nbr.idx].edges[nbrModEdge]);
00568 }
00569 else if (nbrOpnode == 1) {
00570 if (nbrOthernode == 0)
00571 newNbrRef = C->addElement(C->theElements[nbr.idx].nodes[0],
00572 C->theElements[nbr.idx].nodes[1], mIdx,
00573 C->theElements[nbr.idx].edges[nbrModEdge],
00574 newNbrEdgeRef, newLongRef);
00575 else
00576 newNbrRef = C->addElement(mIdx, C->theElements[nbr.idx].nodes[1],
00577 C->theElements[nbr.idx].nodes[2],
00578 newNbrEdgeRef,
00579 C->theElements[nbr.idx].edges[nbrModEdge],
00580 newLongRef);
00581 }
00582 else {
00583 if (nbrOthernode == 0)
00584 newNbrRef = C->addElement(C->theElements[nbr.idx].nodes[0], mIdx,
00585 C->theElements[nbr.idx].nodes[2], newLongRef,
00586 newNbrEdgeRef,
00587 C->theElements[nbr.idx].edges[nbrModEdge]);
00588 else
00589 newNbrRef = C->addElement(mIdx, C->theElements[nbr.idx].nodes[1],
00590 C->theElements[nbr.idx].nodes[2], newLongRef,
00591 C->theElements[nbr.idx].edges[nbrModEdge],
00592 newNbrEdgeRef);
00593 }
00594
00595
00596 edges[modEdge].updateElement(C, myRef, newElemRef);
00597 C->theEdges[newEdgeRef.idx].updateElement(nullRef, myRef);
00598 C->theEdges[newEdgeRef.idx].updateElement(nullRef, newElemRef);
00599 C->theEdges[newLongRef.idx].updateElement(nullRef, newElemRef);
00600 C->theEdges[newLongRef.idx].updateElement(nullRef, newNbrRef);
00601 C->theEdges[newNbrEdgeRef.idx].updateElement(nullRef, nbr);
00602 C->theEdges[newNbrEdgeRef.idx].updateElement(nullRef, newNbrRef);
00603 C->theElements[nbr.idx].edges[nbrModEdge].updateElement(C, nbr, newNbrRef);
00604 C->theElements[newElemRef.idx].setTargetArea(targetArea);
00605 C->theElements[newNbrRef.idx].setTargetArea(C->theElements[nbr.idx].getTargetArea());
00606 nodes[othernode] = mIdx;
00607 edges[modEdge] = newEdgeRef;
00608 C->theElements[nbr.idx].nodes[nbrOthernode] = mIdx;
00609 C->theElements[nbr.idx].edges[nbrModEdge] = newNbrEdgeRef;
00610
00611
00612 if (C->theClient) C->theClient->split(myRef.idx, longEdge, othernode, 0.5,
00613 LOCAL_FIRST);
00614 if (C->theClient) C->theClient->split(nbr.idx, nbrLongEdge, nbrOthernode,
00615 0.5, LOCAL_SECOND);
00616
00617
00618 tellDepend();
00619 C->theElements[nbr.idx].tellDepend();
00620
00621
00622
00623 calculateArea();
00624 C->theElements[newElemRef.idx].calculateArea();
00625 C->theElements[newNbrRef.idx].calculateArea();
00626 C->theElements[nbr.idx].calculateArea();
00627 }
00628
00629 void element::splitHelp(int longEdge)
00630 {
00631 int othernode, opnode, modEdge, otherEdge;
00632 int newNodeIdx;
00633
00634
00635
00636
00637
00638 opnode = (longEdge + 2) % 3;
00639 othernode = longEdge;
00640 modEdge = opnode;
00641 otherEdge = (longEdge + 1) % 3;
00642 if (!(otherNode == C->theNodes[nodes[othernode]])) {
00643 othernode = (longEdge + 1) % 3;
00644 modEdge = othernode;
00645 otherEdge = opnode;
00646 }
00647
00648 edgeRef modEdgeRef = edges[modEdge];
00649
00650
00651 if (!edges[modEdge].lock(C))
00652 return;
00653 if (!edges[otherEdge].lock(C)) {
00654 edges[modEdge].unlock(C);
00655 return;
00656 }
00657
00658
00659 newNodeIdx = C->addNode(newNode);
00660 edgeRef newEdgeRef = C->addEdge();
00661 elemRef newElemRef;
00662 if (opnode == 0) {
00663 if (othernode == 1)
00664 newElemRef = C->addElement(nodes[0], nodes[1], newNodeIdx,
00665 edges[modEdge], newLongEdgeRef, newEdgeRef);
00666 else
00667 newElemRef = C->addElement(nodes[0], newNodeIdx, nodes[2], newEdgeRef,
00668 newLongEdgeRef, edges[modEdge]);
00669 }
00670 else if (opnode == 1) {
00671 if (othernode == 0)
00672 newElemRef = C->addElement(nodes[0], nodes[1], newNodeIdx,
00673 edges[modEdge], newEdgeRef, newLongEdgeRef);
00674 else
00675 newElemRef = C->addElement(newNodeIdx, nodes[1], nodes[2], newEdgeRef,
00676 edges[modEdge], newLongEdgeRef);
00677 }
00678 else {
00679 if (othernode == 0)
00680 newElemRef = C->addElement(nodes[0], newNodeIdx, nodes[2],
00681 newLongEdgeRef, newEdgeRef, edges[modEdge]);
00682 else
00683 newElemRef = C->addElement(newNodeIdx, nodes[1], nodes[2],
00684 newLongEdgeRef, edges[modEdge], newEdgeRef);
00685 }
00686
00687 C->theEdges[newEdgeRef.idx].updateElement(nullRef, myRef);
00688 C->theEdges[newEdgeRef.idx].updateElement(nullRef, newElemRef);
00689 newLongEdgeRef.updateElement(C, nullRef, newElemRef);
00690 edges[modEdge].updateElement(C, myRef, newElemRef);
00691 C->theElements[newElemRef.idx].setTargetArea(targetArea);
00692 nodes[othernode] = newNodeIdx;
00693 edges[modEdge] = newEdgeRef;
00694
00695
00696 if (C->theClient) C->theClient->split(myRef.idx, longEdge, othernode, 0.5,
00697 BOUND_SECOND);
00698
00699 tellDepend();
00700 specialRequest = pendingRequest = requestResponse = 0;
00701
00702
00703 edges[longEdge].unlock(C);
00704 newLongEdgeRef.unlock(C);
00705 edges[otherEdge].unlock(C);
00706 modEdgeRef.unlock(C);
00707
00708
00709 calculateArea();
00710 C->theElements[newElemRef.idx].calculateArea();
00711 }
00712
00713 void element::splitResponse(int longEdge)
00714 {
00715 int opnode, othernode, modEdge, otherEdge;
00716
00717
00718
00719
00720 opnode = (longEdge + 2) % 3;
00721 othernode = longEdge;
00722 modEdge = opnode;
00723 otherEdge = (longEdge + 1) % 3;
00724 edgeRef modEdgeRef = edges[modEdge];
00725
00726
00727 if (!edges[longEdge].lock(C)) return;
00728 if (!edges[modEdge].lock(C)) {
00729 edges[longEdge].unlock(C);
00730 return;
00731 }
00732 if (!edges[otherEdge].lock(C)) {
00733 edges[modEdge].unlock(C);
00734 edges[longEdge].unlock(C);
00735 return;
00736 }
00737
00738
00739 int fixnode = 3 - opnode - othernode;
00740 node m;
00741 C->theNodes[nodes[othernode]].midpoint(C->theNodes[nodes[fixnode]], &m);
00742
00743
00744 int mIdx = C->addNode(m);
00745 edgeRef newEdgeRef = C->addEdge();
00746 edgeRef newLongRef = C->addEdge();
00747 elemRef newElemRef;
00748 if (opnode == 0) {
00749 if (othernode == 1)
00750 newElemRef = C->addElement(nodes[0], nodes[1], mIdx, edges[modEdge],
00751 newLongRef, newEdgeRef);
00752 else
00753 newElemRef = C->addElement(nodes[0], mIdx, nodes[2], newEdgeRef,
00754 newLongRef, edges[modEdge]);
00755 }
00756 else if (opnode == 1) {
00757 if (othernode == 0)
00758 newElemRef = C->addElement(nodes[0], nodes[1], mIdx, edges[modEdge],
00759 newEdgeRef, newLongRef);
00760 else
00761 newElemRef = C->addElement(mIdx, nodes[1], nodes[2], newEdgeRef,
00762 edges[modEdge], newLongRef);
00763 }
00764 else {
00765 if (othernode == 0)
00766 newElemRef = C->addElement(nodes[0], mIdx, nodes[2], newLongRef,
00767 newEdgeRef, edges[modEdge]);
00768 else
00769 newElemRef = C->addElement(mIdx, nodes[1], nodes[2], newLongRef,
00770 edges[modEdge], newEdgeRef);
00771 }
00772
00773 edges[modEdge].updateElement(C, myRef, newElemRef);
00774 C->theEdges[newEdgeRef.idx].updateElement(nullRef, myRef);
00775 C->theEdges[newEdgeRef.idx].updateElement(nullRef, newElemRef);
00776 C->theEdges[newLongRef.idx].updateElement(nullRef, newElemRef);
00777
00778 if (!newLongRef.lock(C)) CkAbort("ERROR locking new long edge.\n");
00779
00780 mesh[specialRequester.cid].specialRequestResponse(specialRequester.idx,
00781 m.X(), m.Y(), C->theNodes[nodes[othernode]].X(),
00782 C->theNodes[nodes[othernode]].Y(), newLongRef);
00783
00784 nodes[othernode] = mIdx;
00785 edges[modEdge] = newEdgeRef;
00786 C->theElements[newElemRef.idx].setTargetArea(targetArea);
00787
00788
00789 if (C->theClient) C->theClient->split(myRef.idx, longEdge, othernode, 0.5,
00790 BOUND_FIRST);
00791
00792 specialRequest = pendingRequest = requestResponse = 0;
00793 tellDepend();
00794
00795
00796 edges[otherEdge].unlock(C);
00797 modEdgeRef.unlock(C);
00798
00799
00800 calculateArea();
00801 C->theElements[newElemRef.idx].calculateArea();
00802 }
00803
00804 void element::refineNeighbor(int longEdge)
00805 {
00806 elemRef nbr = getNeighbor(longEdge);
00807
00808
00809 if (!nbr.hasDependent(C)) {
00810 double nbrArea = nbr.getArea(C);
00811 nbr.setDependent(C, myRef.idx, myRef.cid);
00812 depend = 1;
00813 if (nbr.cid == myRef.cid)
00814
00815 C->theElements[nbr.idx].setTargetArea(nbrArea);
00816 else
00817 mesh[nbr.cid].refineElement(nbr.idx, nbrArea);
00818 }
00819
00820
00821
00822
00823
00824 }
00825
00826 void element::updateEdges(edgeRef e0, edgeRef e1, edgeRef e2)
00827 {
00828 edges[0] = e0;
00829 edges[1] = e1;
00830 edges[2] = e2;
00831 }
00832
00833
00834 chunk::chunk(chunkMsg *m)
00835 : TCharmClient1D(m->myThreads), numElements(0), numEdges(0), numNodes(0),
00836 sizeElements(0), sizeEdges(0), sizeNodes(0),
00837 debug_counter(0), refineInProgress(0), modified(0),
00838 meshLock(0), meshExpandFlag(0), theClient(NULL)
00839 {
00840 refineResultsStorage=NULL;
00841 cid = thisIndex;
00842 numChunks = m->nChunks;
00843 CkFreeMsg(m);
00844 tcharmClientInit();
00845 thread->resume();
00846 }
00847
00848 void chunk::refineElement(int i, double area)
00849 {
00850
00851 accessLock();
00852 theElements[i].setTargetArea(area);
00853 releaseLock();
00854 modified = 1;
00855 if (!refineInProgress) {
00856 refineInProgress = 1;
00857 mesh[cid].refiningElements();
00858 }
00859 }
00860
00861 void chunk::refiningElements()
00862 {
00863 int i;
00864
00865 CkPrintf("[tmr] Chunk %d: refiningElements\n", cid);
00866 while (modified) {
00867
00868
00869 i = 0;
00870 modified = 0;
00871 CkPrintf("[tmr] Chunk %d: Entering internal refinement loop...\n", cid);
00872 while (i < numElements) {
00873 if (theElements[i].getCachedArea() < 0.0)
00874 theElements[i].calculateArea();
00875 if ((!theElements[i].hasDependency() &&
00876 (((theElements[i].getTargetArea() <= theElements[i].getCachedArea())
00877 && (theElements[i].getTargetArea() >= 0.0))
00878 || theElements[i].isSpecialRequest()
00879 || theElements[i].isPendingRequest()))
00880 || theElements[i].isRequestResponse()) {
00881
00882
00883
00884 modified = 1;
00885 theElements[i].refine();
00886 }
00887 i++;
00888 }
00889
00890 adjustMesh();
00891 CthYield();
00892 }
00893
00894 refineInProgress = 0;
00895 CkPrintf("[tmr] Chunk %d: DONE refiningElements\n", cid);
00896 }
00897
00898
00899 void chunk::updateElement(int i, objRef oldval, objRef newval)
00900 {
00901 accessLock();
00902 theEdges[i].updateElement(elemRef(oldval.cid, oldval.idx),
00903 elemRef(newval.cid, newval.idx));
00904 releaseLock();
00905 }
00906
00907
00908 void chunk::specialRequest(int requestee, elemRef requester)
00909 {
00910 accessLock();
00911 theElements[requestee].setSpecialRequest(requester);
00912 releaseLock();
00913
00914 modified = 1;
00915 if (!refineInProgress) {
00916 refineInProgress = 1;
00917 mesh[cid].refiningElements();
00918 }
00919 }
00920
00921 void chunk::specialRequestResponse(int i, double newNodeX, double newNodeY,
00922 double otherNodeX, double otherNodeY,
00923 edgeRef newLongEdgeRef)
00924 {
00925 node newNode(newNodeX, newNodeY);
00926 node otherNode(otherNodeX, otherNodeY);
00927 accessLock();
00928 theElements[i].setRequestResponse(newNode, otherNode, newLongEdgeRef);
00929 releaseLock();
00930
00931 modified = 1;
00932 if (!refineInProgress) {
00933 refineInProgress = 1;
00934 mesh[cid].refiningElements();
00935 }
00936 }
00937
00938 doubleMsg *chunk::getArea(int i)
00939 {
00940 doubleMsg *dm = new doubleMsg;
00941 accessLock();
00942 dm->aDouble = theElements[i].getArea();
00943 releaseLock();
00944 return dm;
00945 }
00946
00947 intMsg *chunk::lock(int i)
00948 {
00949 intMsg *rm = new intMsg;
00950 accessLock();
00951 if (theEdges[i].locked())
00952 rm->anInt = 0;
00953 else {
00954 theEdges[i].lock();
00955 rm->anInt = 1;
00956 }
00957 releaseLock();
00958 return rm;
00959 }
00960
00961 void chunk::unlock(int i)
00962 {
00963 accessLock();
00964 theEdges[i].unlock();
00965 releaseLock();
00966 }
00967
00968
00969 intMsg *chunk::locked(int i)
00970 {
00971 intMsg *rm = new intMsg;
00972 accessLock();
00973 rm->anInt = theEdges[i].locked();
00974 releaseLock();
00975 return rm;
00976 }
00977
00978 intMsg *chunk::checkElement(objRef oR, int i)
00979 {
00980 intMsg *im = new intMsg;
00981 edgeRef eRef(oR.cid, oR.idx);
00982
00983 accessLock();
00984 im->anInt = theElements[i].checkIfLongEdge(eRef);
00985 releaseLock();
00986 return im;
00987 }
00988
00989 refMsg *chunk::getNeighbor(objRef oR, int i)
00990 {
00991 refMsg *rm = new refMsg;
00992 elemRef er, ar(oR.cid, oR.idx);
00993 accessLock();
00994 er = theEdges[i].getNbrRef(ar);
00995 releaseLock();
00996 rm->aRef = er;
00997 return rm;
00998 }
00999
01000 void chunk::setTargetArea(int i, double area)
01001 {
01002 accessLock();
01003 theElements[i].setTargetArea(area);
01004 releaseLock();
01005 modified = 1;
01006 if (!refineInProgress) {
01007 refineInProgress = 1;
01008 mesh[cid].refiningElements();
01009 }
01010 }
01011
01012 void chunk::updateEdges(int i, edgeRef e0, edgeRef e1, edgeRef e2)
01013 {
01014 accessLock();
01015 theElements[i].updateEdges(e0, e1, e2);
01016 releaseLock();
01017 }
01018
01019 void chunk::setDependent(objRef oR, int i)
01020 {
01021 accessLock();
01022 theElements[i].setDependent(oR.cid, oR.idx);
01023 releaseLock();
01024 modified = 1;
01025 if (!refineInProgress) {
01026 refineInProgress = 1;
01027 mesh[cid].refiningElements();
01028 }
01029 }
01030
01031 intMsg *chunk::hasDependent(int i)
01032 {
01033 intMsg *result = new intMsg;
01034 accessLock();
01035 result->anInt = theElements[i].hasDependent();
01036 releaseLock();
01037 return result;
01038 }
01039
01040 void chunk::unsetDependency(int i)
01041 {
01042 accessLock();
01043 theElements[i].unsetDependency();
01044 releaseLock();
01045 modified = 1;
01046 if (!refineInProgress) {
01047 refineInProgress = 1;
01048 mesh[cid].refiningElements();
01049 }
01050 }
01051
01052
01053
01054 void chunk::accessLock()
01055 {
01056 while (meshExpandFlag)
01057 CthYield();
01058 meshLock--;
01059 }
01060
01061 void chunk::releaseLock()
01062 {
01063 meshLock++;
01064 }
01065
01066 void chunk::adjustFlag()
01067 {
01068 meshExpandFlag = 1;
01069 }
01070
01071 void chunk::adjustLock()
01072 {
01073 while (meshLock != 0)
01074 CthYield();
01075 meshLock = 1;
01076 }
01077
01078 void chunk::adjustRelease()
01079 {
01080 meshLock = meshExpandFlag = 0;
01081 }
01082
01083 void chunk::adjustMesh()
01084 {
01085 if ((sizeElements < numElements) || (sizeNodes < numNodes) || (sizeEdges < numEdges))
01086 CkPrintf("[tmr] WARNING!\n\n Mesh overrun! Data is probably corrupted!!!\n");
01087 if (sizeElements <= numElements*4) {
01088 adjustFlag();
01089 adjustLock();
01090 CkPrintf("[tmr] [%d] Adjusting mesh size...\n", cid);
01091 sizeElements = numElements*4;
01092 sizeEdges = numEdges*12;
01093 sizeNodes = numNodes*12;
01094 theElements.resize(sizeElements);
01095 theEdges.resize(sizeEdges);
01096 theNodes.resize(sizeNodes);
01097 CkPrintf("[tmr] [%d] Done adjusting mesh size...\n", cid);
01098 adjustRelease();
01099 }
01100 }
01101
01102 int chunk::addNode(node n)
01103 {
01104 theNodes[numNodes] = n;
01105 theNodes[numNodes].init(this);
01106 numNodes++;
01107 return numNodes-1;
01108 }
01109
01110
01111 edgeRef chunk::addEdge()
01112 {
01113 theEdges[numEdges].init(numEdges, this);
01114 edgeRef eRef(cid, numEdges);
01115 numEdges++;
01116 return eRef;
01117 }
01118
01119 elemRef chunk::addElement(int n1, int n2, int n3)
01120 {
01121 int n[3] = {n1, n2, n3};
01122 elemRef eRef(cid, numElements);
01123 theElements[numElements].init(n, numElements, this);
01124 theElements[numElements].calculateArea();
01125 numElements++;
01126 modified = 1;
01127 if (!refineInProgress) {
01128 refineInProgress = 1;
01129 mesh[cid].refiningElements();
01130 }
01131 return eRef;
01132 }
01133
01134 elemRef chunk::addElement(int n1, int n2, int n3,
01135 edgeRef er1, edgeRef er2, edgeRef er3)
01136 {
01137 int n[3] = {n1, n2, n3};
01138 edgeRef e[3] = {er1, er2, er3};
01139
01140 elemRef eRef(cid, numElements);
01141 theElements[numElements].init(n, e, numElements, this);
01142 theElements[numElements].calculateArea();
01143 numElements++;
01144 modified = 1;
01145 if (!refineInProgress) {
01146 refineInProgress = 1;
01147 mesh[cid].refiningElements();
01148 }
01149 return eRef;
01150 }
01151
01152
01153
01154 void chunk::print()
01155 {
01156 accessLock();
01157 debug_print(debug_counter);
01158 debug_counter++;
01159 releaseLock();
01160 }
01161
01162 void chunk::debug_print(int c)
01163 {
01164 FILE *fp;
01165 char filename[30];
01166 int i, j;
01167
01168 memset(filename, 0, 30);
01169 sprintf(filename, "mesh_debug_%d.%d", cid, c);
01170 fp = fopen(filename, "w");
01171
01172 fprintf(fp, "%d %d\n", cid, numElements);
01173 for (i=0; i<numElements; i++) {
01174 for (j=0; j<3; j++)
01175 fprintf(fp, "%f %f ", theNodes[theElements[i].nodes[j]].X(),
01176 theNodes[theElements[i].nodes[j]].Y());
01177 fprintf(fp, "%d %f\n", i, theElements[i].getTargetArea());
01178 for (j=0; j<3; j++) {
01179 fprintf(fp, "%d ", ((theElements[i].getEdge(j).locked(this))?2:0));
01180 }
01181 fprintf(fp, "\n");
01182 }
01183 fclose(fp);
01184 }
01185
01186 void chunk::out_print()
01187 {
01188 FILE *fp;
01189 char filename[30];
01190 int i;
01191
01192 memset(filename, 0, 30);
01193 sprintf(filename, "mesh.out");
01194 fp = fopen(filename, "a");
01195
01196 if (cid == 0)
01197 fprintf(fp, "%d\n", numChunks);
01198 fprintf(fp, " %d %d %d %d\n", cid, numNodes, numEdges, numElements);
01199 for (i=0; i<numNodes; i++)
01200 fprintf(fp, " %f %f\n", theNodes[i].X(), theNodes[i].Y());
01201 for (i=0; i<numEdges; i++) {
01202 fprintf(fp, " ");
01203 fprintf(fp, " %d %d ", theEdges[i].elements[0].idx, theEdges[i].elements[0].cid);
01204 fprintf(fp, " %d %d\n", theEdges[i].elements[1].idx, theEdges[i].elements[1].cid);
01205 }
01206 for (i=0; i<numElements; i++) {
01207 fprintf(fp, " %d %d ", theElements[i].nodes[0], cid);
01208 fprintf(fp, " %d %d ", theElements[i].nodes[1], cid);
01209 fprintf(fp, " %d %d ", theElements[i].nodes[2], cid);
01210 fprintf(fp, " ");
01211 fprintf(fp, " %d %d ", theElements[i].edges[0].idx, theElements[i].edges[0].cid);
01212 fprintf(fp, " %d %d ", theElements[i].edges[1].idx, theElements[i].edges[1].cid);
01213 fprintf(fp, " %d %d\n", theElements[i].edges[2].idx, theElements[i].edges[2].cid);
01214 }
01215 fprintf(fp, "\n");
01216 fclose(fp);
01217 }
01218
01219 void chunk::updateNodeCoords(int nNode, double *coord, int nEl)
01220 {
01221 int i;
01222
01223 #if 1
01224
01225 if (nEl != numElements || nNode != numNodes) {
01226 CkPrintf("ERROR: inconsistency in REFINE2D's updateNodeCoords on chunk %d:\n"
01227 " your nEl (%d); my numElements (%d)\n"
01228 " your nNode (%d); my numNodes (%d)\n",
01229 cid, nEl, numElements, nNode,numNodes);
01230 CkAbort("User code/library numbering inconsistency in REFINE2D");
01231 }
01232 #endif
01233
01234
01235 for (i=0; i<numNodes; i++){
01236 theNodes[i].init(coord[2*i], coord[2*i + 1]);
01237 CkPrintf("[tmr] Chunk %d Node %d %.8lf %.8lf \n",cid,i,theNodes[i].X(),theNodes[i].Y());
01238 }
01239
01240
01241 for (i=0; i<numElements; i++){
01242 theElements[i].calculateArea();
01243 CkPrintf("[tmr] Chunk %d Element %d area = %.8lf \n",cid,i, theElements[i].getArea());
01244 }
01245 sanityCheck();
01246 }
01247
01248 void chunk::multipleRefine(double *desiredArea, refineClient *client)
01249 {
01250 int i;
01251 theClient = client;
01252
01253 CkPrintf("[tmr] Chunk %d: multipleRefine\n", cid);
01254
01255 for (i=0; i<numElements; i++)
01256 if (desiredArea[i] < theElements[i].getArea()) {
01257 theElements[i].setTargetArea(desiredArea[i]);
01258 CkPrintf("[tmr] Chunk %d: Element %d to be refined from %.8lf to below %.8lf \n",
01259 cid, i, theElements[i].getArea(), desiredArea[i]);
01260 }
01261
01262 if (CkMyPe() == 0)
01263 for (i=0; i<numChunks; i++)
01264 mesh[i].out_print();
01265
01266
01267 modified = 1;
01268 if (!refineInProgress) {
01269 refineInProgress = 1;
01270 mesh[cid].refiningElements();
01271 }
01272 }
01273
01274
01275
01276 void chunk::sanityCheck(void)
01277 {
01278 int i;
01279 if (numElements<0 || (int)theElements.size()<numElements)
01280 CkAbort("REFINE2D chunk elements insane!");
01281 if (numEdges<0 || (int)theEdges.size()<numEdges)
01282 CkAbort("REFINE2D chunk edges insane!");
01283 if (numNodes<0 || (int)theNodes.size()<numNodes)
01284 CkAbort("REFINE2D chunk nodes insane!");
01285 for (i=0;i<numElements;i++) {
01286 theElements[i].sanityCheck(this,elemRef(cid,i));
01287 }
01288 for (i=0;i<numEdges;i++) {
01289 theEdges[i].sanityCheck(this,edgeRef(cid,i));
01290 }
01291 }
01292
01293 void objRef::sanityCheck(chunk *C)
01294 {
01295 if (isNull())
01296 CkAbort("REFINE2D objRef is unexpectedly null");
01297 }
01298 void element::sanityCheck(chunk *c,elemRef shouldRef)
01299 {
01300 if (myRef!=shouldRef)
01301 CkAbort("REFINE2D elem has wrong ref");
01302
01303 for (int i=0;i<3;i++) {
01304
01305 edges[i].sanityCheck(c);
01306 }
01307 }
01308 void edge::sanityCheck(chunk *c,edgeRef shouldRef)
01309 {
01310 if (myRef!=shouldRef)
01311 CkAbort("REFINE2D edge has wrong ref");
01312
01313 int nonNullElements=0;
01314 for (int i=0;i<2;i++) {
01315
01316 if (!elements[i].isNull()) {
01317 elements[i].sanityCheck(c);
01318 nonNullElements++;
01319 }
01320 }
01321 if (!(nonNullElements==1 || nonNullElements==2))
01322 CkAbort("REFINE2D edge has unexpected number of neighbors!");
01323 }
01324
01325
01326
01327
01328 void chunk::allocMesh(int nEl)
01329 {
01330 sizeElements = nEl * 2;
01331 sizeNodes = sizeEdges = sizeElements * 3;
01332 theElements.resize(sizeElements);
01333 theNodes.resize(sizeNodes);
01334 theEdges.resize(sizeEdges);
01335 for (int i=0; i<sizeElements; i++) {
01336 theElements[i].init();
01337 theEdges[i].init();
01338 }
01339 }
01340
01341 void chunk::newMesh(int nEl, int nGhost, const int *conn_, const int *gid_, int idxOffset)
01342 {
01343 int i, j;
01344
01345 CkPrintf("[tmr] newMesh on chunk %d...\n", cid);
01346 numElements = nEl;
01347 numGhosts = nGhost;
01348 allocMesh(nEl);
01349 int *conn = new int[3*numGhosts];
01350 int *gid = new int[2*numGhosts];
01351
01352
01353 for (i=0; i<numElements; i++) {
01354 int nodes[3];
01355 edgeRef edges[3];
01356 for (j=0; j<3; j++) {
01357 int c=conn_[i*3+j]-idxOffset;
01358 conn[i*3 + j]=c;
01359 nodes[j] = c;
01360 edges[j].init();
01361 }
01362 theElements[i].init(nodes, edges, i, this);
01363 gid[i*2] = cid;
01364 gid[i*2 + 1] = i;
01365 }
01366
01367
01368 for (i=nEl; i<nGhost; i++) {
01369 for (j=0; j<3; j++)
01370 conn[i*3+j] = conn_[i*3+j]-idxOffset;
01371 gid[i*2+0] = gid_[i*2]-idxOffset;
01372 gid[i*2+1] = gid_[i*2 + 1]-idxOffset;
01373 }
01374
01375
01376
01377
01378
01379 int n1localIdx, n2localIdx, newEdge;
01380
01381 deriveNodes();
01382
01383 for (i=0; i<numElements; i++) {
01384 elemRef myRef(cid,i);
01385 for (j=0; j<3; j++) {
01386 n1localIdx = j;
01387 n2localIdx = (j+1) % 3;
01388
01389
01390 if (theElements[i].edges[j] == nullRef) {
01391
01392 elemRef nbrRef;
01393 int edgeIdx = getNbrRefOnEdge(theElements[i].nodes[n1localIdx],
01394 theElements[i].nodes[n2localIdx],
01395 conn, numGhosts, gid, i, &nbrRef);
01396 if (edgeLocal(myRef, nbrRef)) {
01397 newEdge = addNewEdge();
01398
01399 theEdges[newEdge].updateElement(nullRef, myRef);
01400 theEdges[newEdge].updateElement(nullRef, nbrRef);
01401
01402 theElements[i].updateEdge(j, theEdges[newEdge].getRef());
01403
01404 if (nbrRef.cid==cid)
01405 theElements[nbrRef.idx].updateEdge(edgeIdx,
01406 theEdges[newEdge].getRef());
01407 else if (nbrRef.cid != -1)
01408 mesh[nbrRef.cid].addRemoteEdge(nbrRef.idx, edgeIdx,
01409 theEdges[newEdge].getRef());
01410 }
01411
01412 }
01413 }
01414 }
01415 delete[] conn;
01416 delete[] gid;
01417 CkPrintf("[tmr] Finished newMesh on chunk %d...\n", cid);
01418 }
01419
01420 void chunk::deriveNodes()
01421 {
01422 int i, j;
01423 int aNode;
01424
01425 numNodes = 0;
01426 for (i=0; i<numElements; i++) {
01427 for (j=0; j<3; j++) {
01428 aNode = theElements[i].nodes[j];
01429 if (aNode >= 0) {
01430 theNodes[aNode].init(this);
01431 if ((aNode + 1) > numNodes)
01432 numNodes = aNode + 1;
01433 }
01434 else CkAbort("[tmr] ERROR: negative node id found in conn...\n");
01435 }
01436 }
01437 }
01438
01439 void chunk::addRemoteEdge(int elem, int localEdge, edgeRef er)
01440 {
01441 while (sizeElements == 0) CthYield();
01442 theElements[elem].updateEdge(localEdge, er);
01443 }
01444
01445 int chunk::edgeLocal(elemRef e1, elemRef e2)
01446 {
01447 if (e1.cid==-1 || e2.cid==-1)
01448 return 1;
01449 if (e1.cid == e2.cid)
01450 return 1;
01451 if (e1.idx > e2.idx)
01452 return 1;
01453 else if ((e1.idx == e2.idx) && (e1.cid > e2.cid))
01454 return 1;
01455 else return 0;
01456 }
01457
01458 int chunk::addNewEdge()
01459 {
01460 theEdges[numEdges].init(numEdges, this);
01461 numEdges++;
01462 return numEdges-1;
01463 }
01464
01465 int chunk::getNbrRefOnEdge(int n1, int n2, int *conn, int nGhost, int *gid,
01466 int idx, elemRef *er)
01467 {
01468 int i, e;
01469 er->init();
01470 for (i=idx+1; i<nGhost; i++)
01471 if ((e = hasEdge(n1, n2, conn, i)) != -1) {
01472 er->init(gid[i*2], gid[i*2+1]);
01473 return e;
01474 }
01475 return -1;
01476 }
01477
01478 int chunk::hasEdge(int n1, int n2, int *conn, int idx)
01479 {
01480 for (int i=0; i<3; i++) {
01481 int a=i;
01482 int b=(i+1)%3;
01483 if (((conn[idx*3+a] == n1) && (conn[idx*3+b] == n2)) ||
01484 ((conn[idx*3+b] == n1) && (conn[idx*3+a] == n2)))
01485 return i;
01486 }
01487 return -1;
01488
01489 }
01490
01491 #include "refine.def.h"