00001 
00002 
00003 
00004 #include <math.h>
00005 #include <vector>
00006 #include "charm++.h"
00007 #include "tcharm.h"
00008 #include "charm-api.h"
00009 
00010 
00011 
00012 #define LOCAL_FIRST 0x2
00013 #define LOCAL_SECOND 0x0
00014 #define BOUND_FIRST 0x3
00015 #define BOUND_SECOND 0x1
00016 
00017 class node;
00018 class chunk;
00019 class elemRef;
00020 
00021 
00022 
00023 
00024 
00025 class objRef {
00026  public:
00027   int cid, idx;
00028   objRef() { cid = -1;  idx = -1; }
00029   objRef(int chunkId, int objIdx) { cid = chunkId; idx = objIdx; }
00030   void init() { cid = -1; idx = -1; }
00031   void init(int chunkId, int objIdx) { cid = chunkId; idx = objIdx; }
00032   int operator==(const objRef& o) const { return((cid == o.cid) && (idx == o.idx)); }
00033   int operator!=(const objRef& o) const { return !( (*this)==o ); }
00034   int isNull(void) const {return cid==-1;}
00035   void sanityCheck(chunk *C);
00036   void pup(PUP::er &p) { p(cid); p(idx); }
00037 };
00038 
00039 
00040 
00041 class edgeRef : public objRef {
00042  public:
00043   edgeRef() :objRef() {}
00044   edgeRef(int c,int i) :objRef(c,i) {}
00045 
00046   void updateElement(chunk *C, elemRef oldval, elemRef newval);
00047   int lock(chunk *C);
00048   void unlock(chunk *C);
00049   int locked(chunk *C) const;
00050 };
00051 
00052 class elemRef : public objRef {
00053  public:
00054   elemRef() : objRef() {}
00055   elemRef(int c, int i) : objRef(c,i) {}
00056 
00057   int checkIfLongEdge(chunk *C, edgeRef e);
00058   double getArea(chunk *C);
00059   void setTargetArea(chunk *C, double ta);
00060   void updateEdges(chunk *C, edgeRef e0, edgeRef e1, edgeRef e2);
00061   void unsetDependency(chunk *C);
00062   void setDependent(chunk *C, int anIdx, int aCid);
00063   int hasDependent(chunk *C);
00064 };
00065 
00066 #include "refine.decl.h"
00067 
00068 extern CProxy_chunk mesh;
00069 CtvExtern(chunk *, _refineChunk);
00070 
00071 
00072 
00073 class chunkMsg : public CMessage_chunkMsg {
00074  public:
00075   int nChunks;
00076   CProxy_TCharm myThreads;
00077 };
00078 
00079 
00080 class refMsg : public CMessage_refMsg {
00081  public:
00082   objRef aRef;
00083   int idx;
00084 };
00085 
00086 
00087 class doubleMsg : public CMessage_doubleMsg {
00088  public:
00089   double aDouble;
00090 };
00091 
00092 
00093 class intMsg : public CMessage_intMsg {
00094  public:
00095   int anInt;
00096 };
00097 
00098 
00099 
00100 class node {
00101   
00102 
00103   
00104   double x, y;  
00105   chunk *C;
00106 
00107  public:
00108   
00109   node() { C = NULL; }
00110   node(double a, double b) { init(a,b); }
00111 
00112   
00113   
00114   void init() { x = -1.0; y = -1.0; C = NULL; }
00115   void init(double a, double b) { x = a; y = b; }
00116   void init(chunk *cPtr) { C = cPtr; }
00117   void init(double a, double b, chunk *cPtr) { x = a; y = b; C = cPtr; }
00118 
00119   
00120   node& operator=(const node& n) { x = n.x; y = n.y; return *this; }
00121   
00122   int operator==(const node& n) const { return ((x == n.x) && (y == n.y)); }
00123 
00124   
00125   double X() const { return x; }
00126   double Y() const { return y; }
00127 
00128   
00129   double distance(const node& n) const {
00130     double dx = n.x - x, dy = n.y - y;
00131     return (sqrt ((dx * dx) + (dy * dy)));
00132   }
00133 
00134   
00135   void midpoint(const node& n, node *result) const {
00136     result->x = (x + n.x) / 2.0;  result->y = (y + n.y) / 2.0;
00137   }
00138 };
00139 
00140 
00141 class edge {
00142   
00143   
00144   
00145 
00146   
00147   
00148   
00149   
00150   
00151   
00152   
00153   
00154   edgeRef myRef;
00155   chunk *C;
00156   int theLock;  
00157 
00158  public:
00159   elemRef elements[2];
00160 
00161   
00162   edge() { 
00163     for (int i=0; i<2; i++)
00164       elements[i].init();
00165     myRef.init();  C = NULL;  theLock = 0; 
00166   }
00167   
00168   void sanityCheck(chunk *C,edgeRef ref);
00169   
00170   
00171   
00172   void init() { theLock = 0; } 
00173   void init(int i, chunk *cPtr);
00174   void init(elemRef *e, int i, chunk *cPtr);
00175 
00176   
00177   
00178   
00179   
00180   void updateElement(elemRef oldval, elemRef newval);
00181   const edgeRef &getRef() const { return myRef; } 
00182 
00183   
00184   
00185   
00186   const elemRef &getNbrRef(const elemRef &er) { 
00187     if (er == elements[0])
00188       return elements[1];
00189     else if (!(er == elements[1]))
00190       CkAbort("ERROR: edge::getNbrRef: input edgeRef not on edge\n");
00191     return elements[0];
00192   }
00193   
00194   void lock() { theLock = 1; }
00195   void unlock() { theLock = 0; }
00196   int locked() { return theLock; }
00197 };
00198 
00199 class element {
00200   
00201   
00202   
00203 
00204   
00205   
00206   
00207   
00208   
00209   double targetArea, currentArea;
00210 
00211   
00212   
00213   
00214   
00215   
00216   
00217   
00218   int depend;
00219   
00220   
00221   elemRef dependent;
00222 
00223   
00224   
00225   int specialRequest, pendingRequest, requestResponse;
00226   elemRef specialRequester;
00227   node newNode, otherNode;
00228   edgeRef newLongEdgeRef;
00229   
00230   
00231   elemRef myRef;
00232   chunk *C;
00233 
00234  public:
00235   
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243   int nodes[3];
00244   edgeRef edges[3];
00245   
00246   element(); 
00247   
00248   void sanityCheck(chunk *C,elemRef ref);
00249     
00250   
00251   
00252   void init(); 
00253   void init(int *n, edgeRef *e, int index, chunk *chk);
00254   void init(int *n, int index, chunk *chk);
00255   void updateEdge(int idx, edgeRef e) { edges[idx] = e; }
00256   void updateEdges(edgeRef e0, edgeRef e1, edgeRef e2);
00257   
00258   
00259   node getNode(int i) const;
00260   const edgeRef &getEdge(int i) const { return edges[i]; }
00261   
00262   int getOpNode(int e) { return (e+2)%3; }
00263   
00264   int getOtherNode(int e) { return e; }
00265   
00266   elemRef getNeighbor(int e) const;
00267   
00268   
00269   
00270   
00271   double getArea();
00272   void calculateArea();
00273   void setTargetArea(double area) {
00274     if (((targetArea > area) || (targetArea < 0.0))  &&  (area >= 0.0))
00275       targetArea = area;
00276   }
00277   double getTargetArea() { return targetArea; }
00278   double getCachedArea() { return currentArea; }
00279 
00280   
00281   void setDependency() { depend = 1; }
00282   void unsetDependency() { depend = 0; }
00283   int hasDependency() { return (depend); }
00284 
00285   
00286   void setDependent(elemRef e) { dependent = e; }
00287   void setDependent(int cId, int i) { dependent.cid = cId; dependent.idx = i; }
00288   void unsetDependent() { dependent.idx = dependent.cid = -1; }
00289   int hasDependent() { return ((dependent.idx!=-1) && (dependent.cid!=-1)); }
00290   void tellDepend() {
00291     if (hasDependent()) {
00292       dependent.unsetDependency(C);
00293       unsetDependent();
00294     }
00295   }
00296     
00297   
00298   
00299   
00300   
00301   
00302   
00303   
00304   
00305   
00306   
00307   
00308   
00309   
00310   
00311   
00312   
00313   void setSpecialRequest(elemRef r) { specialRequest=1; specialRequester=r; }
00314   int isSpecialRequest() { return (specialRequest == 1); }
00315   int isPendingRequest() { return (pendingRequest == 1); }
00316   int isRequestResponse() { return (requestResponse == 1); }
00317   void setRequestResponse(node n, node o, edgeRef e) { 
00318     requestResponse = 1; 
00319     newNode = n;
00320     otherNode = o;
00321     newLongEdgeRef = e;
00322   }
00323 
00324   
00325   
00326   
00327   
00328   
00329   
00330   
00331   
00332   
00333   
00334   void refine();
00335   
00336   
00337   
00338   
00339   
00340   void refineNeighbor(int longEdge);
00341   
00342   
00343   
00344   
00345   
00346   
00347   void splitBorder(int longEdge);
00348   void splitNeighbors(int longEdge);
00349   
00350   
00351   
00352   void splitBorderLocal(int longEdge, int opnode, int othernode, int modEdge);
00353   void splitNeighborsLocal(int longEdge, int opnode, int othernode, 
00354                int modEdge, int nbrLongEdge, int nbrOpnode,
00355                int nbrOthernode, int nbrModEdge, const elemRef &nbr);
00356   
00357   
00358   
00359   
00360   
00361   
00362   
00363   
00364   
00365   
00366   void splitHelp(int longEdge);
00367   void splitResponse(int longEdge);
00368 
00369   
00370   
00371   
00372   int findLongestEdge();
00373   
00374   
00375   
00376   
00377   int checkNeighbor(int longEdge);
00378   
00379   int checkIfLongEdge(edgeRef e);
00380 };
00381 
00386 class refineClient {
00387 public:
00388   virtual ~refineClient() {}
00389 
00430   virtual void split(int triNo,int edgeOfTri,int movingNode,double frac) =0;
00431   virtual void split(int triNo,int edgeOfTri,int movingNode,double frac,int flags) =0;
00432 
00433 };
00434 
00435 class refineResults; 
00436 
00437 
00438 class chunk : public TCharmClient1D {
00439   
00440   
00441   
00442 
00443   
00444   int sizeElements, sizeEdges, sizeNodes;
00445   
00446   
00447   
00448   
00449   
00450   int debug_counter, refineInProgress, modified;
00451 
00452   
00453   
00454   
00455   
00456   
00457   
00458   
00459   
00460   
00461   int meshLock, meshExpandFlag;
00462 
00463   
00464   void deriveNodes();
00465   int edgeLocal(elemRef e1, elemRef e2);
00466   int findEdge(int n1, int n2);
00467   int addNewEdge();
00468   int getNbrRefOnEdge(int n1, int n2, int *conn, int nGhost, int *gid, 
00469               int idx, elemRef *er);
00470   int hasEdge(int n1, int n2, int *conn, int idx);
00471   
00472  public:
00473   refineResults *refineResultsStorage;
00474  
00475   
00476   int cid;
00477   int numElements, numEdges, numNodes, numGhosts, numChunks;
00478   std::vector<element> theElements;
00479   std::vector<edge> theEdges;
00480   std::vector<node> theNodes;
00481 
00482   
00483   refineClient *theClient;
00484 
00485   
00486   chunk(chunkMsg *);
00487   chunk(CkMigrateMessage *m) : TCharmClient1D(m) { };
00488   
00489   void sanityCheck(void);
00490   
00491   void setupThreadPrivate(CthThread forThread) {
00492     CtvAccessOther(forThread, _refineChunk) = this;
00493   }
00494   
00495   
00496   
00497   void refineElement(int i, double area);
00498   
00499   void refiningElements();
00500 
00501   
00502   
00503   void updateElement(int i, objRef oldval, objRef newval);
00504   void specialRequest(int reqestee, elemRef requester);
00505   void specialRequestResponse(int i, double newNodeX, double newNodeY, 
00506                   double otherNodeX, double otherNodeY, 
00507                   edgeRef newLongEdgeRef);
00508   doubleMsg *getArea(int i);
00509   intMsg *lock(int i);
00510   void unlock(int i);
00511   intMsg *locked(int i);
00512   intMsg *checkElement(objRef oR, int i);
00513   refMsg *getNeighbor(objRef oR, int i);
00514   void setTargetArea(int i, double area);
00515   void updateEdges(int i, edgeRef e0, edgeRef e1, edgeRef e2);
00516   void unsetDependency(int i);
00517   void setDependent(objRef oR, int i);
00518   intMsg *hasDependent(int i);
00519 
00520   
00521   void accessLock();  
00522   void releaseLock(); 
00523   void adjustFlag();  
00524   void adjustLock();  
00525   void adjustRelease();  
00526 
00527   
00528   void print();
00529 
00530   
00531 
00532   
00533 
00534   
00535   void updateNodeCoords(int nNode, double *coord, int nEl);
00536   
00537   
00538   
00539   
00540   void multipleRefine(double *desiredArea, refineClient *client);
00541   void newMesh(int nEl, int nGhost,const int *conn_,const int *gid_, int idxOffset);
00542   void addRemoteEdge(int elem, int localEdge, edgeRef er);
00543 
00544   
00545   
00546   void setModified() { modified = 1; }
00547   int isModified() { return modified; }
00548   void setRefining() { refineInProgress = 1; }
00549   int isRefining() { return refineInProgress; }
00550 
00551   
00552   void allocMesh(int nEl);
00553   void adjustMesh();
00554   int addNode(node n);
00555   edgeRef addEdge();
00556   elemRef addElement(int n1, int n2, int n3);
00557   elemRef addElement(int n1, int n2, int n3,
00558              edgeRef er1, edgeRef er2, edgeRef er3);
00559 
00560   void debug_print(int c);  
00561   void out_print();  
00562 };