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 };