00001
00002
00003
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include "chunk.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 chunk::chunk(int nChunks)
00020 : numElements(0), numNodes(0), sizeElements(0), sizeNodes(0),
00021 coordsRecvd(0), debug_counter(0), refineInProgress(0),
00022 modified(0), accessLock(0), adjustLock(0), lock(0), lockCount(0),
00023 lockHolder(-1), lockPrio(-1.0), smoothness(0.25), lockList(NULL), theClient(NULL)
00024
00025 {
00026 refineResultsStorage=NULL;
00027 cid = thisIndex;
00028 numChunks = nChunks;
00029
00030
00031 }
00032
00033 void chunk::refineElement(int idx, double volume)
00034 {
00035
00036 CmiAssert((idx < numElements) && (idx >= 0));
00037 CmiAssert((volume >= 0.0) || (volume == -1.0));
00038
00039 theElements[idx].setTargetVolume(volume);
00040 modified = 1;
00041 if (!refineInProgress) {
00042 refineInProgress = 1;
00043 CkPrintf("Chunk %d activating...\n", cid);
00044 mesh[cid].refiningElements();
00045 }
00046 }
00047
00048 void chunk::refineElement(int idx)
00049 {
00050 double vol = theElements[idx].getTargetVolume();
00051 CmiAssert((idx < numElements) && (idx >= 0));
00052 if ((vol == -1.0) || (vol >= theElements[idx].getVolume()))
00053 vol = theElements[idx].getVolume();
00054 theElements[idx].setTargetVolume(vol);
00055 modified = 1;
00056 if (!refineInProgress) {
00057 refineInProgress = 1;
00058 CkPrintf("Chunk %d activating...\n", cid);
00059 mesh[cid].refiningElements();
00060 }
00061 }
00062
00063 void chunk::refiningElements()
00064 {
00065 int i;
00066
00067 while (modified) {
00068
00069 i = 0;
00070 modified = 0;
00071
00072 while (i < numElements) {
00073 if ((theElements[i].getTargetVolume() <= theElements[i].getVolume())
00074 && (theElements[i].getTargetVolume() >= 0.0)) {
00075
00076 modified = 1;
00077 if (theElements[i].LEtest())
00078 theElements[i].refineLE();
00079 else if (theElements[i].LFtest())
00080 theElements[i].refineLF();
00081 else if (theElements[i].CPtest())
00082 theElements[i].refineCP();
00083 else theElements[i].refineLE();
00084 }
00085 i++;
00086 adjustMesh();
00087 }
00088 CthYield();
00089 }
00090
00091 if (CkMyPe() == 0) for (int j=0; j<numChunks; j++) mesh[j].print();
00092 refineInProgress = 0;
00093 CkPrintf("Chunk %d going inactive...\n", cid);
00094 }
00095
00096
00097
00098 void chunk::coarsenElement(int idx, double volume)
00099 {
00100
00101 CmiAssert((idx < numElements) && (idx >= 0));
00102 CmiAssert((volume >= 0.0) || (volume == -1.0));
00103 if (!theElements[idx].isPresent()) return;
00104 theElements[idx].resetTargetVolume(volume);
00105 modified = 1;
00106 if (!coarsenInProgress) {
00107 coarsenInProgress = 1;
00108 mesh[cid].coarseningElements();
00109 }
00110 }
00111
00112
00113 void chunk::coarseningElements()
00114 {
00115 int i;
00116
00117 while (modified) {
00118 i = 0;
00119 modified = 0;
00120 while (i < numElements) {
00121 if (theElements[i].isPresent() &&
00122 ((theElements[i].getTargetVolume() > theElements[i].getVolume())
00123 && (theElements[i].getTargetVolume() >= 0.0))) {
00124
00125 modified = 1;
00126 theElements[i].coarsen();
00127 if (CkMyPe() == 0) for (int j=0; j<5; j++) mesh[j].print();
00128 }
00129 i++;
00130 }
00131 CthYield();
00132 }
00133 coarsenInProgress = 0;
00134 }
00135
00136 void chunk::improveMesh()
00137 {
00138 for (int i=0; i<numElements; i++)
00139 theElements[i].improveElement();
00140 }
00141
00142 void chunk::relocatePoints()
00143 {
00144 for (int i=0; i<numNodes; i++)
00145 theNodes[i].relocateNode();
00146 }
00147
00148 void chunk::flippingElements()
00149 {
00150 int edge[2] = {2, 3};
00151
00152 if (cid == 0)
00153 theElements[0].flip32(edge);
00154
00155 }
00156
00157 intMsg *chunk::lockChunk(int lh, double prio)
00158 {
00159 intMsg *im = new intMsg;
00160 im->anInt = lockLocalChunk(lh, prio);
00161 return im;
00162 }
00163
00164 int chunk::lockLocalChunk(int lh, double prio)
00165 {
00166
00167
00168 if (!lock) {
00169
00170
00171 removeLock(lh);
00172 insertLock(lh, prio);
00173 if ((lockList->prio == prio) && (lockList->holder == lh)) {
00174 prioLockStruct *tmp = lockList;
00175
00176
00177 lock = 1; lockHolder = lh; lockPrio = prio; lockCount = 1;
00178 lockList = lockList->next;
00179 free(tmp);
00180 return 1;
00181 }
00182 removeLock(lh);
00183
00184
00185 return 0;
00186 }
00187 else {
00188 if ((prio == lockPrio) && (lh == lockHolder)) {
00189 lockCount++;
00190 return 1;
00191 }
00192 if (lh == lockHolder) {
00193 CkPrintf("ERROR: chunk holding lock trying to relock with different prio! lockHolder=%d prio=%f newprio=%f\n", lockHolder, lockPrio, prio);
00194 CmiAssert(lh != lockHolder);
00195 }
00196 removeLock(lh);
00197 insertLock(lh, prio);
00198 if ((lockList->prio == prio) && (lockList->holder == lh)) {
00199 if ((prio > lockPrio) ||
00200 ((prio == lockPrio) && (lh < lockHolder))) {
00201
00202
00203 return -1;
00204 }
00205 }
00206 removeLock(lh);
00207
00208
00209 return 0;
00210 }
00211 }
00212
00213 void chunk::insertLock(int lh, double prio)
00214 {
00215 prioLockStruct *newLock, *tmp;
00216
00217 newLock = (prioLockStruct *)malloc(sizeof(prioLockStruct));
00218 newLock->prio = prio;
00219 newLock->holder = lh;
00220 newLock->next = NULL;
00221 if (!lockList) lockList = newLock;
00222 else {
00223 if ((prio > lockList->prio) ||
00224 (prio == lockList->prio) && (lh < lockList->holder)) {
00225
00226 newLock->next = lockList;
00227 lockList = newLock;
00228 }
00229 else {
00230 tmp = lockList;
00231 while (tmp->next) {
00232 if ((prio < tmp->next->prio) || ((prio == tmp->next->prio) &&
00233 (lh > tmp->next->holder)))
00234 tmp = tmp->next;
00235 else break;
00236 }
00237 newLock->next = tmp->next;
00238 tmp->next = newLock;
00239 }
00240 }
00241 }
00242
00243 void chunk::removeLock(int lh)
00244 {
00245 prioLockStruct *tmp = lockList, *del;
00246 if (!lockList) return;
00247 if (tmp->holder == lh) {
00248 lockList = lockList->next;
00249 free(tmp);
00250 }
00251 else {
00252 while (tmp->next && (tmp->next->holder != lh))
00253 tmp = tmp->next;
00254 if (tmp->next) {
00255 del = tmp->next;
00256 tmp->next = del->next;
00257 free(del);
00258 }
00259 }
00260 }
00261
00262 void chunk::unlockChunk(int lh)
00263 {
00264 unlockLocalChunk(lh);
00265 }
00266
00267 void chunk::unlockLocalChunk(int lh)
00268 {
00269 if (lockHolder == lh) {
00270 lockCount--;
00271 if (lockCount == 0) {
00272 lock = 0;
00273 lockHolder = -1;
00274 lockPrio = -1.0;
00275
00276 }
00277 }
00278 }
00279
00280
00281
00282 void chunk::print()
00283 {
00284 getAccessLock();
00285 debug_print(debug_counter);
00286 debug_counter++;
00287 releaseAccessLock();
00288 }
00289
00290 void chunk::out_print()
00291 {
00292 FILE *fp;
00293 char filename[30];
00294 int i;
00295
00296 memset(filename, 0, 30);
00297 sprintf(filename, "mesh.out");
00298 fp = fopen(filename, "a");
00299
00300 if (cid == 0)
00301 fprintf(fp, "%d\n", numChunks);
00302 fprintf(fp, " %d %d %d\n", cid, numNodes, numElements);
00303 for (i=0; i<numNodes; i++)
00304 fprintf(fp, " %f %f %f\n", theNodes[i].getCoord(0), theNodes[i].getCoord(1), theNodes[i].getCoord(2));
00305 for (i=0; i<numElements; i++) {
00306 if (theElements[i].isPresent()) {
00307 fprintf(fp, " %d %d ", theElements[i].nodes[0].idx, theElements[i].nodes[0].cid);
00308 fprintf(fp, " %d %d ", theElements[i].nodes[1].idx, theElements[i].nodes[1].cid);
00309 fprintf(fp, " %d %d ", theElements[i].nodes[2].idx, theElements[i].nodes[2].cid);
00310 fprintf(fp, " %d %d ", theElements[i].nodes[3].idx, theElements[i].nodes[3].cid);
00311 }
00312 }
00313 fprintf(fp, "\n");
00314 fclose(fp);
00315 }
00316
00317
00318 nodeMsg *chunk::getNode(int n)
00319 {
00320 CmiAssert((n < numNodes) && (n >= 0));
00321 nodeMsg *nm = new nodeMsg;
00322 nm->coord[0] = theNodes[n].getCoord(0);
00323 nm->coord[1] = theNodes[n].getCoord(1);
00324 nm->coord[2] = theNodes[n].getCoord(2);
00325 return nm;
00326 }
00327
00328 void chunk::updateNodeCoord(nodeMsg *m)
00329 {
00330 CmiAssert((m->idx < numNodes) && (m->idx >= 0));
00331 theNodes[m->idx].set(m->coord[0], m->coord[1], m->coord[2]);
00332 CkFreeMsg(m);
00333 }
00334
00335 void chunk::relocationVote(nodeVoteMsg *m)
00336 {
00337 node oldNode(m->oldCoord[0], m->oldCoord[1], m->oldCoord[2]);
00338 node newNode(m->newCoord[0], m->newCoord[1], m->newCoord[2]);
00339
00340 for (int i=0; i<numNodes; i++)
00341 if (theNodes[i] == oldNode) {
00342 theNodes[i].relocationVote(newNode);
00343 return;
00344 }
00345 CkFreeMsg(m);
00346 }
00347
00348
00349 doubleMsg *chunk::getVolume(intMsg *im)
00350 {
00351 CmiAssert((im->anInt < numElements) && (im->anInt >= 0));
00352 doubleMsg *dm = new doubleMsg;
00353 dm->aDouble = theElements[im->anInt].getVolume();
00354 CkFreeMsg(im);
00355 return dm;
00356 }
00357
00358 void chunk::setTargetVolume(doubleMsg *dm)
00359 {
00360 CmiAssert((dm->idx < numElements) && (dm->idx >= 0));
00361 CmiAssert((dm->aDouble >= 0.0) || (dm->aDouble == -1.0));
00362 theElements[dm->idx].setTargetVolume(dm->aDouble);
00363 CkFreeMsg(dm);
00364 modified = 1;
00365 if (!refineInProgress) {
00366 refineInProgress = 1;
00367 mesh[cid].refiningElements();
00368 }
00369 }
00370
00371 void chunk::resetTargetVolume(doubleMsg *dm)
00372 {
00373 CmiAssert((dm->idx < numElements) && (dm->idx >= 0));
00374 CmiAssert((dm->aDouble >= 0.0) || (dm->aDouble == -1.0));
00375 theElements[dm->idx].resetTargetVolume(dm->aDouble);
00376 CkFreeMsg(dm);
00377 modified = 1;
00378 }
00379
00380 flip23response *chunk::flip23remote(flip23request *fr)
00381 {
00382 CmiAssert((fr->requestee < numElements) && (fr->requestee >= 0));
00383 flip23response *f23r;
00384 getAccessLock();
00385 f23r = theElements[fr->requestee].flip23remote(fr);
00386 releaseAccessLock();
00387 return f23r;
00388 }
00389
00390 flip32response *chunk::flip32remote(flip32request *fr)
00391 {
00392 CmiAssert((fr->requestee < numElements) && (fr->requestee >= 0));
00393 flip32response *f32r;
00394 getAccessLock();
00395 f32r = theElements[fr->requestee].flip32remote(fr);
00396 releaseAccessLock();
00397 return f32r;
00398 }
00399
00400 flip32response *chunk::remove32element(flip32request *fr)
00401 {
00402 CmiAssert((fr->requestee < numElements) && (fr->requestee >= 0));
00403 flip32response *f32r;
00404 getAccessLock();
00405 f32r = theElements[fr->requestee].remove32element(fr);
00406 releaseAccessLock();
00407 return f32r;
00408 }
00409
00410 intMsg *chunk::checkFace(int idx, elemRef face)
00411 {
00412 intMsg *result = new intMsg;
00413 getAccessLock();
00414 result->anInt = theElements[idx].hasFace(face);
00415 releaseAccessLock();
00416 return result;
00417 }
00418
00419 intMsg *chunk::checkFace(int idx, node n1, node n2, node n3, elemRef nbr)
00420 {
00421 intMsg *im = new intMsg;
00422 getAccessLock();
00423 im->anInt = theElements[idx].checkFace(n1, n2, n3, nbr);
00424 releaseAccessLock();
00425 return im;
00426 }
00427
00428
00429
00430 void chunk::debug_print(int c)
00431 {
00432 FILE *fp;
00433 char filename[30];
00434 int i;
00435
00436 memset(filename, 0, 30);
00437 sprintf(filename, "dbg_msh%d.%d", cid, c);
00438 fp = fopen(filename, "w");
00439
00440
00441 for (i=0; i<numNodes; i++) {
00442 fprintf(fp, "%lf %lf %lf ", theNodes[i].getCoord(0),
00443 theNodes[i].getCoord(1), theNodes[i].getCoord(2));
00444
00445
00446
00447
00448
00449
00450 if (i % 3 == 0)
00451 fprintf(fp, "0.0 0.0 0.1\n");
00452 else if (i % 3 == 1)
00453 fprintf(fp, "0.0 0.0 0.1\n");
00454 else fprintf(fp, "0.0 0.0 0.1\n");
00455 }
00456 fprintf(fp, "foo\n");
00457 for (i=0; i<numElements; i++) {
00458 if (theElements[i].present)
00459 fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d\n",
00460 theElements[i].nodes[0].idx, theElements[i].nodes[1].idx,
00461 theElements[i].nodes[2].idx,
00462 theElements[i].nodes[0].idx, theElements[i].nodes[1].idx,
00463 theElements[i].nodes[3].idx,
00464 theElements[i].nodes[0].idx, theElements[i].nodes[2].idx,
00465 theElements[i].nodes[3].idx,
00466 theElements[i].nodes[1].idx, theElements[i].nodes[2].idx,
00467 theElements[i].nodes[3].idx);
00468 }
00469 fclose(fp);
00470 }
00471
00472
00473 elemRef chunk::findNeighbor(nodeRef nr1, nodeRef nr2, nodeRef nr3, int lidx)
00474 {
00475 int i;
00476 refMsg *aResult;
00477 elemRef theResult(-1, -1);
00478
00479 for (i=0; i<numElements; i++)
00480 if (i != lidx)
00481 if (theElements[i].hasNodes(nr1, nr2, nr3)) {
00482 theResult.cid = cid;
00483 theResult.idx = i;
00484 return theResult;
00485 }
00486
00487 for (i=0; i<numChunks; i++)
00488 if (i != cid) {
00489 threeNodeMsg *tnm = new threeNodeMsg;
00490 tnm->coords[0][0] = theNodes[nr1.idx].getCoord(0);
00491 tnm->coords[0][1] = theNodes[nr1.idx].getCoord(1);
00492 tnm->coords[0][2] = theNodes[nr1.idx].getCoord(2);
00493 tnm->coords[1][0] = theNodes[nr2.idx].getCoord(0);
00494 tnm->coords[1][1] = theNodes[nr2.idx].getCoord(1);
00495 tnm->coords[1][2] = theNodes[nr2.idx].getCoord(2);
00496 tnm->coords[2][0] = theNodes[nr3.idx].getCoord(0);
00497 tnm->coords[2][1] = theNodes[nr3.idx].getCoord(1);
00498 tnm->coords[2][2] = theNodes[nr3.idx].getCoord(2);
00499 aResult = mesh[i].findRemoteNeighbor(tnm);
00500 if (aResult->idx >= 0) {
00501 theResult.idx = aResult->idx;
00502 theResult.cid = aResult->cid;
00503 return theResult;
00504 }
00505 }
00506 if (!faceOnSurface(nr1.idx, nr2.idx, nr3.idx))
00507 CkPrintf("ERROR: Search for neighbor of non-surface face FAILED.\n");
00508 return theResult;
00509 }
00510
00511 refMsg *chunk::findRemoteNeighbor(threeNodeMsg *tnm)
00512 {
00513 refMsg *theResult = new refMsg;
00514 node n1(tnm->coords[0][0], tnm->coords[0][1], tnm->coords[0][2]),
00515 n2(tnm->coords[1][0], tnm->coords[1][1], tnm->coords[1][2]),
00516 n3(tnm->coords[2][0], tnm->coords[2][1], tnm->coords[2][2]);
00517
00518 CkFreeMsg(tnm);
00519 for (int i=0; i<numElements; i++)
00520 if (theElements[i].hasNode(n1) && theElements[i].hasNode(n2) &&
00521 theElements[i].hasNode(n3)) {
00522 theResult->idx = i;
00523 theResult->cid = cid;
00524 return theResult;
00525 }
00526 theResult->idx = theResult->cid = -1;
00527 return theResult;
00528 }
00529
00530 nodeRef chunk::findNode(node n)
00531 {
00532 nodeRef foo;
00533 foo.cid = cid;
00534 for (int i=0; i<numNodes; i++)
00535 if (theNodes[i] == n) {
00536 foo.idx = i;
00537 return foo;
00538 }
00539 foo.idx = -1;
00540 return foo;
00541 }
00542
00543 intMsg *chunk::lockLF(int idx, node n1, node n2, node n3, node n4,
00544 elemRef requester, double prio)
00545 {
00546 forcedGetAccessLock();
00547 intMsg *result = new intMsg;
00548 result->anInt = theElements[idx].lockLF(n1, n2, n3, n4, requester, prio);
00549 releaseAccessLock();
00550 return result;
00551 }
00552
00553 splitResponse *chunk::splitLF(int idx, node in1, node in2, node in3, node in4,
00554 elemRef requester)
00555 {
00556 CmiAssert((idx < numElements) && (idx >= 0));
00557 getAccessLock();
00558 splitResponse *sr = theElements[idx].splitLF(in1, in2, in3, in4, requester);
00559 releaseAccessLock();
00560 return sr;
00561 }
00562
00563 LEsplitResult *chunk::LEsplit(LEsplitMsg *lsm)
00564 {
00565 forcedGetAccessLock();
00566 LEsplitResult *lsr = theElements[lsm->idx].LEsplit(lsm->root, lsm->parent,
00567 lsm->newNodeRef, lsm->newNode, lsm->newRootElem, lsm->newElem,
00568 lsm->targetElem, lsm->targetVol, lsm->a, lsm->b);
00569 CkFreeMsg(lsm);
00570 releaseAccessLock();
00571 return lsr;
00572 }
00573
00574 lockResult *chunk::lockArc(lockArcMsg *lm)
00575 {
00576 forcedGetAccessLock();
00577 lockResult *lr =
00578 theElements[lm->idx].lockArc(lm->prioRef, lm->parentRef, lm->prio,
00579 lm->destRef, lm->a, lm->b);
00580 CkFreeMsg(lm);
00581 releaseAccessLock();
00582 return lr;
00583 }
00584
00585 void chunk::unlockArc1(int idx, int prio, elemRef parentRef, elemRef destRef,
00586 node aNode, node bNode)
00587 {
00588 forcedGetAccessLock();
00589 theElements[idx].unlockArc1(prio, parentRef, destRef, aNode, bNode);
00590 releaseAccessLock();
00591 }
00592
00593 void chunk::unlockArc2(int idx, int prio, elemRef parentRef, elemRef destRef,
00594 node aNode, node bNode)
00595 {
00596 forcedGetAccessLock();
00597 theElements[idx].unlockArc2(prio, parentRef, destRef, aNode, bNode);
00598 releaseAccessLock();
00599 }
00600
00601 void chunk::updateFace(int idx, int rcid, int ridx)
00602 {
00603 CmiAssert((idx < numElements) && (idx >= 0));
00604 theElements[idx].updateFace(rcid, ridx);
00605 }
00606
00607 void chunk::updateFace(int idx, elemRef oldElem, elemRef newElem)
00608 {
00609 CmiAssert((idx < numElements) && (idx >= 0));
00610 theElements[idx].updateFace(oldElem, newElem);
00611 }
00612
00613
00614 int chunk::nodeOnSurface(int n)
00615 {
00616 return (!theSurface[n].empty());
00617 }
00618
00619 int chunk::edgeOnSurface(int n1, int n2)
00620 {
00621 for (unsigned int i=0; i<theSurface[n1].size(); i++) {
00622 if (theSurface[n1][i] == n2)
00623 return 1;
00624 }
00625 return 0;
00626 }
00627
00628 int chunk::faceOnSurface(int n1, int n2, int n3)
00629 {
00630 for (unsigned int i=0; i<theSurface[n1].size(); i+=2) {
00631 if (((theSurface[n1][i] == n2) && (theSurface[n1][i+1] == n3))
00632 || ((theSurface[n1][i] == n3) && (theSurface[n1][i+1] == n2)))
00633 return 1;
00634 }
00635 return 0;
00636 }
00637
00638 void chunk::updateFace(int n1, int n2, int n3, int oldNode, int newNode)
00639 {
00640 if (n1 == oldNode) {
00641
00642 simpleRemoveFace(n1, n2, n3);
00643
00644 simpleAddFace(newNode, n2, n3);
00645
00646 simpleUpdateFace(n2, n1, n3, newNode);
00647
00648 simpleUpdateFace(n3, n1, n2, newNode);
00649 }
00650 else if (n2 == oldNode) {
00651 simpleRemoveFace(n2, n1, n3);
00652 simpleAddFace(newNode, n1, n3);
00653 simpleUpdateFace(n1, n2, n3, newNode);
00654 simpleUpdateFace(n3, n2, n1, newNode);
00655 }
00656 else if (n3 == oldNode) {
00657 simpleRemoveFace(n3, n1, n2);
00658 simpleAddFace(newNode, n1, n2);
00659 simpleUpdateFace(n1, n3, n2, newNode);
00660 simpleUpdateFace(n2, n3, n1, newNode);
00661 }
00662 else CkPrintf("ERROR: updateFace: oldNode not on input face!\n");
00663 }
00664
00665 void chunk::simpleUpdateFace(int n1, int n2, int n3, int newNode)
00666 {
00667 for (unsigned int i=0; i<theSurface[n1].size(); i+=2) {
00668 if ((theSurface[n1][i] == n2) && (theSurface[n1][i+1] == n3))
00669 theSurface[n1][i] = newNode;
00670 else if ((theSurface[n1][i] == n3) && (theSurface[n1][i+1] == n2))
00671 theSurface[n1][i+1] = newNode;
00672 }
00673 }
00674
00675 void chunk::simpleRemoveFace(int n1, int n2, int n3)
00676 {
00677 for (unsigned int i=0; i<theSurface[n1].size(); i+=2) {
00678 if (((theSurface[n1][i] == n2) && (theSurface[n1][i+1] == n3))
00679 || ((theSurface[n1][i] == n3) && (theSurface[n1][i+1] == n2))) {
00680 theSurface[n1][i] = theSurface[n1][theSurface[n1].size()-2];
00681 theSurface[n1][i+1] = theSurface[n1][theSurface[n1].size()-1];
00682 theSurface[n1].pop_back();
00683 theSurface[n1].pop_back();
00684 }
00685 }
00686 }
00687
00688 void chunk::addFace(int n1, int n2, int n3)
00689 {
00690 simpleAddFace(n1, n2, n3);
00691 simpleAddFace(n2, n1, n3);
00692 simpleAddFace(n3, n1, n2);
00693 }
00694
00695 void chunk::removeFace(int n1, int n2, int n3)
00696 {
00697 simpleRemoveFace(n1, n2, n3);
00698 simpleRemoveFace(n2, n1, n3);
00699 simpleRemoveFace(n3, n1, n2);
00700 }
00701
00702 void chunk::simpleAddFace(int n1, int n2, int n3)
00703 {
00704 theSurface[n1].push_back(n2);
00705 theSurface[n1].push_back(n3);
00706 }
00707
00708 void chunk::printSurface()
00709 {
00710 for (unsigned int i=0; i<theSurface.size(); i++)
00711 if (theSurface[i].size() > 0) {
00712 CkPrintf("Node %d: ", i);
00713 for (unsigned int j=0; j<theSurface[i].size(); j++)
00714 CkPrintf(" %d", theSurface[i][j]);
00715 CkPrintf("\n");
00716 }
00717 }
00718
00719
00720
00721 void chunk::getAccessLock()
00722 {
00723 while (adjustLock)
00724 CthYield();
00725 accessLock++;
00726 }
00727
00728 void chunk::forcedGetAccessLock()
00729 {
00730 if ((accessLock > 0) || (adjustLock == 0))
00731 accessLock++;
00732 else getAccessLock();
00733 }
00734
00735 void chunk::releaseAccessLock()
00736 {
00737 accessLock--;
00738 }
00739
00740 void chunk::getAdjustLock()
00741 {
00742 adjustLock = 1;
00743 while (accessLock)
00744 CthYield();
00745 }
00746
00747 void chunk::releaseAdjustLock()
00748 {
00749 adjustLock = 0;
00750 }
00751
00752
00753 void chunk::allocMesh(int nEl)
00754 {
00755 sizeElements = nEl + 10000;
00756 sizeNodes = sizeElements * 3;
00757 theElements.resize(sizeElements);
00758 theNodes.resize(sizeNodes);
00759 theSurface.resize(sizeNodes);
00760 for (int i=0; i<sizeElements; i++)
00761 theElements[i].set(cid, i, this);
00762 }
00763
00764 void chunk::adjustMesh()
00765 {
00766 if (3*numElements >= sizeElements) {
00767 getAdjustLock();
00768 CkPrintf("[%d] Adjusting # elements...\n", cid);
00769 sizeElements += 3*numElements;
00770 theElements.resize(sizeElements);
00771 CkPrintf("[%d] Done adjusting # elements...\n", cid);
00772 for (int i=numElements; i<sizeElements; i++)
00773 theElements[i].set(cid, i, this);
00774 releaseAdjustLock();
00775 }
00776 if (3*numElements >= sizeNodes) {
00777 getAdjustLock();
00778 CkPrintf("[%d] Adjusting # nodes...\n", cid);
00779 sizeNodes += 3*numElements;
00780 theNodes.resize(sizeNodes);
00781 theSurface.resize(sizeNodes);
00782 CkPrintf("[%d] Done adjusting # nodes...\n", cid);
00783 releaseAdjustLock();
00784 }
00785 }
00786
00787 nodeRef chunk::addNode(node& n)
00788 {
00789 nodeRef nRef(cid, numNodes);
00790
00791 theNodes[numNodes] = n;
00792 if (n.isFixed() < 0)
00793 CkPrintf("ERROR: chunk::addNode: must initialize fixed status of node!\n");
00794 if (n.onSurface() < 0)
00795 CkPrintf("ERROR: chunk::addNode: must initialize surface status of node!\n");
00796 numNodes++;
00797 return nRef;
00798 }
00799
00800 elemRef chunk::addElement(nodeRef& nr1, nodeRef& nr2, nodeRef& nr3, nodeRef& nr4)
00801 {
00802 elemRef eRef(cid, numElements);
00803 nodeRef n[4] = {nr1, nr2, nr3, nr4};
00804
00805 CmiAssert(numElements < sizeElements);
00806 CmiAssert((nr1.idx >= 0) && (nr1.idx < numNodes));
00807 CmiAssert((nr2.idx >= 0) && (nr2.idx < numNodes));
00808 CmiAssert((nr3.idx >= 0) && (nr3.idx < numNodes));
00809 CmiAssert((nr4.idx >= 0) && (nr4.idx < numNodes));
00810 theElements[numElements].set(cid, numElements, this);
00811 theElements[numElements].set(n);
00812 numElements++;
00813 return eRef;
00814 }
00815
00816 void chunk::removeNode(intMsg *im)
00817 {
00818 CmiAssert((im->anInt < numNodes) && (im->anInt >= 0));
00819 theNodes[im->anInt].reset();
00820 CkFreeMsg(im);
00821 }
00822
00823 void chunk::removeElement(intMsg *im)
00824 {
00825 CmiAssert((im->anInt < numElements) && (im->anInt >= 0));
00826 theElements[im->anInt].clear();
00827 CkFreeMsg(im);
00828 }
00829
00830
00831 void chunk::newMesh(int nEl, int nGhost,const int *conn_,const int *gid_,
00832 int *surface, int nSurFaces, int idxOffset)
00833 {
00834 int i, j;
00835
00836 numElements=nEl;
00837 allocMesh(nEl);
00838
00839
00840 for (i=0; i<numElements; i++) {
00841 nodeRef nodes[4];
00842 for (j=0; j<4; j++) {
00843 nodes[j].idx = conn_[i*4+j]-idxOffset;
00844 nodes[j].cid = cid;
00845 }
00846 theElements[i].set(cid, i, this);
00847 theElements[i].set(nodes);
00848 }
00849
00850
00851 int aNode;
00852 numNodes = 0;
00853 for (i=0; i<numElements; i++) {
00854 for (j=0; j<4; j++) {
00855 aNode = theElements[i].nodes[j].idx;
00856 theNodes[aNode].set(cid, aNode, this);
00857 theNodes[aNode].notFixed();
00858 theNodes[aNode].notSurface();
00859 if ((aNode + 1) > numNodes)
00860 numNodes = aNode + 1;
00861 }
00862 }
00863
00864
00865 for (i=0; i<nSurFaces; i++) {
00866 addFace(surface[3*i], surface[3*i+1], surface[3*i+2]);
00867 theNodes[surface[3*i]].setSurface();
00868 theNodes[surface[3*i+1]].setSurface();
00869 theNodes[surface[3*i+2]].setSurface();
00870 }
00871 printSurface();
00872
00873 for (i=0; i<numNodes; i++)
00874 if (nodeOnSurface(i))
00875 theNodes[i].setSurface();
00876 }
00877
00878 void chunk::deriveFaces()
00879 {
00880 int f, i,j,k,l;
00881 nodeRef nr1, nr2, nr3;
00882 for (i=0; i<numElements; i++) {
00883 f = 0;
00884 CkPrintf("Deriving faces for element %d on chunk %d\n", i, cid);
00885 for (j=0; j<4; j++)
00886 for (k=j+1; k<4; k++)
00887 for (l=k+1; l<4; l++) {
00888 CkPrintf("Looking for face %d from nodes (%d,%d,%d)\n",f,j,k,l);
00889 nr1 = theElements[i].getNode(j);
00890 nr2 = theElements[i].getNode(k);
00891 nr3 = theElements[i].getNode(l);
00892 theElements[i].faceElements[f] = findNeighbor(nr1, nr2, nr3, i);
00893 f++;
00894 }
00895 }
00896 CkPrintf("Done deriving faces!\n");
00897 }
00898
00899 void chunk::updateNodeCoords(int nNode, double *coord, int nEl, int nFx,
00900 int *fixed)
00901 {
00902 int i;
00903
00904 if (nEl != numElements)
00905 CkPrintf("ERROR: updateNodeCoords: nEl(%d) != numElements(%d) on chunk %d\n", nEl, numElements, cid);
00906 if (nNode != numNodes)
00907 CkPrintf("ERROR: updateNodeCoords: nNode(%d) != numNodes(%d) on chunk %d\n", nNode, numNodes, cid);
00908
00909
00910 for (i=0; i<numNodes; i++)
00911 theNodes[i].set(coord[3*i], coord[3*i + 1], coord[3*i + 2]);
00912
00913 for (i=0; i<nFx; i++)
00914 theNodes[fixed[i]].fix();
00915 }
00916
00917 void chunk::refine(double *desiredVolume, refineClient *client)
00918 {
00919 int i;
00920 theClient = client;
00921
00922
00923 for (i=0; i<numElements; i++)
00924 if (desiredVolume[i] < theElements[i].getVolume())
00925 theElements[i].setTargetVolume(desiredVolume[i]);
00926
00927
00928 modified = 1;
00929 refineInProgress = 1;
00930 mesh[cid].refiningElements();
00931 }
00932
00933 void chunk::coarsen(double *desiredVolume, refineClient *client)
00934 {
00935 }
00936
00937 void chunk::improve(refineClient *client)
00938 {
00939 }
00940
00941
00942 void chunk::newMesh(meshMsg *mm)
00943 {
00944 newMesh(mm->numElements, mm->numGhosts, mm->conn, mm->gid, mm->surface,
00945 mm->numSurFaces, mm->idxOffset);
00946 CkFreeMsg(mm);
00947 }
00948
00949 void chunk::updateNodeCoords(coordMsg *cm)
00950 {
00951 updateNodeCoords(cm->numNodes, cm->coords, cm->numElements, cm->numFixed,
00952 cm->fixedNodes);
00953 CkFreeMsg(cm);
00954 }
00955
00956 void chunk::refine()
00957 {
00958
00959
00960
00961
00962
00963
00964
00965
00966 if (cid == 0) {
00967
00968 theElements[0].setTargetVolume(theElements[0].getVolume()/3000.0);
00969 }
00970
00971 }
00972
00973 void chunk::start()
00974 {
00975 modified = 1;
00976 if (!refineInProgress) {
00977 refineInProgress = 1;
00978 mesh[cid].refiningElements();
00979 }
00980 }
00981
00982 void chunk::improve()
00983 {
00984 mesh[cid].improveMesh();
00985 }
00986
00987 void chunk::finalizeImprovements()
00988 {
00989 mesh[cid].relocatePoints();
00990 }
00991
00992 void chunk::checkRefine()
00993 {
00994 double vol, tvol;
00995 for (int i=0; i<numElements; i++) {
00996 vol = theElements[i].getVolume();
00997 if (vol >= 0.000416) {
00998 CkPrintf("WARNING: On chunk %d element %d is not adequately refined: volume=%f\n",
00999 cid, i, vol);
01000 }
01001 }
01002 }
01003
01004 #include "PMAF.def.h"