00001
00002
00003
00004
00005
00006
00007
00008 #ifndef VERIFIER_H_
00009 #define VERIFIER_H_
00010 #include "Element.h"
00011 #include "Tuple.h"
00012 #include <stack>
00013 #include <set>
00014
00015 class Verifier {
00016 public:
00017 Verifier() { }
00018 bool verify(Graph* graph) {
00019 return checkConsistency(graph) && checkReachability(graph) && checkDelaunayProperty(graph);
00020 }
00021
00022 private:
00023 bool checkConsistency(Graph* graph){
00024 bool error = false;
00025 for (Graph::active_iterator ii = graph->active_begin(), ee = graph->active_end(); ii != ee; ++ii) {
00026 GNode node = *ii;
00027
00028 Element& element = node.getData(Galois::NONE);
00029
00030 if (element.getDim() == 2) {
00031 if (graph->neighborsSize(node, Galois::NONE) != 1) {
00032 std::cerr << "-> Segment " << element << " has " << graph->neighborsSize(node, Galois::NONE) << " relation(s)\n";
00033 error = true;
00034 }
00035 } else if (element.getDim() == 3) {
00036 if (graph->neighborsSize(node, Galois::NONE) != 3) {
00037 std::cerr << "-> Triangle " << element << " has " << graph->neighborsSize(node, Galois::NONE) << " relation(s)";
00038 error = true;
00039 }
00040 } else {
00041 std::cerr << "-> Figures with " << element.getDim() << " edges";
00042 error = true;
00043 }
00044 }
00045 if (error)
00046 return false;
00047 return true;
00048 }
00049
00050 bool checkReachability(Graph* graph){
00051 std::stack<GNode> remaining;
00052 std::set<GNode> found;
00053 remaining.push(*(graph->active_begin()));
00054
00055 while (!remaining.empty()) {
00056 GNode node = remaining.top();
00057 remaining.pop();
00058 if (!found.count(node)) {
00059 assert(graph->containsNode(node) && "Reachable node was removed from graph");
00060 found.insert(node);
00061 int i = 0;
00062 for (Graph::neighbor_iterator ii = graph->neighbor_begin(node, Galois::NONE), ee = graph->neighbor_end(node, Galois::NONE); ii != ee; ++ii) {
00063 assert(i < 3);
00064 assert(graph->containsNode(*ii));
00065 assert(node != *ii);
00066 ++i;
00067
00068 remaining.push(*ii);
00069 }
00070 }
00071 }
00072
00073 if (found.size() != graph->size()) {
00074 std::cerr << "Not all elements are reachable. ";
00075 std::cerr << "Found: " << found.size() << " needed: " << graph->size() << ".\n";
00076 assert(0 && "Not all elements are reachable");
00077 return false;
00078 }
00079 return true;
00080 }
00081
00082 bool checkDelaunayProperty(Graph* graph){
00083 for (Graph::active_iterator ii = graph->active_begin(), ee = graph->active_end(); ii != ee; ++ii) {
00084 GNode node = *ii;
00085 Element& e = node.getData(Galois::NONE);
00086 for (Graph::neighbor_iterator jj = graph->neighbor_begin(node, Galois::NONE), eejj = graph->neighbor_end(node, Galois::NONE); jj != eejj; ++jj) {
00087 GNode neighborNode = *jj;
00088 Element& e2 = neighborNode.getData(Galois::NONE);
00089 if (e.getDim() == 3 && e2.getDim() == 3) {
00090 const Tuple* t2 = getTupleT2OfRelatedEdge(e, e2);
00091 if (!t2) {
00092 std::cerr << "missing tuple\n";
00093 return false;
00094 }
00095 if (e.inCircle(*t2)) {
00096 std::cerr << "delaunay property violated: "
00097 "point " << *t2 << " in element " << e << "\n";
00098 return false;
00099 }
00100 }
00101 }
00102 }
00103 return true;
00104 }
00105
00106 const Tuple* getTupleT2OfRelatedEdge(Element& e1, Element& e2) {
00107 int e2_0 = -1;
00108 int e2_1 = -1;
00109 int phase = 0;
00110
00111 for (int i = 0; i < e1.getDim(); i++) {
00112 for (int j = 0; j < e2.getDim(); j++) {
00113 if (e1.getPoint(i) == e2.getPoint(j)) {
00114 if (phase == 0) {
00115 e2_0 = j;
00116 phase = 1;
00117 break;
00118 } else {
00119 e2_1 = j;
00120 for (int k = 0; k < 3; k++) {
00121 if (k != e2_0 && k != e2_1) {
00122 return &(e2.getPoint(k));
00123 }
00124 }
00125 }
00126 }
00127 }
00128 }
00129 return NULL;
00130 }
00131 };
00132
00133 #endif