00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "charm.h"
00011 #include "fem.h"
00012 #include "fem_impl.h"
00013 #include "fem_mesh_modify.h"
00014
00015 CProxy_femMeshModify meshMod;
00016
00017 CLINKAGE int FEM_add_node(int mesh, int* adjacent_nodes, int num_adjacent_nodes, int *chunks, int numChunks, int forceShared, int upcall){
00018 return FEM_add_node(FEM_Mesh_lookup(mesh,"FEM_add_node"), adjacent_nodes, num_adjacent_nodes, chunks, numChunks, forceShared, upcall);
00019 }
00020 CLINKAGE void FEM_remove_node(int mesh,int node){
00021 return FEM_remove_node(FEM_Mesh_lookup(mesh,"FEM_remove_node"), node);
00022 }
00023 CLINKAGE int FEM_remove_element(int mesh, int element, int elem_type, int permanent){
00024 return FEM_remove_element(FEM_Mesh_lookup(mesh,"FEM_remove_element"), element, elem_type, permanent);
00025 }
00026 CLINKAGE int FEM_purge_element(int mesh, int element, int elem_type) {
00027 return FEM_purge_element(FEM_Mesh_lookup(mesh,"FEM_remove_element"), element, elem_type);
00028 }
00029 CLINKAGE int FEM_add_element(int mesh, int* conn, int conn_size, int elem_type, int chunkNo){
00030 return FEM_add_element(FEM_Mesh_lookup(mesh,"FEM_add_element"), conn, conn_size, elem_type, chunkNo);
00031 }
00032 CLINKAGE int FEM_Modify_Lock(int mesh, int* affectedNodes, int numAffectedNodes, int* affectedElts, int numAffectedElts, int elemtype){
00033 return FEM_Modify_Lock(FEM_Mesh_lookup(mesh,"FEM_Modify_Lock"), affectedNodes, numAffectedNodes, affectedElts, numAffectedElts, elemtype);
00034 }
00035 CLINKAGE int FEM_Modify_Unlock(int mesh){
00036 return FEM_Modify_Unlock(FEM_Mesh_lookup(mesh,"FEM_Modify_Unlock"));
00037 }
00038 CLINKAGE int FEM_Modify_LockN(int mesh, int nodeId, int readLock) {
00039 return FEM_Modify_LockN(FEM_Mesh_lookup(mesh,"FEM_Modify_LockN"),nodeId, readLock);
00040 }
00041 CLINKAGE int FEM_Modify_UnlockN(int mesh, int nodeId, int readLock) {
00042 return FEM_Modify_UnlockN(FEM_Mesh_lookup(mesh,"FEM_Modify_UnlockN"),nodeId, readLock);
00043 }
00044
00045
00046 void FEM_Mesh_dataP(FEM_Mesh *fem_mesh,int entity,int attr,void *data, int firstItem,int length, int datatype,int width) {
00047 IDXL_Layout lo(datatype,width);
00048 FEM_Mesh_data_layoutP(fem_mesh,entity,attr,data,firstItem,length,lo);
00049 }
00050
00051 void FEM_Mesh_data_layoutP(FEM_Mesh *fem_mesh,int entity,int attr,void *data, int firstItem,int length, IDXL_Layout_t layout) {
00052 const char *caller="FEM_Mesh_data_layout";
00053 FEM_Mesh_data_layoutP(fem_mesh,entity,attr,data,firstItem,length,
00054 IDXL_Layout_List::get().get(layout,caller));
00055 }
00056
00057 void FEM_Mesh_data_layoutP(FEM_Mesh *m,int entity,int attr,void *data, int firstItem,int length, const IDXL_Layout &layout) {
00058 const char *caller="FEM_Mesh_data";
00059
00060
00061 FEM_Attribute *a=m->lookup(entity,caller)->lookup(attr,caller);
00062
00063 if (m->isSetting())
00064 a->set(data,firstItem,length,layout,caller);
00065 else
00066 a->get(data,firstItem,length,layout,caller);
00067 }
00068
00069
00070
00071 inline int is_shared(FEM_Mesh *m, int node){
00072 return m->getfmMM()->getfmUtil()->isShared(node);
00073 }
00074
00075
00076 CLINKAGE void FEM_Print_Mesh_Summary(int mesh){
00077 CkPrintf("---------------FEM_Print_Mesh_Summary-------------\n");
00078 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Print_Mesh_Summary");
00079
00080
00081 CkPrintf(" Nodes: %d/%d and ghost nodes: %d/%d\n", m->node.count_valid(), m->node.size(),m->node.getGhost()->count_valid(),m->node.getGhost()->size());
00082
00083
00084 CkPrintf(" Element Types: %d\n", m->elem.size());
00085 for (int t=0;t<m->elem.size();t++)
00086 if (m->elem.has(t)) {
00087 unsigned int numEl = m->elem[t].size();
00088 unsigned int numElG = m->elem[t].getGhost()->size();
00089 unsigned int numValidEl = m->elem[t].count_valid();
00090 unsigned int numValidElG = m->elem[t].getGhost()->count_valid();
00091 CkPrintf(" Element type %d contains %d/%d elements and %d/%d ghosts\n", t, numValidEl, numEl, numValidElG, numElG);
00092
00093 }
00094
00095 CkPrintf("\n");
00096 }
00097
00098
00099 CLINKAGE void FEM_Print_n2n(int mesh, int nodeid){
00100 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Print_Mesh_Summary");
00101 m->getfmMM()->getfmUtil()->FEM_Print_n2n(m, nodeid);
00102 }
00103
00104 CLINKAGE void FEM_Print_n2e(int mesh, int eid){
00105 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Print_Mesh_Summary");
00106 m->getfmMM()->getfmUtil()->FEM_Print_n2e(m, eid);
00107 }
00108
00109
00110
00111 CLINKAGE void FEM_Print_e2n(int mesh, int eid){
00112 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Print_Mesh_Summary");
00113 m->getfmMM()->getfmUtil()->FEM_Print_e2n(m, eid);
00114 }
00115
00116 CLINKAGE void FEM_Print_e2e(int mesh, int eid){
00117 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_Print_Mesh_Summary");
00118 m->getfmMM()->getfmUtil()->FEM_Print_e2e(m, eid);
00119 }
00120
00121
00122 int FEM_add_node_local(FEM_Mesh *m, int addGhost){
00123 int newNode;
00124 if(addGhost){
00125 newNode = m->node.getGhost()->get_next_invalid(m,true,true);
00126 m->n2e_removeAll(FEM_To_ghost_index(newNode));
00127 m->n2n_removeAll(FEM_To_ghost_index(newNode));
00128 }
00129 else{
00130 newNode = m->node.get_next_invalid(m,true,false);
00131 m->n2e_removeAll(newNode);
00132 m->n2n_removeAll(newNode);
00133
00134 if(newNode >= m->getfmMM()->fmLockN.size()) {
00135 m->getfmMM()->fmLockN.push_back(new FEM_lockN(newNode,m->getfmMM()));
00136 }
00137 else {
00138 m->getfmMM()->fmLockN[newNode]->reset(newNode,m->getfmMM());
00139 }
00140 }
00141 return newNode;
00142 }
00143
00144
00145 int FEM_add_node(FEM_Mesh *m, int* adjacentNodes, int numAdjacentNodes, int*chunks, int numChunks, int forceShared, int upcall){
00146
00147
00148
00149
00150 int index = m->getfmMM()->getIdx();
00151
00152 #ifdef DEBUG
00153 CmiMemoryCheck();
00154 #endif
00155 if(numChunks==1 && chunks[0]!=index) {
00156
00157 int chunkNo = chunks[0];
00158 addNodeMsg *am = new (numAdjacentNodes,numChunks,0) addNodeMsg;
00159 am->chk = index;
00160 am->nBetween = numAdjacentNodes;
00161 for(int i=0; i<numAdjacentNodes; i++) {
00162 am->between[i] = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,adjacentNodes[i],chunkNo,0);
00163 CkAssert(am->between[i]!=-1);
00164 }
00165 am->chunks[0] = chunkNo;
00166 am->numChunks = numChunks;
00167 am->upcall = upcall;
00168 intMsg *imsg = new intMsg(-1);
00169
00170
00171 m->getfmMM()->getfmUtil()->idxllock(m,chunkNo,0);
00172 imsg = meshMod[chunkNo].addNodeRemote(am);
00173 int newghost = FEM_add_node_local(m,1);
00174 m->node.ghost->ghostRecv.addNode(newghost,chunkNo);
00175
00176
00177 m->getfmMM()->getfmUtil()->idxlunlock(m,chunkNo,0);
00178
00179
00180
00181 return FEM_To_ghost_index(newghost);
00182 }
00183 int newNode = FEM_add_node_local(m, 0);
00184 int sharedCount = 0;
00185
00186 FEM_Interpolate *inp = m->getfmMM()->getfmInp();
00187 FEM_Interpolate::NodalArgs nm;
00188 nm.n = newNode;
00189 for(int i=0; i<numAdjacentNodes; i++) {
00190 nm.nodes[i] = adjacentNodes[i];
00191 }
00192 nm.frac = 0.5;
00193 nm.addNode = true;
00194 inp->FEM_InterpolateNodeOnEdge(nm);
00195
00196 if(numChunks>1) {
00197
00198 for(int i=0;i<numAdjacentNodes;i++){
00199
00200 if(is_shared(m, adjacentNodes[i]))
00201 {
00202 sharedCount++;
00203
00204
00205
00206 }
00207 }
00208
00209
00210
00211 if((sharedCount==numAdjacentNodes && numAdjacentNodes!=0) && forceShared!=-1 ) {
00212
00213 m->getfmMM()->getfmUtil()->splitEntitySharing(m, newNode, numAdjacentNodes, adjacentNodes, numChunks, chunks);
00214 }
00215 }
00216 #ifdef DEBUG
00217 CmiMemoryCheck();
00218 #endif
00219 return newNode;
00220 }
00221
00222
00223
00224 void FEM_add_shared_node_remote(FEM_Mesh *m, int chk, int nBetween, int *between){
00225
00226 #ifdef DEBUG
00227 CmiMemoryCheck();
00228 #endif
00229 int newnode = FEM_add_node_local(m, 0);
00230
00231
00232
00233
00234
00235 m->getfmMM()->getfmUtil()->splitEntityRemote(m, chk, newnode, nBetween, between);
00236 #ifdef DEBUG
00237 CmiMemoryCheck();
00238 #endif
00239 }
00240
00241
00242 void FEM_remove_node_local(FEM_Mesh *m, int node) {
00243
00244 int numAdjNodes, numAdjElts;
00245 int *adjNodes, *adjElts;
00246 #ifdef DEBUG
00247 CmiMemoryCheck();
00248 #endif
00249 m->n2n_getAll(node, &adjNodes, &numAdjNodes);
00250 m->n2e_getAll(node, &adjElts, &numAdjElts);
00251
00252
00253 if(FEM_Is_ghost_index(node)){
00254 CkAssert((numAdjNodes==0) && (numAdjElts==0));
00255
00256
00257 const IDXL_Rec *irec = m->node.ghost->ghostRecv.getRec(FEM_To_ghost_index(node));
00258
00259 int size = 0;
00260 if(irec) size = irec->getShared();
00261 int *chunks1, *inds1;
00262 if(size>0) {
00263 chunks1 = new int[size];
00264 inds1 = new int[size];
00265 }
00266 for(int i=0; i<size; i++) {
00267 chunks1[i] = irec->getChk(i);
00268 inds1[i] = irec->getIdx(i);
00269 }
00270 int index = m->getfmMM()->getIdx();
00271 for(int i=0; i<size; i++) {
00272 int chk = chunks1[i];
00273 int sharedIdx = inds1[i];
00274 m->node.ghost->ghostRecv.removeNode(FEM_To_ghost_index(node),chk);
00275 meshMod[chk].removeIDXLRemote(index,sharedIdx,1);
00276 }
00277 if(size>0) {
00278 delete [] chunks1;
00279 delete [] inds1;
00280 }
00281 m->node.ghost->set_invalid(FEM_To_ghost_index(node),true);
00282 }
00283 else {
00284
00285 const IDXL_Rec *irec = m->node.ghostSend.getRec(node);
00286 int size = 0;
00287 if(irec) size = irec->getShared();
00288 if(size > 0) {
00289 int *chknos = (int*)malloc(size*sizeof(int));
00290 int *sharedIndices = (int*)malloc(size*sizeof(int));
00291 for(int i=0; i<size; i++) {
00292 chknos[i] = irec->getChk(i);
00293 sharedIndices[i] = irec->getIdx(i);
00294 }
00295 for(int chkno=0; chkno<size; chkno++) {
00296 int remoteChunk = chknos[chkno];
00297 int sharedIdx = sharedIndices[chkno];
00298
00299 meshMod[remoteChunk].removeGhostNode(m->getfmMM()->getIdx(), sharedIdx);
00300 m->node.ghostSend.removeNode(node, remoteChunk);
00301 }
00302 free(chknos);
00303 free(sharedIndices);
00304 }
00305
00306
00307
00308
00309
00310
00311 CkAssert((numAdjNodes==0) && (numAdjElts==0));
00312
00313 m->node.set_invalid(node,true);
00314 m->getfmMM()->fmLockN[node]->reset(node,m->getfmMM());
00315 }
00316 if(numAdjNodes != 0) delete[] adjNodes;
00317 if(numAdjElts != 0) delete[] adjElts;
00318 #ifdef DEBUG
00319 CmiMemoryCheck();
00320 #endif
00321 return;
00322 }
00323
00324
00325
00326
00327
00328 void FEM_remove_node(FEM_Mesh *m, int node){
00329
00330 CkAssert(node >= 0);
00331
00332
00333
00334 #ifdef DEBUG
00335 CmiMemoryCheck();
00336 #endif
00337 if(FEM_Is_ghost_index(node)) {
00338
00339 }
00340
00341 CkAssert(m->node.is_valid(node));
00342
00343
00344 if(is_shared(m, node)){
00345
00346 int numAdjNodes, numAdjElts;
00347 int *adjNodes, *adjElts;
00348 m->n2n_getAll(node, &adjNodes, &numAdjNodes);
00349 m->n2e_getAll(node, &adjElts, &numAdjElts);
00350 CkAssert((numAdjNodes==0) && (numAdjElts==0));
00351
00352
00353
00354
00355 m->getfmMM()->getfmUtil()->removeNodeAll(m, node);
00356
00357
00358
00359
00360 if(numAdjNodes!=0) delete[] adjNodes;
00361 if(numAdjElts!=0) delete[] adjElts;
00362 }
00363 else {
00364 FEM_remove_node_local(m,node);
00365 }
00366 #ifdef DEBUG
00367 CmiMemoryCheck();
00368 #endif
00369 }
00370
00371
00372
00373 void FEM_remove_element_local(FEM_Mesh *m, int element, int etype){
00374
00375
00376 const int nodesPerEl = m->elem[etype].getConn().width();
00377 int *adjnodes = new int[nodesPerEl];
00378 #ifdef DEBUG
00379 CmiMemoryCheck();
00380 #endif
00381 m->e2n_getAll(element, adjnodes, etype);
00382 for(int i=0;i<nodesPerEl;i++) {
00383
00384 m->n2e_remove(adjnodes[i],element);
00385 }
00386
00387
00388 const int numAdjElts = nodesPerEl;
00389 int *adjelts = new int[numAdjElts];
00390 m->e2e_getAll(element, adjelts, etype);
00391 for(int i=0;i<numAdjElts;i++){
00392 m->e2e_replace(adjelts[i],element,-1);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402 for(int i=0;i<nodesPerEl;i++)
00403 for(int j=i+1;j<nodesPerEl;j++){
00404 m->n2n_remove(adjnodes[i],adjnodes[j]);
00405 m->n2n_remove(adjnodes[j],adjnodes[i]);
00406 }
00407
00408 for(int i=0;i<numAdjElts;i++){
00409 if(adjelts[i] != -1){
00410 int *adjnodes2 = new int[nodesPerEl];
00411 m->e2n_getAll(adjelts[i], adjnodes2, etype);
00412
00413 for(int j=0;j<nodesPerEl;j++){
00414 for(int k=j+1;k<nodesPerEl;k++){
00415 if(!m->n2n_exists(adjnodes2[j],adjnodes2[k]))
00416 m->n2n_add(adjnodes2[j],adjnodes2[k]);
00417 if(!m->n2n_exists(adjnodes2[k],adjnodes2[j]))
00418 m->n2n_add(adjnodes2[k],adjnodes2[j]);
00419 }
00420 }
00421
00422 delete[] adjnodes2;
00423 }
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433 #ifdef DEBUG
00434 CmiMemoryCheck();
00435 #endif
00436
00437 delete[] adjelts;
00438 delete[] adjnodes;
00439 #ifdef DEBUG
00440 CmiMemoryCheck();
00441 #endif
00442 return;
00443 }
00444
00445
00446 int FEM_remove_element(FEM_Mesh *m, int elementid, int elemtype, int permanent){
00447
00448
00449 if(elementid == -1) return -1;
00450 int index = m->getfmMM()->getfmUtil()->getIdx();
00451
00452 #ifdef DEBUG
00453 CmiMemoryCheck();
00454 #endif
00455 if(FEM_Is_ghost_index(elementid)){
00456
00457 int ghostid = FEM_To_ghost_index(elementid);
00458 const IDXL_Rec *irec = m->elem[elemtype].ghost->ghostRecv.getRec(ghostid);
00459 int size = irec->getShared();
00460 CkAssert(size == 1);
00461 int remoteChunk = irec->getChk(0);
00462 int sharedIdx = irec->getIdx(0);
00463
00464 removeElemMsg *rm = new removeElemMsg;
00465 rm->chk = index;
00466 rm->elementid = sharedIdx;
00467 rm->elemtype = elemtype;
00468 rm->permanent = permanent;
00469 meshMod[remoteChunk].removeElementRemote(rm);
00470
00471
00472
00473
00474 return remoteChunk;
00475 }
00476 else {
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 const IDXL_Rec *irec = m->elem[elemtype].ghostSend.getRec(elementid);
00488 if(irec){
00489 int numSharedChunks = irec->getShared();
00490 int connSize = m->elem[elemtype].getConn().width();
00491 if(numSharedChunks>0) {
00492 int *chknos = (int*)malloc(numSharedChunks*sizeof(int));
00493 int *inds = (int*)malloc(numSharedChunks*sizeof(int));
00494 for(int i=0; i<numSharedChunks; i++) {
00495 chknos[i] = irec->getChk(i);
00496 inds[i] = irec->getIdx(i);
00497 }
00498 int *newghost, *ghostidx, *losingThisNode, *nodes, *willBeGhost;
00499 if(permanent>=0) {
00500 newghost = new int[connSize];
00501 ghostidx = new int[connSize];
00502 losingThisNode = new int[connSize];
00503 nodes = new int[connSize];
00504 willBeGhost = new int[connSize];
00505 int *elems;
00506 int numElems;
00507 m->e2n_getAll(elementid,nodes,elemtype);
00508 for(int i=0; i<connSize; i++) {
00509 newghost[i] = -1;
00510 ghostidx[i] = -1;
00511
00512 losingThisNode[i] = 1;
00513 m->n2e_getAll(nodes[i], &elems, &numElems);
00514 for(int k=0; k<numElems; k++) {
00515 if((!FEM_Is_ghost_index(elems[k])) && (elems[k]!=elementid)) {
00516 losingThisNode[i] = 0;
00517 break;
00518 }
00519 }
00520 if(losingThisNode[i]) {
00521 willBeGhost[i] = 1;
00522 }
00523 free(elems);
00524 }
00525 if(losingThisNode[0]==1 && losingThisNode[1]==1 && losingThisNode[2]==1) {
00526
00527
00528 for(int i=0; i<connSize; i++) {
00529 int *ndnbrs;
00530 int numndnbrs;
00531 m->n2n_getAll(nodes[i], &ndnbrs, &numndnbrs);
00532 willBeGhost[i]=0;
00533 for(int n1=0; n1<numndnbrs; n1++) {
00534 if(ndnbrs[n1]>=0 && ndnbrs[n1]!=nodes[(i+1)%connSize] && ndnbrs[n1]!=nodes[(i+2)%connSize]) {
00535 willBeGhost[i]=1;
00536 }
00537 }
00538 }
00539 }
00540 for(int i=0; i<connSize; i++) {
00541 if(losingThisNode[i]==1 && willBeGhost[i]==1) {
00542 newghost[i] = FEM_add_node_local(m,1);
00543 ghostidx[i] = FEM_To_ghost_index(newghost[i]);
00544
00545 FEM_Modify_LockAll(m,nodes[i],false);
00546 }
00547 }
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557 for(int i=0; i<numSharedChunks; i++) {
00558 #ifdef DEBUG
00559 CmiMemoryCheck();
00560 #endif
00561 bool lockedRemoteIDXL = false;
00562 int chk = chknos[i];
00563 int sharedIdx = inds[i];
00564 int numGhostNodes = 0;
00565 int *ghostIndices = (int*)malloc(connSize*sizeof(int));
00566 int numGhostRN = 0;
00567 CkVec<int> ghostRNIndices;
00568 int numGhostRE = 0;
00569 CkVec<int> ghostREIndices;
00570 int numSharedNodes = 0;
00571 int *sharedIndices = (int*)malloc(connSize*sizeof(int));
00572
00573
00574 if(permanent>=0) {
00575
00576
00577
00578 CkVec<int> testelems;
00579 const IDXL_List ll = m->elem[elemtype].ghostSend.addList(chk);
00580 int size = ll.size();
00581 const IDXL_List ln = m->node.ghostSend.addList(chk);
00582 int sizeN = ln.size();
00583 const IDXL_List lre = m->elem[elemtype].ghost->ghostRecv.addList(chk);
00584 int lresize = lre.size();
00585 const IDXL_List lrn = m->node.ghost->ghostRecv.addList(chk);
00586 int lrnsize = lrn.size();
00587
00588 for(int j=0; j<connSize; j++) {
00589 int *elems;
00590 int numElems;
00591 #ifdef DEBUG
00592 CmiMemoryCheck();
00593 #endif
00594 m->n2e_getAll(nodes[j], &elems, &numElems);
00595
00596 if(chk != permanent) {
00597
00598 bool shouldBeDeleted = true;
00599 for(int k=0; k<numElems; k++) {
00600 if(elems[k]==elementid) continue;
00601 if(elems[k]>0) {
00602 if(m->getfmMM()->fmUtil->exists_in_IDXL(m,elems[k],chk,3)!=-1) {
00603 shouldBeDeleted = false;
00604 break;
00605 }
00606 }
00607 }
00608
00609
00610
00611 if(shouldBeDeleted) {
00612 const IDXL_Rec *irecsh = m->node.shared.getRec(nodes[j]);
00613 if(irecsh!=NULL) {
00614 for(int k=0; k<irecsh->getShared(); k++) {
00615 if(shouldBeDeleted) {
00616 shouldBeDeleted = meshMod[irecsh->getChk(k)].shouldLoseGhost(index,irecsh->getIdx(k),chk)->b;
00617 }
00618 }
00619 }
00620 }
00621
00622
00623 if(shouldBeDeleted) {
00624
00625 int shidx = m->getfmMM()->fmUtil->exists_in_IDXL(m,nodes[j],chk,1);
00626 if(shidx!=-1) {
00627 m->node.ghostSend.removeNode(nodes[j], chk);
00628 ghostIndices[numGhostNodes] = shidx;
00629 numGhostNodes++;
00630 }
00631 }
00632 }
00633
00634
00635 if(losingThisNode[j]) {
00636
00637 for(int k=0; k<numElems; k++) {
00638 int *nds = (int*)malloc(m->elem[elemtype].getConn().width()*sizeof(int));
00639 if(FEM_Is_ghost_index(elems[k]) && m->getfmMM()->getfmUtil()->exists_in_IDXL(m,elems[k],chk,4,elemtype)!=-1) {
00640 m->e2n_getAll(elems[k], nds, elemtype);
00641 int geShouldBeDeleted = 1;
00642 for(int l=0; l<connSize; l++) {
00643 if(!FEM_Is_ghost_index(nds[l]) && (nodes[j]!=nds[l])) {
00644 if(losingThisNode[(j+1)%connSize]==1 && nds[l]==nodes[(j+1)%connSize]) continue;
00645 else if(losingThisNode[(j+2)%connSize]==1 && nds[l]==nodes[(j+2)%connSize]) continue;
00646 geShouldBeDeleted = 0;
00647 }
00648 }
00649 if(geShouldBeDeleted) {
00650 int sge = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,elems[k],chk,4,elemtype);
00651 m->elem[elemtype].ghost->ghostRecv.removeNode(FEM_To_ghost_index(elems[k]), chk);
00652 FEM_remove_element_local(m,elems[k],elemtype);
00653 m->elem[elemtype].ghost->set_invalid(FEM_From_ghost_index(elems[k]),false);
00654 ghostREIndices.push_back(sge);
00655 numGhostRE++;
00656
00657
00658 for(int l=0; l<connSize; l++) {
00659 int *elts;
00660 int numElts;
00661 #ifdef DEBUG
00662 CmiMemoryCheck();
00663 #endif
00664 m->n2e_getAll(nds[l], &elts, &numElts);
00665
00666 if(nds[l]<-1) {
00667 bool removeflag = true;
00668 for(int lm=0; lm<numElts; lm++) {
00669
00670 if(elts[lm]!=elems[k]) {
00671 removeflag = false;
00672 }
00673 }
00674 if(removeflag) {
00675
00676 int sgn = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nds[l],chk,2);
00677 m->node.ghost->ghostRecv.removeNode(FEM_To_ghost_index(nds[l]), chk);
00678 if(numElts==0) FEM_remove_node_local(m,nds[l]);
00679 ghostRNIndices.push_back(sgn);
00680 numGhostRN++;
00681 }
00682 }
00683 if(numElts!=0) delete[] elts;
00684 }
00685 }
00686 }
00687 free(nds);
00688 }
00689
00690 int ssn = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodes[j],chk,0);
00691
00692
00693
00694 if(!lockedRemoteIDXL) m->getfmMM()->getfmUtil()->idxllock(m,chk,0);
00695 lockedRemoteIDXL = true;
00696 bool losingacorner = false;
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 if(ssn!=-1) {
00707 if(willBeGhost[j]==1) {
00708 m->node.ghost->ghostRecv.addNode(newghost[j],chk);
00709 }
00710 else {
00711 ssn -= 500000000;
00712 }
00713 if(!losingacorner) {
00714 m->node.shared.removeNode(nodes[j], chk);
00715 }
00716 sharedIndices[numSharedNodes] = ssn;
00717 numSharedNodes++;
00718 }
00719 if(i==numSharedChunks-1) {
00720
00721 for(int k=0; k<numElems; k++) {
00722 bool flagElem = false;
00723 if(FEM_Is_ghost_index(elems[k])) {
00724 if(m->elem[0].ghost->is_valid(FEM_From_ghost_index(elems[k]))) flagElem = true;
00725 }
00726 else {
00727 if(m->elem[0].is_valid(elems[k])) flagElem = true;
00728 }
00729 if(flagElem) {
00730 m->e2n_replace(elems[k],nodes[j],ghostidx[j],elemtype);
00731 m->n2e_remove(nodes[j],elems[k]);
00732 m->n2e_add(ghostidx[j],elems[k]);
00733 testelems.push_back(elems[k]);
00734 }
00735 }
00736 int *n2ns;
00737 int numn2ns;
00738 m->n2n_getAll(nodes[j],&n2ns,&numn2ns);
00739 for(int k=0; k<numn2ns; k++) {
00740 m->n2n_replace(n2ns[k],nodes[j],ghostidx[j]);
00741 m->n2n_remove(nodes[j],n2ns[k]);
00742 m->n2n_add(ghostidx[j],n2ns[k]);
00743 }
00744 if(numn2ns!=0) delete[] n2ns;
00745 const IDXL_Rec *irec1 = m->node.shared.getRec(nodes[j]);
00746 if(!irec1) {
00747 if(!losingacorner) FEM_remove_node_local(m,nodes[j]);
00748
00749
00750 }
00751 }
00752 }
00753 if(numElems!=0) delete[] elems;
00754 }
00755
00756
00757 for(int testelemsc=0; testelemsc <testelems.size(); testelemsc++) {
00758 int el = testelems[testelemsc];
00759 if(FEM_Is_ghost_index(el)) {
00760 CkAssert(m->elem[0].ghost->is_valid(FEM_From_ghost_index(el))==1);
00761 }
00762 else {
00763 CkAssert(m->elem[0].is_valid(el)==1);
00764 }
00765 }
00766 }
00767 #ifdef DEBUG
00768 CmiMemoryCheck();
00769 #endif
00770 removeGhostElemMsg *rm = new (numGhostNodes, numGhostRN, numGhostRE, numSharedNodes, 0) removeGhostElemMsg;
00771 rm->chk = index;
00772 rm->elemtype = elemtype;
00773 rm->elementid = sharedIdx;
00774 rm->numGhostIndex = numGhostNodes;
00775 for(int j=0; j<numGhostNodes; j++) {
00776 rm->ghostIndices[j] = ghostIndices[j];
00777 }
00778 rm->numGhostRNIndex = numGhostRN;
00779 for(int j=0; j<numGhostRN; j++) {
00780 rm->ghostRNIndices[j] = ghostRNIndices[j];
00781 }
00782 rm->numGhostREIndex = numGhostRE;
00783 for(int j=0; j<numGhostRE; j++) {
00784 rm->ghostREIndices[j] = ghostREIndices[j];
00785 }
00786 rm->numSharedIndex = numSharedNodes;
00787 for(int j=0; j<numSharedNodes; j++) {
00788 rm->sharedIndices[j] = sharedIndices[j];
00789 }
00790 meshMod[chk].removeGhostElem(rm);
00791
00792 if(lockedRemoteIDXL) m->getfmMM()->getfmUtil()->idxlunlock(m,chk,0);
00793 free(ghostIndices);
00794 free(sharedIndices);
00795 }
00796 free(chknos);
00797 free(inds);
00798 if(permanent>=0) {
00799 delete [] newghost;
00800 delete [] ghostidx;
00801 delete [] losingThisNode;
00802 delete [] nodes;
00803 delete [] willBeGhost;
00804 }
00805 }
00806 }
00807
00808 FEM_remove_element_local(m, elementid, elemtype);
00809 #ifdef DEBUG
00810 CmiMemoryCheck();
00811 #endif
00812 }
00813 return index;
00814 }
00815
00816 void FEM_remove_element_remote(FEM_Mesh *m, int element, int elemtype){
00817
00818 }
00819
00820 int FEM_purge_element(FEM_Mesh *m, int elementid, int elemtype) {
00821 if(elementid==-1) return 1;
00822 int index = m->getfmMM()->idx;
00823 if(FEM_Is_ghost_index(elementid)) {
00824 const IDXL_Rec *irec1 = m->elem[elemtype].ghost->ghostRecv.getRec(FEM_To_ghost_index(elementid));
00825 int remotechk = irec1->getChk(0);
00826 int sharedIdx = irec1->getIdx(0);
00827 meshMod[remotechk].purgeElement(index,sharedIdx);
00828 }
00829 else {
00830 const IDXL_Rec *irec = m->elem[elemtype].ghostSend.getRec(elementid);
00831 if(irec){
00832 int numSharedChunks = irec->getShared();
00833 int connSize = m->elem[elemtype].getConn().width();
00834 int *chknos, *inds;
00835 if(numSharedChunks>0) {
00836 chknos = (int*)malloc(numSharedChunks*sizeof(int));
00837 inds = (int*)malloc(numSharedChunks*sizeof(int));
00838 for(int i=0; i<numSharedChunks; i++) {
00839 chknos[i] = irec->getChk(i);
00840 inds[i] = irec->getIdx(i);
00841 }
00842 }
00843 for(int i=0; i<numSharedChunks; i++) {
00844 meshMod[chknos[i]].cleanupIDXL(index,inds[i]);
00845 m->elem[elemtype].ghostSend.removeNode(elementid, chknos[i]);
00846 }
00847 if(numSharedChunks>0) {
00848 free(chknos);
00849 free(inds);
00850 }
00851 }
00852 }
00853
00854 if(!FEM_Is_ghost_index(elementid)){
00855 m->elem[elemtype].set_invalid(elementid,false);
00856 }
00857 return 1;
00858 }
00859
00860
00861
00862
00863 void update_new_element_e2e(FEM_Mesh *m, int newEl, int elemType){
00864 CkAssert(elemType==0);
00865
00866
00867 FEM_ElemAdj_Layer *g = m->getElemAdjLayer();
00868 CkAssert(g->initialized);
00869 const int nodesPerTuple = g->nodesPerTuple;
00870 const int tuplesPerElem = g->elem[elemType].tuplesPerElem;
00871 tupleTable table(nodesPerTuple);
00872 FEM_Symmetries_t allSym;
00873
00874
00875
00876
00877 const int nodesPerElem = m->elem[elemType].getNodesPer();
00878 int *adjnodes = new int[nodesPerElem];
00879 CkVec<int> elist;
00880 m->e2n_getAll(newEl, adjnodes, elemType);
00881 #ifdef DEBUG
00882 CmiMemoryCheck();
00883 #endif
00884 for(int i=0;i<nodesPerElem;i++){
00885 int sz;
00886 int *adjelements=0;
00887 m->n2e_getAll(adjnodes[i], &adjelements, &sz);
00888 for(int j=0;j<sz;j++){
00889 int found=0;
00890
00891 for(int i=0;i<elist.length();i++)
00892 if(elist[i] == adjelements[j])
00893 found=1;
00894 if(!found){
00895 elist.push_back(adjelements[j]);
00896 }
00897 }
00898 if(sz!=0) delete[] adjelements;
00899 }
00900 delete[] adjnodes;
00901
00902
00903
00904 for(int i=0;i<elist.length();i++){
00905 int nextElem = elist[i];
00906 int tuple[tupleTable::MAX_TUPLE];
00907 int *conn;
00908 if(FEM_Is_ghost_index(nextElem))
00909 conn=((FEM_Elem*)m->elem[elemType].getGhost())->connFor(FEM_To_ghost_index(nextElem));
00910 else
00911 conn=m->elem[elemType].connFor(nextElem);
00912 for (int u=0;u<tuplesPerElem;u++) {
00913 for (int i=0;i<nodesPerTuple;i++) {
00914 int eidx=g->elem[elemType].elem2tuple[i+u*g->nodesPerTuple];
00915 if (eidx==-1)
00916 tuple[i]=-1;
00917 else
00918 tuple[i]=conn[eidx];
00919 }
00920 table.addTuple(tuple,new elemList(0,nextElem,elemType,allSym,u));
00921 }
00922 }
00923
00924
00925
00926
00927 table.beginLookup();
00928
00929
00930 elemList *l;
00931 FEM_IndexAttribute *elemAdjTypesAttr = (FEM_IndexAttribute *)m->elem[elemType].lookup(FEM_ELEM_ELEM_ADJ_TYPES,"update_new_element_e2e");
00932 FEM_IndexAttribute *elemAdjAttr = (FEM_IndexAttribute *)m->elem[elemType].lookup(FEM_ELEM_ELEM_ADJACENCY,"update_new_element_e2e");
00933 FEM_IndexAttribute *elemAdjTypesAttrGhost = (FEM_IndexAttribute *)m->elem[elemType].getGhost()->lookup(FEM_ELEM_ELEM_ADJ_TYPES,"update_new_element_e2e");
00934 FEM_IndexAttribute *elemAdjAttrGhost = (FEM_IndexAttribute *)m->elem[elemType].getGhost()->lookup(FEM_ELEM_ELEM_ADJACENCY,"update_new_element_e2e");
00935
00936 AllocTable2d<int> &adjTable = elemAdjAttr->get();
00937 int *adjs = adjTable.getData();
00938 AllocTable2d<int> &adjTypesTable = elemAdjTypesAttr->get();
00939 int *adjTypes = adjTypesTable.getData();
00940 AllocTable2d<int> &adjTableGhost = elemAdjAttrGhost->get();
00941 int *adjsGhost = adjTableGhost.getData();
00942 AllocTable2d<int> &adjTypesTableGhost = elemAdjTypesAttrGhost->get();
00943 int *adjTypesGhost = adjTypesTableGhost.getData();
00944
00945 while (NULL!=(l=table.lookupNext())) {
00946 if (l->next==NULL) {}
00947 else {
00948
00949 for (const elemList *a=l;a!=NULL;a=a->next){
00950 for (const elemList *b=a->next;b!=NULL;b=b->next){
00951 if((a->localNo != b->localNo) || (a->type != b->type)){
00952
00953
00954 if(FEM_Is_ghost_index(a->localNo)){
00955 const int j = FEM_To_ghost_index(a->localNo)*tuplesPerElem + a->tupleNo;
00956 adjsGhost[j] = b->localNo;
00957 adjTypesGhost[j] = b->type;
00958 }
00959 else{
00960 const int j= a->localNo*tuplesPerElem + a->tupleNo;
00961 adjs[j] = b->localNo;
00962 adjTypes[j] = b->type;
00963 }
00964
00965
00966 if(FEM_Is_ghost_index(b->localNo)){
00967 const int j = FEM_To_ghost_index(b->localNo)*tuplesPerElem + b->tupleNo;
00968 adjsGhost[j] = a->localNo;
00969 adjTypesGhost[j] = a->type;
00970 }
00971 else{
00972 const int j= b->localNo*tuplesPerElem + b->tupleNo;
00973 adjs[j] = a->localNo;
00974 adjTypes[j] = a->type;
00975 }
00976 }
00977 }
00978 }
00979 }
00980 }
00981 }
00982
00983
00984 int FEM_add_element_local(FEM_Mesh *m, const int *conn, int connSize, int elemType, int addGhost){
00985
00986 int newEl;
00987 if(addGhost){
00988 newEl = m->elem[elemType].getGhost()->get_next_invalid(m,false,true);
00989 ((FEM_Elem*)m->elem[elemType].getGhost())->connIs(newEl,conn);
00990 newEl = FEM_From_ghost_index(newEl);
00991 }
00992 else{
00993 newEl = m->elem[elemType].get_next_invalid(m,false,false);
00994 m->elem[elemType].connIs(newEl,conn);
00995 }
00996
00997 #ifdef DEBUG
00998 CmiMemoryCheck();
00999 #endif
01000
01001 for(int i=0;i<connSize;i++){
01002 m->n2e_add(conn[i],newEl);
01003 for(int j=i+1;j<connSize;j++){
01004 if(! m->n2n_exists(conn[i],conn[j]))
01005 m->n2n_add(conn[i],conn[j]);
01006 if(! m->n2n_exists(conn[j],conn[i]))
01007 m->n2n_add(conn[j],conn[i]);
01008 }
01009 }
01010
01011
01012 m->e2e_removeAll(newEl);
01013 update_new_element_e2e(m,newEl,elemType);
01014
01015 int *adjes = new int[connSize];
01016 m->e2e_getAll(newEl, adjes, 0);
01017 CkAssert(!((adjes[0]==adjes[1] && adjes[0]!=-1) || (adjes[1]==adjes[2] && adjes[1]!=-1) || (adjes[2]==adjes[0] && adjes[2]!=-1)));
01018 delete[] adjes;
01019 return newEl;
01020 }
01021
01022
01023 int FEM_add_element(FEM_Mesh *m, int* conn, int connSize, int elemType, int chunkNo){
01024 int newEl = -1;
01025 int index = m->getfmMM()->getIdx();
01026 int buildGhosts = 0;
01027 int sharedcount=0;
01028 int ghostcount=0;
01029 int localcount=0;
01030 CkAssert(conn[0]!=conn[1] &&conn[1]!=conn[2] &&conn[2]!=conn[0]);
01031 int *nodetype = (int *)malloc(connSize *sizeof(int));
01032 for(int i=0;i<connSize;i++){
01033 CkAssert(conn[i]!=-1);
01034 if(is_shared(m,conn[i])) {
01035 nodetype[i] = 1;
01036 sharedcount++;
01037 }
01038 else if(FEM_Is_ghost_index(conn[i])) {
01039 nodetype[i] = 2;
01040 ghostcount++;
01041 }
01042 else {
01043 nodetype[i] = 0;
01044 }
01045 }
01046 #ifdef DEBUG
01047 CmiMemoryCheck();
01048 #endif
01049 localcount = connSize - (sharedcount + ghostcount);
01050 if(sharedcount==0 && ghostcount==0){
01051 newEl = FEM_add_element_local(m,conn,connSize,elemType,0);
01052
01053 }
01054 else if(ghostcount==0 && sharedcount > 0 && localcount > 0){
01055 newEl = FEM_add_element_local(m,conn,connSize,elemType,0);
01056 buildGhosts = 1;
01057 }
01058 else if(ghostcount==0 && sharedcount > 0 && localcount == 0){
01059
01060
01061
01062 if(!(chunkNo==index || chunkNo==-1)) {
01063 addElemMsg *am = new (connSize, 0, 0) addElemMsg;
01064 int chk = index;
01065 am->chk = chk;
01066 am->elemtype = elemType;
01067 am->connSize = connSize;
01068 am->numGhostIndex = 0;
01069 for(int i=0; i<connSize; i++) {
01070 CkAssert(nodetype[i] == 1);
01071 am->conn[i] = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,conn[i],chunkNo,0);
01072 CkAssert(am->conn[i] >= 0);
01073 }
01074 #ifdef DEBUG
01075 CmiMemoryCheck();
01076 #endif
01077 meshMod[chunkNo].addElementRemote(am);
01078
01079
01080
01081 const IDXL_List ilist = m->elem[elemType].ghost->ghostRecv.addList(chunkNo);
01082 int size = ilist.size();
01083 newEl = ilist[size-1];
01084 newEl = FEM_To_ghost_index(newEl);
01085 free(nodetype);
01086 return newEl;
01087 }
01088 newEl = FEM_add_element_local(m,conn,connSize,elemType,0);
01089 buildGhosts = 1;
01090 }
01091
01092 else if(ghostcount > 0 ) {
01093
01094 if((chunkNo!=-1) && (chunkNo==index)) {
01095
01096
01097 for(int i=0; i<connSize; i++) {
01098 if(nodetype[i]==2) {
01099
01100 #ifdef DEBUG
01101 CmiMemoryCheck();
01102 #endif
01103 int numchunks;
01104 IDXL_Share **chunks1;
01105 m->getfmMM()->getfmUtil()->getChunkNos(0,conn[i],&numchunks,&chunks1);
01106
01107 int newN = m->getfmMM()->getfmUtil()->Replace_node_local(m, conn[i], -1);
01108
01109 for(int j=0; j<numchunks; j++) {
01110 int chk = chunks1[j]->chk;
01111 if(chk==index) continue;
01112
01113
01114 m->getfmMM()->getfmUtil()->idxllock(m,chk,0);
01115 m->node.shared.addNode(newN,chk);
01116
01117 int idx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m, conn[i], chk, 2);
01118 m->node.ghost->ghostRecv.removeNode(FEM_To_ghost_index(conn[i]), chk);
01119 meshMod[chk].addToSharedList(index, idx);
01120
01121
01122 m->getfmMM()->getfmUtil()->idxlunlock(m, chk, 0);
01123 }
01124 nodetype[i] = 1;
01125 sharedcount++;
01126 ghostcount--;
01127
01128 FEM_remove_node_local(m,conn[i]);
01129 conn[i] = newN;
01130
01131
01132 for(int j=0; j<numchunks; j++) {
01133 delete chunks1[j];
01134 }
01135 if(numchunks != 0) free(chunks1);
01136 }
01137 }
01138 newEl = FEM_add_element_local(m,conn,connSize,elemType,0);
01139 buildGhosts = 1;
01140 }
01141 else {
01142 int numSharedChunks = 0;
01143 int remoteChunk = -1;
01144 if(chunkNo==-1) {
01145 CkAssert(false);
01146
01147
01148
01149
01150
01151
01152
01153 CkVec<int> **allShared;
01154 CkVec<int> *allChunks;
01155 int **sharedConn;
01156 m->getfmMM()->getfmUtil()->buildChunkToNodeTable(nodetype, sharedcount, ghostcount, localcount, conn, connSize, &allShared, &numSharedChunks, &allChunks, &sharedConn);
01157
01158 for(int i=0; i<numSharedChunks; i++) {
01159 #ifdef DEBUG
01160 CmiMemoryCheck();
01161 #endif
01162 remoteChunk = i;
01163 for(int j=0; j<connSize; j++) {
01164 if(sharedConn[i][j] == -1 || sharedConn[i][j] == 2) {
01165 remoteChunk = -1;
01166 break;
01167 }
01168
01169
01170
01171 }
01172 if(remoteChunk == i) break;
01173 else remoteChunk = -1;
01174 }
01175 if(remoteChunk==-1) {
01176
01177 if(chunkNo != -1) {
01178
01179 remoteChunk = chunkNo;
01180 for(int k=0; k<numSharedChunks; k++) {
01181 if(chunkNo == (*allChunks)[k]) {
01182 for(int l=0; l<connSize; l++) {
01183 if(sharedConn[k][l]==-1 || sharedConn[k][l]==2) {
01184
01185 }
01186 }
01187 }
01188 }
01189 }
01190 else {
01191 CkPrintf("[%d]ERROR: Can not derive where (%d,%d,%d) belongs to\n",index,conn[0],conn[1],conn[2]);
01192 CkAssert(false);
01193 }
01194 }
01195 remoteChunk = (*allChunks)[remoteChunk];
01196
01197 CkPrintf("[%d]Error: I derived it should go to chunk %d, which is not %d\n",index,remoteChunk,chunkNo);
01198 for(int k=0; k<numSharedChunks; k++) {
01199 free(sharedConn[k]);
01200 }
01201 if(numSharedChunks!=0) free(sharedConn);
01202 for(int k=0; k<connSize; k++) {
01203 delete allShared[k];
01204 }
01205 free(allShared);
01206 }
01207 else {
01208 remoteChunk=chunkNo;
01209 }
01210 int numGhostNodes = 0;
01211 for(int i=0; i<connSize; i++) {
01212 if(nodetype[i] == 2) {
01213 numGhostNodes++;
01214 }
01215 }
01216 CkAssert(numGhostNodes > 0);
01217 addElemMsg *am = new (connSize, numGhostNodes, 0) addElemMsg;
01218 int chk = index;
01219 am->chk = chk;
01220 am->elemtype = elemType;
01221 am->connSize = connSize;
01222 am->numGhostIndex = numGhostNodes;
01223 int j = 0;
01224 for(int i=0; i<connSize; i++) {
01225 #ifdef DEBUG
01226 CmiMemoryCheck();
01227 #endif
01228 if(nodetype[i] == 1) {
01229 am->conn[i] = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,conn[i],remoteChunk,0);
01230 CkAssert(am->conn[i] >= 0);
01231 }
01232 else if(nodetype[i] == 2) {
01233 am->conn[i] = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,conn[i],remoteChunk,2);
01234 CkAssert(am->conn[i] >= 0);
01235 am->ghostIndices[j] = i;
01236 j++;
01237 }
01238 }
01239 meshMod[remoteChunk].addElementRemote(am);
01240
01241
01242
01243 const IDXL_List ilist = m->elem[elemType].ghost->ghostRecv.addList(remoteChunk);
01244 int size = ilist.size();
01245 newEl = ilist[size-1];
01246 newEl = FEM_To_ghost_index(newEl);
01247 }
01248 }
01249 else if(ghostcount > 0 && localcount == 0 && sharedcount == 0) {
01250
01251
01252
01253
01254
01255 }
01256 else if(ghostcount > 0 && localcount > 0 && sharedcount > 0){
01257
01258
01259
01260
01261
01262
01263
01264
01265 }
01266 else if(ghostcount > 0 && localcount > 0 && sharedcount == 0) {
01267
01268 }
01269
01270 if(buildGhosts==1) {
01271
01272
01273
01274
01275
01276
01277
01278
01279 CkVec<int> **allShared;
01280 int numSharedChunks = 0;
01281 CkVec<int> *allChunks;
01282 int **sharedConn;
01283 m->getfmMM()->getfmUtil()->buildChunkToNodeTable(nodetype, sharedcount, ghostcount, localcount, conn, connSize, &allShared, &numSharedChunks, &allChunks, &sharedConn);
01284
01285 for(int i=0; i<numSharedChunks; i++) {
01286 #ifdef DEBUG
01287 CmiMemoryCheck();
01288 #endif
01289 int chk = (*allChunks)[i];
01290 if(chk == index) continue;
01291
01292
01293
01294
01295 m->getfmMM()->getfmUtil()->idxllock(m, chk, 0);
01296 m->elem[elemType].ghostSend.addNode(newEl,chk);
01297
01298 int numNodesToAdd = 0;
01299 int numSharedGhosts = 0;
01300 int numSharedNodes = 0;
01301 int *sharedGhosts = (int *)malloc((connSize-1)*sizeof(int));
01302 int *sharedNodes = (int *)malloc((connSize)*sizeof(int));
01303 int *nodesToAdd = (int *)malloc((connSize)*sizeof(int));
01304 for(int j=0; j<connSize; j++) {
01305 int sharedNode = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,conn[j],chk,0);
01306 if(sharedNode == -1) {
01307
01308 int sharedGhost = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,conn[j],chk,1);
01309 if( sharedGhost == -1) {
01310
01311
01312 const IDXL_Rec *irec = m->node.shared.getRec(conn[j]);
01313 if(irec) {
01314 int noShared = irec->getShared();
01315 for(int sharedck=0; sharedck<noShared; sharedck++) {
01316 int ckshared = irec->getChk(sharedck);
01317 int idxshared = irec->getIdx(sharedck);
01318 if(ckshared == chk) continue;
01319 CkAssert(chk!=index && chk!=ckshared && ckshared!=index);
01320 int idxghostsend = meshMod[ckshared].getIdxGhostSend(index,idxshared,chk)->i;
01321 if(idxghostsend != -1) {
01322 m->node.ghostSend.addNode(conn[j],chk);
01323 meshMod[chk].updateIdxlList(index,idxghostsend,ckshared);
01324 sharedGhost = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,conn[j],chk,1);
01325 CkAssert(sharedGhost != -1);
01326 break;
01327 }
01328
01329 }
01330 }
01331
01332 }
01333 if(sharedGhost == -1) {
01334 nodesToAdd[numNodesToAdd] = conn[j];
01335 numNodesToAdd++;
01336 }
01337 else {
01338
01339 sharedGhosts[numSharedGhosts] = sharedGhost;
01340 numSharedGhosts++;
01341 }
01342 }
01343 else {
01344
01345 sharedNodes[numSharedNodes] = sharedNode;
01346 numSharedNodes++;
01347 }
01348 }
01349 #ifdef DEBUG
01350 CmiMemoryCheck();
01351 #endif
01352 addGhostElemMsg *fm = new (numSharedGhosts, numSharedNodes, 0)addGhostElemMsg;
01353 fm->chk = index;
01354 fm->elemType = elemType;
01355 fm->numGhostIndex = numSharedGhosts;
01356 for(int j=0; j<numSharedGhosts; j++) {
01357 fm->ghostIndices[j] = sharedGhosts[j];
01358 }
01359 fm->numSharedIndex = numSharedNodes;
01360 for(int j=0; j<numSharedNodes; j++) {
01361 fm->sharedIndices[j] = sharedNodes[j];
01362 }
01363 for(int j=0; j<numNodesToAdd; j++) {
01364 m->node.ghostSend.addNode(nodesToAdd[j],chk);
01365 }
01366 free(nodesToAdd);
01367 fm->connSize = connSize;
01368 meshMod[chk].addGhostElem(fm);
01369
01370
01371
01372 m->getfmMM()->getfmUtil()->idxlunlock(m, chk, 0);
01373 free(sharedGhosts);
01374 free(sharedNodes);
01375 }
01376 for(int k=0; k<numSharedChunks; k++) {
01377 free(sharedConn[k]);
01378 }
01379 if(numSharedChunks!=0) free(sharedConn);
01380 for(int k=0; k<connSize; k++) {
01381 delete allShared[k];
01382 }
01383 free(allShared);
01384 }
01385
01386 free(nodetype);
01387 return newEl;
01388 }
01389
01390
01391 int FEM_add_element_remote(){
01392
01393
01394
01395
01396
01397
01398
01399 return 0;
01400 }
01401
01402
01403 int FEM_Modify_Lock(FEM_Mesh *m, int* affectedNodes, int numAffectedNodes, int* affectedElts, int numAffectedElts, int elemtype) {
01404 return m->getfmMM()->getfmLock()->lock(numAffectedNodes, affectedNodes, numAffectedElts, affectedElts, elemtype);
01405 }
01406
01407 int FEM_Modify_Unlock(FEM_Mesh *m) {
01408 return m->getfmMM()->getfmLock()->unlock();
01409 }
01410
01411 int FEM_Modify_LockN(FEM_Mesh *m, int nodeId, int readlock) {
01412 int ret = -1;
01413 if(is_shared(m,nodeId)) {
01414
01415 int index = m->getfmMM()->getIdx();
01416 int numchunks;
01417 IDXL_Share **chunks1;
01418 m->getfmMM()->getfmUtil()->getChunkNos(0,nodeId,&numchunks,&chunks1);
01419 int minChunk = MAX_CHUNK;
01420 for(int j=0; j<numchunks; j++) {
01421 int pchk = chunks1[j]->chk;
01422 if(pchk < minChunk) minChunk = pchk;
01423 }
01424 for(int j=0; j<numchunks; j++) {
01425 delete chunks1[j];
01426 }
01427 if(numchunks!=0) free(chunks1);
01428 CkAssert(minChunk!=MAX_CHUNK);
01429 if(minChunk==index) {
01430 if(readlock) {
01431 ret = m->getfmMM()->getfmLockN(nodeId)->rlock();
01432 } else {
01433 ret = m->getfmMM()->getfmLockN(nodeId)->wlock(index);
01434 }
01435 if(ret==1) {
01436 m->getfmMM()->getfmLockN(nodeId)->verifyLock();
01437 }
01438 return ret;
01439 }
01440 else {
01441 CkAssert(minChunk!=MAX_CHUNK);
01442 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,minChunk,0);
01443 if(sharedIdx < 0) return -1;
01444 if(readlock) {
01445 ret = meshMod[minChunk].lockRemoteNode(sharedIdx, index, 0, 1)->i;
01446 } else {
01447 ret = meshMod[minChunk].lockRemoteNode(sharedIdx, index, 0, 0)->i;
01448 }
01449 if(ret==1) {
01450 meshMod[minChunk].verifyLock(index,sharedIdx,0);
01451 }
01452 return ret;
01453 }
01454 }
01455 else if(FEM_Is_ghost_index(nodeId)) {
01456
01457 #ifdef DEBUG
01458 CmiMemoryCheck();
01459 #endif
01460 int index = m->getfmMM()->getIdx();
01461 int numchunks;
01462 IDXL_Share **chunks1;
01463 m->getfmMM()->getfmUtil()->getChunkNos(0,nodeId,&numchunks,&chunks1);
01464 int minChunk = MAX_CHUNK;
01465 for(int j=0; j<numchunks; j++) {
01466 int pchk = chunks1[j]->chk;
01467 if(pchk == index) continue;
01468 if(pchk < minChunk) minChunk = pchk;
01469 }
01470 for(int j=0; j<numchunks; j++) {
01471 delete chunks1[j];
01472 }
01473 if(numchunks!=0) free(chunks1);
01474 if(minChunk==MAX_CHUNK) return -1;
01475 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,minChunk,2);
01476 if(sharedIdx < 0) return -1;
01477 if(readlock) {
01478 ret = meshMod[minChunk].lockRemoteNode(sharedIdx, index, 1, 1)->i;
01479 } else {
01480 ret = meshMod[minChunk].lockRemoteNode(sharedIdx, index, 1, 0)->i;
01481 }
01482
01483
01484
01485
01486
01487
01488 return ret;
01489 }
01490 else {
01491 if(readlock) {
01492 ret = m->getfmMM()->getfmLockN(nodeId)->rlock();
01493 } else {
01494 int index = m->getfmMM()->getIdx();
01495 ret = m->getfmMM()->getfmLockN(nodeId)->wlock(index);
01496 }
01497
01498
01499
01500 return ret;
01501 }
01502 #ifdef DEBUG
01503 CmiMemoryCheck();
01504 #endif
01505 return -1;
01506 }
01507
01508 int FEM_Modify_UnlockN(FEM_Mesh *m, int nodeId, int readlock) {
01509 #ifdef DEBUG
01510 CmiMemoryCheck();
01511 #endif
01512 if(is_shared(m,nodeId)) {
01513
01514 int index = m->getfmMM()->getIdx();
01515 int numchunks;
01516 IDXL_Share **chunks1;
01517 m->getfmMM()->getfmUtil()->getChunkNos(0,nodeId,&numchunks,&chunks1);
01518 int minChunk = MAX_CHUNK;
01519 for(int j=0; j<numchunks; j++) {
01520 int pchk = chunks1[j]->chk;
01521 if(pchk < minChunk) minChunk = pchk;
01522 }
01523 for(int j=0; j<numchunks; j++) {
01524 delete chunks1[j];
01525 }
01526 if(numchunks!=0) free(chunks1);
01527 if(minChunk==index) {
01528 if(readlock) {
01529 return m->getfmMM()->getfmLockN(nodeId)->runlock();
01530 } else {
01531 return m->getfmMM()->getfmLockN(nodeId)->wunlock(index);
01532 }
01533 }
01534 else {
01535 CkAssert(minChunk!=MAX_CHUNK);
01536 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,minChunk,0);
01537 if(readlock) {
01538 return meshMod[minChunk].unlockRemoteNode(sharedIdx, index, 0, 1)->i;
01539 } else {
01540 return meshMod[minChunk].unlockRemoteNode(sharedIdx, index, 0, 0)->i;
01541 }
01542 }
01543 }
01544 else if(FEM_Is_ghost_index(nodeId)) {
01545
01546 int index = m->getfmMM()->getIdx();
01547 int numchunks;
01548 IDXL_Share **chunks1;
01549 m->getfmMM()->getfmUtil()->getChunkNos(0,nodeId,&numchunks,&chunks1);
01550 int minChunk = MAX_CHUNK;
01551 for(int j=0; j<numchunks; j++) {
01552 int pchk = chunks1[j]->chk;
01553 if(pchk == index) continue;
01554 if(pchk < minChunk) minChunk = pchk;
01555 }
01556 for(int j=0; j<numchunks; j++) {
01557 delete chunks1[j];
01558 }
01559 if(numchunks!=0) free(chunks1);
01560 if(minChunk==MAX_CHUNK) return -1;
01561 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,minChunk,2);
01562 if(readlock) {
01563 return meshMod[minChunk].unlockRemoteNode(sharedIdx, index, 1, 1)->i;
01564 } else {
01565 return meshMod[minChunk].unlockRemoteNode(sharedIdx, index, 1, 0)->i;
01566 }
01567 }
01568 else {
01569 if(readlock) {
01570 return m->getfmMM()->getfmLockN(nodeId)->runlock();
01571 } else {
01572 int index = m->getfmMM()->getIdx();
01573 return m->getfmMM()->getfmLockN(nodeId)->wunlock(index);
01574 }
01575 }
01576 return -1;
01577 }
01578
01579
01580
01581 void FEM_Modify_LockAll(FEM_Mesh*m, int nodeId, bool lockall) {
01582 int index = m->getfmMM()->getIdx();
01583 int numchunks;
01584 const IDXL_Rec *irec = m->node.shared.getRec(nodeId);
01585
01586 if(irec) {
01587 numchunks = irec->getShared();
01588 if(!lockall) {
01589 int minchunk=MAX_CHUNK;
01590 int sharedIdx = -1;
01591 for(int i=0; i<numchunks; i++) {
01592 int pchk = irec->getChk(i);
01593 if(pchk<minchunk) {
01594 minchunk = pchk;
01595 sharedIdx = irec->getIdx(i);
01596 }
01597 }
01598 CkAssert(minchunk!=MAX_CHUNK && sharedIdx!=-1);
01599
01600 int done = meshMod[minchunk].lockRemoteNode(sharedIdx, index, 0, 0)->i;
01601
01602 }
01603 else {
01604 for(int i=0; i<numchunks; i++) {
01605 int pchk = irec->getChk(i);
01606 int sharedIdx = irec->getIdx(i);
01607 int done = meshMod[pchk].lockRemoteNode(sharedIdx, index, 0, 0)->i;
01608 }
01609 m->getfmMM()->getfmLockN(nodeId)->wlock(index);
01610 }
01611 }
01612 return;
01613 }
01614
01615
01616 void FEM_Modify_LockUpdate(FEM_Mesh*m, int nodeId, bool lockall) {
01617 int index = m->getfmMM()->getIdx();
01618 int numchunks;
01619 const IDXL_Rec *irec = m->node.shared.getRec(nodeId);
01620
01621
01622 if(irec) {
01623 numchunks = irec->getShared();
01624 int minchunk=MAX_CHUNK;
01625 int minI=-1;
01626 for(int i=0; i<numchunks; i++) {
01627 int pchk = irec->getChk(i);
01628 if(pchk<minchunk) {
01629 minchunk = pchk;
01630 minI=i;
01631 }
01632 }
01633 if(!lockall) {
01634 if(minchunk>index) {
01635 int prevminchunk=minchunk;
01636 minchunk=index;
01637 int sharedIdx = irec->getIdx(minI);
01638 CkAssert(prevminchunk!=MAX_CHUNK && sharedIdx!=-1);
01639 meshMod[prevminchunk].unlockRemoteNode(sharedIdx, index, 0, 0);
01640 }
01641 else if(minchunk < index) {
01642
01643 int sharedIdx = irec->getIdx(minI);
01644 meshMod[minchunk].lockRemoteNode(sharedIdx, index, 0, 0);
01645 m->getfmMM()->getfmLockN(nodeId)->wunlock(index);
01646 }
01647 }
01648 else {
01649 if(minchunk>index) minchunk=index;
01650 if(minchunk!=index) {
01651 m->getfmMM()->getfmLockN(nodeId)->wunlock(index);
01652 }
01653 for(int i=0; i<numchunks; i++) {
01654 int pchk = irec->getChk(i);
01655 if(pchk!=minchunk) {
01656 int sharedIdx = irec->getIdx(i);
01657 meshMod[pchk].unlockRemoteNode(sharedIdx, index, 0, 0);
01658 }
01659 }
01660 }
01661 }
01662 return;
01663 }
01664
01665
01666
01667
01668
01669 void FEM_Modify_correctLockN(FEM_Mesh *m, int nodeId) {
01670 int index = m->getfmMM()->getIdx();
01671 int numchunks;
01672 IDXL_Share **chunks1;
01673 m->getfmMM()->getfmUtil()->getChunkNos(0,nodeId,&numchunks,&chunks1);
01674 int minChunk = MAX_CHUNK;
01675 int owner = -1;
01676 for(int j=0; j<numchunks; j++) {
01677 int pchk = chunks1[j]->chk;
01678 if(pchk < minChunk) minChunk = pchk;
01679 }
01680 if(is_shared(m,nodeId)) {
01681 for(int j=0; j<numchunks; j++) {
01682 int pchk = chunks1[j]->chk;
01683 if(pchk == index) owner = m->getfmMM()->getfmLockN(nodeId)->lockOwner();
01684 else {
01685 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,pchk,0);
01686 owner = meshMod[pchk].hasLockRemoteNode(sharedIdx, index, 0)->i;
01687 }
01688 if(owner != -1) {
01689 if(pchk == minChunk) {
01690
01691 break;
01692 }
01693 else {
01694
01695 int locknodes = nodeId;
01696 int gotlocks = 1;
01697 int done = -1;
01698 if(pchk==index) m->getfmMM()->getfmLockN(nodeId)->wunlock(index);
01699 else {
01700 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,pchk,0);
01701 meshMod[pchk].unlockRemoteNode(sharedIdx, index, 0, 0);
01702 }
01703 if(minChunk==index) done = m->getfmMM()->getfmLockN(nodeId)->wlock(index);
01704 else {
01705 CkAssert(minChunk!=MAX_CHUNK);
01706 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,minChunk,0);
01707 done = meshMod[minChunk].lockRemoteNode(sharedIdx, index, 0, 0)->i;
01708 }
01709 break;
01710 }
01711 }
01712 }
01713 }
01714 else if(FEM_Is_ghost_index(nodeId)) {
01715
01716 for(int j=0; j<numchunks; j++) {
01717 int pchk = chunks1[j]->chk;
01718 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,pchk,2);
01719 owner = meshMod[pchk].hasLockRemoteNode(sharedIdx, index, 1)->i;
01720 if(owner != -1) {
01721 if(pchk == minChunk) {
01722
01723 break;
01724 }
01725 else {
01726
01727 int locknodes = nodeId;
01728 int gotlocks = 1;
01729 int done = -1;
01730 int sharedIdx = m->getfmMM()->getfmUtil()->exists_in_IDXL(m,nodeId,pchk,2);
01731 meshMod[pchk].unlockRemoteNode(sharedIdx, index, 1, 0);
01732 gotlocks=-1;
01733 while(done==-1) {
01734 done = m->getfmMM()->fmAdaptL->lockNodes(&gotlocks, &locknodes, 0, &locknodes, 1);
01735 }
01736 break;
01737 }
01738 }
01739 }
01740 if(owner==-1) {
01741 int locknodes = nodeId;
01742 int done = -1;
01743 int gotlocks=-1;
01744 while(done==-1) {
01745 done = m->getfmMM()->fmAdaptL->lockNodes(&gotlocks, &locknodes, 0, &locknodes, 1);
01746 }
01747 }
01748 }
01749 for(int j=0; j<numchunks; j++) {
01750 delete chunks1[j];
01751 }
01752 if(numchunks!=0) free(chunks1);
01753 return;
01754 }
01755
01756 CLINKAGE void FEM_REF_INIT(int mesh, int dim) {
01757 CkArrayID femRefId;
01758 int cid;
01759 int size;
01760 TCharm *tc=TCharm::get();
01761
01762 #ifdef DEBUG
01763 CmiMemoryCheck();
01764 #endif
01765 MPI_Comm comm = MPI_COMM_WORLD;
01766 MPI_Comm_rank(comm,&cid);
01767 MPI_Comm_size(comm,&size);
01768 if(cid==0) {
01769 CkArrayOptions opts;
01770 opts.bindTo(tc->getProxy());
01771 femMeshModMsg *fm = new femMeshModMsg;
01772 femRefId = CProxy_femMeshModify::ckNew(fm, opts);
01773 }
01774 MPI_Bcast(&femRefId, sizeof(CkArrayID), MPI_BYTE, 0, comm);
01775 meshMod = femRefId;
01776
01777 femMeshModMsg *fm = new femMeshModMsg(size,cid);
01778 meshMod[cid].insert(fm);
01779
01780 #ifdef DEBUG
01781 CmiMemoryCheck();
01782 #endif
01783 FEM_Mesh *m=FEM_Mesh_lookup(mesh,"FEM_REF_INIT");
01784 FEMMeshMsg *msg = new FEMMeshMsg(m,dim);
01785 meshMod[cid].setFemMesh(msg);
01786 #ifdef DEBUG
01787 CmiMemoryCheck();
01788 #endif
01789
01790 return;
01791 }
01792
01793
01794 void FEM_Ghost_Essential_attributes(FEM_Mesh *m, int coord_attr, int bc_attr, int nodeid) {
01795 femMeshModify *theMod = m->getfmMM();
01796 FEM_MUtil *util = theMod->getfmUtil();
01797 int index = theMod->idx;
01798
01799 if(FEM_Is_ghost_index(nodeid)) {
01800
01801 int numchunks;
01802 IDXL_Share **chunks1;
01803 util->getChunkNos(0,nodeid,&numchunks,&chunks1);
01804 for(int j=0; j<numchunks; j++) {
01805 int chk = chunks1[j]->chk;
01806 if(chk==index) continue;
01807 int ghostidx = util->exists_in_IDXL(m,nodeid,chk,2);
01808 double2Msg *d = meshMod[chk].getRemoteCoord(index,ghostidx);
01809 intMsg *im = meshMod[chk].getRemoteBound(index,ghostidx);
01810 double *coord = new double[2];
01811 coord[0] = d->i; coord[1] = d->j;
01812 int bound = im->i;
01813 CkVec<FEM_Attribute *>*attrs = m->node.ghost->getAttrVec();
01814 for (int i=0; i<attrs->size(); i++) {
01815 FEM_Attribute *a = (FEM_Attribute *)(*attrs)[i];
01816 if (a->getAttr() == theMod->fmAdaptAlgs->coord_attr) {
01817 FEM_DataAttribute *d = (FEM_DataAttribute *)a;
01818 d->getDouble().setRow(FEM_From_ghost_index(nodeid),coord,0);
01819 }
01820 else if(a->getAttr() == FEM_BOUNDARY) {
01821 FEM_DataAttribute *d = (FEM_DataAttribute *)a;
01822 d->getInt().setRow(FEM_From_ghost_index(nodeid),bound);
01823 }
01824 }
01825 delete [] coord;
01826 for(int j=0; j<numchunks; j++) {
01827 delete chunks1[j];
01828 }
01829 if(numchunks != 0) free(chunks1);
01830 break;
01831 }
01832 }
01833
01834 return;
01835 }
01836
01837
01838 femMeshModify::femMeshModify(femMeshModMsg *fm) {
01839 numChunks = fm->numChunks;
01840 idx = fm->myChunk;
01841 fmLock = new FEM_lock(idx, this);
01842 fmUtil = new FEM_MUtil(idx, this);
01843 fmAdapt = NULL;
01844 fmAdaptL = NULL;
01845 fmAdaptAlgs = NULL;
01846 fmInp = NULL;
01847 fmMesh = NULL;
01848 }
01849
01850 femMeshModify::~femMeshModify() {
01851 if(fmLock != NULL) {
01852 delete fmLock;
01853 }
01854 if(fmUtil != NULL) {
01855 delete fmUtil;
01856 }
01857 }
01858
01859 void femMeshModify::setFemMesh(FEMMeshMsg *fm) {
01860 fmMesh = fm->m;
01861 fmMesh->setFemMeshModify(this);
01862 fmAdapt = new FEM_Adapt(fmMesh, this);
01863 fmAdaptL = new FEM_AdaptL(fmMesh, this);
01864 int dim = fm->dimn;
01865 fmAdaptAlgs = new FEM_Adapt_Algs(fmMesh, this, dim);
01866 fmInp = new FEM_Interpolate(fmMesh, this);
01867
01868 int nsize = fmMesh->node.size();
01869 for(int i=0; i<nsize; i++) {
01870 fmLockN.push_back(new FEM_lockN(i,this));
01871 }
01872
01873
01874
01875
01876 for(int i=0; i<numChunks*5; i++) {
01877 fmIdxlLock.push_back(false);
01878 }
01879
01880 for(int i=0; i<nsize; i++) {
01881 if(fmAdaptL->isCorner(i)) {
01882 fmfixedNodes.push_back(i);
01883 }
01884 }
01885 #ifdef DEBUG
01886 CmiMemoryCheck();
01887 #endif
01888 return;
01889 }
01890
01891 intMsg *femMeshModify::lockRemoteChunk(int2Msg *msg) {
01892 intMsg *imsg = new intMsg(0);
01893 int ret = fmLock->lock(msg->i, msg->j);
01894 imsg->i = ret;
01895 return imsg;
01896 }
01897
01898 intMsg *femMeshModify::unlockRemoteChunk(int2Msg *msg) {
01899 intMsg *imsg = new intMsg(0);
01900 int ret = fmLock->unlock(msg->i, msg->j);
01901 imsg->i = ret;
01902 return imsg;
01903 }
01904
01905 intMsg *femMeshModify::lockRemoteNode(int sharedIdx, int fromChk, int isGhost, int readLock) {
01906 #ifdef DEBUG
01907 CmiMemoryCheck();
01908 #endif
01909 int localIdx;
01910 if(isGhost) {
01911 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 1);
01912 } else {
01913 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
01914 }
01915
01916 #ifdef DEBUG
01917 CmiMemoryCheck();
01918 #endif
01919 intMsg *imsg = new intMsg(0);
01920 #ifdef DEBUG
01921 CmiMemoryCheck();
01922 #endif
01923 int ret;
01924 if(localIdx == -1) {
01925 ret = -1;
01926 }
01927 else {
01928 if(readLock) {
01929 ret = fmLockN[localIdx]->rlock();
01930 } else {
01931 #ifdef DEBUG
01932 CmiMemoryCheck();
01933 #endif
01934 ret = fmLockN[localIdx]->wlock(fromChk);
01935 #ifdef DEBUG
01936 CmiMemoryCheck();
01937 #endif
01938 }
01939 }
01940 imsg->i = ret;
01941 #ifdef DEBUG
01942 CmiMemoryCheck();
01943 #endif
01944 return imsg;
01945 }
01946
01947 intMsg *femMeshModify::unlockRemoteNode(int sharedIdx, int fromChk, int isGhost, int readLock) {
01948 #ifdef DEBUG
01949 CmiMemoryCheck();
01950 #endif
01951 int localIdx;
01952 if(isGhost) {
01953 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 1);
01954 } else {
01955 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
01956 }
01957 CkAssert(localIdx != -1);
01958 intMsg *imsg = new intMsg(0);
01959 int ret;
01960 if(readLock) {
01961 ret = fmLockN[localIdx]->runlock();
01962 } else {
01963 ret = fmLockN[localIdx]->wunlock(fromChk);
01964 }
01965 imsg->i = ret;
01966 #ifdef DEBUG
01967 CmiMemoryCheck();
01968 #endif
01969 return imsg;
01970 }
01971
01972 intMsg *femMeshModify::hasLockRemoteNode(int sharedIdx, int fromChk, int isGhost) {
01973 #ifdef DEBUG
01974 CmiMemoryCheck();
01975 #endif
01976 int localIdx;
01977 if(isGhost) {
01978 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 1);
01979 } else {
01980 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
01981 }
01982 CkAssert(localIdx != -1);
01983 intMsg *imsg = new intMsg(0);
01984 int ret = fmLockN[localIdx]->lockOwner();
01985 imsg->i = ret;
01986 #ifdef DEBUG
01987 CmiMemoryCheck();
01988 #endif
01989 return imsg;
01990 }
01991
01992 void femMeshModify::modifyLockAll(int fromChk, int sharedIdx) {
01993 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 1);
01994 FEM_Modify_LockAll(fmMesh, localIdx);
01995 return;
01996 }
01997
01998 intMsg *femMeshModify::addNodeRemote(addNodeMsg *msg) {
01999 #ifdef DEBUG
02000 CmiMemoryCheck();
02001 #endif
02002 intMsg *imsg = new intMsg(-1);
02003
02004 int *localIndices = (int*)malloc(msg->nBetween*sizeof(int));
02005 int *chunks = (int*)malloc(msg->numChunks*sizeof(int));
02006 CkAssert(msg->numChunks==1);
02007 chunks[0] = msg->chunks[0];
02008 for(int i=0; i<msg->nBetween; i++) {
02009 localIndices[i] = fmUtil->lookup_in_IDXL(fmMesh, msg->between[i], chunks[0], 0);
02010 CkAssert(localIndices[i] != -1);
02011 }
02012 int ret = FEM_add_node(fmMesh, localIndices, msg->nBetween, chunks, msg->numChunks, msg->forceShared, msg->upcall);
02013
02014
02015 fmMesh->node.ghostSend.addNode(ret,chunks[0]);
02016 imsg->i = fmUtil->exists_in_IDXL(fmMesh,ret,chunks[0],1);
02017 free(localIndices);
02018 #ifdef DEBUG
02019 CmiMemoryCheck();
02020 #endif
02021 return imsg;
02022 }
02023
02024 void femMeshModify::addSharedNodeRemote(sharedNodeMsg *fm) {
02025 #ifdef DEBUG
02026 CmiMemoryCheck();
02027 #endif
02028 FEM_add_shared_node_remote(fmMesh, fm->chk, fm->nBetween, fm->between);
02029 #ifdef DEBUG
02030 CmiMemoryCheck();
02031 #endif
02032 return;
02033 }
02034
02035 void femMeshModify::removeSharedNodeRemote(removeSharedNodeMsg *fm) {
02036 #ifdef DEBUG
02037 CmiMemoryCheck();
02038 #endif
02039 fmUtil->removeNodeRemote(fmMesh, fm->chk, fm->index);
02040 #ifdef DEBUG
02041 CmiMemoryCheck();
02042 #endif
02043 return;
02044 }
02045
02046 void femMeshModify::addGhostElem(addGhostElemMsg *fm) {
02047 #ifdef DEBUG
02048 CmiMemoryCheck();
02049 #endif
02050 fmUtil->addGhostElementRemote(fmMesh, fm->chk, fm->elemType, fm->numGhostIndex, fm->ghostIndices, fm->numSharedIndex, fm->sharedIndices, fm->connSize);
02051 #ifdef DEBUG
02052 CmiMemoryCheck();
02053 #endif
02054 return;
02055 }
02056
02057 chunkListMsg *femMeshModify::getChunksSharingGhostNode(int2Msg *i2m) {
02058 chunkListMsg *clm;
02059 #ifdef DEBUG
02060 CmiMemoryCheck();
02061 #endif
02062 clm = fmUtil->getChunksSharingGhostNodeRemote(fmMesh, i2m->i, i2m->j);
02063 #ifdef DEBUG
02064 CmiMemoryCheck();
02065 #endif
02066 return clm;
02067 }
02068
02069 void femMeshModify::addElementRemote(addElemMsg *fm) {
02070 #ifdef DEBUG
02071 CmiMemoryCheck();
02072 #endif
02073 fmUtil->addElemRemote(fmMesh, fm->chk, fm->elemtype, fm->connSize, fm->conn, fm->numGhostIndex, fm->ghostIndices);
02074 #ifdef DEBUG
02075 CmiMemoryCheck();
02076 #endif
02077 return;
02078 }
02079
02080 void femMeshModify::removeGhostElem(removeGhostElemMsg *fm) {
02081 #ifdef DEBUG
02082 CmiMemoryCheck();
02083 #endif
02084 fmUtil->removeGhostElementRemote(fmMesh, fm->chk, fm->elementid, fm->elemtype, fm->numGhostIndex, fm->ghostIndices, fm->numGhostRNIndex, fm->ghostRNIndices, fm->numGhostREIndex, fm->ghostREIndices, fm->numSharedIndex, fm->sharedIndices);
02085 #ifdef DEBUG
02086 CmiMemoryCheck();
02087 #endif
02088 return;
02089 }
02090
02091 void femMeshModify::removeElementRemote(removeElemMsg *fm) {
02092 #ifdef DEBUG
02093 CmiMemoryCheck();
02094 #endif
02095 fmUtil->removeElemRemote(fmMesh, fm->chk, fm->elementid, fm->elemtype, fm->permanent);
02096 #ifdef DEBUG
02097 CmiMemoryCheck();
02098 #endif
02099 return;
02100 }
02101
02102 void femMeshModify::removeGhostNode(int fromChk, int sharedIdx) {
02103 #ifdef DEBUG
02104 CmiMemoryCheck();
02105 #endif
02106 fmUtil->removeGhostNodeRemote(fmMesh, fromChk, sharedIdx);
02107 #ifdef DEBUG
02108 CmiMemoryCheck();
02109 #endif
02110 return;
02111 }
02112
02113 intMsg *femMeshModify::eatIntoElement(int fromChk, int sharedIdx) {
02114 intMsg *imsg = new intMsg(-1);
02115 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 4);
02116 if(localIdx==-1) return imsg;
02117 int newEl = fmUtil->eatIntoElement(FEM_To_ghost_index(localIdx));
02118 int returnIdx = fmUtil->exists_in_IDXL(fmMesh, newEl, fromChk, 3);
02119
02120 if(returnIdx==-1) {
02121
02122
02123 const int nodesPerEl = fmMesh->elem[0].getConn().width();
02124 int *adjnodes = new int[nodesPerEl];
02125 int numLocks = nodesPerEl + 1;
02126 int *lockednodes = new int[numLocks];
02127 fmMesh->e2n_getAll(newEl, adjnodes, 0);
02128 int newNode = -1;
02129 bool foundNewNode = false;
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166 int *gotlocks = new int[numLocks];
02167 for(int i=0; i<nodesPerEl; i++) {
02168 lockednodes[i] = adjnodes[i];
02169 gotlocks[i] = 1;
02170 }
02171 if(foundNewNode) {
02172 lockednodes[nodesPerEl] = newNode;
02173 gotlocks[nodesPerEl] = 1;
02174 }
02175 else numLocks--;
02176 fmAdaptL->unlockNodes(gotlocks, lockednodes, 0, lockednodes, numLocks);
02177 delete[] lockednodes;
02178 delete[] gotlocks;
02179 delete[] adjnodes;
02180 }
02181 imsg->i = returnIdx;
02182 return imsg;
02183 }
02184
02185 intMsg *femMeshModify::getLockOwner(int fromChk, int sharedIdx) {
02186 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
02187 int ret = fmUtil->getLockOwner(localIdx);
02188 intMsg *imsg = new intMsg(ret);
02189 return imsg;
02190 }
02191
02192 boolMsg *femMeshModify::knowsAbtNode(int fromChk, int toChk, int sharedIdx) {
02193 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 1);
02194 bool ret = fmUtil->knowsAbtNode(toChk,localIdx);
02195 boolMsg *bmsg = new boolMsg(ret);
02196 return bmsg;
02197 }
02198
02199
02200 void femMeshModify::refine_flip_element_leb(int fromChk, int propElemT,
02201 int propNodeT, int newNodeT,
02202 int nbrOpNodeT, int nbrghost, double longEdgeLen)
02203 {
02204 #ifdef DEBUG
02205 CmiMemoryCheck();
02206 #endif
02207 int propElem, propNode, newNode, nbrOpNode;
02208 propElem = getfmUtil()->lookup_in_IDXL(fmMesh, propElemT, fromChk, 3, 0);
02209 propNode = getfmUtil()->lookup_in_IDXL(fmMesh, propNodeT, fromChk, 0, -1);
02210 newNode = getfmUtil()->lookup_in_IDXL(fmMesh, newNodeT, fromChk, 0, -1);
02211 if(nbrghost) {
02212 nbrOpNode = getfmUtil()->lookup_in_IDXL(fmMesh, nbrOpNodeT, fromChk, 1,-1);
02213 }
02214 else {
02215 nbrOpNode = getfmUtil()->lookup_in_IDXL(fmMesh, nbrOpNodeT, fromChk, 0,-1);
02216 }
02217 fmAdaptAlgs->refine_flip_element_leb(propElem, propNode, newNode, nbrOpNode, longEdgeLen);
02218 #ifdef DEBUG
02219 CmiMemoryCheck();
02220 #endif
02221 return;
02222 }
02223
02224 void femMeshModify::addToSharedList(int fromChk, int sharedIdx) {
02225 #ifdef DEBUG
02226 CmiMemoryCheck();
02227 #endif
02228 fmUtil->addToSharedList(fmMesh, fromChk, sharedIdx);
02229 #ifdef DEBUG
02230 CmiMemoryCheck();
02231 #endif
02232 }
02233
02234 void femMeshModify::updateNodeAttrs(int fromChk, int sharedIdx, double coordX, double coordY, int bound, bool isGhost) {
02235 #ifdef DEBUG
02236 CmiMemoryCheck();
02237 #endif
02238 int localIdx = -1;
02239 if(!isGhost) {
02240 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
02241 }
02242 else localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 2);
02243 double *coord = new double[2];
02244 coord[0] = coordX; coord[1] = coordY;
02245 CkVec<FEM_Attribute *>*attrs = (fmMesh->node).getAttrVec();
02246 for (int i=0; i<attrs->size(); i++) {
02247 FEM_Attribute *a = (FEM_Attribute *)(*attrs)[i];
02248 if (a->getAttr() == fmAdaptAlgs->coord_attr) {
02249 FEM_DataAttribute *d = (FEM_DataAttribute *)a;
02250 d->getDouble().setRow(localIdx,coord,0);
02251 }
02252 else if(a->getAttr() == FEM_BOUNDARY) {
02253 FEM_DataAttribute *d = (FEM_DataAttribute *)a;
02254 d->getInt().setRow(localIdx,bound);
02255 }
02256 }
02257 delete [] coord;
02258 #ifdef DEBUG
02259 CmiMemoryCheck();
02260 #endif
02261 return;
02262 }
02263
02264 double2Msg *femMeshModify::getRemoteCoord(int fromChk, int ghostIdx) {
02265 #ifdef DEBUG
02266 CmiMemoryCheck();
02267 #endif
02268 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, ghostIdx, fromChk, 1);
02269 double coord[2];
02270 FEM_Mesh_dataP(fmMesh, FEM_NODE, fmAdaptAlgs->coord_attr, coord, localIdx, 1, FEM_DOUBLE, 2);
02271 double2Msg *d = new double2Msg(coord[0], coord[1]);
02272 #ifdef DEBUG
02273 CmiMemoryCheck();
02274 #endif
02275 return d;
02276 }
02277
02278 intMsg *femMeshModify::getRemoteBound(int fromChk, int ghostIdx) {
02279 #ifdef DEBUG
02280 CmiMemoryCheck();
02281 #endif
02282 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, ghostIdx, fromChk, 1);
02283 int bound;
02284 FEM_Mesh_dataP(fmMesh, FEM_NODE, FEM_BOUNDARY, &bound, localIdx, 1, FEM_INT, 1);
02285 intMsg *d = new intMsg(bound);
02286 #ifdef DEBUG
02287 CmiMemoryCheck();
02288 #endif
02289 return d;
02290 }
02291
02292 intMsg *femMeshModify::getIdxGhostSend(int fromChk, int idxshared, int toChk) {
02293 #ifdef DEBUG
02294 CmiMemoryCheck();
02295 #endif
02296 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, idxshared, fromChk, 0);
02297 int idxghostsend = -1;
02298 if(localIdx != -1) {
02299 const IDXL_Rec *irec = fmMesh->node.ghostSend.getRec(localIdx);
02300 if(irec) {
02301 for(int i=0; i<irec->getShared(); i++) {
02302 if(irec->getChk(i) == toChk) {
02303 idxghostsend = fmUtil->exists_in_IDXL(fmMesh, localIdx, toChk, 1);
02304 break;
02305 }
02306 }
02307 }
02308 }
02309 intMsg *d = new intMsg(idxghostsend);
02310 #ifdef DEBUG
02311 CmiMemoryCheck();
02312 #endif
02313 return d;
02314 }
02315
02316 void femMeshModify::updateIdxlList(int fromChk, int idxTrans, int transChk) {
02317 #ifdef DEBUG
02318 CmiMemoryCheck();
02319 #endif
02320 int idxghostrecv = fmUtil->lookup_in_IDXL(fmMesh, idxTrans, transChk, 2);
02321 CkAssert(idxghostrecv != -1);
02322 fmMesh->node.ghost->ghostRecv.addNode(idxghostrecv,fromChk);
02323 #ifdef DEBUG
02324 CmiMemoryCheck();
02325 #endif
02326 return;
02327 }
02328
02329 void femMeshModify::addTransIDXLRemote(int fromChk, int sharedIdx, int transChk) {
02330 #ifdef DEBUG
02331 CmiMemoryCheck();
02332 #endif
02333 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, transChk, 0);
02334 CkAssert(localIdx != -1);
02335 fmMesh->node.ghostSend.addNode(localIdx,fromChk);
02336 #ifdef DEBUG
02337 CmiMemoryCheck();
02338 #endif
02339 return;
02340 }
02341
02342 void femMeshModify::removeIDXLRemote(int fromChk, int sharedIdx, int type) {
02343 #ifdef DEBUG
02344 CmiMemoryCheck();
02345 #endif
02346 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, type);
02347 CkAssert(localIdx != -1);
02348 fmMesh->node.ghostSend.removeNode(localIdx,fromChk);
02349 #ifdef DEBUG
02350 CmiMemoryCheck();
02351 #endif
02352 return;
02353 }
02354
02355 void femMeshModify::verifyIdxlList(int fromChk, int size, int type) {
02356 #ifdef DEBUG
02357 CmiMemoryCheck();
02358 #endif
02359 fmUtil->verifyIdxlListRemote(fmMesh, fromChk, size, type);
02360 #ifdef DEBUG
02361 CmiMemoryCheck();
02362 #endif
02363 return;
02364 }
02365
02366 void femMeshModify::idxllockRemote(int fromChk, int type) {
02367 if(type==1) type = 2;
02368 else if(type ==2) type = 1;
02369 else if(type ==3) type = 4;
02370 else if(type ==4) type = 3;
02371 #ifdef DEBUG
02372 CmiMemoryCheck();
02373 #endif
02374 fmUtil->idxllockLocal(fmMesh, fromChk, type);
02375 #ifdef DEBUG
02376 CmiMemoryCheck();
02377 #endif
02378 return;
02379 }
02380
02381 void femMeshModify::idxlunlockRemote(int fromChk, int type) {
02382 if(type==1) type = 2;
02383 else if(type ==2) type = 1;
02384 else if(type ==3) type = 4;
02385 else if(type ==4) type = 3;
02386 #ifdef DEBUG
02387 CmiMemoryCheck();
02388 #endif
02389 fmUtil->idxlunlockLocal(fmMesh, fromChk, type);
02390 #ifdef DEBUG
02391 CmiMemoryCheck();
02392 #endif
02393 return;
02394 }
02395
02396 boolMsg *femMeshModify::verifyLock(int fromChk, int sharedIdx, int isGhost) {
02397 int localIdx;
02398 if(isGhost) {
02399 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 1);
02400 } else {
02401 localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
02402 }
02403
02404 boolMsg *bmsg = new boolMsg(0);
02405 bool ret;
02406 if(localIdx == -1) {
02407 ret = false;
02408 }
02409 else {
02410 ret = fmLockN[localIdx]->verifyLock();
02411 }
02412 bmsg->b = ret;
02413 return bmsg;
02414 }
02415
02416 void femMeshModify::verifyghostsend(verifyghostsendMsg *vmsg) {
02417 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, vmsg->sharedIdx, vmsg->fromChk, 1);
02418 const IDXL_Rec *irec = fmMesh->node.shared.getRec(localIdx);
02419 if (irec!=NULL) {
02420 int numsh = irec->getShared();
02421 CkAssert(numsh==vmsg->numchks-1);
02422 for(int i=0; i<numsh; i++) {
02423 int ckl = irec->getChk(i);
02424 bool found = false;
02425 for(int j=0; j<numsh+1; j++) {
02426 if(vmsg->chunks[j]==ckl) {
02427 found = true; break;
02428 }
02429 }
02430 CkAssert(found);
02431 }
02432 }
02433 }
02434
02435 findgsMsg *femMeshModify::findghostsend(int fromChk, int sharedIdx) {
02436 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
02437 int *chkl, numchkl=0;
02438 fmUtil->findGhostSend(localIdx, &chkl, &numchkl);
02439 findgsMsg *fmsg = new(numchkl)findgsMsg();
02440 fmsg->numchks = numchkl;
02441 for(int i=0; i<numchkl; i++) fmsg->chunks[i] = chkl[i];
02442 if(numchkl>0) delete[] chkl;
02443 return fmsg;
02444 }
02445
02446 void femMeshModify::updateghostsend(verifyghostsendMsg *vmsg) {
02447 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, vmsg->sharedIdx, vmsg->fromChk, 0);
02448 fmUtil->UpdateGhostSend(localIdx, vmsg->chunks, vmsg->numchks);
02449 delete vmsg;
02450 }
02451
02452 boolMsg *femMeshModify::shouldLoseGhost(int fromChk, int sharedIdx, int toChk) {
02453 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
02454 int *elems, numElems;
02455 fmMesh->n2e_getAll(localIdx, &elems, &numElems);
02456 bool shouldBeDeleted = true;
02457 for(int k=0; k<numElems; k++) {
02458 if(elems[k]>=0) {
02459 if(fmMesh->getfmMM()->fmUtil->exists_in_IDXL(fmMesh,elems[k],toChk,3)!=-1) {
02460 shouldBeDeleted = false;
02461 break;
02462 }
02463 }
02464 }
02465 if(numElems>0) delete[] elems;
02466 boolMsg *bmsg = new boolMsg(shouldBeDeleted);
02467 return bmsg;
02468 }
02469
02470 void femMeshModify::addghostsendl(int fromChk, int sharedIdx, int toChk, int transIdx) {
02471 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 0);
02472 int sharedghost = fmUtil->exists_in_IDXL(fmMesh,localIdx,toChk,1);
02473 if(sharedghost==-1) {
02474
02475 fmMesh->node.ghostSend.addNode(localIdx,toChk);
02476 meshMod[toChk].addghostsendl1(idx,fromChk,transIdx);
02477
02478 }
02479 }
02480
02481 void femMeshModify::addghostsendl1(int fromChk, int transChk, int transIdx) {
02482 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, transIdx, transChk, 2);
02483 fmMesh->node.ghost->ghostRecv.addNode(localIdx,fromChk);
02484 }
02485
02486 void femMeshModify::addghostsendr(int fromChk, int sharedIdx, int toChk, int transIdx) {
02487 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 2);
02488 int sharedghost = fmUtil->exists_in_IDXL(fmMesh,FEM_To_ghost_index(localIdx),toChk,2);
02489 if(sharedghost==-1) {
02490
02491 fmMesh->node.ghost->ghostRecv.addNode(localIdx,toChk);
02492 meshMod[toChk].addghostsendr1(idx,fromChk,transIdx);
02493
02494 }
02495 }
02496
02497 void femMeshModify::addghostsendr1(int fromChk, int transChk, int transIdx) {
02498 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, transIdx, transChk, 0);
02499 fmMesh->node.ghostSend.addNode(localIdx,fromChk);
02500 }
02501
02502 boolMsg *femMeshModify::willItLose(int fromChk, int sharedIdx) {
02503 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 3);
02504 int nnbrs[3];
02505 fmMesh->e2n_getAll(localIdx,nnbrs,0);
02506
02507 bool willlose = true;
02508 for(int i=0; i<3; i++) {
02509 int *enbrs, numenbrs;
02510 fmMesh->n2e_getAll(nnbrs[i],&enbrs,&numenbrs);
02511 willlose = true;
02512 for(int j=0; j<numenbrs; j++) {
02513 if(enbrs[j]>=0 && enbrs[j]!=localIdx) {
02514 willlose = false;
02515 break;
02516 }
02517 }
02518 if(numenbrs>0) delete [] enbrs;
02519 if(willlose) break;
02520 }
02521 boolMsg *bmsg = new boolMsg(willlose);
02522 return bmsg;
02523 }
02524
02525 void femMeshModify::interpolateElemCopy(int fromChk, int sharedIdx1, int sharedIdx2) {
02526 int localIdx1 = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx1, fromChk, 3);
02527 int localIdx2 = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx2, fromChk, 3);
02528 CkAssert(localIdx1!=-1 && localIdx2!=-1);
02529 fmUtil->copyElemData(0,localIdx1,localIdx2);
02530 }
02531
02532 void femMeshModify::cleanupIDXL(int fromChk, int sharedIdx) {
02533 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 4);
02534 CkAssert(fmUtil->exists_in_IDXL(fmMesh,FEM_To_ghost_index(localIdx),fromChk,4)!=-1);
02535 fmMesh->elem[0].ghost->ghostRecv.removeNode(localIdx, fromChk);
02536 fmMesh->elem[0].getGhost()->set_invalid(localIdx,false);
02537 }
02538
02539 void femMeshModify::purgeElement(int fromChk, int sharedIdx) {
02540 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 3);
02541 CkAssert(localIdx!=-1);
02542 FEM_purge_element(fmMesh,localIdx,0);
02543 }
02544
02545
02546 elemDataMsg *femMeshModify::packElemData(int fromChk, int sharedIdx) {
02547 int localIdx = fmUtil->lookup_in_IDXL(fmMesh, sharedIdx, fromChk, 3);
02548 CkAssert(localIdx!=-1);
02549 CkVec<FEM_Attribute *>*elemattrs = (fmMesh->elem[0]).getAttrVec();
02550 int count = 0;
02551 PUP::sizer psizer;
02552 for(int j=0;j<elemattrs->size();j++){
02553 FEM_Attribute *elattr = (FEM_Attribute *)(*elemattrs)[j];
02554 if(elattr->getAttr() < FEM_ATTRIB_FIRST){
02555 elattr->pupSingle(psizer, localIdx);
02556 count++;
02557 }
02558 }
02559 elemDataMsg *edm = new (psizer.size()) elemDataMsg(count);
02560
02561 PUP::toMem pmem(edm->data);
02562 for(int j=0;j<elemattrs->size();j++){
02563 FEM_Attribute *elattr = (FEM_Attribute *)(*elemattrs)[j];
02564 if(elattr->getAttr() < FEM_ATTRIB_FIRST){
02565 elattr->pupSingle(pmem, localIdx);
02566 }
02567 }
02568 return edm;
02569 }
02570
02571 #include "FEMMeshModify.def.h"