00001 #ifndef EDGE_H
00002 #define EDGE_H
00003 
00004 #include "charm++.h"
00005 #include "node.h"
00006 #include "ref.h"
00007 #include "refine.decl.h"
00008 
00009 class edge {
00010  public:
00011   int pending, newNodeIdx;
00012   double length;
00013   elemRef waitingFor;
00014   node newNode;
00015   int incidentNode, fixNode;
00016   int boundary;
00017   edgeRef newEdgeRef; 
00018   chunk *C;
00019   edgeRef myRef;
00020   elemRef elements[2];  
00021   int nodes[2];  
00022   int present;  
00023   edge() { unsetPending(); present = 0; }
00024   edge(int idx, int cid, chunk *myChk) { 
00025     unsetPending(); myRef.set(cid, idx); C = myChk; present = 1;
00026     nodes[0] = nodes[1] = -1;
00027   }
00028   edge(elemRef e1, elemRef e2, int p) {
00029     elements[0] = e1;  elements[1] = e2;  pending = p; 
00030   }
00031   edge(elemRef e1, elemRef e2) {
00032     elements[0] = e1;  elements[1] = e2;  unsetPending();
00033   }
00034   edge(const edge& e) {
00035     for (int i=0; i<2; i++)  elements[i] = e.elements[i];
00036     pending = e.pending;
00037     newNodeIdx = e.newNodeIdx;
00038     C = e.C;
00039     waitingFor = e.waitingFor;
00040     newNode = e.newNode;
00041     incidentNode = e.incidentNode;
00042     fixNode = e.fixNode;
00043     newEdgeRef = e.newEdgeRef;
00044     myRef = e.myRef;
00045     present = e.present;
00046     length = e.length;
00047     boundary = e.boundary;
00048     nodes[0] = e.nodes[0];
00049     nodes[1] = e.nodes[1];
00050   }
00051   void set(int idx, int cid, chunk *myChk)  { 
00052     unsetPending(); myRef.set(cid, idx); C = myChk; present = 1;
00053   }
00054   void set(elemRef e1, elemRef e2) { elements[0] = e1;  elements[1] = e2; }
00055   void set(elemRef *e) { elements[0] = e[0]; elements[1] = e[1]; }
00056   void setNodes(int n1, int n2) { nodes[0] = n1; nodes[1] = n2; CkAssert(n1!=n2);}
00057   void setBoundary(int b) { boundary = b;}
00058   int getBoundary() { return boundary;}
00059   void reset();
00060   edge& operator=(const edge& e) { 
00061     for (int i=0; i<2; i++)  elements[i] = e.elements[i];
00062     pending = e.pending;
00063     newNodeIdx = e.newNodeIdx;
00064     C = e.C;
00065     waitingFor = e.waitingFor;
00066     newNode = e.newNode;
00067     incidentNode = e.incidentNode;
00068     fixNode = e.fixNode;
00069     newEdgeRef = e.newEdgeRef;
00070     myRef = e.myRef;
00071     present = e.present;
00072     boundary = e.boundary;
00073     nodes[0] = e.nodes[0];
00074     nodes[1] = e.nodes[1];
00075     return *this; 
00076   }
00077   int isPresent() { return present; }
00078   void update(elemRef oldval, elemRef newval) {
00079     CkAssert((elements[0] == oldval) || (elements[1] == oldval));
00080     if (elements[0] == oldval)  elements[0] = newval;
00081     else  elements[1] = newval;
00082   }
00083   void updateNode(int oldval, int newval) {
00084     CkAssert((nodes[0] == oldval) || (nodes[1] == oldval));
00085     if (nodes[0] == oldval)  nodes[0] = newval;
00086     else  nodes[1] = newval;
00087   }
00088   elemRef& getElement(int idx) {
00089     CkAssert((idx==0) || (idx==1));
00090     return elements[idx];
00091   }
00092   elemRef& getNot(elemRef er) {
00093     CkAssert((elements[0] == er) || (elements[1] == er));
00094     if (elements[0] == er) return elements[1];
00095     else return elements[0];
00096   }
00097   void setPending() { pending = 1; }
00098   void unsetPending() { pending = 0; }
00099   int isPending(elemRef e);
00100   void checkPending(elemRef e);
00101   void checkPending(elemRef e, elemRef ne);
00102   int split(int *m, edgeRef *e_prime, int oIdx, int fIdx,
00103         elemRef requester, int *local, int *first, int *nullNbr);
00104   void collapse(elemRef requester, int kIdx, int dIdx, elemRef kNbr,
00105         elemRef dNbr, edgeRef kEdge, edgeRef dEdge, node newN, 
00106         double frac);
00107   int flipPrevent(elemRef requester, int kIdx, int dIdx, elemRef kNbr,
00108            elemRef dNbr, edgeRef kEdge, edgeRef dEdge, node newN);
00109   int existsOn(FEM_Comm_Rec *cl, int chunkID) {
00110     int count = cl->getShared();
00111     for (int i=0; i<count; i++) {
00112       if (chunkID == cl->getChk(i)) return i;
00113     }
00114     return -1;
00115   }
00116   void translateSharedNodeIDs(int *kIdx, int *dIdx, elemRef req);
00117   void unlockCloudRemoveEdge(int dIdxlShared, int kIdxlShared, 
00118                  FEM_Comm_Rec *dNodeRec, FEM_Comm_Rec *kNodeRec);
00119   void localCollapse(int kIdx, int dIdx, elemRef *req, node *newNode, 
00120              double frac, elemRef *keepNbr, elemRef *delNbr, 
00121              edgeRef *kEdge, edgeRef *dEdge, int local, int first);
00122   void updateCloud(int kIdx, int dIdx, node newNode, int *dIdxl, int *kIdxl,
00123            FEM_Comm_Rec **dNodeRec, FEM_Comm_Rec **kNodeRec);
00124   int buildLockingCloud(int kIdx, int dIdx, elemRef *req, elemRef *nbr);
00125   void sanityCheck(chunk *c, edgeRef shouldRef);
00126   void sanityCheck(int node1, int node2, int eIdx);
00127 };
00128 
00129 #endif