00001 #ifndef ELEMENT_H
00002 #define ELEMENT_H
00003
00004 #include <math.h>
00005 #include "ref.h"
00006 #include "refine.decl.h"
00007
00008
00009
00010 #define LOCAL_FIRST 0x2
00011 #define LOCAL_SECOND 0x0
00012 #define BOUND_FIRST 0x3
00013 #define BOUND_SECOND 0x1
00014
00015 extern CProxy_chunk mesh;
00016
00017 class element {
00018
00019
00020
00021
00022
00023
00024
00025
00026 double targetArea, currentArea;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 public:
00037 int nodes[3];
00038 edgeRef edges[3];
00039 elemRef myRef;
00040 chunk *C;
00041 int present;
00042 short nonCoarsenCount;
00043
00045 element() { targetArea = currentArea = -1.0; nonCoarsenCount = 0; }
00046 element(int cid, int idx, chunk *C) { set(); set(cid, idx, C); }
00047 element(int *n) { set(); set(n); }
00048 element(int *n, edgeRef *e) { set(); set(n, e); }
00049 element(int n1, int n2, int n3, edgeRef e1, edgeRef e2, edgeRef e3) {
00050 set(); set(n1, n2, n3, e1, e2, e3);
00051 }
00052 element(int cid, int idx, chunk *C, int n1, int n2, int n3,
00053 edgeRef e1, edgeRef e2, edgeRef e3) {
00054 set(); set(cid, idx, C); set(n1, n2, n3, e1, e2, e3);
00055 }
00057 element(const element& e) {
00058 targetArea = e.targetArea; currentArea = e.currentArea;
00059 nonCoarsenCount = e.nonCoarsenCount;
00060 present = e.present;
00061 for (int i=0; i<3; i++) {
00062 nodes[i] = e.nodes[i]; edges[i] = e.edges[i];
00063 }
00064 myRef = e.myRef; C = e.C;
00065 }
00067 element& operator=(const element& e) {
00068 targetArea = e.targetArea; currentArea = e.currentArea;
00069 nonCoarsenCount = e.nonCoarsenCount;
00070 present = e.present;
00071 for (int i=0; i<3; i++) {
00072 nodes[i] = e.nodes[i]; edges[i] = e.edges[i];
00073 }
00074 myRef = e.myRef; C = e.C;
00075 return *this;
00076 }
00077
00079 void set() {
00080 targetArea = currentArea = -1.0;
00081 present = 0;
00082 nonCoarsenCount = 0;
00083 }
00084 void set(int c, int i, chunk *ck) {
00085 set(); myRef.set(c, i); C = ck; present = 1; nonCoarsenCount = 0;
00086 }
00087 void set(int *n) {
00088 present = 1;
00089 nonCoarsenCount = 0;
00090 for (int i=0; i<3; i++) nodes[i] = n[i];
00091 }
00092 void set(int *n, edgeRef *e) {
00093 present = 1;
00094 nonCoarsenCount = 0;
00095 for (int i=0; i<3; i++) {
00096 nodes[i] = n[i];
00097 edges[i] = e[i];
00098 }
00099 }
00100 void set(int n1, int n2, int n3) {
00101 present = 1;
00102 nonCoarsenCount = 0;
00103 nodes[0] = n1; nodes[1] = n2; nodes[2] = n3;
00104 }
00105 void set(int n1, int n2, int n3, edgeRef e1, edgeRef e2, edgeRef e3) {
00106 present = 1;
00107 nonCoarsenCount = 0;
00108 nodes[0] = n1; nodes[1] = n2; nodes[2] = n3;
00109 edges[0] = e1; edges[1] = e2; edges[2] = e3;
00110 }
00111 void set(edgeRef& e1, edgeRef& e2, edgeRef& e3) {
00112 present = 1;
00113 nonCoarsenCount = 0;
00114 edges[0] = e1; edges[1] = e2; edges[2] = e3;
00115 }
00116 void set(int idx, edgeRef e) { nonCoarsenCount = 0; edges[idx] = e; }
00117
00119 void update(edgeRef& oldval, edgeRef& newval) {
00120 CkAssert((edges[0]==oldval) || (edges[1]==oldval) || (edges[2]==oldval));
00121 if (edges[0] == oldval) edges[0] = newval;
00122 else if (edges[1] == oldval) edges[1] = newval;
00123 else edges[2] = newval;
00124 }
00126 void update(int oldNode, int newNode) {
00127 CkAssert((nodes[0]==oldNode)||(nodes[1]==oldNode)||(nodes[2]==oldNode));
00128 if (nodes[0] == oldNode) nodes[0] = newNode;
00129 else if (nodes[1] == oldNode) nodes[1] = newNode;
00130 else if (nodes[2] == oldNode) nodes[2] = newNode;
00131 }
00132
00134 int getNode(int nodeIdx) { return nodes[nodeIdx]; }
00136 edgeRef getEdge(int edgeIdx) { return edges[edgeIdx]; }
00138 int getEdgeIdx(edgeRef e) {
00139 CkAssert((e==edges[0]) || (e==edges[1]) || (e==edges[2]));
00140 if (edges[0] == e) return 0;
00141 else if (edges[1] == e) return 1;
00142 else return 2;
00143 }
00145 int getNodeIdx(int n) {
00146 CkAssert((n==nodes[0]) || (n==nodes[1]) || (n==nodes[2]));
00147 if (nodes[0] == n) return 0;
00148 else if (nodes[1] == n) return 1;
00149 else return 2;
00150 }
00152 elemRef getElement(int edgeIdx) { return edges[edgeIdx].getNbr(myRef); }
00154 int lockOpNode(edgeRef e, double l);
00156 void unlockOpNode(edgeRef e);
00157
00158 void clear() { present = 0; }
00159 int isPresent() { return present; }
00160
00161
00162
00163
00164 double getArea() { calculateArea(); return currentArea; }
00165 void calculateArea();
00166 void minimizeTargetArea(double area) {
00167 if (((targetArea > area) || (targetArea < 0.0)) && (area >= 0.0))
00168 targetArea = area;
00169 }
00170 void resetTargetArea(double area) { targetArea = area; }
00171 void setTargetArea(double area) {
00172 if ((area < targetArea) || (targetArea < 0.0)) targetArea = area; }
00173 double getTargetArea() { return targetArea; }
00174 double getCachedArea() { return currentArea; }
00175
00176 void refine();
00177 void split(int longEdge);
00178 void coarsen();
00179 void collapse(int shortEdge);
00180 int findNewNodeDetails(node *newNode, double *frac, int kBc, int dBc,
00181 int kFx, int dFx, int *kNd, int *dNd, short *nonCC,
00182 int *kEg, int *dEg, elemRef *kNbr, elemRef *dNbr,
00183 elemRef *nbr);
00184 void translateNodeIDs(int *kIdx, int *dIdx, int sEg, int kNd, int dNd);
00185 int findLongestEdge();
00186 int findShortestEdge();
00187 double getShortestEdge(double *angle);
00188 double getAreaQuality();
00189 double getLargestEdge(double *angle);
00190 int isLongestEdge(edgeRef& e);
00191 bool flipTest(node*, node*);
00192 bool flipInverseTest(node*, node*);
00193 void incnonCoarsen(void);
00194 void resetnonCoarsen(void) { nonCoarsenCount = 0; }
00195 int safeToCoarsen(short *nonCC, int sEg, elemRef dNbr, elemRef kNbr,
00196 elemRef nbr);
00197 int safeToCoarsen(edgeRef e);
00198 int neighboring(elemRef e1, elemRef e2);
00199 int neighboring(elemRef e);
00200
00201
00202
00203
00204
00205
00206 void sanityCheck(chunk *c, elemRef shouldRef, int n);
00207 };
00208
00209 #endif