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