122 const ParameterList& pL = GetParameterList();
124 Teuchos::RCP<Aggregates> aggregates = Get<Teuchos::RCP<Aggregates>>(fineLevel,
"Aggregates");
125 Teuchos::RCP<const Teuchos::Comm<int>> comm = aggregates->GetMap()->getComm();
126 int numProcs = comm->getSize();
127 int myRank = comm->getRank();
128 string masterFilename = pL.get<std::string>(
"aggregation: output filename");
129 string pvtuFilename =
"";
130 string localFilename = pL.get<std::string>(
"Output filename");
131 string filenameToWrite;
133 doCoarseGraphEdges_ = pL.get<
bool>(
"aggregation: output file: coarse graph edges");
134 doFineGraphEdges_ = pL.get<
bool>(
"aggregation: output file: fine graph edges");
135 doAggQuality_ = pL.get<
bool>(
"aggregation: output file: aggregate qualities");
136 doMaterial_ = pL.get<
bool>(
"aggregation: output file: material");
137 if (masterFilename.length()) {
139 filenameToWrite = masterFilename;
140 if (filenameToWrite.rfind(
".vtu") == string::npos)
141 filenameToWrite.append(
".vtu");
142 if (numProcs > 1 && filenameToWrite.rfind(
"%PROCID") == string::npos)
143 filenameToWrite.insert(filenameToWrite.rfind(
".vtu"),
"-proc%PROCID");
145 filenameToWrite = localFilename;
146 LocalOrdinal DofsPerNode = Get<LocalOrdinal>(fineLevel,
"DofsPerNode");
147 Teuchos::RCP<AmalgamationInfo> amalgInfo = Get<RCP<AmalgamationInfo>>(fineLevel,
"UnAmalgamationInfo");
148 Teuchos::RCP<Matrix> Amat = Get<RCP<Matrix>>(fineLevel,
"A");
149 Teuchos::RCP<Matrix> Ac;
150 if (doCoarseGraphEdges_)
151 Ac = Get<RCP<Matrix>>(coarseLevel,
"A");
152 Teuchos::RCP<CoordinateMultiVector> coords = Teuchos::null;
153 Teuchos::RCP<CoordinateMultiVector> coordsCoarse = Teuchos::null;
155 qualities_ = Get<Teuchos::RCP<MultiVector>>(coarseLevel,
"AggregateQualities");
157 material_ = Get<Teuchos::RCP<MultiVector>>(fineLevel,
"Material");
158 Teuchos::RCP<LWGraph> fineGraph = Teuchos::null;
159 Teuchos::RCP<LWGraph> coarseGraph = Teuchos::null;
160 if (doFineGraphEdges_)
161 fineGraph = Get<RCP<LWGraph>>(fineLevel,
"Graph");
162 if (doCoarseGraphEdges_)
163 coarseGraph = Get<RCP<LWGraph>>(coarseLevel,
"Graph");
166 coords = Get<RCP<CoordinateMultiVector>>(fineLevel,
"Coordinates");
168 if (doCoarseGraphEdges_)
169 coordsCoarse = Get<RCP<CoordinateMultiVector>>(coarseLevel,
"Coordinates");
170 dims_ = coords->getNumVectors();
172 if (aggregates->AggregatesCrossProcessors()) {
173 RCP<Import> coordImporter = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(coords->getMap(), Amat->getColMap());
174 RCP<CoordinateMultiVector> ghostedCoords = Xpetra::MultiVectorFactory<coordinate_type, LocalOrdinal, GlobalOrdinal, Node>::Build(Amat->getColMap(), dims_);
175 ghostedCoords->doImport(*coords, *coordImporter, Xpetra::INSERT);
176 coords = ghostedCoords;
177 coords_ = ghostedCoords;
179 if (doCoarseGraphEdges_) {
180 RCP<Import> coordImporter = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(coordsCoarse->getMap(), Ac->getColMap());
181 RCP<CoordinateMultiVector> ghostedCoords = Xpetra::MultiVectorFactory<coordinate_type, LocalOrdinal, GlobalOrdinal, Node>::Build(Ac->getColMap(), dims_);
182 ghostedCoords->doImport(*coordsCoarse, *coordImporter, Xpetra::INSERT);
183 coordsCoarse = ghostedCoords;
184 coordsCoarse_ = ghostedCoords;
188 GetOStream(
Runtime0) <<
"AggregationExportFactory: DofsPerNode: " << DofsPerNode << std::endl;
190 Teuchos::RCP<LocalOrdinalMultiVector> vertex2AggId = aggregates->GetVertex2AggId();
191 vertex2AggId_ = vertex2AggId;
194 std::vector<GlobalOrdinal> numAggsGlobal(numProcs, 0);
195 std::vector<GlobalOrdinal> numAggsLocal(numProcs, 0);
196 std::vector<GlobalOrdinal> minGlobalAggId(numProcs, 0);
198 numAggsLocal[myRank] = aggregates->GetNumAggregates();
199 Teuchos::reduceAll(*comm, Teuchos::REDUCE_SUM, numProcs, &numAggsLocal[0], &numAggsGlobal[0]);
200 for (
int i = 1; i < Teuchos::as<int>(numAggsGlobal.size()); ++i) {
201 numAggsGlobal[i] += numAggsGlobal[i - 1];
202 minGlobalAggId[i] = numAggsGlobal[i - 1];
207 aggsOffset_ = minGlobalAggId[myRank];
208 ArrayRCP<LO> aggStart;
209 ArrayRCP<GlobalOrdinal> aggToRowMap;
210 amalgInfo->UnamalgamateAggregates(*aggregates, aggStart, aggToRowMap);
211 int timeStep = pL.get<
int>(
"Output file: time step");
212 int iter = pL.get<
int>(
"Output file: iter");
218 string masterStem =
"";
220 masterStem = filenameToWrite.substr(0, filenameToWrite.rfind(
".vtu"));
221 masterStem = this->
replaceAll(masterStem,
"%PROCID",
"");
223 pvtuFilename = masterStem +
"-master.pvtu";
224 string baseFname = filenameToWrite;
226 GetOStream(
Runtime0) <<
"AggregationExportFactory: outputfile \"" << filenameToWrite <<
"\"" << std::endl;
227 ofstream fout(filenameToWrite.c_str());
228 GO numAggs = aggregates->GetNumAggregates();
230 GO indexBase = aggregates->GetMap()->getIndexBase();
231 GO offset = amalgInfo->GlobalOffset();
232 vector<GlobalOrdinal> nodeIds;
233 for (
int i = 0; i < numAggs; ++i) {
234 fout <<
"Agg " << minGlobalAggId[myRank] + i <<
" Proc " << myRank <<
":";
237 for (
int k = aggStart[i]; k < aggStart[i + 1]; ++k) {
238 nodeIds.push_back((aggToRowMap[k] - offset - indexBase) / DofsPerNode + indexBase);
242 std::sort(nodeIds.begin(), nodeIds.end());
243 typename std::vector<GlobalOrdinal>::iterator endLocation = std::unique(nodeIds.begin(), nodeIds.end());
244 nodeIds.erase(endLocation, nodeIds.end());
247 for (
typename std::vector<GlobalOrdinal>::iterator printIt = nodeIds.begin(); printIt != nodeIds.end(); printIt++)
248 fout <<
" " << *printIt;
255 TEUCHOS_TEST_FOR_EXCEPTION(coords.is_null(),
Exceptions::RuntimeError,
"AggExportFactory could not get coordinates, but they are required for VTK output.");
257 numNodes_ = coords->getLocalLength();
259 aggSizes_ = aggregates->ComputeAggregateSizesArrayRCP();
261 string aggStyle =
"Point Cloud";
263 aggStyle = pL.get<
string>(
"aggregation: output file: agg style");
264 }
catch (std::exception& e) {
266 vector<int> vertices;
267 vector<int> geomSizes;
269 nodeMap_ = Amat->getMap();
271 isRoot_.push_back(aggregates->IsRoot(i));
275 if (myRank == 0 && (numProcs != 1 || doCoarseGraphEdges_ || doFineGraphEdges_)) {
276 ofstream pvtu(pvtuFilename.c_str());
277 writePVTU_(pvtu, baseFname, numProcs);
280 if (aggStyle ==
"Point Cloud")
281 this->doPointCloud(vertices, geomSizes, numAggs_, numNodes_);
282 else if (aggStyle ==
"Jacks") {
283 auto vertex2AggIds = vertex2AggId_->getDataNonConst(0);
284 this->doJacks(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggIds);
285 }
else if (aggStyle ==
"Jacks++")
286 doJacksPlus_(vertices, geomSizes);
287 else if (aggStyle ==
"Convex Hulls")
288 doConvexHulls(vertices, geomSizes);
290 GetOStream(
Warnings0) <<
" Unrecognized agg style.\n Possible values are Point Cloud, Jacks, Jacks++, and Convex Hulls.\n Defaulting to Point Cloud." << std::endl;
291 aggStyle =
"Point Cloud";
292 this->doPointCloud(vertices, geomSizes, numAggs_, numNodes_);
294 writeFile_(fout, aggStyle, vertices, geomSizes);
295 if (doCoarseGraphEdges_) {
296 string fname = filenameToWrite;
297 string cEdgeFile = fname.insert(fname.rfind(
".vtu"),
"-coarsegraph");
298 std::ofstream edgeStream(cEdgeFile.c_str());
299 doGraphEdges_(edgeStream, Ac, coarseGraph,
false, DofsPerNode);
301 if (doFineGraphEdges_) {
302 string fname = filenameToWrite;
303 string fEdgeFile = fname.insert(fname.rfind(
".vtu"),
"-finegraph");
304 std::ofstream edgeStream(fEdgeFile.c_str());
305 doGraphEdges_(edgeStream, Amat, fineGraph,
true, DofsPerNode);
307 if (myRank == 0 && pL.get<
bool>(
"aggregation: output file: build colormap")) {
338 ArrayView<const Scalar> values;
340 vector<pair<int, int>> vert1;
341 vector<pair<int, int>> vert2;
343 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> xCoords = coords_->getData(0);
344 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> yCoords = coords_->getData(1);
345 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> zCoords = Teuchos::null;
347 zCoords = coords_->getData(2);
349 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> cx = coordsCoarse_->getData(0);
350 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> cy = coordsCoarse_->getData(1);
351 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> cz = Teuchos::null;
353 cz = coordsCoarse_->getData(2);
355 if (A->isGloballyIndexed()) {
356 ArrayView<const GlobalOrdinal> indices;
359 A->getGlobalRowView(globRow, indices, values);
360 auto neighbors = G->getNeighborVertices((
LocalOrdinal)globRow);
363 while (gEdge !=
int(neighbors.length)) {
365 if (neighbors(gEdge) == indices[aEdge]) {
367 vert1.push_back(pair<int, int>(
int(globRow), neighbors(gEdge)));
372 vert2.push_back(pair<int, int>(
int(globRow), neighbors(gEdge)));
377 vert1.push_back(pair<int, int>(
int(globRow), neighbors(gEdge)));
383 ArrayView<const LocalOrdinal> indices;
386 A->getLocalRowView(locRow, indices, values);
387 auto neighbors = G->getNeighborVertices(locRow);
391 while (gEdge !=
int(neighbors.length)) {
393 if (neighbors(gEdge) == indices[aEdge]) {
394 vert1.push_back(pair<int, int>(locRow, neighbors(gEdge)));
398 vert2.push_back(pair<int, int>(locRow, neighbors(gEdge)));
402 vert1.push_back(pair<int, int>(locRow, neighbors(gEdge)));
408 for (
size_t i = 0; i < vert1.size(); i++) {
409 if (vert1[i].first > vert1[i].second) {
410 int temp = vert1[i].first;
411 vert1[i].first = vert1[i].second;
412 vert1[i].second = temp;
415 for (
size_t i = 0; i < vert2.size(); i++) {
416 if (vert2[i].first > vert2[i].second) {
417 int temp = vert2[i].first;
418 vert2[i].first = vert2[i].second;
419 vert2[i].second = temp;
422 sort(vert1.begin(), vert1.end());
423 vector<pair<int, int>>::iterator newEnd = unique(vert1.begin(), vert1.end());
424 vert1.erase(newEnd, vert1.end());
425 sort(vert2.begin(), vert2.end());
426 newEnd = unique(vert2.begin(), vert2.end());
427 vert2.erase(newEnd, vert2.end());
429 points1.reserve(2 * vert1.size());
430 for (
size_t i = 0; i < vert1.size(); i++) {
431 points1.push_back(vert1[i].first);
432 points1.push_back(vert1[i].second);
435 points2.reserve(2 * vert2.size());
436 for (
size_t i = 0; i < vert2.size(); i++) {
437 points2.push_back(vert2[i].first);
438 points2.push_back(vert2[i].second);
440 vector<int> unique1 = this->makeUnique(points1);
441 vector<int> unique2 = this->makeUnique(points2);
442 fout <<
"<VTKFile type=\"UnstructuredGrid\" byte_order=\"LittleEndian\">" << endl;
443 fout <<
" <UnstructuredGrid>" << endl;
444 fout <<
" <Piece NumberOfPoints=\"" << unique1.size() + unique2.size() <<
"\" NumberOfCells=\"" << vert1.size() + vert2.size() <<
"\">" << endl;
445 fout <<
" <PointData Scalars=\"Node Aggregate Processor\">" << endl;
446 fout <<
" <DataArray type=\"Int32\" Name=\"Node\" format=\"ascii\">" << endl;
449 for (
size_t i = 0; i < unique1.size(); i++) {
450 fout << CONTRAST_1_ <<
" ";
455 for (
size_t i = 0; i < unique2.size(); i++) {
456 fout << CONTRAST_2_ <<
" ";
457 if ((i + 2 * vert1.size()) % 25 == 24)
462 fout <<
" </DataArray>" << endl;
463 fout <<
" <DataArray type=\"Int32\" Name=\"Aggregate\" format=\"ascii\">" << endl;
465 for (
size_t i = 0; i < unique1.size(); i++) {
466 fout << CONTRAST_1_ <<
" ";
471 for (
size_t i = 0; i < unique2.size(); i++) {
472 fout << CONTRAST_2_ <<
" ";
473 if ((i + 2 * vert2.size()) % 25 == 24)
478 fout <<
" </DataArray>" << endl;
479 fout <<
" <DataArray type=\"Int32\" Name=\"Processor\" format=\"ascii\">" << endl;
481 for (
size_t i = 0; i < unique1.size() + unique2.size(); i++) {
482 fout << myRank_ <<
" ";
488 fout <<
" </DataArray>" << endl;
489 fout <<
" </PointData>" << endl;
490 fout <<
" <Points>" << endl;
491 fout <<
" <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">" << endl;
493 for (
size_t i = 0; i < unique1.size(); i++) {
495 fout << xCoords[unique1[i]] <<
" " << yCoords[unique1[i]] <<
" ";
497 fout << zCoords[unique1[i]] <<
" ";
504 fout << cx[unique1[i]] <<
" " << cy[unique1[i]] <<
" ";
506 fout << cz[unique1[i]] <<
" ";
514 for (
size_t i = 0; i < unique2.size(); i++) {
516 fout << xCoords[unique2[i]] <<
" " << yCoords[unique2[i]] <<
" ";
518 fout << zCoords[unique2[i]] <<
" ";
525 fout << cx[unique2[i]] <<
" " << cy[unique2[i]] <<
" ";
527 fout << cz[unique2[i]] <<
" ";
530 if ((i + unique1.size()) % 2)
536 fout <<
" </DataArray>" << endl;
537 fout <<
" </Points>" << endl;
538 fout <<
" <Cells>" << endl;
539 fout <<
" <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << endl;
541 for (
size_t i = 0; i < points1.size(); i++) {
542 fout << points1[i] <<
" ";
547 for (
size_t i = 0; i < points2.size(); i++) {
548 fout << points2[i] + unique1.size() <<
" ";
549 if ((i + points1.size()) % 10 == 9)
554 fout <<
" </DataArray>" << endl;
555 fout <<
" <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << endl;
558 for (
size_t i = 0; i < vert1.size() + vert2.size(); i++) {
560 fout << offset <<
" ";
566 fout <<
" </DataArray>" << endl;
567 fout <<
" <DataArray type=\"Int32\" Name=\"types\" format=\"ascii\">" << endl;
569 for (
size_t i = 0; i < vert1.size() + vert2.size(); i++) {
576 fout <<
" </DataArray>" << endl;
577 fout <<
" </Cells>" << endl;
578 fout <<
" </Piece>" << endl;
579 fout <<
" </UnstructuredGrid>" << endl;
580 fout <<
"</VTKFile>" << endl;
587 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> xCoords = coords_->getData(0);
588 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> yCoords = coords_->getData(1);
589 Teuchos::ArrayRCP<const typename Teuchos::ScalarTraits<Scalar>::coordinateType> zCoords = Teuchos::null;
591 zCoords = coords_->getData(2);
593 auto vertex2AggIds = vertex2AggId_->getDataNonConst(0);
595 Teuchos::ArrayRCP<const Scalar> qualities;
597 qualities = qualities_->getData(0);
599 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar>> material;
601 size_t dim = material_->getNumVectors();
602 material.resize(dim);
603 for (
size_t k = 0; k < dim; k++)
604 material[k] = material_->getData(k);
607 vector<int> uniqueFine = this->makeUnique(vertices);
609 fout <<
"<!--" << styleName <<
" Aggregates Visualization-->" << endl;
610 fout <<
"<VTKFile type=\"UnstructuredGrid\" byte_order=\"LittleEndian\">" << endl;
611 fout <<
" <UnstructuredGrid>" << endl;
612 fout <<
" <Piece NumberOfPoints=\"" << uniqueFine.size() <<
"\" NumberOfCells=\"" << geomSizes.size() <<
"\">" << endl;
613 fout <<
" <PointData Scalars=\"Node Aggregate Processor\">" << endl;
614 fout <<
" <DataArray type=\"Int32\" Name=\"Node\" format=\"ascii\">" << endl;
618 for (
size_t i = 0; i < uniqueFine.size(); i++) {
620 fout << uniqueFine[i] <<
" ";
622 fout << nodeMap_->getGlobalElement(uniqueFine[i]) <<
" ";
628 fout <<
" </DataArray>" << endl;
629 fout <<
" <DataArray type=\"Int32\" Name=\"Aggregate\" format=\"ascii\">" << endl;
631 for (
size_t i = 0; i < uniqueFine.size(); i++) {
632 if (vertex2AggIds[uniqueFine[i]] == -1)
633 fout << vertex2AggIds[uniqueFine[i]] <<
" ";
635 fout << aggsOffset_ + vertex2AggIds[uniqueFine[i]] <<
" ";
641 fout <<
" </DataArray>" << endl;
642 fout <<
" <DataArray type=\"Int32\" Name=\"Processor\" format=\"ascii\">" << endl;
644 for (
size_t i = 0; i < uniqueFine.size(); i++) {
645 fout << myRank_ <<
" ";
651 fout <<
" </DataArray>" << endl;
653 fout <<
" <DataArray type=\"Float64\" Name=\"Quality\" format=\"ascii\">" << endl;
655 for (
size_t i = 0; i < uniqueFine.size(); i++) {
656 fout << qualities[vertex2AggIds[uniqueFine[i]]] <<
" ";
662 fout <<
" </DataArray>" << endl;
666 size_t dim = material_->getNumVectors();
667 fout <<
" <DataArray type=\"Float64\" NumberOfComponents=\"" << dim <<
"\" Name=\"Material\" format=\"ascii\">" << endl;
669 for (
size_t i = 0; i < uniqueFine.size(); i++) {
670 for (
size_t k = 0; k < dim; k++) {
671 fout << material[k][uniqueFine[i]] <<
" ";
677 fout <<
" </DataArray>" << endl;
679 fout <<
" </PointData>" << endl;
680 fout <<
" <Points>" << endl;
681 fout <<
" <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">" << endl;
683 for (
size_t i = 0; i < uniqueFine.size(); i++) {
684 fout << xCoords[uniqueFine[i]] <<
" " << yCoords[uniqueFine[i]] <<
" ";
688 fout << zCoords[uniqueFine[i]] <<
" ";
694 fout <<
" </DataArray>" << endl;
695 fout <<
" </Points>" << endl;
696 fout <<
" <Cells>" << endl;
697 fout <<
" <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << endl;
699 for (
size_t i = 0; i < vertices.size(); i++) {
700 fout << vertices[i] <<
" ";
706 fout <<
" </DataArray>" << endl;
707 fout <<
" <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << endl;
710 for (
size_t i = 0; i < geomSizes.size(); i++) {
711 accum += geomSizes[i];
712 fout << accum <<
" ";
718 fout <<
" </DataArray>" << endl;
719 fout <<
" <DataArray type=\"Int32\" Name=\"types\" format=\"ascii\">" << endl;
721 for (
size_t i = 0; i < geomSizes.size(); i++) {
722 switch (geomSizes[i]) {
740 fout <<
" </DataArray>" << endl;
741 fout <<
" </Cells>" << endl;
742 fout <<
" </Piece>" << endl;
743 fout <<
" </UnstructuredGrid>" << endl;
744 fout <<
"</VTKFile>" << endl;