47 #ifndef MUELU_VISUALIZATIONHELPERS_DEF_HPP_
48 #define MUELU_VISUALIZATIONHELPERS_DEF_HPP_
50 #include <Xpetra_Matrix.hpp>
51 #include <Xpetra_CrsMatrixWrap.hpp>
52 #include <Xpetra_ImportFactory.hpp>
53 #include <Xpetra_MultiVectorFactory.hpp>
56 #include "MueLu_Graph.hpp"
63 #ifdef HAVE_MUELU_CGAL
64 #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
65 #include <CGAL/convex_hull_2.h>
66 #include <CGAL/Polyhedron_3.h>
67 #include <CGAL/convex_hull_3.h>
73 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
77 validParamList->
set< std::string > (
"visualization: output filename",
"viz%LEVELID",
"filename for VTK-style visualization output");
78 validParamList->
set<
int > (
"visualization: output file: time step", 0,
"time step variable for output file name");
79 validParamList->
set<
int > (
"visualization: output file: iter", 0,
"nonlinear iteration variable for output file name");
80 validParamList->
set<std::string> (
"visualization: style",
"Point Cloud",
"style of aggregate visualization for VTK output. Can be 'Point Cloud', 'Jacks', 'Convex Hulls'");
81 validParamList->
set<
bool> (
"visualization: build colormap",
false,
"Whether to build a random color map in a separate xml file.");
82 validParamList->
set<
bool> (
"visualization: fine graph edges",
false,
"Whether to draw all fine node connections along with the aggregates.");
84 return validParamList;
87 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
89 vertices.reserve(numFineNodes);
90 geomSizes.reserve(numFineNodes);
93 vertices.push_back(i);
94 geomSizes.push_back(1);
98 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
102 vertices.reserve(vertices.size() + 3 * (numFineNodes - numLocalAggs));
103 geomSizes.reserve(vertices.size() + 2 * (numFineNodes - numLocalAggs));
105 for(
int i = 0; i < numLocalAggs; i++)
109 int numInAggFound = 0;
110 for(
int j = 0; j < numFineNodes; j++)
117 if(vertex2AggId[root] == vertex2AggId[j])
119 vertices.push_back(root);
120 vertices.push_back(j);
121 geomSizes.push_back(2);
123 vertices.push_back(j);
124 geomSizes.push_back(1);
134 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
135 void VisualizationHelpers<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doConvexHulls2D(std::vector<int>& vertices, std::vector<int>& geomSizes, LO numLocalAggs, LO numFineNodes,
const std::vector<bool>& ,
const ArrayRCP<LO>& vertex2AggId,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& xCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& yCoords) {
139 for(
int agg = 0; agg < numLocalAggs; agg++) {
140 std::vector<int> aggNodes;
141 for(
int i = 0; i < numFineNodes; i++) {
142 if(vertex2AggId[i] == agg)
143 aggNodes.push_back(i);
148 "CoarseningVisualization::doConvexHulls2D: aggregate contains zero nodes!");
149 if(aggNodes.size() == 1) {
150 vertices.push_back(aggNodes.front());
151 geomSizes.push_back(1);
154 if(aggNodes.size() == 2) {
155 vertices.push_back(aggNodes.front());
156 vertices.push_back(aggNodes.back());
157 geomSizes.push_back(2);
161 int N = (int) aggNodes.size();
162 using MyPair = std::pair<myVec2,int>;
163 std::vector<MyPair> pointsAndIndex(N);
164 for(
int i=0; i<N; i++) {
165 pointsAndIndex[i] = std::make_pair(
myVec2(xCoords[aggNodes[i]], yCoords[aggNodes[i]]),i);
169 std::sort(pointsAndIndex.begin(),pointsAndIndex.end(),[](
const MyPair &a,
const MyPair &b) {
170 return a.first.x < b.first.x || (a.first.x == b.first.x && a.first.y < b.first.y);
176 for(
int i=0; i<N; i++) {
177 if(ccw(pointsAndIndex[i].first,pointsAndIndex[(i+1)%N].first,pointsAndIndex[(i+2)%N].first)!=0) {
184 vertices.push_back(aggNodes[pointsAndIndex.front().second]);
185 vertices.push_back(aggNodes[pointsAndIndex.back().second]);
186 geomSizes.push_back(2);
189 std::vector<int> hull(2*N);
193 for(
int i=0; i<N; i++) {
194 while (count >=2 && ccw(pointsAndIndex[hull[count-2]].first,pointsAndIndex[hull[count-1]].first,pointsAndIndex[i].first)<=0) {
202 for(
int i=N-1; i>0; i--) {
203 while(count >= t && ccw(pointsAndIndex[hull[count-2]].first,pointsAndIndex[hull[count-1]].first,pointsAndIndex[i-1].first)<=0) {
210 hull.resize(count-1);
213 for(
int i=0; i<(int)hull.size(); i++) {
214 TEUCHOS_TEST_FOR_EXCEPTION(ccw(pointsAndIndex[hull[i]].first,pointsAndIndex[hull[(i+1)%hull.size()]].first,pointsAndIndex[hull[(i+1)%hull.size()]].first) == 1,
Exceptions::RuntimeError,
"CoarseningVisualization::doConvexHulls2D: counter-clockwise verification fails");
218 for(
int i=0; i<(int)hull.size(); i++) {
219 hull[i] = aggNodes[pointsAndIndex[hull[i]].second];
222 vertices.reserve(vertices.size() + hull.size());
223 for(
size_t i = 0; i < hull.size(); i++) {
224 vertices.push_back(hull[i]);
226 geomSizes.push_back(hull.size());
232 #ifdef HAVE_MUELU_CGAL
233 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
234 void VisualizationHelpers<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doCGALConvexHulls2D(std::vector<int>& vertices, std::vector<int>& geomSizes, LO numLocalAggs, LO numFineNodes,
const std::vector<bool>& isRoot,
const ArrayRCP<LO>& vertex2AggId,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& xCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& yCoords) {
236 typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
237 typedef K::Point_2 Point_2;
239 for(
int agg = 0; agg < numLocalAggs; agg++) {
240 std::vector<int> aggNodes;
241 std::vector<Point_2> aggPoints;
242 for(
int i = 0; i < numFineNodes; i++) {
243 if(vertex2AggId[i] == agg) {
244 Point_2 p(xCoords[i], yCoords[i]);
245 aggPoints.push_back(p);
246 aggNodes.push_back(i);
251 "CoarseningVisualization::doCGALConvexHulls2D: aggregate contains zero nodes!");
252 if(aggNodes.size() == 1) {
253 vertices.push_back(aggNodes.front());
254 geomSizes.push_back(1);
257 if(aggNodes.size() == 2) {
258 vertices.push_back(aggNodes.front());
259 vertices.push_back(aggNodes.back());
260 geomSizes.push_back(2);
264 bool collinear =
true;
266 std::vector<int>::iterator it = aggNodes.begin();
267 myVec3 firstPoint(xCoords[*it], yCoords[*it], 0);
269 myVec3 secondPoint(xCoords[*it], yCoords[*it], 0);
271 myVec3 norm1(-(secondPoint.
y - firstPoint.
y), secondPoint.
x - firstPoint.
x, 0);
273 myVec3 thisNorm(yCoords[*it] - firstPoint.
y, firstPoint.
x - xCoords[*it], 0);
275 double temp = thisNorm.
x;
276 thisNorm.
x = thisNorm.
y;
278 double comp = dotProduct(norm1, thisNorm);
279 if(-1e-8 > comp || comp > 1e-8) {
285 while(it != aggNodes.end());
290 std::vector<int>::iterator min = aggNodes.begin();
291 std::vector<int>::iterator max = aggNodes.begin();
292 for(std::vector<int>::iterator it = ++aggNodes.begin(); it != aggNodes.end(); it++) {
293 if(xCoords[*it] < xCoords[*min])
295 else if(xCoords[*it] == xCoords[*min]) {
296 if(yCoords[*it] < yCoords[*min])
299 if(xCoords[*it] > xCoords[*max])
301 else if(xCoords[*it] == xCoords[*max]) {
302 if(yCoords[*it] > yCoords[*max])
307 vertices.push_back(*min);
308 vertices.push_back(*max);
309 geomSizes.push_back(2);
314 std::vector<Point_2> result;
315 CGAL::convex_hull_2( aggPoints.begin(), aggPoints.end(), std::back_inserter(result) );
317 for (
size_t r = 0; r < result.size(); r++) {
319 for(
size_t l = 0; l < aggNodes.size(); l++)
321 if(fabs(result[r].x() - xCoords[aggNodes[l]]) < 1e-12 &&
322 fabs(result[r].y() - yCoords[aggNodes[l]]) < 1e-12)
324 vertices.push_back(aggNodes[l]);
330 geomSizes.push_back(result.size());
337 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
338 void VisualizationHelpers<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doConvexHulls3D(std::vector<int>& vertices, std::vector<int>& geomSizes, LO numLocalAggs, LO numFineNodes,
const std::vector<bool>& ,
const ArrayRCP<LO>& vertex2AggId,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& xCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& yCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& zCoords) {
343 typedef std::list<int>::iterator Iter;
344 for(
int agg = 0; agg < numLocalAggs; agg++) {
345 std::list<int> aggNodes;
346 for(
int i = 0; i < numFineNodes; i++) {
347 if(vertex2AggId[i] == agg)
348 aggNodes.push_back(i);
352 "CoarseningVisualization::doConvexHulls3D: aggregate contains zero nodes!");
353 if(aggNodes.size() == 1) {
354 vertices.push_back(aggNodes.front());
355 geomSizes.push_back(1);
357 }
else if(aggNodes.size() == 2) {
358 vertices.push_back(aggNodes.front());
359 vertices.push_back(aggNodes.back());
360 geomSizes.push_back(2);
364 bool areCollinear =
true;
366 Iter it = aggNodes.begin();
367 myVec3 firstVec(xCoords[*it], yCoords[*it], zCoords[*it]);
371 myVec3 secondVec(xCoords[*it], yCoords[*it], zCoords[*it]);
372 comp = vecSubtract(secondVec, firstVec);
375 for(; it != aggNodes.end(); it++) {
376 myVec3 thisVec(xCoords[*it], yCoords[*it], zCoords[*it]);
377 myVec3 cross = crossProduct(vecSubtract(thisVec, firstVec), comp);
378 if(mymagnitude(cross) > 1e-10) {
379 areCollinear =
false;
388 Iter min = aggNodes.begin();
389 Iter max = aggNodes.begin();
390 Iter it = ++aggNodes.begin();
391 for(; it != aggNodes.end(); it++) {
392 if(xCoords[*it] < xCoords[*min]) min = it;
393 else if(xCoords[*it] == xCoords[*min]) {
394 if(yCoords[*it] < yCoords[*min]) min = it;
395 else if(yCoords[*it] == yCoords[*min]) {
396 if(zCoords[*it] < zCoords[*min]) min = it;
399 if(xCoords[*it] > xCoords[*max]) max = it;
400 else if(xCoords[*it] == xCoords[*max]) {
401 if(yCoords[*it] > yCoords[*max]) max = it;
402 else if(yCoords[*it] == yCoords[*max]) {
403 if(zCoords[*it] > zCoords[*max])
408 vertices.push_back(*min);
409 vertices.push_back(*max);
410 geomSizes.push_back(2);
413 bool areCoplanar =
true;
416 Iter vert = aggNodes.begin();
417 myVec3 v1(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
419 myVec3 v2(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
421 myVec3 v3(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
424 while(mymagnitude(crossProduct(vecSubtract(v1, v2), vecSubtract(v1, v3))) < 1e-10) {
426 v3 =
myVec3(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
429 for(; vert != aggNodes.end(); vert++) {
430 myVec3 pt(xCoords[*vert], yCoords[*vert], zCoords[*vert]);
431 if(fabs(pointDistFromTri(pt, v1, v2, v3)) > 1e-12) {
438 myVec3 planeNorm = getNorm(v1, v2, v3);
439 planeNorm.
x = fabs(planeNorm.
x);
440 planeNorm.
y = fabs(planeNorm.
y);
441 planeNorm.
z = fabs(planeNorm.
z);
442 std::vector<myVec2> points;
443 std::vector<int> nodes;
444 if(planeNorm.
x >= planeNorm.
y && planeNorm.
x >= planeNorm.
z) {
446 for(Iter it = aggNodes.begin(); it != aggNodes.end(); it++) {
447 nodes.push_back(*it);
448 points.push_back(
myVec2(yCoords[*it], zCoords[*it]));
451 if(planeNorm.
y >= planeNorm.
x && planeNorm.
y >= planeNorm.
z) {
453 for(Iter it = aggNodes.begin(); it != aggNodes.end(); it++) {
454 nodes.push_back(*it);
455 points.push_back(
myVec2(xCoords[*it], zCoords[*it]));
458 if(planeNorm.
z >= planeNorm.
x && planeNorm.
z >= planeNorm.
y) {
459 for(Iter it = aggNodes.begin(); it != aggNodes.end(); it++) {
460 nodes.push_back(*it);
461 points.push_back(
myVec2(xCoords[*it], yCoords[*it]));
464 std::vector<int> convhull2d = giftWrap(points, nodes, xCoords, yCoords);
465 geomSizes.push_back(convhull2d.size());
466 vertices.reserve(vertices.size() + convhull2d.size());
467 for(
size_t i = 0; i < convhull2d.size(); i++)
468 vertices.push_back(convhull2d[i]);
472 Iter exIt = aggNodes.begin();
473 int extremeSix[] = {*exIt, *exIt, *exIt, *exIt, *exIt, *exIt};
475 for(; exIt != aggNodes.end(); exIt++) {
477 if(xCoords[*it] < xCoords[extremeSix[0]] ||
478 (xCoords[*it] == xCoords[extremeSix[0]] && yCoords[*it] < yCoords[extremeSix[0]]) ||
479 (xCoords[*it] == xCoords[extremeSix[0]] && yCoords[*it] == yCoords[extremeSix[0]] && zCoords[*it] < zCoords[extremeSix[0]]))
481 if(xCoords[*it] > xCoords[extremeSix[1]] ||
482 (xCoords[*it] == xCoords[extremeSix[1]] && yCoords[*it] > yCoords[extremeSix[1]]) ||
483 (xCoords[*it] == xCoords[extremeSix[1]] && yCoords[*it] == yCoords[extremeSix[1]] && zCoords[*it] > zCoords[extremeSix[1]]))
485 if(yCoords[*it] < yCoords[extremeSix[2]] ||
486 (yCoords[*it] == yCoords[extremeSix[2]] && zCoords[*it] < zCoords[extremeSix[2]]) ||
487 (yCoords[*it] == yCoords[extremeSix[2]] && zCoords[*it] == zCoords[extremeSix[2]] && xCoords[*it] < xCoords[extremeSix[2]]))
489 if(yCoords[*it] > yCoords[extremeSix[3]] ||
490 (yCoords[*it] == yCoords[extremeSix[3]] && zCoords[*it] > zCoords[extremeSix[3]]) ||
491 (yCoords[*it] == yCoords[extremeSix[3]] && zCoords[*it] == zCoords[extremeSix[3]] && xCoords[*it] > xCoords[extremeSix[3]]))
493 if(zCoords[*it] < zCoords[extremeSix[4]] ||
494 (zCoords[*it] == zCoords[extremeSix[4]] && xCoords[*it] < xCoords[extremeSix[4]]) ||
495 (zCoords[*it] == zCoords[extremeSix[4]] && xCoords[*it] == xCoords[extremeSix[4]] && yCoords[*it] < yCoords[extremeSix[4]]))
497 if(zCoords[*it] > zCoords[extremeSix[5]] ||
498 (zCoords[*it] == zCoords[extremeSix[5]] && xCoords[*it] > xCoords[extremeSix[5]]) ||
499 (zCoords[*it] == zCoords[extremeSix[5]] && xCoords[*it] == xCoords[extremeSix[5]] && yCoords[*it] > zCoords[extremeSix[5]]))
503 for(
int i = 0; i < 6; i++) {
504 myVec3 thisExtremeVec(xCoords[extremeSix[i]], yCoords[extremeSix[i]], zCoords[extremeSix[i]]);
505 extremeVectors[i] = thisExtremeVec;
510 for(
int i = 0; i < 5; i++) {
511 for(
int j = i + 1; j < 6; j++) {
512 double thisDist = distance(extremeVectors[i], extremeVectors[j]);
513 if(thisDist > maxDist) {
520 std::list<myTriangle> hullBuilding;
522 aggNodes.remove(extremeSix[base1]);
523 aggNodes.remove(extremeSix[base2]);
526 tri.
v1 = extremeSix[base1];
527 tri.
v2 = extremeSix[base2];
531 myVec3 b1 = extremeVectors[base1];
532 myVec3 b2 = extremeVectors[base2];
534 for(Iter node = aggNodes.begin(); node != aggNodes.end(); node++) {
535 myVec3 nodePos(xCoords[*node], yCoords[*node], zCoords[*node]);
536 double dist = mymagnitude(crossProduct(vecSubtract(nodePos, b1), vecSubtract(nodePos, b2))) / mymagnitude(vecSubtract(b2, b1));
544 hullBuilding.push_back(tri);
545 myVec3 b3(xCoords[*thirdNode], yCoords[*thirdNode], zCoords[*thirdNode]);
546 aggNodes.erase(thirdNode);
549 int fourthVertex = -1;
550 for(Iter node = aggNodes.begin(); node != aggNodes.end(); node++) {
551 myVec3 thisNode(xCoords[*node], yCoords[*node], zCoords[*node]);
552 double nodeDist = pointDistFromTri(thisNode, b1, b2, b3);
553 if(nodeDist > maxDist) {
555 fourthVertex = *node;
558 aggNodes.remove(fourthVertex);
559 myVec3 b4(xCoords[fourthVertex], yCoords[fourthVertex], zCoords[fourthVertex]);
562 tri = hullBuilding.front();
563 tri.
v1 = fourthVertex;
564 hullBuilding.push_back(tri);
565 tri = hullBuilding.front();
566 tri.
v2 = fourthVertex;
567 hullBuilding.push_back(tri);
568 tri = hullBuilding.front();
569 tri.
v3 = fourthVertex;
570 hullBuilding.push_back(tri);
572 myVec3 barycenter((b1.
x + b2.
x + b3.
x + b4.
x) / 4.0, (b1.
y + b2.
y + b3.
y + b4.
y) / 4.0, (b1.
z + b2.
z + b3.
z + b4.
z) / 4.0);
573 for(std::list<myTriangle>::iterator tetTri = hullBuilding.begin(); tetTri != hullBuilding.end(); tetTri++) {
574 myVec3 triVert1(xCoords[tetTri->v1], yCoords[tetTri->v1], zCoords[tetTri->v1]);
575 myVec3 triVert2(xCoords[tetTri->v2], yCoords[tetTri->v2], zCoords[tetTri->v2]);
576 myVec3 triVert3(xCoords[tetTri->v3], yCoords[tetTri->v3], zCoords[tetTri->v3]);
577 myVec3 trinorm = getNorm(triVert1, triVert2, triVert3);
578 myVec3 ptInPlane = tetTri == hullBuilding.begin() ? b1 : b4;
579 if(isInFront(barycenter, ptInPlane, trinorm)) {
582 int temp = tetTri->v1;
583 tetTri->v1 = tetTri->v2;
595 for(std::list<myTriangle>::iterator tetTri = hullBuilding.begin(); tetTri != hullBuilding.end(); tetTri++) {
596 myVec3 triVert1(xCoords[tetTri->v1], yCoords[tetTri->v1], zCoords[tetTri->v1]);
597 myVec3 triVert2(xCoords[tetTri->v2], yCoords[tetTri->v2], zCoords[tetTri->v2]);
598 myVec3 triVert3(xCoords[tetTri->v3], yCoords[tetTri->v3], zCoords[tetTri->v3]);
599 trinorms[index] = getNorm(triVert1, triVert2, triVert3);
602 std::list<int> startPoints1;
603 std::list<int> startPoints2;
604 std::list<int> startPoints3;
605 std::list<int> startPoints4;
608 Iter point = aggNodes.begin();
609 while(!aggNodes.empty())
611 myVec3 pointVec(xCoords[*point], yCoords[*point], zCoords[*point]);
614 if(isInFront(pointVec, b1, trinorms[0])) {
615 startPoints1.push_back(*point);
616 point = aggNodes.erase(point);
617 }
else if(isInFront(pointVec, b4, trinorms[1])) {
618 startPoints2.push_back(*point);
619 point = aggNodes.erase(point);
620 }
else if(isInFront(pointVec, b4, trinorms[2])) {
621 startPoints3.push_back(*point);
622 point = aggNodes.erase(point);
623 }
else if(isInFront(pointVec, b4, trinorms[3])) {
624 startPoints4.push_back(*point);
625 point = aggNodes.erase(point);
627 point = aggNodes.erase(point);
632 typedef std::list<myTriangle>::iterator TriIter;
633 TriIter firstTri = hullBuilding.begin();
642 if(!startPoints1.empty())
643 processTriangle(hullBuilding, start1, startPoints1, barycenter, xCoords, yCoords, zCoords);
644 if(!startPoints2.empty())
645 processTriangle(hullBuilding, start2, startPoints2, barycenter, xCoords, yCoords, zCoords);
646 if(!startPoints3.empty())
647 processTriangle(hullBuilding, start3, startPoints3, barycenter, xCoords, yCoords, zCoords);
648 if(!startPoints4.empty())
649 processTriangle(hullBuilding, start4, startPoints4, barycenter, xCoords, yCoords, zCoords);
652 vertices.reserve(vertices.size() + 3 * hullBuilding.size());
653 for(TriIter hullTri = hullBuilding.begin(); hullTri != hullBuilding.end(); hullTri++) {
654 vertices.push_back(hullTri->v1);
655 vertices.push_back(hullTri->v2);
656 vertices.push_back(hullTri->v3);
657 geomSizes.push_back(3);
662 #ifdef HAVE_MUELU_CGAL
663 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
664 void VisualizationHelpers<Scalar, LocalOrdinal, GlobalOrdinal, Node>::doCGALConvexHulls3D(std::vector<int>& vertices, std::vector<int>& geomSizes, LO numLocalAggs, LO numFineNodes,
const std::vector<bool>& isRoot,
const ArrayRCP<LO>& vertex2AggId,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& xCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& yCoords,
const Teuchos::ArrayRCP<
const typename Teuchos::ScalarTraits<Scalar>::coordinateType>& zCoords) {
666 typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
667 typedef K::Point_3 Point_3;
668 typedef CGAL::Polyhedron_3<K> Polyhedron_3;
669 typedef std::vector<int>::iterator Iter;
670 for(
int agg = 0; agg < numLocalAggs; agg++) {
671 std::vector<int> aggNodes;
672 std::vector<Point_3> aggPoints;
673 for(
int i = 0; i < numFineNodes; i++) {
674 if(vertex2AggId[i] == agg) {
675 Point_3 p(xCoords[i], yCoords[i], zCoords[i]);
676 aggPoints.push_back(p);
677 aggNodes.push_back(i);
682 "CoarseningVisualization::doCGALConvexHulls3D: aggregate contains zero nodes!");
683 if(aggNodes.size() == 1) {
684 vertices.push_back(aggNodes.front());
685 geomSizes.push_back(1);
687 }
else if(aggNodes.size() == 2) {
688 vertices.push_back(aggNodes.front());
689 vertices.push_back(aggNodes.back());
690 geomSizes.push_back(2);
694 bool areCollinear =
true;
696 Iter it = aggNodes.begin();
697 myVec3 firstVec(xCoords[*it], yCoords[*it], zCoords[*it]);
701 myVec3 secondVec(xCoords[*it], yCoords[*it], zCoords[*it]);
702 comp = vecSubtract(secondVec, firstVec);
705 for(; it != aggNodes.end(); it++) {
706 myVec3 thisVec(xCoords[*it], yCoords[*it], zCoords[*it]);
707 myVec3 cross = crossProduct(vecSubtract(thisVec, firstVec), comp);
708 if(mymagnitude(cross) > 1e-8) {
709 areCollinear =
false;
718 Iter min = aggNodes.begin();
719 Iter max = aggNodes.begin();
720 Iter it = ++aggNodes.begin();
721 for(; it != aggNodes.end(); it++) {
722 if(xCoords[*it] < xCoords[*min]) min = it;
723 else if(xCoords[*it] == xCoords[*min]) {
724 if(yCoords[*it] < yCoords[*min]) min = it;
725 else if(yCoords[*it] == yCoords[*min]) {
726 if(zCoords[*it] < zCoords[*min]) min = it;
729 if(xCoords[*it] > xCoords[*max]) max = it;
730 else if(xCoords[*it] == xCoords[*max]) {
731 if(yCoords[*it] > yCoords[*max]) max = it;
732 else if(yCoords[*it] == yCoords[*max]) {
733 if(zCoords[*it] > zCoords[*max])
738 vertices.push_back(*min);
739 vertices.push_back(*max);
740 geomSizes.push_back(2);
746 CGAL::convex_hull_3( aggPoints.begin(), aggPoints.end(), result);
749 Polyhedron_3::Facet_iterator fi;
750 for (fi = result.facets_begin(); fi != result.facets_end(); fi++) {
751 int cntVertInAgg = 0;
752 Polyhedron_3::Halfedge_around_facet_const_circulator hit = fi->facet_begin();
754 const Point_3 & pp = hit->vertex()->point();
756 for(
size_t l = 0; l < aggNodes.size(); l++)
758 if(fabs(pp.x() - xCoords[aggNodes[l]]) < 1e-12 &&
759 fabs(pp.y() - yCoords[aggNodes[l]]) < 1e-12 &&
760 fabs(pp.z() - zCoords[aggNodes[l]]) < 1e-12)
762 vertices.push_back(aggNodes[l]);
767 }
while (++hit != fi->facet_begin());
768 geomSizes.push_back(cntVertInAgg);
776 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
781 std::vector<std::pair<int, int> > vert1;
787 for(
int gEdge = 0; gEdge < int(neighbors.
size()); ++gEdge) {
788 vert1.push_back(std::pair<int, int>(locRow, neighbors[gEdge]));
791 for(
size_t i = 0; i < vert1.size(); i ++) {
792 if(vert1[i].first > vert1[i].second) {
793 int temp = vert1[i].first;
794 vert1[i].first = vert1[i].second;
795 vert1[i].second = temp;
798 std::sort(vert1.begin(), vert1.end());
799 std::vector<std::pair<int, int> >::iterator newEnd = unique(vert1.begin(), vert1.end());
800 vert1.erase(newEnd, vert1.end());
802 vertices.reserve(2 * vert1.size());
803 geomSizes.reserve(vert1.size());
804 for(
size_t i = 0; i < vert1.size(); i++) {
805 vertices.push_back(vert1[i].first);
806 vertices.push_back(vert1[i].second);
807 geomSizes.push_back(2);
811 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
814 const double ccw_zero_threshold=1e-8;
815 double val = (b.
x - a.
x) * (c.
y - a.
y) - (b.
y - a.
y) * (c.
x - a.
x);
816 return (val > ccw_zero_threshold) ? 1 : ( (val < -ccw_zero_threshold) ? -1 : 0);
819 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
822 return myVec3(v1.
y * v2.
z - v1.
z * v2.
y, v1.
z * v2.
x - v1.
x * v2.
z, v1.
x * v2.
y - v1.
y * v2.
x);
825 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
828 return v1.
x * v2.
x + v1.
y * v2.
y;
831 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
834 return v1.
x * v2.
x + v1.
y * v2.
y + v1.
z * v2.
z;
837 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
840 myVec3 rel(point.
x - inPlane.
x, point.
y - inPlane.
y, point.
z - inPlane.
z);
841 return dotProduct(rel, n) > 1e-12 ?
true :
false;
844 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
847 return sqrt(dotProduct(vec, vec));
850 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
853 return sqrt(dotProduct(vec, vec));
856 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
859 return mymagnitude(vecSubtract(p1, p2));
863 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
866 return mymagnitude(vecSubtract(p1, p2));
869 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
875 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
881 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
887 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
890 return crossProduct(vecSubtract(v2, v1), vecSubtract(v3, v1));
894 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
898 myVec3 norm = getNorm(v1, v2, v3);
900 double normScl = mymagnitude(norm);
902 if (normScl > 1e-8) {
906 rv = fabs(dotProduct(norm, vecSubtract(point, v1)));
909 myVec3 test1 = vecSubtract(v3, v1);
910 myVec3 test2 = vecSubtract(v2, v1);
911 bool useTest1 = mymagnitude(test1) > 0.0 ?
true :
false;
912 bool useTest2 = mymagnitude(test2) > 0.0 ?
true :
false;
913 if(useTest1 ==
true) {
914 double normScl1 = mymagnitude(test1);
918 rv = fabs(dotProduct(test1, vecSubtract(point, v1)));
919 }
else if (useTest2 ==
true) {
920 double normScl2 = mymagnitude(test2);
924 rv = fabs(dotProduct(test2, vecSubtract(point, v1)));
927 "VisualizationHelpers::pointDistFromTri: Could not determine the distance of a point to a triangle.");
934 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
940 typedef std::list<int>::iterator Iter;
941 typedef std::list<myTriangle>::iterator TriIter;
942 typedef list<pair<int, int> >::iterator EdgeIter;
945 myVec3 v1(xCoords[tri.
v1], yCoords[tri.
v1], zCoords[tri.
v1]);
946 myVec3 v2(xCoords[tri.
v2], yCoords[tri.
v2], zCoords[tri.
v2]);
947 myVec3 v3(xCoords[tri.
v3], yCoords[tri.
v3], zCoords[tri.
v3]);
949 Iter farPoint = pointsInFront.begin();
950 for(Iter point = pointsInFront.begin(); point != pointsInFront.end(); point++)
952 myVec3 pointVec(xCoords[*point], yCoords[*point], zCoords[*point]);
953 double dist = pointDistFromTri(pointVec, v1, v2, v3);
957 farPointVec = pointVec;
963 vector<myTriangle> visible;
964 for(TriIter it = tris.begin(); it != tris.end();)
966 myVec3 vec1(xCoords[it->v1], yCoords[it->v1], zCoords[it->v1]);
967 myVec3 vec2(xCoords[it->v2], yCoords[it->v2], zCoords[it->v2]);
968 myVec3 vec3(xCoords[it->v3], yCoords[it->v3], zCoords[it->v3]);
969 myVec3 norm = getNorm(vec1, vec2, vec3);
970 if(isInFront(farPointVec, vec1, norm))
972 visible.push_back(*it);
980 list<pair<int, int> > horizon;
983 for(vector<myTriangle>::iterator it = visible.begin(); it != visible.end(); it++)
985 pair<int, int> e1(it->v1, it->v2);
986 pair<int, int> e2(it->v2, it->v3);
987 pair<int, int> e3(it->v1, it->v3);
989 if(e1.first > e1.second)
992 e1.first = e1.second;
995 if(e2.first > e2.second)
998 e2.first = e2.second;
1001 if(e3.first > e3.second)
1003 int temp = e3.first;
1004 e3.first = e3.second;
1007 horizon.push_back(e1);
1008 horizon.push_back(e2);
1009 horizon.push_back(e3);
1015 EdgeIter it = horizon.begin();
1016 while(it != horizon.end())
1018 int occur = count(horizon.begin(), horizon.end(), *it);
1021 pair<int, int> removeVal = *it;
1022 while(removeVal == *it && !(it == horizon.end()))
1023 it = horizon.erase(it);
1030 list<myTriangle> newTris;
1031 for(EdgeIter it = horizon.begin(); it != horizon.end(); it++)
1033 myTriangle t(it->first, it->second, *farPoint);
1034 newTris.push_back(t);
1037 vector<myTriangle> trisToProcess;
1038 vector<list<int> > newFrontPoints;
1039 for(TriIter it = newTris.begin(); it != newTris.end(); it++)
1041 myVec3 t1(xCoords[it->v1], yCoords[it->v1], zCoords[it->v1]);
1042 myVec3 t2(xCoords[it->v2], yCoords[it->v2], zCoords[it->v2]);
1043 myVec3 t3(xCoords[it->v3], yCoords[it->v3], zCoords[it->v3]);
1044 if(isInFront(barycenter, t1, getNorm(t1, t2, t3)))
1054 myVec3 outwardNorm = getNorm(t1, t2, t3);
1056 tris.push_back(*it);
1057 trisToProcess.push_back(tris.back());
1059 list<int> newInFront;
1060 for(Iter point = pointsInFront.begin(); point != pointsInFront.end();)
1062 myVec3 pointVec(xCoords[*point], yCoords[*point], zCoords[*point]);
1063 if(isInFront(pointVec, t1, outwardNorm))
1065 newInFront.push_back(*point);
1066 point = pointsInFront.erase(point);
1071 newFrontPoints.push_back(newInFront);
1073 vector<myTriangle> allRemoved;
1074 for(
int i = 0; i < int(trisToProcess.size()); i++)
1076 if(!newFrontPoints[i].empty())
1080 if(find(allRemoved.begin(), allRemoved.end(), trisToProcess[i]) == allRemoved.end() && !(trisToProcess[i] == tri))
1082 vector<myTriangle> removedList = processTriangle(tris, trisToProcess[i], newFrontPoints[i], barycenter, xCoords, yCoords, zCoords);
1083 for(
int j = 0; j < int(removedList.size()); j++)
1084 allRemoved.push_back(removedList[j]);
1091 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1094 "CoarseningVisualization::giftWrap: Gift wrap algorithm input has to have at least 3 points!");
1096 #if 1 // TAW's version to determine "minimal" node
1098 double min_x =points[0].x;
1099 double min_y =points[0].y;
1100 for(std::vector<int>::iterator it = nodes.begin(); it != nodes.end(); it++) {
1101 int i = it - nodes.begin();
1102 if(points[i].x < min_x) min_x = points[i].x;
1103 if(points[i].y < min_y) min_y = points[i].y;
1108 myVec2 dummy_min(min_x, min_y);
1111 std::vector<int> hull;
1113 double mindist = distance(min,dummy_min);
1114 std::vector<int>::iterator minNode = nodes.begin();
1115 for(std::vector<int>::iterator it = nodes.begin(); it != nodes.end(); it++) {
1116 int i = it - nodes.begin();
1117 if(distance(points[i],dummy_min) < mindist) {
1118 mindist = distance(points[i],dummy_min);
1123 hull.push_back(*minNode);
1124 #else // Brian's code
1125 std::vector<int> hull;
1126 std::vector<int>::iterator minNode = nodes.begin();
1128 for(std::vector<int>::iterator it = nodes.begin(); it != nodes.end(); it++)
1130 int i = it - nodes.begin();
1131 if(points[i].x < min.
x || (fabs(points[i].x - min.
x) < 1e-10 && points[i].y < min.
y))
1137 hull.push_back(*minNode);
1140 bool includeMin =
false;
1144 std::vector<int>::iterator leftMost = nodes.begin();
1145 if(!includeMin && leftMost == minNode)
1149 std::vector<int>::iterator it = leftMost;
1151 for(; it != nodes.end(); it++)
1153 if(it == minNode && !includeMin)
1155 if(*it == hull.back())
1159 myVec2 leftMostVec = points[leftMost - nodes.begin()];
1160 myVec2 lastVec(xCoords[hull.back()], yCoords[hull.back()]);
1161 myVec2 testNorm = getNorm(vecSubtract(leftMostVec, lastVec));
1163 myVec2 itVec(xCoords[*it], yCoords[*it]);
1164 double dotProd = dotProduct(testNorm, vecSubtract(itVec, lastVec));
1165 if(-1e-8 < dotProd && dotProd < 1e-8)
1169 myVec2 itDist = vecSubtract(itVec, lastVec);
1170 myVec2 leftMostDist = vecSubtract(leftMostVec, lastVec);
1171 if(fabs(itDist.
x) + fabs(itDist.
y) > fabs(leftMostDist.
x) + fabs(leftMostDist.
y)) {
1175 else if(dotProd > 0) {
1181 if(*leftMost == *minNode)
1183 hull.push_back(*leftMost);
1191 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1194 using namespace std;
1195 vector<int> uniqueNodes = vertices;
1196 sort(uniqueNodes.begin(), uniqueNodes.end());
1197 vector<int>::iterator newUniqueFineEnd = unique(uniqueNodes.begin(), uniqueNodes.end());
1198 uniqueNodes.erase(newUniqueFineEnd, uniqueNodes.end());
1201 for(
int i = 0; i < int(vertices.size()); i++)
1204 int hi = uniqueNodes.size() - 1;
1206 int search = vertices[i];
1209 mid = lo + (hi - lo) / 2;
1210 if(uniqueNodes[mid] == search)
1212 else if(uniqueNodes[mid] > search)
1217 if(uniqueNodes[mid] != search)
1218 throw runtime_error(
"Issue in makeUnique_() - a point wasn't found in list.");
1224 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1227 const int pos = result.find(replaceWhat);
1230 result.replace(pos, replaceWhat.size(), replaceWithWhat);
1235 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1237 std::string filenameToWrite = getBaseFileName(numProcs, level, pL);
1239 return filenameToWrite;
1242 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1244 std::string filenameToWrite = pL.
get<std::string>(
"visualization: output filename");
1245 int timeStep = pL.
get<
int>(
"visualization: output file: time step");
1246 int iter = pL.
get<
int>(
"visualization: output file: iter");
1248 if(filenameToWrite.rfind(
".vtu") == std::string::npos)
1249 filenameToWrite.append(
".vtu");
1250 if(numProcs > 1 && filenameToWrite.rfind(
"%PROCID") == std::string::npos)
1251 filenameToWrite.insert(filenameToWrite.rfind(
".vtu"),
"-proc%PROCID");
1254 filenameToWrite = this->
replaceAll(filenameToWrite,
"%TIMESTEP",
toString(timeStep));
1256 return filenameToWrite;
1259 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1261 std::string filenameToWrite = getBaseFileName(numProcs, level, pL);
1262 std::string masterStem = filenameToWrite.substr(0, filenameToWrite.rfind(
".vtu"));
1263 masterStem = this->
replaceAll(masterStem,
"%PROCID",
"");
1264 std::string pvtuFilename = masterStem +
"-master.pvtu";
1265 return pvtuFilename;
1268 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1270 std::string styleName =
"PointCloud";
1272 std::string indent =
" ";
1273 fout <<
"<!--" << styleName <<
" Aggregates Visualization-->" << std::endl;
1274 fout <<
"<VTKFile type=\"UnstructuredGrid\" byte_order=\"LittleEndian\">" << std::endl;
1275 fout <<
" <UnstructuredGrid>" << std::endl;
1276 fout <<
" <Piece NumberOfPoints=\"" << uniqueFine.size() <<
"\" NumberOfCells=\"" << geomSizesFine.size() <<
"\">" << std::endl;
1277 fout <<
" <PointData Scalars=\"Node Aggregate Processor\">" << std::endl;
1280 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1282 std::string indent =
" ";
1283 fout <<
" <DataArray type=\"Int32\" Name=\"Node\" format=\"ascii\">" << std::endl;
1286 for(
size_t i = 0; i < uniqueFine.size(); i++)
1290 fout << uniqueFine[i] <<
" ";
1293 fout << nodeMap->getGlobalElement(uniqueFine[i]) <<
" ";
1295 fout << std::endl << indent;
1298 fout <<
" </DataArray>" << std::endl;
1301 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1303 std::string indent =
" ";
1304 fout <<
" <DataArray type=\"Int32\" Name=\"Aggregate\" format=\"ascii\">" << std::endl;
1306 for(
int i = 0; i < int(uniqueFine.size()); i++)
1308 fout << myAggOffset + vertex2AggId[uniqueFine[i]] <<
" ";
1310 fout << std::endl << indent;
1313 fout <<
" </DataArray>" << std::endl;
1314 fout <<
" <DataArray type=\"Int32\" Name=\"Processor\" format=\"ascii\">" << std::endl;
1316 for(
int i = 0; i < int(uniqueFine.size()); i++)
1318 fout << myRank <<
" ";
1320 fout << std::endl << indent;
1323 fout <<
" </DataArray>" << std::endl;
1324 fout <<
" </PointData>" << std::endl;
1327 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1329 std::string indent =
" ";
1330 fout <<
" <Points>" << std::endl;
1331 fout <<
" <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
1333 for(
int i = 0; i < int(uniqueFine.size()); i++)
1335 fout << fx[uniqueFine[i]] <<
" " << fy[uniqueFine[i]] <<
" ";
1339 fout << fz[uniqueFine[i]] <<
" ";
1341 fout << std::endl << indent;
1344 fout <<
" </DataArray>" << std::endl;
1345 fout <<
" </Points>" << std::endl;
1348 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1350 std::string indent =
" ";
1351 fout <<
" <Cells>" << std::endl;
1352 fout <<
" <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl;
1354 for(
int i = 0; i < int(vertices.size()); i++)
1356 fout << vertices[i] <<
" ";
1358 fout << std::endl << indent;
1361 fout <<
" </DataArray>" << std::endl;
1362 fout <<
" <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl;
1365 for(
int i = 0; i < int(geomSize.size()); i++)
1367 accum += geomSize[i];
1368 fout << accum <<
" ";
1370 fout << std::endl << indent;
1373 fout <<
" </DataArray>" << std::endl;
1374 fout <<
" <DataArray type=\"Int32\" Name=\"types\" format=\"ascii\">" << std::endl;
1376 for(
int i = 0; i < int(geomSize.size()); i++)
1393 fout << std::endl << indent;
1396 fout <<
" </DataArray>" << std::endl;
1397 fout <<
" </Cells>" << std::endl;
1400 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1402 fout <<
" </Piece>" << std::endl;
1403 fout <<
" </UnstructuredGrid>" << std::endl;
1404 fout <<
"</VTKFile>" << std::endl;
1408 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1413 pvtu <<
"<VTKFile type=\"PUnstructuredGrid\" byte_order=\"LittleEndian\">" << std::endl;
1414 pvtu <<
" <PUnstructuredGrid GhostLevel=\"0\">" << std::endl;
1415 pvtu <<
" <PPointData Scalars=\"Node Aggregate Processor\">" << std::endl;
1416 pvtu <<
" <PDataArray type=\"Int32\" Name=\"Node\"/>" << std::endl;
1417 pvtu <<
" <PDataArray type=\"Int32\" Name=\"Aggregate\"/>" << std::endl;
1418 pvtu <<
" <PDataArray type=\"Int32\" Name=\"Processor\"/>" << std::endl;
1419 pvtu <<
" </PPointData>" << std::endl;
1420 pvtu <<
" <PPoints>" << std::endl;
1421 pvtu <<
" <PDataArray type=\"Float64\" NumberOfComponents=\"3\"/>" << std::endl;
1422 pvtu <<
" </PPoints>" << std::endl;
1423 for(
int i = 0; i < numProcs; i++) {
1425 pvtu <<
" <Piece Source=\"" <<
replaceAll(baseFname,
"%PROCID",
toString(i)) <<
"\"/>" << std::endl;
1430 for(
int i = 0; i < numProcs; i++)
1433 pvtu <<
" <Piece Source=\"" << fn.insert(fn.rfind(
".vtu"),
"-finegraph") <<
"\"/>" << std::endl;
1444 pvtu <<
" </PUnstructuredGrid>" << std::endl;
1445 pvtu <<
"</VTKFile>" << std::endl;
1449 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1452 std::ofstream color(
"random-colormap.xml");
1453 color <<
"<ColorMap name=\"MueLu-Random\" space=\"RGB\">" << std::endl;
1456 color <<
" <Point x=\"" << -1 <<
"\" o=\"1\" r=\"1\" g=\"0\" b=\"0\"/>" << std::endl;
1457 color <<
" <Point x=\"" << -2 <<
"\" o=\"1\" r=\"1\" g=\"0.6\" b=\"0\"/>" << std::endl;
1458 color <<
" <Point x=\"" << -3 <<
"\" o=\"1\" r=\"1\" g=\"1\" b=\"0\"/>" << std::endl;
1460 for(
int i = 0; i < 5000; i += 4) {
1461 color <<
" <Point x=\"" << i <<
"\" o=\"1\" r=\"" << (rand() % 50) / 256.0 <<
"\" g=\"" << (rand() % 256) / 256.0 <<
"\" b=\"" << (rand() % 256) / 256.0 <<
"\"/>" << std::endl;
1463 color <<
"</ColorMap>" << std::endl;
1466 catch(std::exception& e) {
1468 "VisualizationHelpers::buildColormap: Error while building colormap file: " << e.what());
static void doPointCloud(std::vector< int > &vertices, std::vector< int > &geomSizes, LO numLocalAggs, LO numFineNodes)
MueLu::DefaultLocalOrdinal LocalOrdinal
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
std::string getPVTUFileName(int numProcs, int myRank, int level, const Teuchos::ParameterList &pL) const
void writeFileVTKOpening(std::ofstream &fout, std::vector< int > &uniqueFine, std::vector< int > &geomSizesFine) const
void writeFileVTKCoordinates(std::ofstream &fout, std::vector< int > &uniqueFine, Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &fx, Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &fy, Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &fz, int dim) const
std::string replaceAll(std::string result, const std::string &replaceWhat, const std::string &replaceWithWhat) const
static void doConvexHulls2D(std::vector< int > &vertices, std::vector< int > &geomSizes, LO numLocalAggs, LO numFineNodes, const std::vector< bool > &isRoot, const ArrayRCP< LO > &vertex2AggId, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &xCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &yCoords)
static void doCGALConvexHulls3D(std::vector< int > &vertices, std::vector< int > &geomSizes, LO numLocalAggs, LO numFineNodes, const std::vector< bool > &isRoot, const ArrayRCP< LO > &vertex2AggId, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &xCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &yCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &zCoords)
T & get(const std::string &name, T def_value)
void writeFileVTKData(std::ofstream &fout, std::vector< int > &uniqueFine, LocalOrdinal myAggOffset, ArrayRCP< LocalOrdinal > &vertex2AggId, int myRank) const
static void doCGALConvexHulls2D(std::vector< int > &vertices, std::vector< int > &geomSizes, LO numLocalAggs, LO numFineNodes, const std::vector< bool > &isRoot, const ArrayRCP< LO > &vertex2AggId, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &xCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &yCoords)
virtual size_t GetNodeNumVertices() const =0
Return number of vertices owned by the calling node.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void buildColormap() const
std::vector< int > makeUnique(std::vector< int > &vertices) const
replaces node indices in vertices with compressed unique indices, and returns list of unique points ...
std::string getFileName(int numProcs, int myRank, int level, const Teuchos::ParameterList &pL) const
void writeFileVTKNodes(std::ofstream &fout, std::vector< int > &uniqueFine, Teuchos::RCP< const Map > &nodeMap) const
RCP< ParameterList > GetValidParameterList() const
static int ccw(const myVec2 &a, const myVec2 &b, const myVec2 &c)
static double pointDistFromTri(myVec3 point, myVec3 v1, myVec3 v2, myVec3 v3)
static double dotProduct(myVec2 v1, myVec2 v2)
void writePVTU(std::ofstream &pvtu, std::string baseFname, int numProcs, bool bFineEdges=false, bool bCoarseEdges=false) const
std::string getBaseFileName(int numProcs, int level, const Teuchos::ParameterList &pL) const
static void doConvexHulls3D(std::vector< int > &vertices, std::vector< int > &geomSizes, LO numLocalAggs, LO numFineNodes, const std::vector< bool > &isRoot, const ArrayRCP< LO > &vertex2AggId, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &xCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &yCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &zCoords)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultGlobalOrdinal GlobalOrdinal
static void doGraphEdges(std::vector< int > &vertices, std::vector< int > &geomSizes, Teuchos::RCP< GraphBase > &G, Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &fx, Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &fy, Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &fz)
static void doJacks(std::vector< int > &vertices, std::vector< int > &geomSizes, LO numLocalAggs, LO numFineNodes, const std::vector< bool > &isRoot, const ArrayRCP< LO > &vertex2AggId)
static myVec2 getNorm(myVec2 v)
static myVec3 crossProduct(myVec3 v1, myVec3 v2)
static myVec2 vecSubtract(myVec2 v1, myVec2 v2)
static double distance(myVec2 p1, myVec2 p2)
void writeFileVTKCells(std::ofstream &fout, std::vector< int > &uniqueFine, std::vector< LocalOrdinal > &vertices, std::vector< LocalOrdinal > &geomSize) const
static bool isInFront(myVec3 point, myVec3 inPlane, myVec3 n)
Exception throws to report errors in the internal logical of the program.
static std::vector< myTriangle > processTriangle(std::list< myTriangle > &tris, myTriangle tri, std::list< int > &pointsInFront, myVec3 &barycenter, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &xCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &yCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &zCoords)
static double mymagnitude(myVec2 vec)
void replaceAll(std::string &str, const std::string &from, const std::string &to)
virtual Teuchos::ArrayView< const LocalOrdinal > getNeighborVertices(LocalOrdinal v) const =0
Return the list of vertices adjacent to the vertex 'v'.
static std::vector< int > giftWrap(std::vector< myVec2 > &points, std::vector< int > &nodes, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &xCoords, const Teuchos::ArrayRCP< const typename Teuchos::ScalarTraits< Scalar >::coordinateType > &yCoords)
void writeFileVTKClosing(std::ofstream &fout) const