00001
00002
00003
00004
00005
00006 #include "ParFUM.h"
00007 #include "ParFUM_internals.h"
00008
00009
00010
00011 #define ERVAL -1000000000 //might cause a problem if there are 100million nodes
00012 #define ERVAL1 -1000000001
00013
00018 int FEM_AdaptL::lockNodes(int *gotlocks, int *lockrnodes, int numRNodes, int *lockwnodes, int numWNodes) {
00019 #ifdef CPSD
00020 return true;
00021 #endif
00022 bool donelocks = false;
00023 int numNodes = numRNodes + numWNodes;
00024 for(int i=0; i<numNodes; i++) gotlocks[i] = 0;
00025 int tryCounts=0;
00026 int ret = 1;
00027
00028 while(!donelocks) {
00029 for(int i=0; i<numRNodes; i++) {
00030 if(lockrnodes[i]==-1) {
00031 gotlocks[i] = 1;
00032 continue;
00033 }
00034 if(FEM_Is_ghost_index(lockrnodes[i])) {
00035 if(!theMesh->node.ghost->is_valid(FEM_To_ghost_index(lockrnodes[i]))) {
00036 ret = -3;
00037 break;
00038 }
00039 } else {
00040 if(!theMesh->node.is_valid(lockrnodes[i])) {
00041 ret = -3;
00042 break;
00043 }
00044 }
00045 if(gotlocks[i]<=0) {
00046 gotlocks[i] = FEM_Modify_LockN(theMesh, lockrnodes[i], 1);
00047 if(gotlocks[i]==-2) {
00048 gotlocks[i] = -1;
00049 return -2;
00050 }
00051 }
00052 }
00053 for(int i=0; i<numWNodes; i++) {
00054 if(lockwnodes[i]==-1) {
00055 gotlocks[numRNodes+i] = 1;
00056 continue;
00057 }
00058 if(FEM_Is_ghost_index(lockwnodes[i])) {
00059 if(!theMesh->node.ghost->is_valid(FEM_To_ghost_index(lockwnodes[i]))) {
00060 #ifdef DEBUG_LOCKS
00061 CkPrintf("[%d] Trying to lock invalid ghost %d\n",theMod->idx,lockwnodes[i]);
00062 #endif
00063 ret = -3;
00064 break;
00065 }
00066 } else {
00067 if(!theMesh->node.is_valid(lockwnodes[i])) {
00068 #ifdef DEBUG_LOCKS
00069 CkPrintf("[%d] Trying to lock invalid node %d\n",theMod->idx,lockwnodes[i]);
00070 #endif
00071 ret = -3;
00072 break;
00073 }
00074 }
00075 if(gotlocks[numRNodes+i]<=0) {
00076 gotlocks[numRNodes+i] = FEM_Modify_LockN(theMesh, lockwnodes[i], 0);
00077 if(gotlocks[numRNodes+i]==-2) {
00078 gotlocks[numRNodes+i] = -1;
00079 return -2;
00080 }
00081 }
00082 }
00083 if(ret==-3) return ret;
00084 bool tmplocks = true;
00085 for(int i=0; i<numNodes; i++) {
00086 tmplocks = tmplocks && (gotlocks[i]>0);
00087 }
00088 if(tmplocks) {
00089 donelocks = true;
00090 }
00091 else {
00092 tryCounts++;
00093 if(tryCounts>=10) return -1;
00094 CthYield();
00095 }
00096 }
00097 return 1;
00098 }
00099
00102 int FEM_AdaptL::unlockNodes(int *gotlocks, int *lockrnodes, int numRNodes, int *lockwnodes, int numWNodes) {
00103 #ifdef CPSD
00104 return true;
00105 #endif
00106 bool donelocks = false;
00107 int numNodes = numRNodes + numWNodes;
00108 int *ungetlocks = (int*)malloc(numNodes*sizeof(int));
00109 for(int i=0; i<numRNodes; i++) {
00110 if(lockrnodes[i]==-1) {
00111 ungetlocks[i] = 1;
00112 continue;
00113 }
00114 if(FEM_Is_ghost_index(lockrnodes[i])) {
00115 if(!theMesh->node.ghost->is_valid(FEM_To_ghost_index(lockrnodes[i]))) {
00116 gotlocks[i] = -1;
00117 }
00118 } else {
00119 if(!theMesh->node.is_valid(lockrnodes[i])) {
00120 gotlocks[i] = -1;
00121 }
00122 }
00123 if(gotlocks[i]>0) ungetlocks[i] = FEM_Modify_UnlockN(theMesh, lockrnodes[i], 1);
00124 else ungetlocks[i] = 1;
00125 }
00126 for(int i=0; i<numWNodes; i++) {
00127 if(lockwnodes[i]==-1) {
00128 ungetlocks[numRNodes+i] = 1;
00129 continue;
00130 }
00131 if(FEM_Is_ghost_index(lockwnodes[i])) {
00132 if(!theMesh->node.ghost->is_valid(FEM_To_ghost_index(lockwnodes[i]))) {
00133 gotlocks[i] = -1;
00134 #ifdef DEBUG_LOCKS
00135 CkPrintf("[%d] Trying to unlock invalid ghost %d\n",theMod->idx,lockwnodes[i]);
00136 #endif
00137 }
00138 } else {
00139 if(!theMesh->node.is_valid(lockwnodes[i])) {
00140 gotlocks[i] = -1;
00141 #ifdef DEBUG_LOCKS
00142 CkPrintf("[%d] Trying to unlock invalid node %d\n",theMod->idx,lockwnodes[i]);
00143 #endif
00144 }
00145 }
00146 if(gotlocks[numRNodes+i]>0) ungetlocks[numRNodes+i] = FEM_Modify_UnlockN(theMesh, lockwnodes[i], 0);
00147 else ungetlocks[numRNodes+i] = 1;
00148 }
00149 bool tmplocks = true;
00150 for(int i=0; i<numNodes; i++) {
00151 tmplocks = tmplocks && (ungetlocks[i]>0);
00152 }
00153 if(tmplocks) donelocks = true;
00154 free(ungetlocks);
00155 return 1;
00156 }
00157
00158
00159
00160 int FEM_AdaptL::edge_flip(int n1, int n2) {
00161 int e1, e1_n1, e1_n2, e1_n3, n3;
00162 int e2, e2_n1, e2_n2, e2_n3, n4;
00163 int numNodes = 4;
00164 int locknodes[4];
00165 int gotlocks[4];
00166 bool done = false;
00167 int isEdge = 0;
00168 int numtries = 0;
00169 bool warned = false;
00170
00171 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00172 if(isEdge == -1) {
00173
00174 return -1;
00175 }
00176 locknodes[0] = n1;
00177 locknodes[1] = n2;
00178 locknodes[2] = n3;
00179 locknodes[3] = n4;
00180 for(int i=0; i<numNodes; i++) {
00181 gotlocks[i] = -1;
00182 }
00183 while(!done) {
00184 int gotlock = lockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00185 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00186 if(isEdge == -1) {
00187 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00188
00189 return -1;
00190 }
00191 if(gotlock==1 && locknodes[2]==n3 && locknodes[3]==n4) {
00192 done = true;
00193 }
00194 else {
00195 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00196 locknodes[2] = n3;
00197 locknodes[3] = n4;
00198 numtries++;
00199 if(numtries>=13+(7*theMod->idx)%43) {
00200 if(!warned) {
00201 CkPrintf("[%d]Warning: Possibly a livelock in edge_flip %d & %d, supporting %d, %d\n",theMod->idx,n1,n2,n3,n4);
00202 warned = true;
00203 }
00204 CthYield();
00205
00206 return -1;
00207 }
00208 CthYield();
00209 }
00210 }
00211 if ((e1 == -1) || (e2 == -1)) {
00212 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00213 return -1;
00214 }
00215 int ret = edge_flip_help(e1, e2, n1, n2, e1_n1, e1_n2, e1_n3, n3, n4,locknodes);
00216
00217
00218
00219
00220 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00221
00222 return ret;
00223 }
00224
00225 int FEM_AdaptL::edge_bisect(int n1, int n2) {
00226 int e1, e1_n1, e1_n2, e1_n3, n3;
00227 int e2, e2_n1, e2_n2, e2_n3, n4;
00228 int numNodes = 4;
00229 int locknodes[4];
00230 int gotlocks[4];
00231 bool done = false;
00232 int isEdge = 0;
00233 int numtries = 0;
00234 bool warned = false;
00235
00236 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00237 if(isEdge == -1) {
00238 #ifdef DEBUG_1
00239 CkPrintf("[%d]Warning: Bisect %d->%d not done as it is no longer a valid edge\n",theMod->idx,n1,n2);
00240 #endif
00241 return -1;
00242 }
00243 locknodes[0] = n1;
00244 locknodes[1] = n2;
00245 locknodes[2] = n3;
00246 locknodes[3] = n4;
00247 for(int i=0; i<numNodes; i++) {
00248 gotlocks[i] = -1;
00249 }
00250 #ifdef CPSD
00251 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00252 #else
00253 while(!done) {
00254 int gotlock = lockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00255 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00256 if(isEdge == -1) {
00257 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00258 #ifdef DEBUG_1
00259 CkPrintf("[%d]Warning: Bisect %d->%d not done as it is no longer a valid edge\n",theMod->idx,n1,n2);
00260 #endif
00261 return -1;
00262 }
00263 if(gotlock==1 && locknodes[2]==n3 && locknodes[3]==n4) {
00264 done = true;
00265 }
00266 else {
00267 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00268 locknodes[2] = n3;
00269 locknodes[3] = n4;
00270 numtries++;
00271 if(numtries>=13+(7*theMod->idx)%43) {
00272 if(!warned) {
00273 CkPrintf("[%d]Warning: Possibly a livelock in edge_bisect %d & %d, supporting %d, %d\n",theMod->idx,n1,n2,n3,n4);
00274 warned = true;
00275 }
00276 numtries = 0;
00277 CthYield();
00278 return -1;
00279 }
00280 CthYield();
00281 }
00282 }
00283 #endif
00284 int ret = edge_bisect_help(e1, e2, n1, n2, e1_n1, e1_n2, e1_n3, e2_n1, e2_n2, e2_n3, n3, n4);
00285 #ifndef CPSD
00286 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00287 #endif
00288 return ret;
00289 }
00290
00291 int FEM_AdaptL::vertex_remove(int n1, int n2) {
00292 int e1, e1_n1, e1_n2, e1_n3, n3;
00293 int e2, e2_n1, e2_n2, e2_n3, n4;
00294 int numNodes = 5;
00295 int numElems = 2;
00296 int locknodes[5];
00297 int gotlocks[5];
00298 bool done = false;
00299 int isEdge = 0;
00300 int numtries = 0;
00301 bool warned = false;
00302
00303 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00304 if(isEdge == -1) {
00305
00306 return -1;
00307 }
00308 if (e1 == -1) {
00309 return 0;
00310 }
00311
00312 int *nbrNodes, nnsize, n5;
00313 theMesh->n2n_getAll(n1, nbrNodes, nnsize);
00314 if(!(nnsize == 4 || (nnsize==3 && e2==-1))) {
00315
00316 return -1;
00317 }
00318 for (int i=0; i<nnsize; i++) {
00319 if ((nbrNodes[i] != n2) && (nbrNodes[i] != n3) && (nbrNodes[i] != n4)) {
00320 n5 = nbrNodes[i];
00321 break;
00322 }
00323 }
00324 free(nbrNodes);
00325 locknodes[0] = n1;
00326 locknodes[1] = n2;
00327 locknodes[2] = n3;
00328 locknodes[3] = n4;
00329 locknodes[4] = n5;
00330 for(int i=0; i<numNodes; i++) {
00331 gotlocks[i] = -1;
00332 }
00333 while(!done) {
00334 int gotlock = lockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00335 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00336 if(isEdge == -1) {
00337 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00338
00339 return -1;
00340 }
00341 if (e1 == -1) {
00342 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00343 return 0;
00344 }
00345
00346 int *nbrNodes, nnsize, n5;
00347 theMesh->n2n_getAll(n1, nbrNodes, nnsize);
00348 for (int i=0; i<nnsize; i++) {
00349 if ((nbrNodes[i] != n2) && (nbrNodes[i] != n3) && (nbrNodes[i] != n4)) {
00350 n5 = nbrNodes[i];
00351 break;
00352 }
00353 }
00354 free(nbrNodes);
00355 if(!(nnsize == 4 || (nnsize==3 && e2==-1))) {
00356 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00357
00358 return -1;
00359 }
00360 if(gotlock==1 && locknodes[2]==n3 && locknodes[3]==n4 && locknodes[4]==n5) {
00361 done = true;
00362 }
00363 else {
00364 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00365 locknodes[2] = n3;
00366 locknodes[3] = n4;
00367 locknodes[4] = n5;
00368 numtries++;
00369 if(numtries>=13+(7*theMod->idx)%43) {
00370 if(!warned) {
00371 CkPrintf("[%d]Warning: Possibly a livelock in vertex_remove %d & %d, supporting %d, %d and %d\n",theMod->idx,n1,n2,n3,n4,n5);
00372 warned = true;
00373 }
00374 numtries = 0;
00375 CthYield();
00376 }
00377 CthYield();
00378 }
00379 }
00380 int ret = vertex_remove_help(e1, e2, n1, n2, e1_n1, e1_n2, e1_n3, e2_n1, e2_n2, e2_n3, n3, n4, n5);
00381 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00382
00383 return ret;
00384 }
00385
00386
00407 int FEM_AdaptL::edge_contraction(int n1, int n2) {
00408 int e1, e1_n1, e1_n2, e1_n3, n3;
00409 int e2, e2_n1, e2_n2, e2_n3, n4;
00410 int numNodes = 4;
00411 int numElems = 2;
00412 int locknodes[4];
00413 int gotlocks[4];
00414 bool done = false;
00415 int isEdge = 0;
00416 int numtries = 0;
00417 int ret = -1;
00418 bool warned = false;
00419 int newe1=-1, newe2=-1;
00420 int acquirecount=0;
00421
00422 bool invalidcoarsen = false;
00423 if(n1<0 || n2<0) {
00424 invalidcoarsen = true;
00425 }
00426 if(n1>0) {
00427 if(!theMesh->node.is_valid(n1))
00428 invalidcoarsen = true;
00429 }
00430 if(n2>0) {
00431 if(!theMesh->node.is_valid(n2))
00432 invalidcoarsen = true;
00433 }
00434 if(invalidcoarsen) {
00435 #ifndef FEM_SILENT
00436 CkPrintf("[%d]Warning: Trying to coarsen invalid edge %d - %d\n",theMod->idx,n1,n2);
00437 #endif
00438 return -1;
00439 }
00440 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00441 if(isEdge == -1) {
00442 #ifndef FEM_SILENT
00443 CkPrintf("[%d]Edge Contract %d->%d not done as it is no longer a valid edge\n",theMod->idx,n1,n2);
00444 #endif
00445 return -1;
00446 }
00447 locknodes[0] = n1;
00448 locknodes[1] = n2;
00449 locknodes[2] = n3;
00450 locknodes[3] = n4;
00451 if (e1 == -1) {
00452 return -1;
00453 }
00454 bool locked;
00455 int gotlock = 0;
00456 for(int i=0; i<numNodes; i++) {
00457 gotlocks[i] = -1;
00458 }
00459 while(!done) {
00460 if(ret==ERVAL1) {
00461 acquirecount++;
00462 ret=-1;
00463
00464 int *newnodes = new int[4];
00465 int newcount=0;
00466 if(newe1!=-1 && newe2!=-1) {
00467 int *e1conns = new int[3];
00468 int *e2conns = new int[3];
00469 theMesh->e2n_getAll(newe1,e1conns,0);
00470 theMesh->e2n_getAll(newe2,e2conns,0);
00471 for(int i=0; i<3; i++) {
00472 for(int j=0; j<3; j++) {
00473 if(e1conns[i] == e2conns[j]) {
00474 newnodes[newcount++] = e1conns[i];
00475 break;
00476 }
00477 }
00478 }
00479 if(newcount!=2) {
00480
00481
00482 CkAssert(FEM_Is_ghost_index(newe1) && FEM_Is_ghost_index(newe2));
00483 if(newe1!=e1) {
00484 theMesh->e2n_getAll(newe1,newnodes,0);
00485 }
00486 if(newe2!=e2) {
00487 theMesh->e2n_getAll(newe2,newnodes,0);
00488 }
00489 newcount=3;
00490
00491 for(int i=0; i<4; i++) {
00492 bool othernodevalid = true;
00493 for(int j=0; j<3; j++) {
00494 if(locknodes[i] == newnodes[j]) othernodevalid = false;
00495 }
00496 if(othernodevalid && FEM_Is_ghost_index(locknodes[i])) {
00497 newnodes[newcount++]=locknodes[i];
00498 }
00499 }
00500 }
00501 else {
00502 for(int i=0; i<3; i++) {
00503 if(e1conns[i]!=newnodes[0] && e1conns[i]!=newnodes[1]) {
00504 newnodes[newcount++] = e1conns[i];
00505 break;
00506 }
00507 }
00508 CkAssert(newcount==3);
00509 for(int i=0; i<3; i++) {
00510 if(e2conns[i]!=newnodes[0] && e2conns[i]!=newnodes[1]) {
00511 newnodes[newcount++] = e2conns[i];
00512 break;
00513 }
00514 }
00515 CkAssert(newcount==4);
00516 }
00517 delete [] e1conns;
00518 delete [] e2conns;
00519 }
00520 else{
00521 if(newe1!=-1) {
00522 theMesh->e2n_getAll(newe1,newnodes,0);
00523 newcount=3;
00524 }
00525 else if(newe2!=-1) {
00526 theMesh->e2n_getAll(newe2,newnodes,0);
00527 newcount=3;
00528 }
00529 }
00530 e1 = newe1;
00531 e2 = newe2;
00532 n1 = newnodes[0];
00533 n2 = newnodes[1];
00534 n3 = newnodes[2];
00535 n4 = newnodes[3];
00536 locknodes[0] = n1;
00537 locknodes[1] = n2;
00538 locknodes[2] = n3;
00539 locknodes[3] = n4;
00540 numNodes = newcount;
00541 delete [] newnodes;
00542 if(numNodes!=0) {
00543 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00544 } else {
00545 isEdge=-1;
00546 }
00547 if(isEdge == -1 || acquirecount>=2) {
00548 if(locked) {
00549
00550
00551 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00552 locked = false;
00553 }
00554 if(acquirecount>2) {
00555 #ifndef FEM_SILENT
00556 CkPrintf("[%d]Edge contract %d->%d not done as it is causes an acquire livelock\n",theMod->idx,n1,n2);
00557 #endif
00558 }
00559 #ifndef FEM_SILENT
00560 CkPrintf("[%d]Edge contract %d->%d not done as it is no longer a valid edge\n",theMod->idx,n1,n2);
00561 #endif
00562 return -1;
00563 }
00564 if (e1==-1 || e2==-1) {
00565 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00566 return -1;
00567 }
00568 if(locknodes[2]==n4 && locknodes[3]==n3) {
00569 n3 = locknodes[2];
00570 n4 = locknodes[3];
00571 }
00572 gotlock = 1;
00573 }
00574 else {
00575 gotlock = lockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00576 }
00577 locked = true;
00578 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00579 if(isEdge == -1) {
00580 if(locked) {
00581 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00582 locked = false;
00583 }
00584 #ifndef FEM_SILENT
00585 CkPrintf("[%d]Edge contract %d->%d not done as it is no longer a valid edge\n",theMod->idx,n1,n2);
00586 #endif
00587 return -1;
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 if(gotlock==1 && locknodes[2]==n3 && locknodes[3]==n4) {
00599 int numtries1=0;
00600 ret = ERVAL;
00601 while(ret==ERVAL && numtries1 < 5) {
00602 newe1=e1; newe2=e2;
00603 ret = edge_contraction_help(&newe1, &newe2, n1, n2, e1_n1, e1_n2, e1_n3, e2_n1, e2_n2, e2_n3, n3, n4);
00604 if(ret == ERVAL1) {
00605 done = false;
00606 }
00607 else if(ret == ERVAL) {
00608 numtries1++;
00609 if(numtries1 >= 5) {
00610 locknodes[2] = n3;
00611 locknodes[3] = n4;
00612 if(locked) {
00613 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00614 locked = false;
00615 }
00616 numtries+=10;
00617 }
00618 CthYield();
00619 }
00620 else {
00621 done = true;
00622 }
00623 }
00624 if(numtries>=50) {
00625 CkPrintf("Possibly a livelock in cloud nodes edge_contract\n");
00626
00627 isEdge = findAdjData(n1, n2, &e1, &e2, &e1_n1, &e1_n2, &e1_n3, &e2_n1, &e2_n2, &e2_n3,&n3, &n4);
00628 if(isEdge!=-1) {
00629 locknodes[2] = n3;
00630 locknodes[3] = n4;
00631 }
00632 if(locked) {
00633 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00634 locked = false;
00635 }
00636 return -1;
00637 }
00638 }
00639 else {
00640 if(locked) {
00641 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00642 locked = false;
00643 }
00644 locknodes[2] = n3;
00645 locknodes[3] = n4;
00646 numtries++;
00647 if(numtries>=50) {
00648 if(!warned) {
00649 CkPrintf("[%d]Warning: Possibly a livelock in edge_contract %d & %d, supporting %d, %d. Avoiding this contract operation.\n",theMod->idx,n1,n2,n3,n4);
00650 warned = true;
00651 }
00652
00653 return -1;
00654 }
00655 CthYield();
00656 }
00657 }
00658 if(locked) {
00659 int deletednode = -1;
00660 if(ret==n1) deletednode = n2;
00661 else if(ret==n2) deletednode = n1;
00662 if(deletednode!=-1) {
00663 for(int i=0; i<numNodes;i++) {
00664 if(locknodes[i]==deletednode) locknodes[i]=-1;
00665 }
00666 }
00667 unlockNodes(gotlocks, locknodes, 0, locknodes, numNodes);
00668 locked = false;
00669 }
00670 return ret;
00671 }
00672
00673 int FEM_AdaptL::edge_contraction_help(int *e1P, int *e2P, int n1, int n2, int e1_n1,
00674 int e1_n2, int e1_n3, int e2_n1,
00675 int e2_n2, int e2_n3, int n3, int n4)
00676 {
00677 int e1=*e1P, e2=*e2P;
00678 int e1chunk=-1, e2chunk=-1;
00679 int index = theMod->getIdx();
00680
00681 int n1_shared=0, n2_shared=0;
00682 bool same = true;
00683 n1_shared = theMod->getfmUtil()->isShared(n1);
00684 n2_shared = theMod->getfmUtil()->isShared(n2);
00685 if(n1_shared && n2_shared) {
00686 const IDXL_Rec *irec1 = theMesh->node.shared.getRec(n1);
00687 const IDXL_Rec *irec2 = theMesh->node.shared.getRec(n2);
00688 if(irec1->getShared() == irec2->getShared()) {
00689 for(int i=0; i<irec1->getShared(); i++) {
00690 same = false;
00691 for(int j=0; j<irec2->getShared(); j++) {
00692 if(irec1->getChk(i) == irec2->getChk(j)) {
00693 same = true; break;
00694 }
00695 }
00696 if(!same) break;
00697 }
00698 }
00699 else {
00700 same = false;
00701 }
00702 if(!same) {
00703 return -1;
00704 }
00705 }
00706 int n1_bound, n2_bound;
00707 FEM_Mesh_dataP(theMesh, FEM_NODE, FEM_BOUNDARY, &n1_bound, n1, 1 , FEM_INT, 1);
00708 FEM_Mesh_dataP(theMesh, FEM_NODE, FEM_BOUNDARY, &n2_bound, n2, 1 , FEM_INT, 1);
00709 if((n1_bound != 0) && (n2_bound != 0) && (n1_bound != n2_bound)) {
00710 bool kcorner = isFixedNode(n1);
00711 bool dcorner = isFixedNode(n2);
00712 bool edgeb = isEdgeBoundary(n1,n2);
00713 if((kcorner && !dcorner && edgeb) || (dcorner && !kcorner && edgeb)) {
00714 }
00715 else {
00716 return -1;
00717 }
00718 }
00719
00720 int e1new=-1;
00721 int e2new=-1;
00722 if(e1>=0) {
00723 int e1conn[3];
00724 theMesh->e2n_getAll(e1, e1conn, 0);
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 for(int i=0; i<3; i++) {
00744
00745 int *e1Elems, esize1;
00746 theMesh->n2e_getAll(e1conn[i], e1Elems, esize1);
00747 int e1count=0;
00748 for(int j=0; j<esize1; j++) {
00749 if(e1Elems[j]>=0) e1count++;
00750 }
00751 if(e1count==1) {
00752 int *elemNbrs = new int[3];
00753 int e1ghostelem=-1;
00754 theMesh->e2e_getAll(e1,elemNbrs,0);
00755 for(int k=0; k<3; k++) {
00756 if(elemNbrs[k] < -1) {
00757 e1ghostelem = elemNbrs[k];
00758 break;
00759 }
00760 }
00761 delete [] elemNbrs;
00762 if(e1ghostelem<-1) {
00763
00764 int e1remoteChk = theMesh->elem[0].ghost->ghostRecv.getRec(FEM_To_ghost_index(e1ghostelem))->getChk(0);
00765 int sharedIdx = theMod->fmUtil->exists_in_IDXL(theMesh,e1,e1remoteChk,3);
00766 #ifndef FEM_SILENT
00767 CkPrintf("[%d]Edge Contraction, edge %d->%d, chunk %d eating into chunk %d\n",theMod->idx, n1, n2, e1remoteChk, index);
00768 #endif
00769 if(FEM_Is_ghost_index(e2)) {
00770 int e2conn[3];
00771 theMesh->e2n_getAll(e2, e2conn, 0);
00772 int gotlocksn4 = 1, lockn4=-1;
00773 for(int k=0; k<3; k++) {
00774 if(e2conn[k]!=n1 && e2conn[k]!=n2) lockn4=e2conn[k];
00775 }
00776
00777
00778 int *n4ns, n4ncount;
00779 bool shouldbeunlocked=true;
00780 theMesh->n2n_getAll(lockn4, n4ns, n4ncount);
00781 for(int k=0; k<n4ncount; k++) {
00782 if(n4ns[k]>=0 && n4ns[k]!=n1 && n4ns[k]!=n2) shouldbeunlocked=false;
00783 }
00784 if(shouldbeunlocked) {
00785 unlockNodes(&gotlocksn4, &lockn4, 0, &lockn4, 1);
00786 }
00787 if(n4ncount!=0) delete[] n4ns;
00788 }
00789 intMsg* imsg1 = meshMod[e1remoteChk].eatIntoElement(index,sharedIdx);
00790 e1new = imsg1->i;
00791 delete imsg1;
00792 if(e1new!=-1) {
00793 e1 = theMod->fmUtil->lookup_in_IDXL(theMesh,e1new,e1remoteChk,4);
00794
00795 e1 = FEM_To_ghost_index(e1);
00796 }
00797 else e1 = -1;
00798 *e1P = e1;
00799 if(esize1>0) delete[] e1Elems;
00800 return ERVAL1;
00801 }
00802 }
00803 if(esize1>0) delete[] e1Elems;
00804 }
00805 }
00806 if(e2>=0) {
00807 int e2conn[3];
00808 int e2remoteChk=-1;
00809 theMesh->e2n_getAll(e2, e2conn, 0);
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 for(int i=0; i<3; i++) {
00829
00830 int *e2Elems, esize2;
00831 theMesh->n2e_getAll(e2conn[i], e2Elems, esize2);
00832 int e2count=0;
00833 for(int j=0; j<esize2; j++) {
00834 if(e2Elems[j]>=0) e2count++;
00835 }
00836 if(e2count==1) {
00837 int *elemNbrs = new int[3];
00838 int e2ghostelem=-1;
00839 theMesh->e2e_getAll(e2,elemNbrs,0);
00840 for(int k=0; k<3; k++) {
00841 if(elemNbrs[k] < -1) {
00842 e2ghostelem = elemNbrs[k];
00843 break;
00844 }
00845 }
00846 delete [] elemNbrs;
00847 if(e2ghostelem<-1) {
00848
00849 int e2remoteChk = theMesh->elem[0].ghost->ghostRecv.getRec(FEM_To_ghost_index(e2ghostelem))->getChk(0);
00850 int sharedIdx = theMod->fmUtil->exists_in_IDXL(theMesh,e2,e2remoteChk,3);
00851 #ifndef FEM_SILENT
00852 CkPrintf("[%d]Edge Contraction, edge %d->%d, chunk %d eating into chunk %d\n",theMod->idx, n1, n2, e2remoteChk, index);
00853 #endif
00854 if(FEM_Is_ghost_index(e1)) {
00855 int e1conn[3];
00856 theMesh->e2n_getAll(e1, e1conn, 0);
00857 int gotlocksn4 = 1, lockn4=-1;
00858 for(int k=0; k<3; k++) {
00859 if(e1conn[k]!=n1 && e1conn[k]!=n2) lockn4=e1conn[k];
00860 }
00861
00862
00863 int *n4ns, n4ncount;
00864 bool shouldbeunlocked=true;
00865 theMesh->n2n_getAll(lockn4, n4ns, n4ncount);
00866 for(int k=0; k<n4ncount; k++) {
00867 if(n4ns[k]>=0 && n4ns[k]!=n1 && n4ns[k]!=n2) shouldbeunlocked=false;
00868 }
00869 if(shouldbeunlocked) {
00870 unlockNodes(&gotlocksn4, &lockn4, 0, &lockn4, 1);
00871 }
00872 if(n4ncount!=0) delete[] n4ns;
00873 }
00874 intMsg* imsg1 = meshMod[e2remoteChk].eatIntoElement(index,sharedIdx);
00875 e2new = imsg1->i;
00876 delete imsg1;
00877 if(e2new!=-1) {
00878 e2 = theMod->fmUtil->lookup_in_IDXL(theMesh,e2new,e2remoteChk,4);
00879
00880 e2 = FEM_To_ghost_index(e2);
00881 }
00882 else e2 = -1;
00883 *e2P = e2;
00884 if(esize2>0) delete[] e2Elems;
00885 return ERVAL1;
00886 }
00887 }
00888 if(esize2>0) delete[] e2Elems;
00889 }
00890 }
00891 if(FEM_Is_ghost_index(e1)) {
00892
00893 int remChk = theMesh->elem[0].ghost->ghostRecv.getRec(FEM_From_ghost_index(e1))->getChk(0);
00894 int shidx = theMesh->elem[0].ghost->ghostRecv.getRec(FEM_From_ghost_index(e1))->getIdx(0);
00895
00896 bool shouldacquire = true;
00897 int e1nbrs[3];
00898 theMesh->e2n_getAll(e1,e1nbrs,0);
00899 for(int i=0; i<3;i++) {
00900 if(FEM_Is_ghost_index(e1nbrs[i])) {
00901 shouldacquire=false; break;
00902 }
00903 }
00904 boolMsg* bmsg = meshMod[remChk].willItLose(index,shidx);
00905 bool shouldacquire1 = bmsg->b;
00906 delete bmsg;
00907 if(shouldacquire && shouldacquire1) {
00908 e1new = theMod->fmUtil->eatIntoElement(e1);
00909 *e1P = e1new;
00910 return ERVAL1;
00911 }
00912 else if(shouldacquire1) return -1;
00913 }
00914 if(FEM_Is_ghost_index(e2)) {
00915
00916 int remChk = theMesh->elem[0].ghost->ghostRecv.getRec(FEM_From_ghost_index(e2))->getChk(0);
00917 int shidx = theMesh->elem[0].ghost->ghostRecv.getRec(FEM_From_ghost_index(e2))->getIdx(0);
00918
00919 bool shouldacquire = true;
00920 int e2nbrs[3];
00921 theMesh->e2n_getAll(e2,e2nbrs,0);
00922 for(int i=0; i<3;i++) {
00923 if(FEM_Is_ghost_index(e2nbrs[i])) {
00924 shouldacquire=false; break;
00925 }
00926 }
00927 boolMsg* bmsg = meshMod[remChk].willItLose(index,shidx);
00928 bool shouldacquire1 = bmsg->b;
00929 delete bmsg;
00930 if(shouldacquire && shouldacquire1) {
00931 e2new = theMod->fmUtil->eatIntoElement(e2);
00932 *e2P = e2new;
00933 return ERVAL1;
00934 }
00935 else if(shouldacquire1) return -1;
00936 }
00937
00938 int conn[3];
00939 int adjnodes[2];
00940 adjnodes[0] = n1;
00941 adjnodes[1] = n2;
00942 int adjelems[2];
00943 adjelems[0] = e1;
00944 adjelems[1] = e2;
00945
00946
00947
00948
00949 int keepnode=-1, deletenode=-1, shared=0;
00950
00951
00952 bool n1fixed = isFixedNode(n1);
00953 bool n2fixed = isFixedNode(n2);
00954 if(n1fixed && n2fixed) {
00955 return -1;
00956 }
00957 if(n1_shared && n2_shared) {
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 if(same) {
00976 if(n2fixed) {
00977 keepnode = n2;
00978 deletenode = n1;
00979 }
00980 else {
00981 keepnode = n1;
00982 deletenode = n2;
00983 }
00984 shared = 2;
00985 } else {
00986 return -1;
00987 }
00988 }
00989 else if(n1_shared && !n2fixed) {
00990
00991 keepnode = n1;
00992 deletenode = n2;
00993 shared = 1;
00994 } else if(n2_shared && !n1fixed) {
00995
00996 keepnode = n2;
00997 deletenode = n1;
00998 shared = 1;
00999 } else if(!n1_shared && !n2_shared) {
01000
01001 if(n2fixed) {
01002 keepnode = n2;
01003 deletenode = n1;
01004 }
01005 else {
01006 keepnode = n1;
01007 deletenode = n2;
01008 }
01009 }
01010 else {
01011 return -1;
01012 }
01013
01014 FEM_Mesh_dataP(theMesh, FEM_NODE, FEM_BOUNDARY, &n1_bound, keepnode, 1 , FEM_INT, 1);
01015 FEM_Mesh_dataP(theMesh, FEM_NODE, FEM_BOUNDARY, &n2_bound, deletenode, 1 , FEM_INT, 1);
01016
01017 FEM_Interpolate *inp = theMod->getfmInp();
01018 FEM_Interpolate::NodalArgs nm;
01019 if((n1_bound != 0) && (n2_bound != 0) && (n1_bound != n2_bound)) {
01020 bool kcorner;
01021 bool dcorner;
01022 if(keepnode==n1) {
01023 kcorner = n1fixed;
01024 dcorner = n2fixed;
01025 }
01026 else {
01027 kcorner = n2fixed;
01028 dcorner = n1fixed;
01029 }
01030 bool edgeb = isEdgeBoundary(keepnode,deletenode);
01031 if(kcorner && !dcorner && edgeb) {
01032 nm.frac = 1.0;
01033 }
01034 else if(dcorner && !kcorner && edgeb) {
01035 nm.frac = 0.0;
01036 }
01037 else {
01038 nm.frac = 0.5;
01039 return -1;
01040 }
01041 }
01042 else if(n1_bound!=0 && n2_bound!=0) {
01043 nm.frac = 0.5;
01044
01045 if(isFixedNode(keepnode)) {
01046 nm.frac = 1.0;
01047 }
01048 else if(isFixedNode(deletenode)) {
01049 nm.frac = 0.0;
01050 }
01051 }
01052 else if(n1_bound != 0) {
01053 nm.frac = 1.0;
01054 }
01055 else if(n2_bound != 0) {
01056 if(shared==2) {
01057 keepnode = n2;
01058 deletenode = n1;
01059 nm.frac = 1.0;
01060 } else {
01061 nm.frac = 0.0;
01062 }
01063 }
01064 else {
01065 nm.frac = 0.5;
01066 }
01067 nm.nodes[0] = keepnode;
01068 nm.nodes[1] = deletenode;
01069 nm.n = keepnode;
01070 nm.addNode = false;
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 int *nbrElems, nesize, echunk;
01085 theMesh->n2e_getAll(deletenode, nbrElems, nesize);
01086 bool locked = false;
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 CkVec<int> lockedNodes;
01218 int *nnNodes, *nn1Nodes;
01219 int nnsize=0, nn1size=0;
01220 int nncount=0;
01221 int numtries=0;
01222 bool done = false;
01223 while(!done) {
01224 lockedNodes.removeAll();
01225 nncount=0;
01226 theMesh->n2n_getAll(deletenode, nnNodes, nnsize);
01227 theMesh->n2n_getAll(keepnode, nn1Nodes, nn1size);
01228 for(int i=0; i<nnsize; i++) {
01229 if(nnNodes[i]!=n1 && nnNodes[i]!=n2 && nnNodes[i]!=n3 && nnNodes[i]!=n4) {
01230 lockedNodes.push_back(nnNodes[i]);
01231 nncount++;
01232 }
01233 }
01234 for(int i=0; i<nn1size; i++) {
01235 if(nn1Nodes[i]!=n1 && nn1Nodes[i]!=n2 && nn1Nodes[i]!=n3 && nn1Nodes[i]!=n4) {
01236 bool nflag1 = false;
01237 for(int j=0; j<nnsize; j++) {
01238 if(nn1Nodes[i]==nnNodes[j]) {
01239 nflag1 = true;
01240 break;
01241 }
01242 }
01243 if(!nflag1) {
01244 lockedNodes.push_back(nn1Nodes[i]);
01245 nncount++;
01246 }
01247 }
01248 }
01249 int *gotlocks=NULL;
01250 int *lockw=NULL;
01251 if(nncount>0) {
01252 gotlocks = new int[nncount];
01253 lockw = new int[nncount];
01254 }
01255 for(int i=0; i<nncount; i++) {
01256 gotlocks[i]=-1;
01257 lockw[i] = lockedNodes[i];
01258 }
01259
01260 int gotlock = lockNodes(gotlocks,lockw,0,lockw,nncount);
01261 locked = true;
01262 numtries++;
01263 if(gotlock==1) {
01264 bool isConn = true;
01265 int *nnNodes1,*nn1Nodes1;
01266 int nnsize1=0,nn1size1=0;
01267 theMesh->n2n_getAll(deletenode, nnNodes1, nnsize1);
01268 if(nnsize!=nnsize1) isConn=false;
01269 else {
01270 for(int i=0; i<nnsize; i++) {
01271 isConn = false;
01272 for(int j=0; j<nnsize1; j++) {
01273 if(nnNodes1[i] == nnNodes[j]) {
01274 isConn=true; break;
01275 }
01276 }
01277 if(!isConn) break;
01278 }
01279 }
01280 if(isConn) {
01281 theMesh->n2n_getAll(keepnode, nn1Nodes1, nn1size1);
01282 if(nn1size!=nn1size1) isConn=false;
01283 else {
01284 for(int i=0; i<nnsize; i++) {
01285 isConn = false;
01286 for(int j=0; j<nnsize1; j++) {
01287 if(nnNodes1[i] == nnNodes[j]) {
01288 isConn=true; break;
01289 }
01290 }
01291 if(!isConn) break;
01292 }
01293 }
01294 }
01295 if(!isConn) {
01296 unlockNodes(gotlocks,lockw,0,lockw,nncount);
01297 if(numtries>=3) {
01298 if(nesize>0) delete[] nbrElems;
01299 if(nnsize1>0) delete[] nnNodes1;
01300 if(nn1size1>0) delete[] nn1Nodes1;
01301 if(nnsize>0) delete[] nnNodes;
01302 if(nn1size>0) delete[] nn1Nodes;
01303 if(nncount>0) {
01304 delete [] lockw;
01305 delete [] gotlocks;
01306 }
01307 return ERVAL;
01308 }
01309 CthYield();
01310 }
01311 else done = true;
01312 if(nnsize1>0) delete[] nnNodes1;
01313 if(nn1size1>0) delete[] nn1Nodes1;
01314 }
01315 else unlockNodes(gotlocks,lockw,0,lockw,nncount);
01316 if(nnsize>0) delete[] nnNodes;
01317 if(nn1size>0) delete[] nn1Nodes;
01318 if(nncount>0) {
01319 delete [] lockw;
01320 delete [] gotlocks;
01321 }
01322 if(numtries>=3 && !done) {
01323 if(nesize>0) delete[] nbrElems;
01324 return ERVAL;
01325 }
01326 }
01327
01328
01329 bool flipSliver = false;
01330 int *nbr1Elems=NULL, nesize1=0;
01331
01332 int n3n2n = theMesh->n2n_getLength(n3);
01333 int n3n2e = theMesh->n2e_getLength(n3);
01334 int n4n2n = theMesh->n2n_getLength(n4);
01335 int n4n2e = theMesh->n2e_getLength(n4);
01336 if(n1==526 && n2==352 && theMod->idx==5) {
01337 CkPrintf("Debugging\n");
01338 }
01339 if((n3n2n==3 && n3n2e==3)||(n4n2n==3 && n4n2e==3)) {
01340 flipSliver = true;
01341 }
01342 if(!flipSliver) {
01343 double *n1_coord = new double[2];
01344 double *n2_coord = new double[2];
01345 double *new_coord = new double[2];
01346 FEM_Mesh_dataP(theMesh, FEM_NODE, theMod->fmAdaptAlgs->coord_attr, (void *)n1_coord, nm.nodes[0], 1, FEM_DOUBLE, 2);
01347 FEM_Mesh_dataP(theMesh, FEM_NODE, theMod->fmAdaptAlgs->coord_attr, (void *)n2_coord, nm.nodes[1], 1, FEM_DOUBLE, 2);
01348 new_coord[0] = nm.frac*n1_coord[0] + (1-nm.frac)*n2_coord[0];
01349 new_coord[1] = nm.frac*n1_coord[1] + (1-nm.frac)*n2_coord[1];
01350 int *conn1 = new int[3];
01351 for (int i=0; i<nesize; i++) {
01352 if ((nbrElems[i] != e1) && (nbrElems[i] != e2)) {
01353 theMesh->e2n_getAll(nbrElems[i], conn);
01354 for(int j=0; j<2; j++) {
01355 if (conn[j] == deletenode) {
01356 conn[j] = conn[2];
01357 conn[2] = deletenode;
01358 }
01359 }
01360 if(theMod->fmAdaptAlgs->controlQualityC(conn[0],conn[1],conn[2],new_coord)) {
01361 flipSliver = true;
01362
01363 break;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382 }
01383 }
01384 if(!flipSliver) {
01385 theMesh->n2e_getAll(keepnode, nbr1Elems, nesize1);
01386 for (int i=0; i<nesize1; i++) {
01387 if ((nbr1Elems[i] != e1) && (nbr1Elems[i] != e2)) {
01388 theMesh->e2n_getAll(nbr1Elems[i], conn1);
01389 for(int j=0; j<2; j++) {
01390 if (conn1[j] == keepnode) {
01391 conn1[j] = conn1[2];
01392 conn1[2] = keepnode;
01393 }
01394 }
01395 if(theMod->fmAdaptAlgs->controlQualityC(conn1[0],conn1[1],conn1[2],new_coord)) {
01396 flipSliver = true;
01397
01398 break;
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 }
01418 }
01419 }
01420 delete [] conn1;
01421 delete [] n1_coord;
01422 delete [] n2_coord;
01423 delete [] new_coord;
01424 }
01425
01426 if(flipSliver) {
01427 #ifdef DEBUG_2
01428 CkPrintf("[%d]Found a flip about to occur for %d-%d collapse, so aborting this\n",theMod->idx,n1,n2);
01429 #endif
01430 int size = lockedNodes.size();
01431 int *gotlocks = (int*)malloc(size*sizeof(int));
01432 int *lockw = (int*)malloc(size*sizeof(int));
01433 for(int k=0; k<size; k++) {
01434 gotlocks[k] = 1;
01435 lockw[k] = lockedNodes[k];
01436 }
01437 if(locked) {
01438 #ifdef DEBUG_LOCKS
01439 CkPrintf("[%d]Trying to unlock %d, %d, & %d\n",theMod->idx,conn[0],conn[1],conn[2]);
01440 #endif
01441 unlockNodes(gotlocks, lockw, 0, lockw, size);
01442 locked = false;
01443 }
01444 free(gotlocks);
01445 free(lockw);
01446
01447 if(nesize>0) delete[] nbrElems;
01448 if(nesize1>0) delete [] nbr1Elems;
01449 return -1;
01450 }
01451
01452 inp->FEM_InterpolateNodeOnEdge(nm);
01453
01454
01455 #ifdef DEBUG_1
01456 CkPrintf("[%d]Edge Contraction, edge %d(%d:%d)->%d(%d:%d) on chunk %d:: deleted %d\n",theMod->idx, n1,n1_bound,n1_shared, n2,n2_bound,n2_shared, theMod->getfmUtil()->getIdx(),deletenode);
01457 #endif
01458 e1chunk = FEM_remove_element(theMesh, e1, 0);
01459 if(e2!=-1) e2chunk = FEM_remove_element(theMesh, e2, 0);
01460 FEM_purge_element(theMesh,e1,0);
01461 if(e2!=-1) FEM_purge_element(theMesh,e2,0);
01462
01463 for (int i=0; i<nesize; i++) {
01464 if ((nbrElems[i] != e1) && (nbrElems[i] != e2)) {
01465 theMesh->e2n_getAll(nbrElems[i], conn);
01466 for (int j=0; j<3; j++) {
01467 if (conn[j] == deletenode) conn[j] = keepnode;
01468 }
01469 int eTopurge = nbrElems[i];
01470 echunk = FEM_remove_element(theMesh, nbrElems[i], 0);
01471 nbrElems[i] = FEM_add_element(theMesh, conn, 3, 0, echunk);
01472 theMod->fmUtil->copyElemData(0,eTopurge,nbrElems[i]);
01473 FEM_purge_element(theMesh,eTopurge,0);
01474 }
01475 }
01476 #ifdef FEM_ELEMSORDERED
01477 int con[3];
01478 for(int i=0; i<nesize1; i++) {
01479 if(nbr1Elems[i]!=e1 && nbr1Elems[i]!=e2) {
01480 theMesh->e2n_getAll(nbr1Elems[i],con);
01481 theMod->fmAdaptAlgs->ensureQuality(con[0],con[1],con[2]);
01482 }
01483 }
01484 #endif
01485 if(nesize1 > 0) delete [] nbr1Elems;
01486
01487
01488 int size = lockedNodes.size();
01489 int *gotlocks = (int*)malloc(size*sizeof(int));
01490 int *lockw = (int*)malloc(size*sizeof(int));
01491 for(int k=0; k<size; k++) {
01492 lockw[k] = lockedNodes[k];
01493 gotlocks[k] = 1;
01494 }
01495 if(locked) {
01496 #ifdef DEBUG_LOCKS
01497 CkPrintf("[%d]Done contraction, Trying to unlock %d, %d, & %d\n",theMod->idx,conn[0],conn[1],conn[2]);
01498 #endif
01499
01500 unlockNodes(gotlocks, lockw, 0, lockw, size);
01501 locked = false;
01502 }
01503 free(gotlocks);
01504 free(lockw);
01505
01506 FEM_remove_node(theMesh, deletenode);
01507 if(nesize>0) delete[] nbrElems;
01508 return keepnode;
01509 }
01510
01511
01512
01513 #undef DEBUG_1
01514