Added edge adjacency to bulk adaptivity. Edge adjacency info is now stored in
authorAaron Becker <abecker3@illinois.edu>
Thu, 26 Jul 2007 21:04:37 +0000 (21:04 +0000)
committerAaron Becker <abecker3@illinois.edu>
Thu, 26 Jul 2007 21:04:37 +0000 (21:04 +0000)
a separate attribute

src/libs/ck-libs/ParFUM/ParFUM.h
src/libs/ck-libs/ParFUM/ParFUMf.h
src/libs/ck-libs/ParFUM/adapt_adj.C
src/libs/ck-libs/ParFUM/adapt_adj.h
src/libs/ck-libs/ParFUM/bulk_adapt_ops.C
src/libs/ck-libs/ParFUM/mesh.C

index b15508fe0e6bc0fc0b6e405bdc1e388b1d76f1ac..d9d3d7d01f0a2fdb2660f4490e19c36b270728af 100644 (file)
@@ -149,10 +149,11 @@ extern "C" {
 
 #define FEM_MESH_SIZING (FEM_ATTRIB_FIRST+15) ///< Target edge length attr.
 
-#define FEM_ADAPT_ADJ (FEM_ATTRIB_FIRST+16) ///< Element to element adjacency used for adaptivity (does not have ghosts)
-#define FEM_ADAPT_LOCK (FEM_ATTRIB_FIRST+17) /// Lock for the bulk adaptivity.. Used for nodes
+#define FEM_ADAPT_FACE_ADJ (FEM_ATTRIB_FIRST+16) ///< Element to element adjacency used for adaptivity (does not have ghosts)
+#define FEM_ADAPT_EDGE_ADJ (FEM_ATTRIB_FIRST+17) ///< Element to element adjacency used for adaptivity (does not have ghosts)
+#define FEM_ADAPT_LOCK (FEM_ATTRIB_FIRST+18) /// Lock for the bulk adaptivity.. Used for nodes
 
-#define FEM_ATTRIB_LAST (FEM_ATTRIB_FIRST+18) ///< This is the last valid attribute code
+#define FEM_ATTRIB_LAST (FEM_ATTRIB_FIRST+19) ///< This is the last valid attribute code
 
   // Specialized routines: 
   void FEM_Mesh_set_conn(int fem_mesh,int entity,
index 60402aa28a7fcede1352877bf813625006b6a4fd..0c6b71dbb228a1fd3e2d6bf8d67c260ac6e2056b 100644 (file)
@@ -50,7 +50,8 @@
           integer, parameter :: FEM_ELEM_ELEM_ADJ_TYPES=(FEM_ATTRIB_FIRST+13)
 !         integer, parameter :: FEM_IS_VALID_ATTR=(FEM_ATTRIB_FIRST+14)                 
        integer, parameter :: FEM_MESH_SIZING=(FEM_ATTRIB_FIRST+15)
-       integer, parameter :: FEM_ADAPT_ADJ=(FEM_ATTRIB_FIRST+16)
+       integer, parameter :: FEM_ADAPT_FACE_ADJ=(FEM_ATTRIB_FIRST+16)
+       integer, parameter :: FEM_ADAPT_EDGE_ADJ=(FEM_ATTRIB_FIRST+17)
 
        integer, parameter :: FEM_INDEX_0=IDXL_INDEX_0
        integer, parameter :: FEM_INDEX_1=IDXL_INDEX_1
index 316ac5c11ddf7c2818d787255ff26cdd2753772a..d897f9f49ff48c4d4f5fb9b1e8a966e8732199c5 100644 (file)
@@ -8,50 +8,80 @@
 #include "ParFUM_internals.h"
 using namespace std;
 
-int nodeSetMap2d_tri[3][2] = {{0,1},{1,2},{2,0}};
-int nodeSetMap2d_quad[4][2] = {{0,1},{1,2},{2,3},{3,0}};
-int nodeSetMap3d_tet[4][3] = {{0,1,2},{0,3,1},{0,2,3},{1,3,2}};
-int nodeSetMap3d_hex[6][4] = {{0,1,2,3},{1,5,6,2},{2,6,7,3},{3,7,4,0},{0,4,5,1},{5,4,6,7}};
-
-int edgeMap3d_tet[6][2] = {{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
-int edgeMap3d_hex[12][2] = {{0,1},{0,3},{0,4},{1,2},{1,5},{2,3},{2,6},{3,7},{4,5},{4,7},{5,6},{6,7}};
-
-int nodeSetMap2d_cohquad[2][2] = {{0,1},{2,3}}; // Cohesive for 2D triangles
-int nodeSetMap3d_cohprism[2][3] = {{0,1,2},{3,4,5}}; // Cohesive for 3D tets
-
-inline void addSharedNodeData(int node,const IDXL_Rec *sharedChunkList,
-            adjNode *adaptAdjTable){
-  adaptAdjTable[node].numSharedPartitions = sharedChunkList->getShared();
-  adaptAdjTable[node].sharedWithPartition = 
-    new int [sharedChunkList->getShared()];
-  adaptAdjTable[node].sharedWithLocalIdx = 
-    new int [sharedChunkList->getShared()];
-  for(int j=0;j<sharedChunkList->getShared();j++){
-    int sharedChunk = sharedChunkList->getChk(j);
-    int sharedIdx = sharedChunkList->getIdx(j);
-    adaptAdjTable[node].sharedWithPartition[j] = sharedChunk;
-    adaptAdjTable[node].sharedWithLocalIdx[j] = sharedIdx;
-  }
+const int faceMap2d_tri[3][2] = {{0,1},{1,2},{2,0}};
+const int faceMap2d_quad[4][2] = {{0,1},{1,2},{2,3},{3,0}};
+const int faceMap3d_tet[4][3] = {{0,1,2},{0,3,1},{0,2,3},{1,3,2}};
+const int faceMap3d_hex[6][4] = {{0,1,2,3},{1,5,6,2},{2,6,7,3},{3,7,4,0},{0,4,5,1},{5,4,6,7}};
+
+const int edgeMap3d_tet[6][2] = {{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
+const int edgeMap3d_hex[12][2] = {{0,1},{0,3},{0,4},{1,2},{1,5},{2,3},{2,6},{3,7},{4,5},{4,7},{5,6},{6,7}};
+
+const int faceMap2d_cohquad[2][2] = {{0,1},{2,3}}; // Cohesive for 2D triangles
+const int faceMap3d_cohprism[2][3] = {{0,1,2},{3,4,5}}; // Cohesive for 3D tets
+
+
+inline void addSharedNodeData(int node, const IDXL_Rec *sharedChunkList,
+            adjNode *adaptAdjTable)
+{
+    adaptAdjTable[node].numSharedPartitions = sharedChunkList->getShared();
+    adaptAdjTable[node].sharedWithPartition = 
+        new int [sharedChunkList->getShared()];
+    adaptAdjTable[node].sharedWithLocalIdx = 
+        new int [sharedChunkList->getShared()];
+    for(int j=0; j<sharedChunkList->getShared(); j++){
+        int sharedChunk = sharedChunkList->getChk(j);
+        int sharedIdx = sharedChunkList->getIdx(j);
+        adaptAdjTable[node].sharedWithPartition[j] = sharedChunk;
+        adaptAdjTable[node].sharedWithLocalIdx[j] = sharedIdx;
+    }
 }
 
-inline void addElementNodeSetData(int elem,const int *conn,int numAdjElems,
-          const int nodesPerElem,int nodeSetSize,
-              int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE],
-          adjNode *adaptAdjTable){
-  for (int j=0; j<numAdjElems; j++) { // one nodeSet per neighbor element
-    adjElem *e = new adjElem(nodeSetSize);
-    e->nodeSetID = j;
-    for (int k=0; k<nodeSetSize; k++) { // Build nodeSet for an element pairing
-      e->nodeSet[k] = conn[elem*nodesPerElem+nodeSetMap[j][k]];
+
+inline void addElementNodeSetData(
+        const int elem, 
+        const int *conn, 
+        const int nodesPerElem,
+        const int numFaces, 
+        const int numEdges, 
+        const int faceSize,
+        const int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE],
+        const int edgeMap[MAX_EDGES][2],
+        adjNode *faceTable, 
+        adjNode* edgeTable)
+{
+    // first add face adjacencies
+    for (int j=0; j<numFaces; j++) { 
+        adjElem *e = new adjElem(faceSize);
+        e->nodeSetID = j;
+        for (int k=0; k<faceSize; k++) { 
+            e->nodeSet[k] = conn[elem * nodesPerElem + faceMap[j][k]];
+        }
+        // Add this element-nodeSet pair to table at min nodeID in the nodeSet
+        e->nodeSet.quickSort();
+        int minNode = e->nodeSet[0];
+        e->elemID = elem;
+        e->next = faceTable[minNode].adjElemList->next;
+        faceTable[minNode].adjElemList->next = e;
+        faceTable[minNode].adjElemCount++;
+    }
+
+    // then add edge adjacencies
+    if (edgeTable) {
+        for (int j=0; j<numEdges; j++) { 
+            adjElem *e = new adjElem(2);
+            for (int k=0; k<2; k++) { 
+                e->nodeSet[k] = conn[elem * nodesPerElem + edgeMap[j][k]];
+            }
+            // Add this element-nodeSet pair to table at min nodeID in the 
+            // nodeSet
+            e->nodeSet.quickSort();
+            int minNode = e->nodeSet[0];
+            e->elemID = elem;
+            e->next = edgeTable[minNode].adjElemList->next;
+            edgeTable[minNode].adjElemList->next = e;
+            edgeTable[minNode].adjElemCount++;
+        }
     }
-    // Add this element-nodeSet pair to table at min nodeID in the nodeSet
-    e->nodeSet.quickSort();
-    int minNode = e->nodeSet[0];
-    e->elemID = elem;
-    e->next = adaptAdjTable[minNode].adjElemList->next;
-    adaptAdjTable[minNode].adjElemList->next = e;
-    adaptAdjTable[minNode].adjElemCount++;
-  }
 }
 
 
@@ -61,561 +91,1045 @@ inline void addElementNodeSetData(int elem,const int *conn,int numAdjElems,
 //searchForNodeSet. It also checks that the elemID of the element
 //being searched does not match with that of searchForElemID.  *found
 //is set to 1 if match is found .. else to 0
-inline adjElem *searchAdjElemInList(adjElem *adjStart,int *searchForNodeSet,
-            int nodeSetSize,int searchForElemID,
-            int *found){
-  adjElem *rover = adjStart; // compare rover->next with adjStart
-  *found = 0;
-  
-  while (rover->next != NULL) {
-    if (rover->next->elemID != searchForElemID) {
-      *found = 1; // found an element that is not myself, possibly a match
-      for (int j=0; j<nodeSetSize; j++) {
-        if (rover->next->nodeSet[j] != searchForNodeSet[j]) {
-          *found = 0; // No, the nodeSets dont match
-          break;
+inline adjElem *searchAdjElemInList(adjElem *adjStart, int *searchForNodeSet,
+            int nodeSetSize, int searchForElemID, int *found)
+{
+    adjElem *rover = adjStart; // compare rover->next with adjStart
+    *found = 0;
+
+    while (rover->next != NULL) {
+        if (rover->next->elemID != searchForElemID) {
+            *found = 1; // found an element that is not myself, 
+                        // possibly a match
+
+            if (nodeSetSize != rover->next->nodeSet.size()) {
+                *found = 0; // not a match
+                continue; 
+            }
+            for (int j=0; j<nodeSetSize; j++) {
+                if (rover->next->nodeSet[j] != searchForNodeSet[j]) {
+                    *found = 0; // not a match
+                    break;
+                }
+            }
+        }
+        if (*found) {
+            break; // We have found a nodeSet that matches adjStart
+        } else {
+            rover = rover->next; // Keep looking for matching nodeSet
         }
-      }
-    }
-    if (*found) {
-      break; // We have found a nodeSet that matches adjStart
-    }else {
-      rover = rover->next; // Keep looking in adjElemList for matching nodeSet
     }
-  }
-  return rover;
+    return rover;
 }
 
+
 /** Create Adaptivity Adjacencies for elemType; dimension inferred. */
 void CreateAdaptAdjacencies(int meshid, int elemType)
 {
-  // Need to derive all of these from elemType;
-  int myRank,numChunks;
-  int numAdjElems;
-  int nodeSetSize; // number of nodes shared by two adjacent elems
-
-  MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
-  MPI_Comm_size(MPI_COMM_WORLD,&numChunks);
-  FEM_Mesh *mesh = FEM_chunk::get("CreateAdaptAdjacencies")->lookup(meshid,"CreateAdaptAdjacencies");
-  FEM_Elem *elem = (FEM_Elem *)mesh->lookup(FEM_ELEM+elemType,"CreateAdaptAdjacencies");
-  FEM_Node *node = (FEM_Node *)mesh->lookup(FEM_NODE,"CreateAdaptAdjacencies");
-  const int numElems = elem->size();
-  const int numNodes = node->size();
-  const int nodesPerElem = (elem->getConn()).width();
-  assert(node->getCoord()!= NULL);
-  const int dim = (node->getCoord())->getWidth();
-  assert(dim == 2|| dim == 3);
-
-  // A nodeSet is a set of nodes that defines a pairing of two
-  // adjacent elements; For example, in 2D triangle meshes, the
-  // nodeSet is the nodes of an edge between two elements.  The
-  // nodeSetMap is an ordering of element-local node IDs that
-  // specifies all possible nodeSets for a particular element type
-  int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
-  guessElementShape(dim,nodesPerElem,&numAdjElems,&nodeSetSize,nodeSetMap);
-  CkAssert(nodeSetSize <= MAX_NODESET_SIZE);
-  
-  // Add the FEM_ADAPT_ADJ attribute to the elements
-  // Set the correct width of the table and then get the pointer to the actual data
-  FEM_DataAttribute *adaptAdjAttr = (FEM_DataAttribute *) elem->lookup(FEM_ADAPT_ADJ,"CreateAdaptAdjacencies");        
-  adaptAdjAttr->setWidth(sizeof(adaptAdj)*numAdjElems);
-  adaptAdj *adaptAdjacencies = (adaptAdj *)(adaptAdjAttr->getChar()).getData();
-
-  // Init adaptAdj array to at least have -1 as partID signifying no neighbor
-  for (int i=0; i<numElems*numAdjElems; i++) {
-    adaptAdjacencies[i].partID = -1;
-    adaptAdjacencies[i].localID = -1;
-  }
-
-  // Create an array of size equal to the number of local nodes, each
-  // entry has a pair: (shared partitions, list of elem-nodeSet pairs)
-  // Call this adaptAdjTable
-  adjNode *adaptAdjTable;
-  adaptAdjTable = new adjNode[numNodes];
-
-  // Loop through shared node list and add the partition ids to adaptAdjTable.
-  for(int i=0;i<numNodes;i++){
-    if(node->is_valid(i)){
-      const IDXL_Rec *sharedChunkList = node->shared.getRec(i);
-      if(sharedChunkList != NULL){
-        addSharedNodeData(i,sharedChunkList,adaptAdjTable);
-      }
+    // Need to derive all of these from elemType;
+    int myRank,numChunks;
+    int faceSize;    // number of nodes shared by two adjacent elems
+    int faceMapSize; // number of faces per element
+    int edgeMapSize; // number of edges per element
+
+    MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
+    MPI_Comm_size(MPI_COMM_WORLD,&numChunks);
+    FEM_Mesh* mesh = FEM_chunk::get("CreateAdaptAdjacencies")->lookup(
+            meshid,"CreateAdaptAdjacencies");
+    FEM_Elem* elem = (FEM_Elem *)mesh->lookup(
+            FEM_ELEM+elemType,"CreateAdaptAdjacencies");
+    FEM_Node* node = (FEM_Node *)mesh->lookup(
+            FEM_NODE,"CreateAdaptAdjacencies");
+
+    const int numElems = elem->size();
+    const int numNodes = node->size();
+    const int nodesPerElem = (elem->getConn()).width();
+    CkAssert(node->getCoord() != NULL);
+    const int dim = (node->getCoord())->getWidth();
+    CkAssert(dim == 2|| dim == 3);
+
+    // A nodeSet is a set of nodes that defines a pairing of two
+    // adjacent elements; For example, in 2D triangle meshes, the
+    // nodeSet is the nodes of an edge between two elements.
+    // These adjacency relationships are defined by face and edge maps that
+    // define which set of nodes constitute faces and edges for each element
+    // type.
+    int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE];
+    int edgeMap[MAX_EDGES][2];
+
+    guessElementShape(dim, nodesPerElem, 
+            &faceSize, &faceMapSize, &edgeMapSize, 
+            faceMap, edgeMap);
+    CkAssert(faceMapSize <= MAX_ADJELEMS);
+    CkAssert(edgeMapSize <= MAX_EDGES);
+    CkAssert(faceSize <= MAX_FACE_SIZE);
+
+    // Add the FEM_ADAPT_FACE_ADJ and FEM_ADAPT_EDGE_ADJ attributes
+    FEM_DataAttribute* adaptAdjAttr = (FEM_DataAttribute*) elem->lookup(
+            FEM_ADAPT_FACE_ADJ, "CreateAdaptAdjacencies");     
+    adaptAdjAttr->setWidth(faceMapSize*sizeof(adaptAdj));
+    adaptAdj* adaptFaceAdjacencies = 
+        reinterpret_cast<adaptAdj*>((adaptAdjAttr->getChar()).getData());
+
+    FEM_DataAttribute* adaptAdjEdgeAttr = (FEM_DataAttribute*) elem->lookup(
+            FEM_ADAPT_EDGE_ADJ, "CreateAdaptAdjacencies");     
+    adaptAdjEdgeAttr->setWidth(edgeMapSize*sizeof(CkVec<adaptAdj>*));
+    CkVec<adaptAdj>** adaptEdgeAdjacencies = edgeMapSize == 0 ?
+        NULL :
+        reinterpret_cast<CkVec<adaptAdj>**>(
+                (adaptAdjEdgeAttr->getInt()).getData());
+
+    // Initialize adaptAdj arrays
+    for (int i=0; i<numElems; i++) {
+        for (int j=0; j<faceMapSize; ++j) {
+            adaptFaceAdjacencies[i*faceMapSize + j].partID = -1;
+            adaptFaceAdjacencies[i*faceMapSize + j].localID = -1;
+        }
+        if (adaptEdgeAdjacencies)
+            adaptEdgeAdjacencies[i] = new CkVec<adaptAdj>;
     }
-  }
 
-  // Pull out conn for elems of elemType
-  const int *conn = (elem->getConn()).getData();
-  
-  for (int i=0; i<numElems; i++) { // Add each element-nodeSet pair to table
-    if(elem->is_valid(i)){
-      addElementNodeSetData(i,conn,numAdjElems,nodesPerElem,nodeSetSize,
-          nodeSetMap,adaptAdjTable);
+    // Create an array of size equal to the number of local nodes, each
+    // entry has a pair: (shared partitions, list of elem-nodeSet pairs)
+    // make one array for face adjacencies and one for edge adjacencies
+
+    adjNode *faceTable;
+    adjNode *edgeTable;
+    faceTable = new adjNode[numNodes];
+    edgeTable = adaptEdgeAdjacencies ? new adjNode[numNodes] : NULL;
+
+    // Loop through the shared node list and add shared partition ids
+    for (int i=0; i<numNodes; i++) {
+        if (node->is_valid(i)) {
+            const IDXL_Rec *sharedChunkList = node->shared.getRec(i);
+            if (sharedChunkList != NULL) {
+                addSharedNodeData(i, sharedChunkList, faceTable);
+                if (edgeTable)
+                    addSharedNodeData(i, sharedChunkList, edgeTable);
+            } else {
+                faceTable[i].sharedWithPartition = NULL;
+                faceTable[i].sharedWithLocalIdx= NULL;
+                if (edgeTable) {
+                    edgeTable[i].sharedWithPartition = NULL;
+                    edgeTable[i].sharedWithLocalIdx= NULL;
+                }
+            }
+        } else {
+            faceTable[i].sharedWithPartition = NULL;
+            faceTable[i].sharedWithLocalIdx= NULL;
+            if (edgeTable) {
+                edgeTable[i].sharedWithPartition = NULL;
+                edgeTable[i].sharedWithLocalIdx= NULL;
+            }
+        }
     }
-  }
-
-  fillLocalAdaptAdjacencies(numNodes,node,adaptAdjTable,adaptAdjacencies,nodeSetSize,numAdjElems,myRank,elemType);
 
+    // add local node adjacency info via connectivity
+    const int *conn = (elem->getConn()).getData();
+    for (int i=0; i<numElems; i++) {
+        if(elem->is_valid(i)){
+            addElementNodeSetData(i, conn, nodesPerElem, faceMapSize, 
+                    edgeMapSize, faceSize, faceMap, edgeMap, faceTable, 
+                    edgeTable);
+        }
+    }
 
-  // Now all elements' local adjacencies are set; remainder in table are 
-  // nodeSets shared with other chunks or nodeSets on domain boundary
+    fillLocalAdaptAdjacencies(
+            numNodes,
+            node,
+            faceTable,
+            edgeTable,
+            faceMapSize,
+            edgeMapSize,
+            adaptFaceAdjacencies,
+            adaptEdgeAdjacencies,
+            myRank,
+            elemType);
+
+    // Now all elements' local adjacencies are set; remainder in table are 
+    // nodeSets shared with other chunks or nodeSets on domain boundary
+    // We handle face nodeSets first, then do the edges.
+
+    MPI_Barrier(MPI_COMM_WORLD);
+    MSA1DREQLIST *requestTable;
+    if (myRank == 0) {
+        requestTable = new MSA1DREQLIST(numChunks,numChunks);
+    } else {
+        requestTable = new MSA1DREQLIST;
+    }
+    MPI_Bcast_pup(*requestTable,0,MPI_COMM_WORLD);
+    requestTable->enroll(numChunks);
+    requestTable->sync();
+
+    makeAdjacencyRequests(
+            numNodes,
+            node,
+            faceTable,
+            requestTable,
+            faceSize,
+            myRank,
+            elemType);
+
+    requestTable->sync();
+    printf("[%d] All face requests made \n",myRank);
+
+    MSA1DREPLYLIST *replyTable;
+    if (myRank == 0) {
+        replyTable = new MSA1DREPLYLIST(numChunks,numChunks);
+    } else {
+        replyTable = new MSA1DREPLYLIST;
+    }
+    MPI_Bcast_pup(*replyTable,0,MPI_COMM_WORLD);
+    replyTable->enroll(numChunks);
+    replyTable->sync();
+
+    replyAdjacencyRequests(
+            requestTable,
+            replyTable,
+            node,
+            faceTable,
+            adaptFaceAdjacencies,
+            adaptEdgeAdjacencies,
+            faceSize,
+            faceMapSize,
+            myRank,
+            elemType,
+            false);
+
+    requestTable->sync();
+    replyTable->sync();
+
+    // Once the replies are back, loop through each reply and update the
+    // adjacencies for each element in the reply
+    CkVec<adjReply> *receivedReplyVec = replyTable->get(myRank).vec;
+    for(int i=0;i< receivedReplyVec->size();i++){
+        adjReply *receivedReply = &(*receivedReplyVec)[i];
+        printf("[%d] Replies received for (%d,%d) (%d,%d,%d)\n",
+                myRank,receivedReply->requestingElemID,
+                receivedReply->requestingNodeSetID,
+                receivedReply->replyingElem.partID,
+                receivedReply->replyingElem.localID,
+                receivedReply->replyingElem.elemType);
+        adaptFaceAdjacencies[receivedReply->requestingElemID*faceMapSize + 
+            receivedReply->requestingNodeSetID] = receivedReply->replyingElem;
+    }
+    replyTable->sync();
 
-  MPI_Barrier(MPI_COMM_WORLD);
-  MSA1DREQLIST *requestTable;
-  if(myRank == 0){
-    requestTable = new MSA1DREQLIST(numChunks,numChunks);
-  }else{
-    requestTable = new MSA1DREQLIST;
-  }
-  MPI_Bcast_pup(*requestTable,0,MPI_COMM_WORLD);
-  requestTable->enroll(numChunks);
-  requestTable->sync();
+    if (adaptEdgeAdjacencies != NULL) {
+        delete requestTable;
+        delete replyTable;
 
-  makeAdjacencyRequests(numNodes,node,adaptAdjTable,requestTable,nodeSetSize,myRank,elemType);
+        // do the same thing for the edges
+        if (myRank == 0) {
+            requestTable = new MSA1DREQLIST(numChunks,numChunks);
+        } else {
+            requestTable = new MSA1DREQLIST;
+        }
+        MPI_Bcast_pup(*requestTable,0,MPI_COMM_WORLD);
+        requestTable->enroll(numChunks);
+        requestTable->sync();
+
+        makeAdjacencyRequests(
+                numNodes,
+                node,
+                edgeTable,
+                requestTable,
+                2,
+                myRank,
+                elemType);
+
+        requestTable->sync();
+        printf("[%d] All edge requests made \n",myRank);
+
+        MSA1DREPLYLIST *replyTable;
+        if (myRank == 0) {
+            replyTable = new MSA1DREPLYLIST(numChunks,numChunks);
+        } else {
+            replyTable = new MSA1DREPLYLIST;
+        }
+        MPI_Bcast_pup(*replyTable,0,MPI_COMM_WORLD);
+        replyTable->enroll(numChunks);
+        replyTable->sync();
+
+        replyAdjacencyRequests(
+                requestTable,
+                replyTable,
+                node,
+                edgeTable,
+                adaptFaceAdjacencies,
+                adaptEdgeAdjacencies,
+                2,
+                edgeMapSize,
+                myRank,
+                elemType,
+                true);
+
+        requestTable->sync();
+        replyTable->sync();
+
+        // Once the replies are back, loop through each reply and update the
+        // adjacencies for each element in the reply
+        CkVec<adjReply> *receivedReplyVec = replyTable->get(myRank).vec;
+        for(int i=0;i< receivedReplyVec->size();i++){
+            adjReply *receivedReply = &(*receivedReplyVec)[i];
+            printf("[%d] Replies received for (%d,%d) (%d,%d,%d)\n",
+                    myRank,receivedReply->requestingElemID,
+                    receivedReply->requestingNodeSetID,
+                    receivedReply->replyingElem.partID,
+                    receivedReply->replyingElem.localID,
+                    receivedReply->replyingElem.elemType);
+            adaptEdgeAdjacencies[receivedReply->requestingElemID*edgeMapSize + 
+                receivedReply->requestingNodeSetID]->push_back(
+                        receivedReply->replyingElem);
+        }
+        replyTable->sync();
+    }
 
-  requestTable->sync();
-  printf("[%d] All requests made \n",myRank);
+    // cleanup
+    delete requestTable;
+    delete replyTable;
+
+    //for (int i=0; i<numNodes; ++i) {
+    //    delete[] faceTable[i].sharedWithPartition;
+    //    delete[] faceTable[i].sharedWithLocalIdx;
+    //    adjElem* e = faceTable[i].adjElemList->next;
+    //    adjElem* dummy;
+    //    //while (e != NULL) {
+    //    //    dummy = e;
+    //    //    e = e->next;
+    //    //    delete dummy;
+    //    //}
+
+    //    if (edgeTable) {
+    //        delete[] edgeTable[i].sharedWithPartition;
+    //        delete[] edgeTable[i].sharedWithLocalIdx;
+    //        e = edgeTable[i].adjElemList->next;
+    //        //while (e != NULL) {
+    //        //    dummy = e;
+    //        //    e = e->next;
+    //        //    delete dummy;
+    //        //}
+    //    }
+    //}
+    delete[] faceTable;
+    delete[] edgeTable;
+}
 
-  MSA1DREPLYLIST *replyTable;
-  if(myRank == 0){
-    replyTable = new MSA1DREPLYLIST(numChunks,numChunks);
-  }else{
-    replyTable = new MSA1DREPLYLIST;
-  }
-  MPI_Bcast_pup(*replyTable,0,MPI_COMM_WORLD);
-  replyTable->enroll(numChunks);
-  replyTable->sync();
-
-       
-  replyAdjacencyRequests(requestTable,replyTable,node,adaptAdjTable,adaptAdjacencies,nodeSetSize,numAdjElems,myRank,elemType);
-
-  requestTable->sync();
-  replyTable->sync();
-
-  //Once the replies are back, loop through each reply and update the
-  //adaptAdjacencies for each element in the reply
-  CkVec<adjReply> *receivedReplyVec = replyTable->get(myRank).vec;
-  for(int i=0;i< receivedReplyVec->size();i++){
-    adjReply *receivedReply = &(*receivedReplyVec)[i];
-    printf("[%d] Replies received for (%d,%d) (%d,%d,%d)\n",myRank,receivedReply->requestingElemID,receivedReply->requestingNodeSetID,receivedReply->replyingElem.partID,receivedReply->replyingElem.localID,receivedReply->replyingElem.elemType);
-    adaptAdjacencies[receivedReply->requestingElemID*numAdjElems + receivedReply->requestingNodeSetID] = receivedReply->replyingElem;
-  }
 
-  replyTable->sync();
-  dumpAdaptAdjacencies(adaptAdjacencies,numElems,numAdjElems,myRank);
-
-/*  mesh->becomeSetting();  
-  //Register the adaptAdjacency with ParFUM
-  FEM_Register_array(meshid,FEM_ELEM+elemType,FEM_ADAPT_ADJ,(void *)adaptAdjacencies,FEM_BYTE,sizeof(adaptAdj)*numAdjElems);
-  //do not delete adaptAdjacencies. It will be used during the rest of adaptivity
-  mesh->becomeGetting();  
-       */
-}
-
-void fillLocalAdaptAdjacencies(int numNodes,FEM_Node *node,adjNode *adaptAdjTable,adaptAdj *adaptAdjacencies,int nodeSetSize,int numAdjElems,int myRank,int elemType){
-
-  for (int i=0; i<numNodes; i++) { 
-    // For each node, match up incident elements
-    // Each adjacency between two elements is represented by two adjElems
-    // We try to match those up
-    if(node->is_valid(i) && adaptAdjTable[i].adjElemList != NULL){  
-      // CkAssert(adaptAdjTable[i].adjElemList != NULL);
-      adjElem *preTarget = adaptAdjTable[i].adjElemList;
-      adjElem *target = adaptAdjTable[i].adjElemList->next;
-      while (target != NULL) { //loop over adjElemList of a node
-        int found = 0; 
-        //target represents an adjacency between two elements
-        //We search for the other adjElem corresponding to that adjancency:
-        //Look for an entry in adjElemList after target such that 
-        //the nodeset of that entry and that of target match but they 
-        //do not belong to the same element. 
-        adjElem *rover = searchAdjElemInList(preTarget,
-                                            target->nodeSet.getVec(),
-                                            nodeSetSize,target->elemID,
-                                            &found); 
-        
-        if (found) { // We found a local element adjacent to target->elemID
-          // Set adjacency of target->elemID corresponding to nodeSet to 
-          // rover->next->elemID, and vice versa
-          // Store adjacency info in adaptAdjacency of each one and
-          // use nodeSetID to index into adaptAdjacency
-          adaptAdjacencies[numAdjElems*target->elemID+target->nodeSetID] = 
-           adaptAdj(myRank,rover->next->elemID,elemType);
-          adaptAdjacencies[numAdjElems*rover->next->elemID+rover->next->nodeSetID] = adaptAdj(myRank,target->elemID,elemType);
-          // Remove both elem-nodeSet pairs from the list
-          adjElem *tmp = rover->next;
-          rover->next = rover->next->next;
-          delete tmp;
-          tmp = target;
-          preTarget->next = target->next;
-          target = target->next;
-          delete tmp;
-        }else { // No match for target was found in adjElemList
-          // This means that either target is on the domain boundary 
-          // or it is on a partition boundary and its neighbor is on another VP
-          // Move target to next entry in adjElemList
-          preTarget = target;
-          target = target->next;
+void fillLocalAdaptAdjacencies(
+        const int numNodes, 
+        FEM_Node* node, 
+        adjNode* faceTable, 
+        adjNode* edgeTable,
+        const int faceMapSize,
+        const int edgeMapSize,
+        adaptAdj* adaptFaceAdjacencies,
+        CkVec<adaptAdj>** adaptEdgeAdjacencies,
+        const int myRank, 
+        const int elemType)
+{
+    adjNode* adjTables[2] = { faceTable, edgeTable };
+    adjNode* adaptAdjTable;
+
+    for (int table=0; table<2; ++table) {
+        adaptAdjTable = adjTables[table];
+        for (int i=0; i<numNodes; i++) { 
+            if (!adaptAdjTable) continue;
+            // For each node, match up incident elements
+            // Each adjacency between two elements is represented by two 
+            // adjElems. We try to match those up
+            if(node->is_valid(i) && adaptAdjTable[i].adjElemList != NULL){  
+                // CkAssert(adaptAdjTable[i].adjElemList != NULL);
+                adjElem *preTarget = adaptAdjTable[i].adjElemList;
+                adjElem *target = adaptAdjTable[i].adjElemList->next;
+                while (target != NULL) { //loop over adjElemList of a node
+                    int found = 0; 
+                    // target represents an adjacency between two elements
+                    // We search for the other adjElem corresponding to that 
+                    // adjancency:
+                    // Look for an entry in adjElemList after target such that 
+                    // the nodeset of that entry and that of target match but 
+                    // they do not belong to the same element. 
+                    adjElem *rover = searchAdjElemInList(
+                            preTarget,
+                            target->nodeSet.getVec(),
+                            target->nodeSet.size(),
+                            target->elemID,
+                            &found); 
+
+                    if (found) { 
+                        // We found a local element adjacent to target->elemID
+                        // Set adjacency of target->elemID corresponding to 
+                        // nodeSet to rover->next->elemID, and vice versa
+                        // Store adjacency info in adaptAdjacency of each one 
+                        // and use nodeSetID to index into adaptAdjacency
+                        
+                        if (table == 0)  { // working on face nodesets
+                            adaptFaceAdjacencies[faceMapSize*target->elemID + 
+                                target->nodeSetID] = adaptAdj(
+                                        myRank, rover->next->elemID, elemType);
+                            adaptFaceAdjacencies[
+                                faceMapSize*rover->next->elemID + 
+                                rover->next->nodeSetID] = adaptAdj(
+                                        myRank, target->elemID, elemType);
+                        } else if (table == 1) { // working on edge nodesets
+                            adaptEdgeAdjacencies[edgeMapSize*target->elemID + 
+                                target->nodeSetID]->push_back(adaptAdj(
+                                            myRank, 
+                                            rover->next->elemID, 
+                                            elemType));
+                            adaptEdgeAdjacencies[
+                                edgeMapSize*rover->next->elemID + 
+                                rover->next->nodeSetID]->push_back(adaptAdj(
+                                            myRank,
+                                            target->elemID,
+                                            elemType));
+                        }
+                        
+                        // Remove both elem-nodeSet pairs from the list
+                        adjElem *tmp = rover->next;
+                        rover->next = rover->next->next;
+                        delete tmp;
+                        tmp = target;
+                        preTarget->next = target->next;
+                        target = target->next;
+                        delete tmp;
+                    } else { 
+                        // No match for target was found in adjElemList
+                        // This means that either target is on the domain 
+                        // boundary or it is on a partition boundary and its 
+                        // neighbor is on another VP. Move target to next 
+                        // entry in adjElemList
+                        preTarget = target;
+                        target = target->next;
+                    }
+                }
+            }
         }
-      }
     }
-  }
 }
 
 
-void makeAdjacencyRequests(int numNodes,FEM_Node *node,adjNode *adaptAdjTable,MSA1DREQLIST *requestTable, int nodeSetSize,int myRank,int elemType){
-
-  for (int i=0; i<numNodes; i++) { // Examine each node's remaining elements
-    if(node->is_valid(i)){
-      if (adaptAdjTable[i].adjElemList->next!=NULL) {
-        adjElem *adjStart = adaptAdjTable[i].adjElemList->next;
-        while (adjStart !=NULL) {
-          // create and empty set, commonSharedChunks
-          std::set<int> commonSharedChunks;
-          for (int j=0; j<nodeSetSize; j++) {
-           // look up sharedWithPartitions for node: 
-           //    adaptAdjTable[i]->adjElemList->nodeset[j]
-           // intersect with commonSharedChunks
-            int sharedNode = adjStart->nodeSet[j];
-            adjNode *sharedNodeAdj = &adaptAdjTable[sharedNode];
-            std::set<int> sharedChunks(sharedNodeAdj->sharedWithPartition,
-                                      sharedNodeAdj->sharedWithPartition+sharedNodeAdj->numSharedPartitions);
-            if(j == 0){
-              commonSharedChunks = sharedChunks;
-            }else{
-              std::set<int> tmpIntersect;
-              set_intersection(commonSharedChunks.begin(), commonSharedChunks.end(), 
-             sharedChunks.begin(), sharedChunks.end(),inserter(tmpIntersect, tmpIntersect.begin()));
-              commonSharedChunks = tmpIntersect;              
-            }
-          }
-          // At this point commonSharedChunks contains the list of
-          // chunks with which the element pointed by adjStart might
-          // be shared
-          int numCommonSharedChunks = commonSharedChunks.size();
-          if(numCommonSharedChunks > 0){
-            //adjStart is possibly shared with these chunks. It is
-            //shared across the adjStart->nodeSet set of nodes.
-            adjRequest *adjRequestList = new adjRequest[numCommonSharedChunks];
-            //Translate the nodes in the nodeSet into the index in the
-            //idxl list for each chunk in the commonSharedChunks
-            for(int j=0;j<nodeSetSize;j++){
-              int sharedNode = adjStart->nodeSet[j];
-              const IDXL_Rec *recSharedNode = node->shared.getRec(sharedNode);
-              int countChunk=0;
-              for(std::set<int>::iterator chunkIterator = commonSharedChunks.begin();
-                      chunkIterator != commonSharedChunks.end();chunkIterator++){
-                int chunk = *chunkIterator;
-                // if(chunk > myRank){
-                if(j == 0){
-                  // if this is the first node we need to initialize
-                  // the adjRequestobject
-                  adjRequestList[countChunk] =  adjRequest(adjStart->elemID,myRank,adjStart->nodeSetID,elemType);
-                }
-                int sharedNodeIdx=-1; // index of sharedNode in the idxl list of chunk
-                //search for this chunk in the list of chunks shared
-                //by this node
-                for(int k=0;k<recSharedNode->getShared();k++){
-                  if(recSharedNode->getChk(k) == chunk){
-                    //found the correct chunk
-                    sharedNodeIdx = recSharedNode->getIdx(k);
-                    break;
-                  }
+void makeAdjacencyRequests(
+        const int numNodes,
+        FEM_Node *node,
+        adjNode *adaptAdjTable,
+        MSA1DREQLIST *requestTable, 
+        const int nodeSetSize,
+        const int myRank,
+        const int elemType)
+{
+    for (int i=0; i<numNodes; i++) { 
+        // Examine each node's remaining elements
+        if(node->is_valid(i)){
+            if (adaptAdjTable[i].adjElemList->next!=NULL) {
+                adjElem *adjStart = adaptAdjTable[i].adjElemList->next;
+                while (adjStart !=NULL) {
+                    // create and empty set, commonSharedChunks
+                    std::set<int> commonSharedChunks;
+                    for (int j=0; j<nodeSetSize; j++) {
+                        // look up sharedWithPartitions for node: 
+                        //    adaptAdjTable[i]->adjElemList->nodeset[j]
+                        // intersect with commonSharedChunks
+                        int sharedNode = adjStart->nodeSet[j];
+                        adjNode *sharedNodeAdj = &adaptAdjTable[sharedNode];
+                        std::set<int> sharedChunks(
+                                sharedNodeAdj->sharedWithPartition,
+                                sharedNodeAdj->sharedWithPartition + 
+                                sharedNodeAdj->numSharedPartitions);
+                        if(j == 0){
+                            commonSharedChunks = sharedChunks;
+                        }else{
+                            std::set<int> tmpIntersect;
+                            set_intersection(
+                                    commonSharedChunks.begin(), 
+                                    commonSharedChunks.end(), 
+                                    sharedChunks.begin(), 
+                                    sharedChunks.end(),
+                                    inserter(
+                                        tmpIntersect, 
+                                        tmpIntersect.begin()));
+                            commonSharedChunks = tmpIntersect;              
+                        }
+                    }
+                    // At this point commonSharedChunks contains the list of
+                    // chunks with which the element pointed by adjStart might
+                    // be shared
+                    int numCommonSharedChunks = commonSharedChunks.size();
+                    if(numCommonSharedChunks > 0){
+                        //adjStart is possibly shared with these chunks. It is
+                        //shared across the adjStart->nodeSet set of nodes.
+                        adjRequest *adjRequestList = 
+                            new adjRequest[numCommonSharedChunks];
+                        // Translate the nodes in the nodeSet into the index in 
+                        // the idxl list for each chunk in the 
+                        // commonSharedChunks
+                        for(int j=0;j<nodeSetSize;j++){
+                            int sharedNode = adjStart->nodeSet[j];
+                            const IDXL_Rec *recSharedNode = 
+                                node->shared.getRec(sharedNode);
+                            int countChunk=0;
+                            for(std::set<int>::iterator chunkIterator = 
+                                    commonSharedChunks.begin();
+                                    chunkIterator != commonSharedChunks.end();
+                                    chunkIterator++){
+                                int chunk = *chunkIterator;
+                                if(j == 0){
+                                    // if this is the first node we need to 
+                                    // initialize the adjRequestobject
+                                    adjRequestList[countChunk] = 
+                                        adjRequest(adjStart->elemID,
+                                                myRank,
+                                                adjStart->nodeSetID,
+                                                elemType);
+                                }
+
+                                // index of sharedNode in the idxl list of 
+                                // chunk search for this chunk in the list of 
+                                // chunks shared by this node
+                                int sharedNodeIdx=-1; 
+                                for(int k=0;k<recSharedNode->getShared();k++){
+                                    if(recSharedNode->getChk(k) == chunk){
+                                        //found the correct chunk
+                                        sharedNodeIdx = 
+                                            recSharedNode->getIdx(k);
+                                        break;
+                                    }
+                                }
+                                CkAssert(sharedNodeIdx != -1);
+                                //The index of sharedNode in the index list of
+                                //chunks has been found.  This needs to be 
+                                //saved in the corresponding translatedNodeSet
+                                adjRequestList[countChunk].
+                                    translatedNodeSet[j] = sharedNodeIdx;
+                                countChunk++;
+                            }
+                        }
+
+                        // Now the nodeNumbers for the nodeSets that might be 
+                        // along chunk boundaries have been translated into 
+                        // idxl indices between the two chunks We now need to 
+                        // write the requests into the msa array requestTable 
+                        int countChunk=0;
+                        for(std::set<int>::iterator chunkIterator = 
+                                commonSharedChunks.begin();
+                                chunkIterator != commonSharedChunks.end();
+                                chunkIterator++){
+                            int chunk = *chunkIterator;
+                            printf("[%d] Sending to chunk %d request (%d,%d,%d,%d) \n",myRank,chunk,adjRequestList[countChunk].elemID,adjRequestList[countChunk].chunkID,adjRequestList[countChunk].elemType,adjRequestList[countChunk].nodeSetID);
+                            (*requestTable).accumulate(
+                                    chunk,adjRequestList[countChunk]);
+                            countChunk++;
+                        }
+                        delete [] adjRequestList;
+                    }
+                    adjStart = adjStart->next;
                 }
-                CkAssert(sharedNodeIdx != -1);
-                //The index of sharedNode in the index list of chunk
-                //has been found.  this needs to be saved in the
-                //corresponding translatedNodeSet
-                adjRequestList[countChunk].translatedNodeSet[j] = sharedNodeIdx;
-                //                }
-                countChunk++;
-              }
             }
+        }
+    }
+}
+
 
-            // Now the nodeNumbers for the nodeSets that might be along
-            // chunk boundaries have been translated into idxl indices
-            // between the two chunks We now need to write the requests
-            // into the msa array requestTable 
-            //
-            // WARNING: This depends on sets getting enumerated in the 
-            // same way always. Might not be true
-            // 
-            // Note: this isn't a problem--set iterators return their 
-            // elements in sorted order -Aaron
-            int countChunk=0;
-            for(std::set<int>::iterator chunkIterator = commonSharedChunks.begin();chunkIterator != commonSharedChunks.end();chunkIterator++){
-              int chunk = *chunkIterator;
-//              if(chunk > myRank){
-                printf("[%d] Sending to chunk %d request (%d,%d,%d,%d) \n",myRank,chunk,adjRequestList[countChunk].elemID,adjRequestList[countChunk].chunkID,adjRequestList[countChunk].elemType,adjRequestList[countChunk].nodeSetID);
-                (*requestTable).accumulate(chunk,adjRequestList[countChunk]);
-//              requestVec.push_back(&adjRequestList[countChunk]);
-//              }
-              countChunk++;
+void replyAdjacencyRequests(
+        MSA1DREQLIST* requestTable,
+        MSA1DREPLYLIST* replyTable,
+        FEM_Node* node,
+        adjNode* adaptAdjTable,
+        adaptAdj* adaptFaceAdjacencies,
+        CkVec<adaptAdj>** adaptEdgeAdjacencies,
+        const int nodeSetSize,
+        const int numAdjElems,
+        const int myRank,
+        const int elemType,
+        bool isEdgeRequest)
+{
+    // look up request table, put answer in reply table 
+    // receive: for local elemID, the adjacency on this set of shared indices 
+    // is (remote elemID, remote partition ID, remote elem type)
+    // add adjacencies to local table
+    // lots of error checking :)
+
+    //Look at each request that in the requestTable for this chunk
+    //Put the data for the requests in our own table and then create replies
+    CkVec<adjRequest> *receivedRequestVec = requestTable->get(myRank).vec;
+    for (int i=0;i<receivedRequestVec->length();i++) {    
+        adjRequest &receivedRequest = (*receivedRequestVec)[i];
+        const IDXL_List &sharedNodeList = 
+            node->shared.getList(receivedRequest.chunkID);
+        CkVec<int> sharedNodes(nodeSetSize);
+        //Translate all the nodes in the nodeSet of the request
+        for (int j=0;j<nodeSetSize;j++) {
+            int sharedNode = sharedNodeList[
+                receivedRequest.translatedNodeSet[j]];
+            sharedNodes[j] = sharedNode;
+        }
+        sharedNodes.quickSort();
+        //We need to find the matching nodeset for the nodeset in the request
+        //We look it up in the adaptAdjTable for the minimum node on this chunk
+        adjNode *minNode = &adaptAdjTable[sharedNodes[0]];
+        int found=0;
+        //search for the nodeSet in the list of adjacencies around minNode
+        adjElem *rover =  searchAdjElemInList(
+                minNode->adjElemList, 
+                sharedNodes.getVec(), 
+                nodeSetSize, 
+                -1, 
+                &found);
+        printf("[%d] Received request (%d,%d,%d,%d) minNode %d found %d\n",
+                myRank,receivedRequest.elemID,receivedRequest.chunkID,
+                receivedRequest.elemType,receivedRequest.nodeSetID,
+                sharedNodes[0],found);
+        if (found) { 
+            //we have found a matching adjElem for the requested nodeset
+            //we shall set the adjacency correctly in the adjacency Table
+            //for the elemID in the found adjElem. We need to send a reply
+            //to the requesting chunk
+            int matchingElemID;
+            matchingElemID = rover->next->elemID;
+
+            if (isEdgeRequest) {
+                CkVec<adaptAdj>* matchingAdaptAdj = adaptEdgeAdjacencies[
+                    matchingElemID*numAdjElems + rover->next->nodeSetID];
+                matchingAdaptAdj->push_back(adaptAdj(
+                            receivedRequest.chunkID,
+                            receivedRequest.elemID, 
+                            receivedRequest.elemType));
+            } else {
+                adaptAdj *matchingAdaptAdj = &adaptFaceAdjacencies[
+                    matchingElemID*numAdjElems + rover->next->nodeSetID];
+                CkAssert(matchingAdaptAdj->localID == -1);
+                matchingAdaptAdj->partID = receivedRequest.chunkID;
+                matchingAdaptAdj->localID = receivedRequest.elemID;
+                matchingAdaptAdj->elemType = receivedRequest.elemType;
             }
-            delete [] adjRequestList;
-          }
-          adjStart = adjStart->next;
+            
+            adjElem *tmp = rover->next;
+            rover->next = tmp->next;
+            delete tmp;
+
+            //Set requesting data in reply to that in receivedRequest
+            //Put in data from rover->next into the replyElem portion of data
+            adjReply reply;
+            reply.requestingElemID = receivedRequest.elemID;
+            reply.requestingNodeSetID = receivedRequest.nodeSetID;
+            reply.replyingElem.partID = myRank;
+            reply.replyingElem.localID = matchingElemID;
+            reply.replyingElem.elemType = elemType;
+            //Write into the replyTable
+            replyTable->accumulate(receivedRequest.chunkID,reply);
+        } else {
+            //we have no matching nodeset for this request.. hopefully some
+            //other chunk does; we can ignore this request
         }
-      }
     }
-  }
 }
 
-void replyAdjacencyRequests(MSA1DREQLIST *requestTable,MSA1DREPLYLIST *replyTable,FEM_Node *node,adjNode *adaptAdjTable,adaptAdj *adaptAdjacencies,int nodeSetSize,int numAdjElems,int myRank,int elemType){
-  // look up request table, put answer in reply table 
-  // receive: for local elemID, the adjacency on this set of shared indices is (remote elemID, remote partition ID, remote elem type)
-  // add adjacencies to local table
-  // lots of error checking :)
+
+inline void findNodeSet(
+        int meshid,
+        int elemType,
+        int* faceSize, 
+        int* faceMapSize, 
+        int* edgeMapSize,
+        int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE],
+        int edgeMap[MAX_EDGES][2])
+{
+    FEM_Mesh *mesh = FEM_chunk::get("GetAdaptAdj")->
+        lookup(meshid,"GetAdaptAdj");
+    FEM_Elem *elem = (FEM_Elem *)mesh->
+        lookup(FEM_ELEM+elemType,"GetAdaptAdj");
+    FEM_Node *node = (FEM_Node *)mesh->
+        lookup(FEM_NODE,"GetAdaptAdj");
+    const int nodesPer = (elem->getConn()).width();
+    assert(node->getCoord()!= NULL);
+    assert(nodesPer > 0 && nodesPer < MAX_FACE_SIZE);
+    const int dim = (node->getCoord())->getWidth();
+    assert(dim == 2|| dim == 3);
+
+    guessElementShape(dim, nodesPer, 
+            faceSize, faceMapSize, edgeMapSize, 
+            nodeSetMap, edgeMap);
+}
+
+void getAndDumpAdaptAdjacencies(
+        const int meshid, 
+        const int numElems, 
+        const int elemType, 
+        const int myRank)
+{
+  int faceSize;
+  int faceMapSize, edgeMapSize;
+  int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE]; // not used
+  int edgeMap[MAX_EDGES][2]; // not used
   
-  //Look at each request that in the requestTable for this chunk
-  //Put the data for the requests in our own table and then create replies
-  CkVec<adjRequest> *receivedRequestVec = requestTable->get(myRank).vec;
-  for(int i=0;i<receivedRequestVec->length();i++){    
-    adjRequest &receivedRequest = (*receivedRequestVec)[i];
-    const IDXL_List &sharedNodeList = node->shared.getList(receivedRequest.chunkID);
-    CkVec<int> sharedNodes(nodeSetSize);
-    //Translate all the nodes in the nodeSet of the request
-    for(int j=0;j<nodeSetSize;j++){
-      int sharedNode = sharedNodeList[receivedRequest.translatedNodeSet[j]];
-      sharedNodes[j] = sharedNode;
-    }
-    sharedNodes.quickSort();
-    //We need to find the matching nodeset for the nodeset in the request
-    //We look it up in the adaptAdjTable for the minimum node on this chunk
-    adjNode *minNode = &adaptAdjTable[sharedNodes[0]];
-    int found=0;
-    //search for the nodeSet in the list of adjacencies around minNode
-    adjElem *rover =  searchAdjElemInList(minNode->adjElemList,sharedNodes.getVec(),nodeSetSize,-1,&found);
-    printf("[%d] Received request (%d,%d,%d,%d) minNode %d found %d\n",myRank,receivedRequest.elemID,receivedRequest.chunkID,receivedRequest.elemType,receivedRequest.nodeSetID,sharedNodes[0],found);
-    if(found){ //we have found a matching adjElem for the requested nodeset
-       //we shall set the adjacency correctly in the adjacency Table
-       //for the elemID in the found adjElem. We need to send a reply
-       //to the requesting chunk
-       int matchingElemID;
-       matchingElemID = rover->next->elemID;
-       adaptAdj *matchingAdaptAdj = &adaptAdjacencies[matchingElemID*numAdjElems + rover->next->nodeSetID];
-       adjElem *tmp = rover->next;
-       rover->next = tmp->next;
-       delete tmp;
-       CkAssert(matchingAdaptAdj->localID == -1);
-       matchingAdaptAdj->partID = receivedRequest.chunkID;
-       matchingAdaptAdj->localID = receivedRequest.elemID;
-       matchingAdaptAdj->elemType = receivedRequest.elemType;
-
-       //Set requesting data in reply to that in receivedRequest
-       //Put in data from rover->next into the replyElem portion of data
-       adjReply reply;
-       reply.requestingElemID = receivedRequest.elemID;
-       reply.requestingNodeSetID = receivedRequest.nodeSetID;
-       reply.replyingElem.partID = myRank;
-       reply.replyingElem.localID = matchingElemID;
-       reply.replyingElem.elemType = elemType;
-       //Write into the replyTable
-       replyTable->accumulate(receivedRequest.chunkID,reply);
-    }else{
-      //we have no matching nodeset for this request.. hopefully some
-      //other chunk does; we can ignore this request
-    }
+  findNodeSet(
+          meshid, elemType,
+          &faceSize, &faceMapSize, &edgeMapSize,
+          nodeSetMap, edgeMap);
+  
+  for (int i=0; i<numElems; i++) {
+      printf("[%d] %d  :",myRank,i);
+      for (int j=0; j<faceMapSize; j++) {
+          adaptAdj *entry = getAdaptAdj(meshid, i, elemType, j);
+          printf("(%d,%d,%d)", entry->partID, entry->localID, entry->elemType);
+      }
+      printf("\n");
+  }
+
+  if (edgeMapSize == 0) return;
+  for (int i=0; i<numElems; i++) {
+      printf("[%d] %d  :", myRank, i);
+      for (int j=0; j<edgeMapSize; j++) {
+          CkVec<adaptAdj>* entry = getEdgeAdaptAdj(meshid, i, elemType, j);
+          for (int k=0; k<entry->size(); ++k) {
+              printf("(%d,%d,%d)", (*entry)[k].partID, (*entry)[k].localID, 
+                      (*entry)[k].elemType);
+          }
+      }
+      printf("\n");
   }
+
 }
 
+// Access functions
+inline adaptAdj* lookupAdaptAdjacencies(
+        const FEM_Mesh* const mesh,
+        const int elemType,
+        int* numAdjacencies)
+{
+    FEM_Elem *elem = (FEM_Elem*)mesh->lookup(
+            FEM_ELEM+elemType, "lookupAdaptAdjacencies");
 
+    FEM_DataAttribute* adaptAttr = (FEM_DataAttribute*)elem->lookup(
+            FEM_ADAPT_FACE_ADJ, "lookupAdaptAdjacencies");
+    *numAdjacencies = adaptAttr->getWidth()/sizeof(adaptAdj);
+    AllocTable2d<unsigned char> &table = adaptAttr->getChar();
 
-void dumpAdaptAdjacencies(adaptAdj *adaptAdjacencies,int numElems,int numAdjElems,int myRank){
-  for(int i=0;i<numElems;i++){
-    printf("[%d] %d  :",myRank,i);
-    for(int j=0;j<numAdjElems;j++){
-      adaptAdj *entry = &adaptAdjacencies[i*numAdjElems+j];
-      printf("(%d,%d,%d)",entry->partID,entry->localID,entry->elemType);
-    }
-    printf("\n");
-  }
+    return (adaptAdj*)(adaptAttr->getChar().getData());
 }
 
-inline void findNodeSet(int meshid,int elemType,int *numAdjElems,int *nodeSetSize,int  nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE]){
-       FEM_Mesh *mesh = FEM_chunk::get("GetAdaptAdj")->lookup(meshid,"GetAdaptAdj");
-  FEM_Elem *elem = (FEM_Elem *)mesh->lookup(FEM_ELEM+elemType,"GetAdaptAdj");
-  FEM_Node *node = (FEM_Node *)mesh->lookup(FEM_NODE,"GetAdaptAdj");
-  const int nodesPer = (elem->getConn()).width();
-  assert(node->getCoord()!= NULL);
-  const int dim = (node->getCoord())->getWidth();
-  assert(dim == 2|| dim == 3);
-  guessElementShape(dim,nodesPer,numAdjElems,nodeSetSize,nodeSetMap);
+inline adaptAdj* lookupAdaptAdjacencies(
+        const int meshid,
+        const int elemType,
+        int* numAdjacencies)
+{
+    FEM_Mesh* mesh = FEM_chunk::get("lookupAdaptAdjacencies")->lookup(
+            meshid, "lookupAdaptAdjacencies");
+    return lookupAdaptAdjacencies(mesh, elemType, numAdjacencies);
 }
 
-void getAndDumpAdaptAdjacencies(int meshid, int numElems, int elemType, int myRank){
-  int numAdjElems;
-  int nodeSetSize, nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE]; // not used
-       findNodeSet(meshid,elemType,&numAdjElems,&nodeSetSize,nodeSetMap);
-  
-  for(int i=0;i<numElems;i++){
-    printf("[%d] %d  :",myRank,i);
-    for(int j=0;j<numAdjElems;j++){
-      adaptAdj *entry = GetAdaptAdj(meshid, adaptAdj(myRank,i,elemType), j);
-      printf("(%d,%d,%d)",entry->partID,entry->localID,entry->elemType);
-    }
-    printf("\n");
-  }
+inline CkVec<adaptAdj>** lookupEdgeAdaptAdjacencies(
+        const FEM_Mesh* const mesh,
+        const int elemType,
+        int* numAdjacencies)
+{
+    FEM_Elem *elem = (FEM_Elem*)mesh->lookup(
+            FEM_ELEM+elemType,"lookupAdaptAdjacencies");
+    FEM_DataAttribute* adaptAdjAttr = (FEM_DataAttribute*)elem->lookup(
+            FEM_ADAPT_EDGE_ADJ, "CreateAdaptAdjacencies");     
+    *numAdjacencies = adaptAdjAttr->getWidth()/sizeof(CkVec<adaptAdj>**);
+    CkVec<adaptAdj>** adaptAdjacencies = 
+        reinterpret_cast<CkVec<adaptAdj>**>((adaptAdjAttr->getInt()).getData());
+    return adaptAdjacencies;
 }
 
-// Access functions
-inline adaptAdj *lookupAdaptAdjacencies(FEM_Mesh *mesh,int elemType,int *numAdjacencies){
-  FEM_Elem *elem = (FEM_Elem *)mesh->lookup(FEM_ELEM+elemType,"lookupAdaptAdjacencies");
-
-  FEM_DataAttribute *adaptAttr = (FEM_DataAttribute *)elem->lookup(FEM_ADAPT_ADJ,"lookupAdaptAdjacencies");
-       *numAdjacencies = adaptAttr->getWidth()/sizeof(adaptAdj);
-  AllocTable2d<unsigned char> &table = adaptAttr->getChar();
+inline CkVec<adaptAdj>** lookupEdgeAdaptAdjacencies(
+        const int meshID,
+        const int elemType,
+        int* numAdjacencies)
+{
+    FEM_Mesh *mesh = FEM_chunk::get("lookupAdaptAdjacencies")->
+        lookup(meshID,"lookupAdaptAdjacencies");
+    return lookupEdgeAdaptAdjacencies(mesh, elemType, numAdjacencies);
+}
 
-  return (adaptAdj  *)table.getData();
+/** Look up elemID in elemType array, access edgeFaceID-th adaptAdj. */
+adaptAdj* getAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int faceID)
+{
+    int numAdjacencies;
+    adaptAdj* adaptAdjacencies = 
+        lookupAdaptAdjacencies(meshID, elemType, &numAdjacencies);
+    return &(adaptAdjacencies[localID*numAdjacencies+faceID]);
 }
 
-inline adaptAdj *lookupAdaptAdjacencies(int meshid,int elemType,int *numAdjacencies){
-  FEM_Mesh *mesh = FEM_chunk::get("lookupAdaptAdjacencies")->lookup(meshid,"lookupAdaptAdjacencies");
-  return lookupAdaptAdjacencies(mesh, elemType, numAdjacencies);
+adaptAdj* getAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const int localID,
+        const int elemType, 
+        const int faceID)
+{
+    int numAdjacencies;
+    adaptAdj* adaptAdjacencies = 
+        lookupAdaptAdjacencies(meshPtr, elemType, &numAdjacencies);
+    return &(adaptAdjacencies[localID*numAdjacencies+faceID]);
 }
 
-/** Look up elemID in elemType array, access edgeFaceID-th adaptAdj. */
-adaptAdj *GetAdaptAdj(int meshid, adaptAdj elem, int edgeFaceID)
+CkVec<adaptAdj>* getEdgeAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int edgeID)
 {
-  int numAdjacencies;
-  adaptAdj *adaptAdjacencies = lookupAdaptAdjacencies(meshid, elem.elemType,
-                                                     &numAdjacencies);
-  return(&(adaptAdjacencies[elem.localID*numAdjacencies+edgeFaceID]));
+    int numAdjacencies;
+    CkVec<adaptAdj>** adaptAdjacencies = 
+        lookupEdgeAdaptAdjacencies(meshID, elemType, &numAdjacencies);
+    return adaptAdjacencies[localID*numAdjacencies+edgeID];
 }
 
-adaptAdj *GetAdaptAdj(FEM_Mesh *meshPtr, adaptAdj elem, int edgeFaceID)
+CkVec<adaptAdj>* getEdgeAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const int localID,
+        const int elemType, 
+        const int edgeID)
 {
-  int numAdjacencies;
-  adaptAdj *adaptAdjacencies = lookupAdaptAdjacencies(meshPtr, elem.elemType,
-                                                     &numAdjacencies);
-  return(&(adaptAdjacencies[elem.localID*numAdjacencies+edgeFaceID]));
+    int numAdjacencies;
+    CkVec<adaptAdj>** adaptAdjacencies = 
+        lookupEdgeAdaptAdjacencies(meshPtr, elemType, &numAdjacencies);
+    return adaptAdjacencies[localID*numAdjacencies+edgeID];
 }
 
 /** Look up elemID in elemType array, calculate edgeFaceID from
     vertexList (with GetEdgeFace below), and access edgeFaceID-th
     adaptAdj with GetAdaptAdj above. */
-adaptAdj *GetAdaptAdj(int meshid, adaptAdj elem, int *vertexList)
+adaptAdj* getAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int* const vertexList)
 {
-  int edgeFaceID = GetEdgeFace(meshid, elem, vertexList);
-  return GetAdaptAdj(meshid, elem, edgeFaceID);
+  int faceID = getElemFace(meshID, elemType, vertexList);
+  return getAdaptAdj(meshID, localID, elemType, faceID);
 }
 
-adaptAdj *GetAdaptAdjOnEdge(int meshid, adaptAdj elem, int edgeID, int *size)
+CkVec<adaptAdj>* getEdgeAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int* const vertexList)
 {
-  return NULL;
+  int edgeID = getElemEdge(meshID, elemType, vertexList);
+  return getEdgeAdaptAdj(meshID, localID, elemType, edgeID);
 }
 
-adaptAdj *GetAdaptAdjOnEdge(FEM_Mesh *meshPtr, adaptAdj elem, int edgeID, int *size)
+adaptAdj* getFaceAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int* const vertexList)
 {
-  return NULL;
+  return getAdaptAdj(meshID, localID, elemType, vertexList);
 }
 
-adaptAdj *GetAdaptAdjOnFace(int meshid, adaptAdj elem, int faceID)
+adaptAdj* getFaceAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int faceID)
 {
-  return NULL;
+    return getAdaptAdj(meshID, localID, elemType, faceID);
 }
 
-adaptAdj *GetAdaptAdjOnFace(FEM_Mesh *meshPtr, adaptAdj elem, int faceID)
+adaptAdj* getFaceAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const int localID,
+        const int elemType, 
+        const int faceID)
 {
-  return NULL;
+    return getAdaptAdj(meshPtr, localID, elemType, faceID);
 }
 
 
-/** Look up elemID in elemType array and determine the set of vertices
-    associated with the edge or face represented by edgeFaceID. */
-void GetVertices(int meshid, adaptAdj elem, int edgeFaceID, int *vertexList)
+
+/** Look up elemID in elemType array and determine the edge or face ID
+    specified by the set of vertices in vertexList. */
+int getElemFace(
+        const int meshID, 
+        const int type, 
+        const int* vertexList)
 {
-  int numAdjacencies;
-  int nodeSetSize, nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
-  findNodeSet(meshid,elem.elemType,&numAdjacencies,&nodeSetSize,nodeSetMap);
+  int faceSize;
+  int faceMapSize;
+  int faceMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
+  int edgeMapSize; // not used
+  int edgeMap[MAX_EDGES][2]; // not used
+  findNodeSet(meshID, type, &faceSize, &faceMapSize, &edgeMapSize,
+         faceMap, edgeMap);
   
-  for (int i=0; i<nodeSetSize; i++) {
-    vertexList[i] = nodeSetMap[edgeFaceID][i];
+  // look for vertexList in the face map
+  std::set<int> vertexSet(vertexList, vertexList+faceSize);
+  for (int i=0; i<faceMapSize; i++) {
+    std::set<int> aNodeSet(faceMap[i], faceMap[i]+faceSize);
+    if (vertexSet == aNodeSet) return i;
   }
+
+  // uh-oh, didn't find it
+  CkAbort("ERROR: GetEdgeFace: vertexList is not a valid face./n");
 }
 
-/** Look up elemID in elemType array and determine the edge or face ID
-    specified by the set of vertices in vertexList. */
-int GetEdgeFace(int meshid, adaptAdj elem, int *vertexList)
+int getElemEdge(
+        const int meshID, 
+        const int type, 
+        const int* vertexList)
 {
-  int numAdjacencies;
-  int nodeSetSize, nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE];
-  findNodeSet(meshid,elem.elemType,&numAdjacencies,&nodeSetSize,nodeSetMap);
+  int faceSize; // not used
+  int faceMapSize; // not used
+  int faceMap[MAX_ADJELEMS][MAX_NODESET_SIZE]; // not used
+  int edgeMapSize;
+  int edgeMap[MAX_EDGES][2];
+  findNodeSet(meshID, type, &faceSize, &faceMapSize, &edgeMapSize,
+         faceMap, edgeMap);
   
-  std::set<int> vertexSet(vertexList, vertexList+nodeSetSize);
-  for (int i=0; i<numAdjacencies; i++) {
-    std::set<int> aNodeSet(nodeSetMap[i], nodeSetMap[i]+nodeSetSize);
-    if (vertexSet == aNodeSet) return i; // CHECK: does set equivalence exist?
+  // look for vertexList in the edge map
+  std::set<int> vertexSet(vertexList, vertexList+2);
+  for (int i=0; i<edgeMapSize; i++) {
+    std::set<int> aNodeSet(edgeMap[i], edgeMap[i]+2);
+    if (vertexSet == aNodeSet) return i;
   }
-  CkAbort("ERROR: GetEdgeFace: vertexList is not a valid nodeSet./n");
+
+  // uh-oh, didn't find it
+  CkAbort("ERROR: GetEdgeFace: vertexList is not a valid edge./n");
 }
 
+
 // Update functions
 /** Look up elemID in elemType array and set the adjacency on
     edgeFaceID to nbr. */
-void SetAdaptAdj(int meshID, adaptAdj elem, int edgeFaceID, adaptAdj nbr)
+void setAdaptAdj(
+        const int meshID, 
+        const adaptAdj elem, 
+        const int faceID, 
+        const adaptAdj nbr)
 {
   int numAdjacencies;
   adaptAdj *adaptAdjTable = lookupAdaptAdjacencies(meshID, elem.elemType,
                                                   &numAdjacencies);
-  adaptAdjTable[elem.localID*numAdjacencies + edgeFaceID] = nbr;
+  adaptAdjTable[elem.localID*numAdjacencies + faceID] = nbr;
 }
 
-void AddToAdaptAdj(int meshid, adaptAdj elem, int edgeID, adaptAdj nbr)
+void addToAdaptAdj(
+        const int meshid, 
+        const adaptAdj elem, 
+        const int edgeID, 
+        const adaptAdj nbr)
 {
+    CkVec<adaptAdj>* adjVec = getEdgeAdaptAdj(meshid, elem.localID, 
+            elem.elemType, edgeID);
+    adjVec->push_back(nbr);
 }
 
-void RemoveFromAdaptAdj(int meshid, adaptAdj elem, int edgeID, adaptAdj nbr)
+void removeFromAdaptAdj(
+        const int meshid, 
+        const adaptAdj elem, 
+        const int edgeID, 
+        const adaptAdj nbr)
 {
+    CkVec<adaptAdj>* adjVec = getEdgeAdaptAdj(meshid, elem.localID, 
+            elem.elemType, edgeID);
+    for (int i=0; i<adjVec->size(); ++i) {
+        if ((*adjVec)[i] == nbr) {
+            adjVec->remove(i);
+            return;
+        }
+    }
+    CkAbort("removeFromAdaptAdj did not find the specified nbr");
 }
 
-/** Lookup elemID in elemType array and search for the edgeID which has originalNbr as
- * a neighbor, then replace originalNbr with newNbr
+/** Lookup elemID in elemType array and search for the face which has 
+ *  originalNbr as a neighbor, then replace originalNbr with newNbr
  */
-void ReplaceAdaptAdj(FEM_Mesh *meshPtr, adaptAdj elem, adaptAdj originalNbr, 
-                    adaptAdj newNbr){
-  int numAdjacencies;
-  adaptAdj *adaptAdjTable = lookupAdaptAdjacencies(meshPtr, elem.elemType,
-                                                  &numAdjacencies);
-  for(int i=0;i<numAdjacencies;i++){
-    if(adaptAdjTable[elem.localID*numAdjacencies+i] == originalNbr){
-      adaptAdjTable[elem.localID*numAdjacencies+i] = newNbr;
-      return;
+void replaceAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr, 
+        const adaptAdj newNbr)
+{
+    int numAdjacencies;
+    adaptAdj *adaptAdjTable = lookupAdaptAdjacencies(meshPtr, elem.elemType,
+            &numAdjacencies);
+    for(int i=0;i<numAdjacencies;i++){
+        if(adaptAdjTable[elem.localID*numAdjacencies+i] == originalNbr){
+            adaptAdjTable[elem.localID*numAdjacencies+i] = newNbr;
+            return;
+        }
     }
-  }
-  CkAbort("ReplaceAdaptAdj did not find the specified originalNbr");
+    CkAbort("replaceAdaptAdj did not find the specified originalNbr");
 }
 
-void ReplaceAdaptAdj(int meshID, adaptAdj elem, adaptAdj originalNbr, 
-                    adaptAdj newNbr){
-  FEM_Mesh *meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(meshID,"ReplaceAdaptAdj");
-  ReplaceAdaptAdj(meshPtr, elem, originalNbr, newNbr);
+
+void replaceAdaptAdj(
+        const int meshID, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr, 
+        const adaptAdj newNbr)
+{
+    FEM_Mesh* meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(
+            meshID,"ReplaceAdaptAdj");
+    replaceAdaptAdj(meshPtr, elem, originalNbr, newNbr);
 }
 
-void ReplaceAdaptAdjOnEdge(int meshID, adaptAdj elem, adaptAdj originalNbr, 
-                    adaptAdj newNbr)
+
+void replaceAdaptAdjOnEdge(
+        const FEM_Mesh* const meshPtr, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr,
+        const adaptAdj newNbr)
 {
+    int numAdjacencies;
+    CkVec<adaptAdj>** adaptAdjTable = lookupEdgeAdaptAdjacencies(
+            meshPtr, elem.elemType, &numAdjacencies);
+    for (int edge=0; edge<numAdjacencies; edge++) {
+        CkVec<adaptAdj>* innerTable = 
+            adaptAdjTable[elem.localID*numAdjacencies + edge];
+        for (int n=0; n<innerTable->size(); ++n) {
+            if((*innerTable)[n] == originalNbr){
+                (*innerTable)[n] = newNbr;
+                return;
+            }
+        }
+    }
+    CkAbort("replaceAdaptAdjOnEdge did not find the specified originalNbr");
 }
 
-void ReplaceAdaptAdjOnEdge(FEM_Mesh *meshPtr, adaptAdj elem, adaptAdj originalNbr,
-                    adaptAdj newNbr)
+
+void replaceAdaptAdjOnEdge(
+        const int meshID, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr, 
+        const adaptAdj newNbr)
 {
+    FEM_Mesh* meshPtr = FEM_chunk::get("ReplaceAdaptAdj")->lookup(
+            meshID,"ReplaceAdaptAdj");
+    replaceAdaptAdjOnEdge(meshPtr, elem, originalNbr, newNbr);
 }
 
-//given the dimensions and nodes per element guess whether the element 
-// is a triangle, quad, tet or hex. At the moment these are the 4 shapes
-// that are handled
-  
-#define copyNodeSetMap(numAdjElems,nodeSetSize,nodeSetMap,srcMap) \
+
+#define copyNodeMap(numEntries,entrySize,map,srcMap) \
 do { \
-  for (int i=0;i<numAdjElems;i++){ \
-    for(int j=0;j<nodeSetSize;j++){ \
-      nodeSetMap[i][j] = srcMap[i][j]; \
+  for (int i=0;i<numEntries;i++){ \
+    for(int j=0;j<entrySize;j++){ \
+      map[i][j] = srcMap[i][j]; \
     } \
   } \
 } while (0) 
 
 
-void guessElementShape(int dim,int nodesPerElem,int *numAdjElems,int *nodeSetSize,int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE]){
+// Given the dimensions and nodes per element guess whether the element 
+// is a triangle, quad, tet or hex. At the moment these are the 4 shapes
+// that are handled  
+void guessElementShape(
+        const int dim, 
+        const int nodesPerElem, 
+        int* faceSize, 
+        int *faceMapSize, 
+        int* edgeMapSize,
+        int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE], 
+        int edgeMap[MAX_EDGES][2])
+{
     switch(dim){
         case 2:
             {
@@ -623,15 +1137,17 @@ void guessElementShape(int dim,int nodesPerElem,int *numAdjElems,int *nodeSetSiz
                 switch (nodesPerElem) {
                     case 3:
                         //Triangles
-                        *numAdjElems = 3;
-                        *nodeSetSize = 2;
-                        copyNodeSetMap(3,2,nodeSetMap,nodeSetMap2d_tri);
+                        *faceSize = 2;
+                        *faceMapSize = 3;
+                        *edgeMapSize = 0;
+                        copyNodeMap(3,2,faceMap,faceMap2d_tri);
                         break;
                     case 4:
                         //quads
-                        *numAdjElems = 4;
-                        *nodeSetSize = 2;
-                        copyNodeSetMap(4,2,nodeSetMap,nodeSetMap2d_quad);
+                        *faceSize = 2;
+                        *faceMapSize = 4;
+                        *edgeMapSize = 0;
+                        copyNodeMap(4,2,faceMap,faceMap2d_quad);
                         break;
                     default:
                         CkPrintf("Unknown element type\n");
@@ -645,15 +1161,19 @@ void guessElementShape(int dim,int nodesPerElem,int *numAdjElems,int *nodeSetSiz
                 switch(nodesPerElem){
                     case 4:
                         //Tetrahedra
-                        *numAdjElems = 4;
-                        *nodeSetSize = 3;
-                        copyNodeSetMap(4,3,nodeSetMap,nodeSetMap3d_tet);
+                        *faceSize = 3;
+                        *faceMapSize = 4;
+                        *edgeMapSize = 6;
+                        copyNodeMap(4,3,faceMap,faceMap3d_tet);
+                        copyNodeMap(6,2,edgeMap,edgeMap3d_tet);
                         break;
-                    case 6:
+                    case 8:
                         //Hexahedra
-                        *numAdjElems = 6;
-                        *nodeSetSize = 4;
-                        copyNodeSetMap(6,4,nodeSetMap,nodeSetMap3d_hex);
+                        *faceSize = 4;
+                        *faceMapSize = 6;
+                        *edgeMapSize = 12;
+                        copyNodeMap(6,4,faceMap,faceMap3d_hex);
+                        copyNodeMap(12,2,edgeMap,edgeMap3d_hex);
                         break;
                     default:
                         CkPrintf("Unknown element type\n");
index 17afcc5a593ecf60e7098a659a1ba85493ca49f0..d280f87fd2192b71e90b5812d6895aaba7ee1e7d 100644 (file)
 #include <algorithm>
 
 #define MAX_ADJELEMS 6
+#define MAX_FACE_SIZE 4
+#define MAX_EDGES 12
+
 #define MAX_NODESET_SIZE 4
 
 // Each instance of adaptAdj represents an element to 
 // element adjacency
 class adaptAdj{
- public:
-  int partID;   // partition ID
-  int localID;  // local entity ID on partition partID
-  int elemType; // element type (tri, quad, tet, hex, etc.)
-  adaptAdj():partID(-1),localID(-1),elemType(-1){};
-  adaptAdj(int _partID,int _localID,int _elemType) : partID(_partID), localID(_localID), elemType(_elemType){};
-  inline adaptAdj &operator=(const adaptAdj &rhs){
-    partID = rhs.partID;
-    localID = rhs.localID;
-    elemType = rhs.elemType;
-    return *this;
-  }
-  inline bool operator==(const adaptAdj &rhs) const{
-    return (partID==rhs.partID && localID==rhs.localID && elemType==rhs.elemType);
-  }
-  virtual void pup(PUP::er &p){
-    p | partID;
-    p | localID;
-    p | elemType;
-  }
+    public:
+        int partID;   // partition ID
+        int localID;  // local entity ID on partition partID
+        int elemType; // element type (tri, quad, tet, hex, etc.)
+        adaptAdj():partID(-1),localID(-1),elemType(-1){};
+        adaptAdj(int _partID,int _localID,int _elemType) : 
+            partID(_partID), 
+            localID(_localID), 
+            elemType(_elemType){};
+        inline adaptAdj &operator=(const adaptAdj &rhs){
+            partID = rhs.partID;
+            localID = rhs.localID;
+            elemType = rhs.elemType;
+            return *this;
+        }
+        inline bool operator==(const adaptAdj &rhs) const{
+            return (partID==rhs.partID && 
+                    localID==rhs.localID && 
+                    elemType==rhs.elemType);
+        }
+        virtual void pup(PUP::er &p){
+            p | partID;
+            p | localID;
+            p | elemType;
+        }
 };
 
 // Each adjElem describes an adjacency by enumerating
 // the nodes that form the "edge" shared by two 
 // adjacent elements
 class adjElem { // list entry for an element incident on a node
- public:
-  int elemID; // local element id
-  int nodeSetID; // which nodeSet in nodeSetMap does this nodeSet refer to
-  CkVec<int> nodeSet; //local node ids
-  adjElem *next;
-  adjElem(int nodeSetSize) : nodeSet(nodeSetSize){};
+    public:
+        int elemID; // local element id
+        int nodeSetID; // which nodeSet in nodeSetMap does this refer to
+        CkVec<int> nodeSet; //local node ids
+        adjElem *next;
+        adjElem(int nodeSetSize):
+            nodeSet(nodeSetSize){};
 };
 
 class adjNode { // struct to store each node's adjacency info
- public:       
-  int *sharedWithPartition; // array of partition IDs on which there is a corresponding
-                            // shared node; this is NULL if this is not a shared node
-  int *sharedWithLocalIdx;  // local Idx in idxl list with the corresponding chunk in sharedWithPartition
-  int numSharedPartitions;
-  int adjElemCount;         // number of entries in adjElemList (below)
-  // max length of adjElemList is 2*nodal degree
-  adjElem *adjElemList;     // list of elems incident on this node
-  adjNode() { 
-    sharedWithPartition = NULL;
-    adjElemList = new adjElem(0); // Create a dummy head node in the list
-    adjElemList->elemID = -1;
-    adjElemList->next = NULL;
-    adjElemCount = 0; 
-    numSharedPartitions=0;
-  }
-  ~adjNode(){ delete [] sharedWithPartition; delete [] sharedWithLocalIdx;}
+    public:    
+        int *sharedWithPartition; // array of partition IDs on which there 
+                                  // is a corresponding shared node; 
+                                  // this is NULL if this is not a shared node
+        int *sharedWithLocalIdx;  // local Idx in idxl list with the 
+                                  // corresponding chunk in sharedWithPartition
+        int numSharedPartitions;
+        int adjElemCount;         // number of entries in adjElemList (below)
+        // max length of adjElemList is 2*nodal degree
+        adjElem *adjElemList;     // list of elems incident on this node
+        adjNode() { 
+            sharedWithPartition = NULL;
+            adjElemList = new adjElem(0); // Create a dummy head node in the 
+                                          // list
+            adjElemList->elemID = -1;
+            adjElemList->next = NULL;
+            adjElemCount = 0; 
+            numSharedPartitions=0;
+        }
+        ~adjNode() { 
+            delete [] sharedWithPartition; 
+            delete [] sharedWithLocalIdx;
+        }
 };
 
 class adjRequest{
- public:
-  int elemID,chunkID,elemType,nodeSetID;
-  int translatedNodeSet[MAX_NODESET_SIZE];
-  adjRequest(): elemID(-1),chunkID(-1),elemType(-1){};
-  adjRequest(int _elemID,int _chunkID,int _nodeSetID,int _elemType ): elemID(_elemID),chunkID(_chunkID),nodeSetID(_nodeSetID), elemType(_elemType){};
-  adjRequest(const adjRequest &rhs){
-    *this = rhs;
-  }
-  inline adjRequest& operator=(const adjRequest &rhs){
-    elemID = rhs.elemID;
-    chunkID = rhs.chunkID;
-    elemType = rhs.elemType;
-    nodeSetID = rhs.nodeSetID;
-    memcpy(&translatedNodeSet[0],&(rhs.translatedNodeSet[0]),MAX_NODESET_SIZE*sizeof(int));
-    return *this;
-  }
-  virtual void pup(PUP::er &p){
-    p | elemID;
-    p | chunkID;
-    p | elemType;
-    p | nodeSetID;
-    p(translatedNodeSet,MAX_NODESET_SIZE);
-  }
+    public:
+        int elemID,chunkID,elemType,nodeSetID;
+        int translatedNodeSet[MAX_NODESET_SIZE];
+        adjRequest():
+            elemID(-1), 
+            chunkID(-1), 
+            elemType(-1){};
+        adjRequest(int _elemID,int _chunkID,int _nodeSetID,int _elemType ): 
+            elemID(_elemID),
+            chunkID(_chunkID),
+            nodeSetID(_nodeSetID),
+            elemType(_elemType){};
+        adjRequest(const adjRequest &rhs){
+            *this = rhs;
+        }
+        inline adjRequest& operator=(const adjRequest &rhs) {
+            elemID = rhs.elemID;
+            chunkID = rhs.chunkID;
+            elemType = rhs.elemType;
+            nodeSetID = rhs.nodeSetID;
+            memcpy(&translatedNodeSet[0],&(rhs.translatedNodeSet[0]),
+                    MAX_NODESET_SIZE*sizeof(int));
+            return *this;
+        }
+        virtual void pup(PUP::er &p){
+            p | elemID;
+            p | chunkID;
+            p | elemType;
+            p | nodeSetID;
+            p(translatedNodeSet,MAX_NODESET_SIZE);
+        }
 };
 
 class adjReply {
- public:
-  int requestingElemID,requestingNodeSetID;
-  adaptAdj replyingElem;
-  adjReply(): requestingElemID(-1),requestingNodeSetID(-1), replyingElem(){};
-  adjReply(const adjReply &rhs){
-    *this = rhs;
-  }
-  
-  inline adjReply& operator=(const adjReply &rhs){
-    requestingElemID = rhs.requestingElemID;
-    requestingNodeSetID = rhs.requestingNodeSetID;
-    replyingElem = rhs.replyingElem;
-               return *this;
-  }
-  virtual void pup(PUP::er &p){
-    p | requestingElemID;
-    p | requestingNodeSetID;
-    replyingElem.pup(p);
-  }
+    public:
+        int requestingElemID,requestingNodeSetID;
+        adaptAdj replyingElem;
+        adjReply(): 
+            requestingElemID(-1),
+            requestingNodeSetID(-1), 
+            replyingElem(){};
+        adjReply(const adjReply &rhs){
+            *this = rhs;
+        }
+        inline adjReply& operator=(const adjReply &rhs){
+            requestingElemID = rhs.requestingElemID;
+            requestingNodeSetID = rhs.requestingNodeSetID;
+            replyingElem = rhs.replyingElem;
+            return *this;
+        }
+        virtual void pup(PUP::er &p){
+            p | requestingElemID;
+            p | requestingNodeSetID;
+            replyingElem.pup(p);
+        }
 };
 
 
@@ -180,67 +205,166 @@ void CreateAdaptAdjacencies(int meshid, int elemType);
 
 // Access functions
 
-// 2D gets
-/** Look up elemID in elemType array, access edgeFaceID-th adaptAdj. */
-adaptAdj *GetAdaptAdj(int meshid, adaptAdj elem, int edgeFaceID);
-adaptAdj *GetAdaptAdj(FEM_Mesh *meshPtr, adaptAdj elem, int edgeFaceID);
-/** Look up elemID in elemType array, calculate edgeFaceID from
-    vertexList (with GetEdgeFace below), and access edgeFaceID-th
-    adaptAdj with GetAdaptAdj above. */
-adaptAdj *GetAdaptAdj(int meshid, adaptAdj elem, int *vertexList);
-
-// 3D gets
-adaptAdj *GetAdaptAdjOnEdge(int meshid, adaptAdj elem, int edgeID, int *size);
-adaptAdj *GetAdaptAdjOnEdge(FEM_Mesh *meshPtr, adaptAdj elem, int edgeID, int *size);
-adaptAdj *GetAdaptAdjOnFace(int meshid, adaptAdj elem, int faceID);
-adaptAdj *GetAdaptAdjOnFace(FEM_Mesh *meshPtr, adaptAdj elem, int faceID);
+// 2D accessors
+adaptAdj *getAdaptAdj(
+        const int meshID, 
+        const int localID, 
+        const int elemType,
+        const int edgeID);
+adaptAdj *getAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const int localID,
+        const int elemType, 
+        const int faceID);
+adaptAdj *getAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int* const vertexList);
+
+// 3D accessors
+CkVec<adaptAdj>* getEdgeAdaptAdj(
+        const int meshid, 
+        const int localID,
+        const int elemType,
+        const int edgeID);
+CkVec<adaptAdj>* getEdgeAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const int localID,
+        const int elemType,
+        int edgeID);
+CkVec<adaptAdj>* getEdgeAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int* const vertexList);
+
+adaptAdj* getFaceAdaptAdj(
+        const int meshID,
+        const int localID,
+        const int elemType, 
+        int faceID);
+adaptAdj* getFaceAdaptAdj(
+        const FEM_Mesh* const meshPtr,
+        const int localID,
+        const int elemType,
+        int faceID);
+adaptAdj* getFaceAdaptAdj(
+        const int meshID, 
+        const int localID,
+        const int elemType, 
+        const int* const vertexList);
 
 /** Look up elemID in elemType array and determine the set of vertices
     associated with the edge or face represented by edgeFaceID. */
 void GetVertices(int meshid, adaptAdj elem, int edgeFaceID, int *vertexList);
+
 /** Look up elemID in elemType array and determine the edge or face ID
     specified by the set of vertices in vertexList. */
-int GetEdgeFace(int meshid, adaptAdj elem, int *vertexList);
+int getElemFace(
+        const int meshID, 
+        const int type, 
+        const int* vertexList);
+int getElemEdge(
+        const int meshID, 
+        const int type, 
+        const int* vertexList);
 
 // Update functions
 /** 2D or 3D (faces): Look up elemID in elemType array and set the adjacency on
     edgeFaceID to nbr. */
-void SetAdaptAdj(int meshid, adaptAdj elem, int edgeFaceID, adaptAdj nbr);
+void setAdaptAdj(
+        const int meshid, 
+        const adaptAdj elem, 
+        const int faceID, 
+        const adaptAdj nbr);
 
 /** 3D: Look up elemID in elemType array and add nbr to the adjacency on
     edgeID. */
-void AddToAdaptAdj(int meshid, adaptAdj elem, int edgeID, adaptAdj nbr);
+void addToAdaptAdj(
+        const int meshid, 
+        const adaptAdj elem, 
+        const int edgeID, 
+        const adaptAdj nbr);
 /** 3D: Look up elemID in elemType array and remove nbr from the adjacency on
     edgeID. */
-void RemoveFromAdaptAdj(int meshid, adaptAdj elem, int edgeID, adaptAdj nbr);
-
-/** Substitute an old neighbor with a new neighbor, assumes 2D or 3D-face neighbor */
-void ReplaceAdaptAdj(int meshID, adaptAdj elem, adaptAdj originalNbr, 
-                    adaptAdj newNbr);
-void ReplaceAdaptAdj(FEM_Mesh *meshPtr, adaptAdj elem, adaptAdj originalNbr,
-                    adaptAdj newNbr);
-/** 3D edge neighbors: Substitution operation needs to know edgeID to reduce search space. */
-void ReplaceAdaptAdjOnEdge(int meshID, adaptAdj elem, adaptAdj originalNbr, 
-                    adaptAdj newNbr);
-void ReplaceAdaptAdjOnEdge(FEM_Mesh *meshPtr, adaptAdj elem, adaptAdj originalNbr,
-                    adaptAdj newNbr);
-
-/**given the dimensions and nodes per element guess whether the element 
- is a triangle, quad, tet or hex. At the moment these are the 4 shapes
- that are handled */
-void guessElementShape(int dim,int nodesPerElem,int *numAdjElems,
-                      int *nodeSetSize,
-                      int nodeSetMap[MAX_ADJELEMS][MAX_NODESET_SIZE]);
-void dumpAdaptAdjacencies(adaptAdj *adaptAdjacencies,int numElems,
-                         int numAdjElems,int myRank);
-void getAndDumpAdaptAdjacencies(int meshid, int numElems, int elemType, int myRank);
-void fillLocalAdaptAdjacencies(int numNodes, FEM_Node *node, adjNode *adaptAdjTable,
-                              adaptAdj *adaptAdjacencies, int nodeSetSize,
-                              int numAdjElems, int myRank, int elemType);
-void makeAdjacencyRequests(int numNodes, FEM_Node *node, adjNode *adaptAdjTable,
-                          MSA1DREQLIST *requestTable, int nodeSetSize, int myRank,
-                          int elemType);
-void replyAdjacencyRequests(MSA1DREQLIST *requestTable, MSA1DREPLYLIST *replyTable,
-                           FEM_Node *node, adjNode *adaptAdjTable, 
-                           adaptAdj *adaptAdjacencies, int nodeSetSize,
-                           int numAdjElems, int myRank, int elemType);
+void removeFromAdaptAdj(
+        const int meshid, 
+        const adaptAdj elem, 
+        const int edgeID, 
+        const adaptAdj nbr);
+
+/** Substitute an old neighbor with a new neighbor, assumes 2D or 3D-face 
+    neighbor */
+void replaceAdaptAdj(
+        const int meshID, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr, 
+        const adaptAdj newNbr);
+void replaceAdaptAdj(
+        const FEM_Mesh* const meshPtr, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr,
+        const adaptAdj newNbr);
+/** 3D edge neighbors: Substitution operation needs to know edgeID to reduce 
+    search space. */
+void replaceAdaptAdjOnEdge(
+        const int meshID, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr, 
+        const  adaptAdj newNbr);
+void replaceAdaptAdjOnEdge(
+        const FEM_Mesh* const meshPtr, 
+        const adaptAdj elem, 
+        const adaptAdj originalNbr, 
+        const adaptAdj newNbr);
+
+/** Given the dimensions and nodes per element guess whether the element 
+    is a triangle, quad, tet or hex. At the moment these are the 4 shapes
+    that are handled */
+void guessElementShape(
+        const int dim,
+        const int nodesPerElem,
+        int* faceSize, 
+        int *faceMapSize, 
+        int* edgeMapSize,
+        int faceMap[MAX_ADJELEMS][MAX_FACE_SIZE],
+        int edgeMap[MAX_EDGES][2]);
+void getAndDumpAdaptAdjacencies(
+        const int meshid, 
+        const int numElems, 
+        const int elemType, 
+        const int myRank);
+
+void fillLocalAdaptAdjacencies(
+        const int numNodes, 
+        FEM_Node* node, 
+        adjNode* faceTable, 
+        adjNode* edgeTable, 
+        const int faceMapSize,
+        const int edgeMapSize,
+        adaptAdj* adaptFaceAdjacencies,
+        CkVec<adaptAdj>** adaptEdgeAdjacencies, 
+        const int myRank, 
+        const int elemType);
+
+void makeAdjacencyRequests(
+        const int numNodes, 
+        FEM_Node* node, 
+        adjNode* adaptAdjTable,
+        MSA1DREQLIST* requestTable, 
+        const int nodeSetSize, 
+        const int myRank,
+        int elemType);
+void replyAdjacencyRequests(
+        MSA1DREQLIST* requestTable, 
+        MSA1DREPLYLIST* replyTable,
+        FEM_Node* node, 
+        adjNode* adaptAdjTable, 
+        adaptAdj* adaptFaceAdjacencies, 
+        CkVec<adaptAdj>** adaptEdgeAdjacencies, 
+        const int nodeSetSize,
+        const int numAdjElems, 
+        const int myRank, 
+        const int elemType,
+        bool isEdgeRequest);
index 28ff7e890fbcdb95c677368e9e9f25eebda06f70..55f0160ef25aba868edaa3c9344ff2d4ef409d25 100644 (file)
@@ -72,7 +72,7 @@ int BulkAdapt::edge_bisect_2D(int elemID, int elemType, int edgeID)
   // lock partitions for the two involved elements
   adaptAdj elemsToLock[2];
   adaptAdj startElem(partitionID, elemID, elemType);
-  adaptAdj nbrElem = *GetAdaptAdj(meshID, startElem, edgeID);
+  adaptAdj nbrElem = *getAdaptAdj(meshID, elemID, elemType, edgeID);
   BULK_DEBUG(printf("[%d] neighbor of elem %d is elem (%d,%d) \n",partitionID,elemID,nbrElem.partID,nbrElem.localID);)
   elemsToLock[0] = startElem;
   elemsToLock[1] = nbrElem;
@@ -106,8 +106,8 @@ int BulkAdapt::edge_bisect_2D(int elemID, int elemType, int edgeID)
     one_side_split_2D(nbrElem, nbrSplitElem, nbrEdgeID, &nbrNode1, &nbrNode2, &newNodeID, false);
 
     // now fix the adjacencies across the new edge to the two new elements
-    adaptAdj *splitElemAdaptAdj = GetAdaptAdj(meshID, splitElem, 0);
-    adaptAdj *nbrSplitElemAdaptAdj = GetAdaptAdj(meshID, nbrSplitElem, 0);
+    adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0);
+    adaptAdj *nbrSplitElemAdaptAdj = getAdaptAdj(meshID, nbrSplitElem.localID, nbrSplitElem.elemType, 0);
     nbrSplitElemAdaptAdj[nbrEdgeID] = splitElem;
     BULK_DEBUG(printf("[%d] For nbrSplitElem %d set adjacency to %d across splitEdge\n",partitionID,nbrSplitElem.localID,splitElem.localID);)
     // POST: start-side operations
@@ -115,7 +115,7 @@ int BulkAdapt::edge_bisect_2D(int elemID, int elemType, int edgeID)
     BULK_DEBUG(printf("[%d] For splitElem %d set adjacency to %d across splitEdge\n",partitionID,splitElem.localID,nbrSplitElem.localID);)
   }
   else if (nbrElem.partID == -1) { // startElem's edgeID is on domain boundary
-    adaptAdj *splitElemAdaptAdj = GetAdaptAdj(meshID, splitElem, 0);
+    adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0);
     splitElemAdaptAdj[edgeID] = adaptAdj(-1, -1, -1);
     BULK_DEBUG(printf("[%d] For splitElem %d splitEdge is on the domain boundary.\n",partitionID,splitElem.localID);)
   }
@@ -134,14 +134,18 @@ int BulkAdapt::edge_bisect_2D(int elemID, int elemType, int edgeID)
     
     adaptAdj nbrSplitElem = am->elem;
     // now fix the adjacencies across the new edge to remote new element
-    adaptAdj *splitElemAdaptAdj = GetAdaptAdj(meshID, splitElem, 0);
+    adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0);
     splitElemAdaptAdj[edgeID] = nbrSplitElem;
     BULK_DEBUG(printf("[%d] For splitElem %d set adjacency to %d across splitEdge\n",partitionID,splitElem.localID,nbrSplitElem.localID);)
   }    
 
   // unlock the two partitions
   localShadow->unlockRegion(lockRegionID);
-  dumpAdaptAdjacencies(GetAdaptAdj(meshID, adaptAdj(partitionID,0,elemType), 0),meshPtr->nElems(),3,partitionID);      
+  getAndDumpAdaptAdjacencies(
+          meshID, 
+          meshPtr->nElems(),
+          elemType,
+          partitionID);
   return 1;
 }
 
@@ -175,7 +179,7 @@ adaptAdj BulkAdapt::remote_edge_bisect_2D(adaptAdj nbrElem, adaptAdj splitElem,
   // split the local neighbor element, i.e. the second "side"
   one_side_split_2D(nbrElem, nbrSplitElem, nbrEdgeID, &nbrNode1, &nbrNode2, &newNodeID, false);
 
-  adaptAdj *nbrSplitElemAdaptAdj = GetAdaptAdj(meshPtr, nbrSplitElem, 0);
+  adaptAdj *nbrSplitElemAdaptAdj = getAdaptAdj(meshPtr, nbrSplitElem.localID, nbrSplitElem.elemType, 0);
   nbrSplitElemAdaptAdj[nbrEdgeID] = splitElem;
   BULK_DEBUG(printf("[%d] For nbrSplitElem %d set adjacency to %d across splitEdge\n",partitionID,nbrSplitElem.localID,splitElem.localID);)
   
@@ -215,8 +219,8 @@ int BulkAdapt::edge_bisect_3D(int elemID, int elemType, int edgeID)
   face[0] = 3 - (relNode[0] + relNode[1] + relNode[2]);
   face[1] = 3 - (relNode[0] + relNode[1] + relNode[3]);
   adaptAdj neighbors[2]; // startElem's neighbors
-  neighbors[0] = *GetAdaptAdj(meshID, startElem, face[0]);
-  neighbors[1] = *GetAdaptAdj(meshID, startElem, face[1]);
+  neighbors[0] = *getAdaptAdj(meshID, startElem.localID, startElem.elemType, face[0]);
+  neighbors[1] = *getAdaptAdj(meshID, startElem.localID, startElem.elemType, face[1]);
 
   bool completed=false;
   if ((neighbors[0].partID > -1) && (neighbors[0].partID == partitionID)) {
@@ -234,8 +238,8 @@ int BulkAdapt::edge_bisect_3D(int elemID, int elemType, int edgeID)
                                  &newNodeID, false);
     
     // now fix the adjacencies across the new edge to the two new elements
-    ReplaceAdaptAdj(meshID, splitElem, neighbors[0], nbrSplitElem);
-    ReplaceAdaptAdj(meshID, nbrSplitElem, startElem, splitElem);
+    replaceAdaptAdj(meshID, splitElem, neighbors[0], nbrSplitElem);
+    replaceAdaptAdj(meshID, nbrSplitElem, startElem, splitElem);
     BULK_DEBUG(printf("[%d] For nbrSplitElem %d set adjacency to %d across splitEdge\n",partitionID,nbrSplitElem.localID,splitElem.localID);)
     BULK_DEBUG(printf("[%d] For splitElem %d set adjacency to %d across splitEdge\n",partitionID,splitElem.localID,nbrSplitElem.localID);)
   }
@@ -261,8 +265,8 @@ int BulkAdapt::edge_bisect_3D(int elemID, int elemType, int edgeID)
                               &newNodeID, false);
       
       // now fix the adjacencies across the new edge to the two new elements
-      ReplaceAdaptAdj(meshID, splitElem, neighbors[1], nbrSplitElem);
-      ReplaceAdaptAdj(meshID, nbrSplitElem, startElem, splitElem);
+      replaceAdaptAdj(meshID, splitElem, neighbors[1], nbrSplitElem);
+      replaceAdaptAdj(meshID, nbrSplitElem, startElem, splitElem);
       BULK_DEBUG(printf("[%d] For nbrSplitElem %d set adjacency to %d across splitEdge\n",partitionID,nbrSplitElem.localID,splitElem.localID);)
       BULK_DEBUG(printf("[%d] For splitElem %d set adjacency to %d across splitEdge\n",partitionID,splitElem.localID,nbrSplitElem.localID);)
     }
@@ -374,8 +378,8 @@ void BulkAdapt::one_side_split_2D(adaptAdj &startElem, adaptAdj &splitElem,
   BULK_DEBUG(printf("[%d] new element %d with conn %d %d %d added \n", partitionID, splitElemID, splitConn[0], splitConn[1], splitConn[2]);)
   // copy startElem.localID's adapt adj for all edges.
   splitElem = adaptAdj(partitionID, splitElemID, startElem.elemType);
-  adaptAdj *startElemAdaptAdj = GetAdaptAdj(meshPtr, startElem, 0);
-  adaptAdj *splitElemAdaptAdj = GetAdaptAdj(meshPtr, splitElem, 0);
+  adaptAdj *startElemAdaptAdj = getAdaptAdj(meshPtr, startElem.localID, startElem.elemType, 0);
+  adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshPtr, splitElem.localID, startElem.elemType, 0);
   memcpy(splitElemAdaptAdj, startElemAdaptAdj, 3*sizeof(adaptAdj));
   adaptAdj startElemNbr;  // startElem's original nbr on the edge that will now border with splitElem
   if (startSide) {
@@ -397,11 +401,11 @@ void BulkAdapt::one_side_split_2D(adaptAdj &startElem, adaptAdj &splitElem,
     BULK_DEBUG(printf("[%d] For splitElem %d edge %d is now set to %d\n",partitionID,splitElem.localID,(edgeID+1)%3,startElem.localID));
   }
   if (startElemNbr.partID == startElem.partID) {
-    ReplaceAdaptAdj(meshPtr, startElemNbr, startElem, splitElem);
+    replaceAdaptAdj(meshPtr, startElemNbr, startElem, splitElem);
     BULK_DEBUG(printf("[%d] For startElemNbr %d replaced startElem %d with splitElem %d\n",partitionID,startElemNbr.localID,startElem.localID,splitElem.localID);)
   }
   else if (startElemNbr.partID != -1) { // startElemNbr exists and is remote
-    // need to call ReplaceAdaptAdj on startElemNbr.partID
+    // need to call replaceAdaptAdj on startElemNbr.partID
     shadowProxy[startElemNbr.partID].remote_adaptAdj_replace(startElemNbr, startElem, splitElem); 
   }
   // interpolate nodal data, copy startElem data to splitElem
@@ -426,7 +430,7 @@ bool BulkAdapt::one_side_split_3D(adaptAdj &startElem, adaptAdj &splitElem,
 
 void BulkAdapt::remote_adaptAdj_replace(adaptAdj elem, adaptAdj oldElem, adaptAdj newElem)
 {
-  ReplaceAdaptAdj(meshPtr, elem, oldElem, newElem);
+  replaceAdaptAdj(meshPtr, elem, oldElem, newElem);
 }
 
 /* LOCAL HELPERS FOR BULK ADAPTIVITY OPERATIONS */
index 9bd46748cca080047234fcca7837afab460e7bab..a8471e69ad5b90fdc9abd3dc071b3f5401be4c81 100644 (file)
@@ -1524,17 +1524,21 @@ void FEM_Entity::create(int attr,const char *caller) {
        chunkNo->setWidth(1);
   }
   else if(attr == FEM_BOUNDARY){
-       allocateBoundary();
-  }else if(attr == FEM_ADAPT_ADJ){
-               FEM_DataAttribute *adaptAdj = new FEM_DataAttribute(this,attr);
-               adaptAdj->setDatatype(FEM_BYTE);
-               add(adaptAdj);
-       }else if(attr == FEM_ADAPT_LOCK){
-               FEM_DataAttribute *adaptLock = new FEM_DataAttribute(this,attr);
-               adaptLock->setDatatype(FEM_INT);
-               adaptLock->setWidth(2);
-               add(adaptLock);
-       }
+      allocateBoundary();
+  }else if(attr == FEM_ADAPT_FACE_ADJ){
+      FEM_DataAttribute *adaptAdj = new FEM_DataAttribute(this,attr);
+      adaptAdj->setDatatype(FEM_BYTE);
+      add(adaptAdj);
+  }else if(attr == FEM_ADAPT_EDGE_ADJ){
+      FEM_DataAttribute *adaptAdj = new FEM_DataAttribute(this,attr);
+      adaptAdj->setDatatype(FEM_BYTE);
+      add(adaptAdj);
+  }else if(attr == FEM_ADAPT_LOCK){
+      FEM_DataAttribute *adaptLock = new FEM_DataAttribute(this,attr);
+      adaptLock->setDatatype(FEM_INT);
+      adaptLock->setWidth(2);
+      add(adaptLock);
+  }
   else {
        //It's an unrecognized tag: abort
        char attrNameStorage[256], msg[1024];