00001 
00002 
00003 #ifndef TRI_H
00004 #define TRI_H
00005 
00006 #include <vector>
00007 #include "charm++.h"
00008 #include "tcharm.h"
00009 #include "charm-api.h"
00010 #include "ref.h"
00011 #include "node.h"
00012 #include "edge.h"
00013 #include "element.h"
00014 #include "refine.decl.h"
00015 #include "messages.h"
00016 #include "mpi.h"
00017 
00018 #define REFINE_PRECISION 0.8
00019 #define COARSEN_PRECISION 0.8
00020 #define QUALITY_MIN 0.5
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 extern CProxy_chunk mesh;
00029 class chunk;
00030 CtvExtern(chunk *, _refineChunk);
00031 
00032 
00037 class refineClient {
00038 public:
00039   virtual ~refineClient() {}
00040 
00074   
00075   virtual void split(int triNo,int edgeOfTri,int movingNode,double frac) {};
00076   
00077   
00078   
00079   
00080  
00081 
00082 
00083 
00084 virtual void split(int tri, int A, int B, int C,  
00085          int D, int _new, double frac,int flag, int origEdgeB, int newEdge1B, 
00086          int newEdge2B){};
00087 
00088                  
00089   
00090   
00091   
00092   
00093   virtual void collapse(int elemId, int nodeToKeep, int nodeToDelete, double newX, double newY, int flag, int updatedEdgeBoundary, double frac) {};
00094   
00095   
00096   virtual void nodeUpdate(int nodeID, double newX, double newY, int boundaryFlag, int shareCount, int *adjChunks, int *adjIndices){};
00097   
00098   virtual void nodeReplaceDelete(int elementID, int relnodeID, int oldNodeID, int newNodeID){};
00099  
00100  
00101 
00102 
00103 
00104 };
00105 
00106 class refineResults; 
00107 class coarsenResults; 
00108 
00109 typedef struct prioLockStruct {
00110   int holderIdx;
00111   int holderCid;
00112   double prio;
00113   prioLockStruct *next;
00114 } *prioLockRequests;
00115 
00116 
00117 class chunk : public TCharmClient1D {
00118   
00119   int sizeElements, sizeEdges, sizeNodes;
00120   
00121   int firstFreeElement, firstFreeEdge, firstFreeNode;
00122 
00123   int edgesSent, edgesRecvd, first;
00124   
00125  typedef struct {
00126     int elID;
00127     double len;
00128   } elemHeap; 
00129   elemHeap *coarsenElements;
00130   elemHeap *refineElements;
00131   elemHeap *refineStack; 
00132   int refineTop, refineHeapSize, coarsenHeapSize; 
00133 
00134   void setupThreadPrivate(CthThread forThread) {
00135     CtvAccessOther(forThread, _refineChunk) = this;
00136   }
00137   
00138   int *conn, *gid, additions;
00139   
00140   
00141   
00142   
00143   int debug_counter, refineInProgress, coarsenInProgress;
00144 
00145   
00146   
00147   
00148   
00149   
00150   
00151   
00152   
00153   
00154   int meshLock, meshExpandFlag;
00155 
00156   
00157   void deriveNodes();
00158   int edgeLocal(elemRef e1, elemRef e2);
00159   int getNbrRefOnEdge(int n1, int n2, int *conn, int nGhost, int *gid, 
00160               int idx, elemRef *er);
00161   int hasEdge(int n1, int n2, int *conn, int idx);
00162   
00163  public:
00164   
00165   
00166   
00167   int cid, numElements, numEdges, numNodes, numGhosts, numChunks;
00168   
00169   int meshID;
00170   FEM_Mesh *meshPtr;
00171 
00172   refineResults *refineResultsStorage;
00173   coarsenResults *coarsenResultsStorage;
00174 
00175   
00176   std::vector<element> theElements;
00177   std::vector<edge> theEdges;
00178   std::vector<node> theNodes;
00179 
00180   
00181   refineClient *theClient;
00182 
00183   
00184   int elementSlots, edgeSlots, nodeSlots;
00185 
00186   int lock, lockHolderIdx, lockHolderCid, lockCount;
00187   double lockPrio;
00188   prioLockRequests lockList;
00189 
00190   
00191   chunk(chunkMsg *);
00192   chunk(CkMigrateMessage *m) : TCharmClient1D(m) { };
00193   
00194   void sanityCheck(void);
00195   void validCheck(void);
00196  
00197   
00198   void deriveBoundaries(int *conn, int *gid);
00199   void tweakMesh();
00200   void improveChunk();
00201   void improve();
00202   
00203   
00204   
00205   void deriveEdges(int *conn, int *gid, const int *edgeBounds, const int *edgeConn,
00206            int nEdges);
00207 
00208   
00209   void refineElement(int idx, double area);
00210   
00211   void refiningElements();
00212 
00213   
00214   void coarsenElement(int idx, double area);
00215   
00216   void coarseningElements();
00217 
00218   
00219   
00220   intMsg *safeToMoveNode(int idx, double x, double y);
00221   splitOutMsg *split(int idx, elemRef e, int oIdx, int fIdx);
00222   void collapse(int idx, elemRef e, int kIdx, int dIdx, elemRef kNbr, 
00223         elemRef dNbr, edgeRef kEdge, edgeRef dEdge, node newN,
00224         double frac);
00225   splitOutMsg *flipPreventE(int idx, elemRef e, int kIdx, int dIdx,
00226                 elemRef kNbr, elemRef dNbr, edgeRef kEdge, 
00227                 edgeRef dEdge, node newN);
00228   void nodeReplaceDelete(int kIdx, int dIdx, node nn, int shared, int *chk, 
00229              int *idx);
00230   boolMsg *flipPrevent(int kIdx, int dIdx, node nn, int shared, int *chk, 
00231              int *idx);
00232   intMsg *isPending(int idx, objRef e);
00233   void checkPending(int idx, objRef aRef);
00234   void checkPending(int idx, objRef aRef1, objRef aRef2);
00235   void updateElement(int idx, objRef oldval, objRef newval, int b);
00236   void updateElementEdge(int idx, objRef oldval, objRef newval);
00237   void updateReferences(int idx, objRef oldval, objRef newval);
00238   doubleMsg *getArea(int n);
00239   void resetEdge(int n);
00240   refMsg *getNbr(int idx, objRef aRef);
00241   void setTargetArea(int idx, double aDouble);
00242   void resetTargetArea(int idx, double aDouble);
00243   void reportPos(int idx, double x, double y);
00244 
00245   
00246   void accessLock();  
00247   void releaseLock(); 
00248   void adjustFlag();  
00249   void adjustLock();  
00250   void adjustRelease();  
00251 
00252   
00253   void print();
00254 
00255   
00256   
00257   void newMesh(int meshID_,int nEl, int nGhost,const int *conn_,const 
00258            int *gid_, int nnodes, const int *boundaries, int nEdges,
00259            const int *edgeConn, const int *edgeBounds, int idxOffset);
00260   
00261   void multipleRefine(double *desiredArea, refineClient *client);
00262   
00263   void multipleCoarsen(double *desiredArea, refineClient *client);
00264   
00265   void updateNodeCoords(int nNode, double *coord, int nEl);
00266 
00267 
00268   
00269   void addRemoteEdge(int elem, int localEdge, edgeRef er);
00270 
00271   
00272   
00273   void setRefining() { refineInProgress = 1; }
00274   int isRefining() { return refineInProgress; }
00275 
00276   
00277   void allocMesh(int nEl);
00278   void adjustMesh();
00279   intMsg *addNode(node n, int b1, int b2, int internal);
00280   
00281   edgeRef addEdge(int n1, int n2, int b);
00282   edgeRef addEdge(int n1, int n2, const int *edgeBounds,const int *edgeConn, int nEdges); 
00283   elemRef addElement(int n1, int n2, int n3);
00284   elemRef addElement(int n1, int n2, int n3,
00285               edgeRef er1, edgeRef er2, edgeRef er3);
00286   void removeNode(int n);
00287   void removeEdge(int n);
00288   void removeElement(int n);
00289   
00290   void debug_print(int c);
00291   void out_print();
00292   void dump();
00293 
00294   intMsg *lockChunk(int lhc, int lhi, double prio);
00295   void unlockChunk(int lhc, int lhi);
00296   int lockLocalChunk(int lhc, int lhi, double prio);
00297   void unlockLocalChunk(int lhc, int lhi);
00298   void removeLock(int lhc, int lhi);
00299   void insertLock(int lhc, int lhi, double prio);
00300   void fixNode(int nIdx, int chkid);
00301   int joinCommLists(int nIdx, int shd, int *chk, int *idx, int *rChk, 
00302             int *rIdx);
00303   void addToStack(int eIdx, double len, int cFlag);
00304   void rebubble(int cFlag);
00305   void Insert(int elID, double len, int cFlag);
00306   int Delete_Min(int cFlag);
00307 
00308   intMsg *getBoundary(int edgeIdx);
00309 
00310   void incnonCoarsen(int idx);
00311   void resetnonCoarsen(int idx);
00312   intMsg *neighboring(int idx, elemRef e);
00313   intMsg *safeToCoarsen(int idx, edgeRef e);
00314 };
00315 
00316 #endif