00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <vector>
00031 #include <algorithm>
00032
00033 class Cavity {
00034 Tuple center;
00035 GNode centerNode;
00036 Element* centerElement;
00037 int dim;
00038 std::vector<GNode,Galois::PerIterAllocTy::rebind<GNode>::other> frontier;
00039
00040 Subgraph pre;
00041
00042 Subgraph post;
00043
00044 typedef std::vector<Subgraph::tmpEdge,Galois::PerIterAllocTy::rebind<Subgraph::tmpEdge>::other> connTy;
00045 connTy connections;
00046
00047 Graph* graph;
00048
00052 GNode getOpposite(GNode node) {
00053 int numOutNeighbors = graph->neighborsSize(node, Galois::ALL);
00054 if (numOutNeighbors != 3) {
00055 assert(0);
00056 }
00057 Element& element = node.getData(Galois::ALL);
00058 Tuple elementTuple = element.getObtuse();
00059 Edge ObtuseEdge = element.getOppositeObtuse();
00060 GNode dst;
00061 for (Graph::neighbor_iterator ii = graph->neighbor_begin(node,Galois::ALL), ee = graph->neighbor_end(node,Galois::ALL); ii != ee; ++ii) {
00062 GNode neighbor = *ii;
00063
00064 Edge edgeData = element.getRelatedEdge(neighbor.getData(Galois::ALL));
00065 if (elementTuple != edgeData.getPoint(0) && elementTuple != edgeData.getPoint(1)) {
00066 assert(dst.isNull());
00067 dst = neighbor;
00068 }
00069 }
00070 assert(!dst.isNull());
00071 return dst;
00072 }
00073
00074 void expand(GNode node, GNode next) {
00075 Element& nextElement = next.getData(Galois::ALL);
00076 if ((!(dim == 2 && nextElement.getDim() == 2 && next != centerNode)) && nextElement.inCircle(center)) {
00077
00078
00079 if ((nextElement.getDim() == 2) && (dim != 2)) {
00080
00081 initialize(next);
00082 build();
00083 } else {
00084 if (!pre.containsNode(next)) {
00085 pre.addNode(next);
00086 frontier.push_back(next);
00087 }
00088 }
00089 } else {
00090
00091
00092 Edge edgeData = nextElement.getRelatedEdge(node.getData(Galois::ALL));
00093 Subgraph::tmpEdge edge(node, next, edgeData);
00094 if (std::find(connections.begin(), connections.end(), edge) == connections.end()) {
00095 connections.push_back(edge);
00096 }
00097 }
00098 }
00099
00100
00101 public:
00102
00103 Cavity(Graph* g, Galois::PerIterAllocTy& cnx)
00104 :frontier(cnx),
00105 pre(cnx),
00106 post(cnx),
00107 connections(cnx),
00108 graph(g)
00109 {}
00110
00111 void initialize(GNode node) {
00112 pre.reset();
00113 post.reset();
00114 connections.clear();
00115 frontier.clear();
00116 centerNode = node;
00117 centerElement = ¢erNode.getData(Galois::ALL);
00118 while (graph->containsNode(centerNode) && centerElement->isObtuse()) {
00119 centerNode = getOpposite(centerNode);
00120 centerElement = ¢erNode.getData(Galois::ALL);
00121 }
00122 center = centerElement->getCenter();
00123 dim = centerElement->getDim();
00124 pre.addNode(centerNode);
00125 frontier.push_back(centerNode);
00126 }
00127
00128 void build() {
00129 while (!frontier.empty()) {
00130 GNode curr = frontier.back();
00131 frontier.pop_back();
00132 for (Graph::neighbor_iterator ii = graph->neighbor_begin(curr,Galois::ALL),
00133 ee = graph->neighbor_end(curr,Galois::ALL);
00134 ii != ee; ++ii) {
00135 GNode neighbor = *ii;
00136 expand(curr, neighbor);
00137 }
00138 }
00139 }
00140
00144 void update() {
00145 if (centerElement->getDim() == 2) {
00146 Element ele1(center, centerElement->getPoint(0));
00147 GNode node1 = graph->createNode(ele1);
00148 post.addNode(node1);
00149 Element ele2(center, centerElement->getPoint(1));
00150 GNode node2 = graph->createNode(ele2);
00151 post.addNode(node2);
00152 }
00153 for (connTy::iterator ii = connections.begin(), ee = connections.end(); ii != ee; ++ii) {
00154 Subgraph::tmpEdge conn = *ii;
00155 Edge& edge = conn.data;
00156 Element new_element(center, edge.getPoint(0), edge.getPoint(1));
00157 GNode ne_node = graph->createNode(new_element);
00158 GNode ne_connection;
00159 if (pre.containsNode(conn.dst)) {
00160 ne_connection = conn.src;
00161 } else {
00162 ne_connection = conn.dst;
00163 }
00164 Element& ne_nodeData = ne_connection.getData(Galois::ALL);
00165 const Edge& new_edge = new_element.getRelatedEdge(ne_nodeData);
00166
00167 post.addEdge(Subgraph::tmpEdge(ne_node, ne_connection, new_edge));
00168
00169 for (Subgraph::iterator ii = post.begin(), ee = post.end(); ii != ee; ++ii) {
00170 GNode node = *ii;
00171 Element& element = node.getData(Galois::ALL);
00172 if (element.isRelated(new_element)) {
00173 const Edge& ele_edge = new_element.getRelatedEdge(element);
00174
00175 post.addEdge(Subgraph::tmpEdge(ne_node, node, ele_edge));
00176
00177 }
00178 }
00179 post.addNode(ne_node);
00180 }
00181 }
00182
00183 Subgraph& getPre() {
00184 return pre;
00185 };
00186 Subgraph& getPost() {
00187 return post;
00188 };
00189
00190 bool isMember(Element * n);
00191
00192 };
00193