7#include <base64_rfc4648.hpp>
10#include <nanoflann.hpp>
31 tAdj cell2nodeSerialDummy;
32 tPbi cell2nodePbiSerialDummy;
34 coordSerialDummy = make_ssp<decltype(coordSerialDummy)::element_type>(
ObjName{
"GetCurrentOutputArrays::coordSerialDummy"},
mesh->getMPI());
35 cell2nodeSerialDummy = make_ssp<decltype(cell2nodeSerialDummy)::element_type>(
ObjName{
"GetCurrentOutputArrays::cell2nodeSerialDummy"},
mesh->getMPI());
42 coordOut.
son = coordSerialDummy;
44 cell2nodeOut.
son = cell2nodeSerialDummy;
48 cell2nodePbiOut.
son = cell2nodePbiSerialDummy;
51 cellElemInfoOut.
son = cellElemInfoSerialDummy;
58 coordOut.
son =
mesh->coords.son;
63 cell2nodePbiOut.
father =
mesh->cell2nodePbi.father;
64 cell2nodePbiOut.
son =
mesh->cell2nodePbi.son;
66 cellElemInfoOut.
father =
mesh->cellElemInfo.father;
67 cellElemInfoOut.
son =
mesh->cellElemInfo.son;
74 static void GetViolentNodeDeduplication(
76 std::vector<index> &nodeDedu2Old, std::vector<index> &nodeOld2Dedu)
86 nNode + nodesExtra.size());
87 using kdtree_t = nanoflann::KDTreeSingleIndexAdaptor<
88 nanoflann::L2_Simple_Adaptor<real, PointCloudFunctional>,
92 kdtree_t kdTree(3, nodesCloud);
93 nodeOld2Dedu.resize(nodesCloud.size(), -1);
94 index iNodeDeduTop{0};
95 for (
index i = 0;
i < nodesCloud.size();
i++)
97 if (nodeOld2Dedu[
i] != -1)
100#if NANOFLANN_VERSION < 0x150
101 std::vector<std::pair<DNDS::index, DNDS::real>> IndicesDists;
103 std::vector<nanoflann::ResultItem<DNDS::index, DNDS::real>> IndicesDists;
105 IndicesDists.reserve(5);
106#if NANOFLANN_VERSION < 0x150
107 nanoflann::SearchParams params{};
109 nanoflann::SearchParameters params{};
111 index nFound = kdTree.radiusSearch(cn.data(), 1e-20, IndicesDists, params);
113 for (
auto &
v : IndicesDists)
117 nodeOld2Dedu.at(
v.first) = iNodeDeduTop;
122 nodeDedu2Old.resize(iNodeDeduTop, -1);
123 for (
index i = 0;
i < nodeOld2Dedu.size();
i++)
124 nodeDedu2Old.at(nodeOld2Dedu.at(
i)) =
i;
129 int arraySiz,
int arraySizPoint,
136 auto mpi =
mesh->getMPI();
138 if (mpi.rank !=
mRank && flag == 0)
144 std::filesystem::path outFile{fname};
145 std::filesystem::create_directories(outFile.parent_path() /
".");
151 std::filesystem::path outPath{fname +
".dir"};
152 std::filesystem::create_directories(outPath);
153 std::array<char, 512> BUF{};
154 std::sprintf(BUF.data(),
"%06d", mpi.rank);
158 std::ofstream fout(fname, std::ios::binary);
161 DNDS::log() <<
"Error: WriteMeshDebugTecASCII open \"" << fname <<
"\" failure" << std::endl;
164 const std::array<char, 9> magic_word{
"#!TDV112"};
165 const int b_magic_word = magic_word.size() - 1;
167 double_t doubleBuf = 0.0;
168 float_t floatBuf = 0.0F;
170 auto writeInt = [&](
int d) ->
void
173 fout.write(
reinterpret_cast<char *
>(&intBuf),
sizeof(intBuf));
175 auto writeFloat = [&](float_t d) ->
void
178 fout.write(
reinterpret_cast<char *
>(&floatBuf),
sizeof(floatBuf));
180 auto writeDouble = [&](double_t d) ->
void
183 fout.write(
reinterpret_cast<char *
>(&doubleBuf),
sizeof(doubleBuf));
185 auto writeString = [&](
const std::string &title) ->
void
189 intBuf =
static_cast<unsigned char>(
i);
190 fout.write(
reinterpret_cast<char *
>(&intBuf),
sizeof(intBuf));
193 fout.write(
reinterpret_cast<char *
>(&intBuf),
sizeof(intBuf));
195 fout.write(magic_word.data(), b_magic_word);
198 writeString(
"Title Here");
199 writeInt(arraySiz + 3 + 1 + arraySizPoint);
203 for (
int idata = 0; idata < arraySizPoint; idata++)
204 writeString(namesPoint(idata));
205 for (
int idata = 0; idata < arraySiz; idata++)
206 writeString(names(idata));
207 writeString(
"iPart");
213 writeString(
"zone_0");
220 else if (
mesh->dim == 3)
222 else if (
mesh->dim == 1)
226 for (
int idim = 0; idim < 3; idim++)
228 for (
int idata = 0; idata < arraySizPoint; idata++)
230 for (
int idata = 0; idata < arraySiz; idata++)
247 std::vector<Geom::tPoint>
249 std::vector<index> nodesExtraAtOriginal;
250 if (
mesh->isPeriodic)
253 for (
rowsize ic2n = 0; ic2n < cell2nodePbiOut.
RowSize(iCell); ic2n++)
254 if (cell2nodePbiOut[iCell][ic2n])
255 nodesExtra.push_back(
mesh->periodicInfo.GetCoordByBits(coordOut[cell2nodeOut[iCell][ic2n]], cell2nodePbiOut[iCell][ic2n])),
256 nodesExtraAtOriginal.push_back(cell2nodeOut(iCell, ic2n));
267 std::vector<index> nodeDedu2Old;
268 std::vector<index> nodeOld2Dedu;
269 GetViolentNodeDeduplication(
nNode, nodesExtra, coordOut, nodeDedu2Old, nodeOld2Dedu);
272 writeInt(nodeDedu2Old.size());
288 for (
int idim = 0; idim < 3; idim++)
290 for (
int idata = 0; idata < arraySizPoint; idata++)
292 for (
int idata = 0; idata < arraySiz; idata++)
304 for (
int idim = 0; idim < 3; idim++)
309 minVal[idim] = std::min(coordOut[iN](idim), minVal[idim]);
310 maxVal[idim] = std::max(coordOut[iN](idim), maxVal[idim]);
314 minVal[idim] = std::min(nodesExtra.at(iN -
nNode)(idim), minVal[idim]);
315 maxVal[idim] = std::max(nodesExtra.at(iN -
nNode)(idim), maxVal[idim]);
319 for (
int idata = 0; idata < arraySiz; idata++)
322 minVal[3 + idata] = std::min(data(idata, iv), minVal[3 + idata]);
323 maxVal[3 + idata] = std::max(data(idata, iv), maxVal[3 + idata]);
326 for (
int idata = 0; idata < arraySizPoint; idata++)
329 minValPoint[idata] = std::min(dataPoint(idata, iv), minValPoint[idata]);
330 maxValPoint[idata] = std::max(dataPoint(idata, iv), maxValPoint[idata]);
333 for (
int idim = 0; idim < 3; idim++)
335 writeDouble(minVal[idim]);
336 writeDouble(maxVal[idim]);
338 for (
int idata = 0; idata < arraySizPoint; idata++)
340 writeDouble(minValPoint[idata]);
341 writeDouble(maxValPoint[idata]);
343 for (
int idata = 0; idata < arraySiz; idata++)
345 writeDouble(minVal[3 + idata]);
346 writeDouble(maxVal[3 + idata]);
349 writeDouble(mpi.size);
351 for (
int idim = 0; idim < 3; idim++)
353 for (
auto iN : nodeDedu2Old)
356 writeDouble(coordOut[iN](idim));
358 writeDouble(nodesExtra.at(iN -
nNode)(idim));
362 for (
int idata = 0; idata < arraySizPoint; idata++)
364 for (
auto iN : nodeDedu2Old)
367 writeDouble(dataPoint(idata, iN));
369 writeDouble(dataPoint(idata, nodesExtraAtOriginal.at(iN -
nNode)));
373 for (
int idata = 0; idata < arraySiz; idata++)
376 writeDouble(data(idata, iv));
390 r =
mesh->getMPI().rank;
405 auto elem =
Elem::Element{cellElemInfoOut[iv]->getElemType()};
406 std::vector<index> c2n = cell2nodeOut[iv];
407 if (
mesh->isPeriodic)
408 for (
rowsize ic2n = 0; ic2n < c2n.size(); ic2n++)
410 if (cell2nodePbiOut[iv][ic2n])
411 c2n[ic2n] = (nExtra++) +
nNode;
415 v = nodeOld2Dedu.at(
v);
416 switch (elem.GetParamSpace())
419 writeInt(c2n[0] + 0LL);
420 writeInt(c2n[1] + 0LL);
423 writeInt(c2n[0] + 0LL);
424 writeInt(c2n[1] + 0LL);
425 writeInt(c2n[2] + 0LL);
426 writeInt(c2n[2] + 0LL);
429 writeInt(c2n[0] + 0LL);
430 writeInt(c2n[1] + 0LL);
431 writeInt(c2n[2] + 0LL);
432 writeInt(c2n[3] + 0LL);
435 writeInt(c2n[0] + 0LL);
436 writeInt(c2n[1] + 0LL);
437 writeInt(c2n[2] + 0LL);
438 writeInt(c2n[2] + 0LL);
439 writeInt(c2n[3] + 0LL);
440 writeInt(c2n[3] + 0LL);
441 writeInt(c2n[3] + 0LL);
442 writeInt(c2n[3] + 0LL);
445 writeInt(c2n[0] + 0LL);
446 writeInt(c2n[1] + 0LL);
447 writeInt(c2n[2] + 0LL);
448 writeInt(c2n[3] + 0LL);
449 writeInt(c2n[4] + 0LL);
450 writeInt(c2n[5] + 0LL);
451 writeInt(c2n[6] + 0LL);
452 writeInt(c2n[7] + 0LL);
455 writeInt(c2n[0] + 0LL);
456 writeInt(c2n[1] + 0LL);
457 writeInt(c2n[2] + 0LL);
458 writeInt(c2n[2] + 0LL);
459 writeInt(c2n[3] + 0LL);
460 writeInt(c2n[4] + 0LL);
461 writeInt(c2n[5] + 0LL);
462 writeInt(c2n[5] + 0LL);
465 writeInt(c2n[0] + 0LL);
466 writeInt(c2n[1] + 0LL);
467 writeInt(c2n[2] + 0LL);
468 writeInt(c2n[3] + 0LL);
469 writeInt(c2n[4] + 0LL);
470 writeInt(c2n[4] + 0LL);
471 writeInt(c2n[4] + 0LL);
472 writeInt(c2n[4] + 0LL);
481 static void updateVTKSeries(std::string seriesName, std::string fname,
real tSimu)
483 using json = nlohmann::json;
485 if (std::filesystem::exists(seriesName))
487 std::ifstream fin(seriesName);
494 j[
"file-series-version"] =
"1.0";
495 j[
"files"] = json::array();
497 std::map<std::string, real> series;
498 for (
auto &f :
j[
"files"])
499 series[f[
"name"].get<std::string>()] = f[
"time"].get<
real>();
500 series[fname] = tSimu;
502 for (
auto &[fn, tS] : series)
504 j[
"files"].emplace_back(json::object());
505 j[
"files"].back()[
"name"] = fn;
506 j[
"files"].back()[
"time"] = tS;
508 std::ofstream fout(seriesName);
521 struct VTKCellTopology
544 VTKCellTopology BuildVTKCellTopology(
550 const std::vector<DNDS::index> &nodeOld2Dedu,
554 result.connectivity.reserve(cell2nodeOut.father->DataSize() * 2);
561 auto elem = Elem::Element{cellElemInfoOut[iCell]->getElemType()};
562 std::vector<DNDS::index> c2n = cell2nodeOut[iCell];
565 if (cell2nodePbiOut(iCell, ic2n))
566 c2n[ic2n] = (nNodeExtra++) +
nNode;
568 v = nodeOld2Dedu.at(
v);
570 result.cellTypes[iCell] = vtkCell.first;
571 for (
auto in : vtkCell.second)
573 cellEnd += vtkCell.second.size();
574 result.offsets[iCell] = cellEnd;
585 void WritePVTUMasterFile(
586 const std::string &fnameIN,
587 const std::filesystem::path &outPath,
588 const std::string &endianName,
589 const std::string &seriesName,
592 int arraySiz,
int vecArraySiz,
593 int arraySizPoint,
int vecArraySizPoint,
598 const std::string &indentV,
599 const std::string &newlineV)
602 auto writeXMLEntity = [&](std::ostream &out,
int level,
const auto &name,
603 const std::vector<std::pair<std::string, std::string>> &attr,
604 auto &&writeContent) ->
void
606 for (
int i = 0;
i < level;
i++)
608 out <<
"<" << name <<
" ";
609 for (
const auto &a : attr)
610 out << a.first <<
"=\"" << a.second <<
"\" ";
611 out <<
">" << newlineV;
612 writeContent(out, level + 1);
613 for (
int i = 0;
i < level;
i++)
615 out <<
"</" << name <<
">" << newlineV;
618 std::filesystem::path foutPP{fnameIN +
".pvtu"};
619 std::ofstream foutP{foutPP};
621 if (!seriesName.empty())
622 updateVTKSeries(seriesName +
".pvtu.series",
getStringForcePath(foutPP.filename()), t);
626 {{
"type",
"PUnstructuredGrid"},
627 {
"byte_order", endianName},
628 {
"header_type",
"UInt64"}},
629 [&](
auto &out,
int level)
632 out, level,
"PUnstructuredGrid",
633 {{
"GhostLevel",
"0"}},
634 [&](
auto &out,
int level)
637 std::string namesAll;
638 for (
int i = 0;
i < arraySiz;
i++)
639 namesAll.append(names(
i) +
" ");
640 std::string vectorsNameAll;
641 for (
int i = 0;
i < vecArraySiz;
i++)
642 vectorsNameAll.append(vectorNames(
i) +
" ");
644 out, level,
"PCellData",
645 {{
"Scalars", namesAll},
646 {
"Vectors", vectorsNameAll}},
647 [&](
auto &out,
int level)
649 for (
int i = 0;
i < arraySiz;
i++)
652 out, level,
"PDataArray",
653 {{
"type",
"Float64"},
655 {
"format",
"ascii"}},
656 [&](
auto &out,
int level) {});
658 for (
int i = 0;
i < vecArraySiz;
i++)
661 out, level,
"PDataArray",
662 {{
"type",
"Float64"},
663 {
"Name", vectorNames(
i)},
664 {
"NumberOfComponents",
"3"},
665 {
"format",
"ascii"}},
666 [&](
auto &out,
int level) {});
672 std::string namesAll;
673 for (
int i = 0;
i < arraySizPoint;
i++)
674 namesAll.append(namesPoint(
i) +
" ");
675 std::string vectorsNameAll;
676 for (
int i = 0;
i < vecArraySizPoint;
i++)
677 vectorsNameAll.append(vectorNamesPoint(
i) +
" ");
679 out, level,
"PPointData",
680 {{
"Scalars", namesAll},
681 {
"Vectors", vectorsNameAll}},
682 [&](
auto &out,
int level)
684 for (
int i = 0;
i < arraySizPoint;
i++)
687 out, level,
"PDataArray",
688 {{
"type",
"Float64"},
689 {
"Name", namesPoint(
i)},
690 {
"format",
"ascii"}},
691 [&](
auto &out,
int level) {});
693 for (
int i = 0;
i < vecArraySizPoint;
i++)
696 out, level,
"PDataArray",
697 {{
"type",
"Float64"},
698 {
"Name", vectorNamesPoint(
i)},
699 {
"NumberOfComponents",
"3"},
700 {
"format",
"ascii"}},
701 [&](
auto &out,
int level) {});
706 out, level,
"PPoints",
708 [&](
auto &out,
int level)
711 out, level,
"PDataArray",
712 {{
"type",
"Float64"},
713 {
"NumberOfComponents",
"3"}},
714 [&](
auto &out,
int level) {});
718 std::array<char, 512> BUF{};
719 std::sprintf(BUF.data(),
"%04d", iRank);
721 outPath.lexically_relative(outPath.parent_path()) / (std::string(BUF.data()) +
".vtu"));
724 {{
"Source", cFileNameRelPVTU}},
725 [&](
auto &out,
int level) {});
752 std::string fname, std::string seriesName,
753 int arraySiz,
int vecArraySiz,
int arraySizPoint,
int vecArraySizPoint,
764 auto mpi =
mesh->getMPI();
765 std::string fnameIN = fname;
767 if (mpi.rank !=
mRank && flag == 0)
773 std::filesystem::path outFile{fname};
774 std::filesystem::create_directories(outFile.parent_path() /
".");
776 if (!seriesName.empty())
777 updateVTKSeries(seriesName +
".vtu.series",
getStringForcePath(outFile.filename()), t);
779 std::filesystem::path outPath;
782 outPath = {fname +
".vtu.dir"};
783 std::filesystem::create_directories(outPath);
784 std::array<char, 512> BUF{};
785 std::sprintf(BUF.data(),
"%04d", mpi.rank);
789 std::ofstream fout(fname);
792 DNDS::log() <<
"Error: PrintSerialPartVTKDataArray open \"" << fname <<
"\" failure" << std::endl;
806 std::vector<Geom::tPoint>
808 std::vector<index> nodesExtraAtOriginal;
809 if (
mesh->isPeriodic)
812 for (
rowsize ic2n = 0; ic2n < cell2nodePbiOut.
RowSize(iCell); ic2n++)
813 if (cell2nodePbiOut[iCell][ic2n])
814 nodesExtra.push_back(
mesh->periodicInfo.GetCoordByBits(coordOut[cell2nodeOut[iCell][ic2n]], cell2nodePbiOut[iCell][ic2n])),
815 nodesExtraAtOriginal.push_back(cell2nodeOut(iCell, ic2n));
826 std::vector<index> nodeDedu2Old;
827 std::vector<index> nodeOld2Dedu;
828 GetViolentNodeDeduplication(
nNode, nodesExtra, coordOut, nodeDedu2Old, nodeOld2Dedu);
831 std::string indentV =
" ";
832 std::string newlineV =
"\n";
834 auto writeXMLEntity = [&](std::ostream &out,
int level,
const auto &name,
const std::vector<std::pair<std::string, std::string>> &attr,
auto &&writeContent) ->
void
836 for (
int i = 0;
i < level;
i++)
838 out <<
"<" << name <<
" ";
839 for (
const auto &a : attr)
840 out << a.first <<
"=\"" << a.second <<
"\" ";
841 out <<
">" << newlineV;
843 writeContent(out, level + 1);
845 for (
int i = 0;
i < level;
i++)
847 out <<
"</" << name <<
">" << newlineV;
850 auto writeCoords = [&](
auto &out,
int level)
853 out, level,
"Points",
855 [&](
auto &out,
int level)
858 out, level,
"DataArray",
859 {{
"type",
"Float64"},
860 {
"NumberOfComponents",
"3"},
861 {
"format", vtuFloatEncodeMode}},
862 [&](
auto &out,
int level)
864 if (vtuFloatEncodeMode ==
"binary")
868 uint64_t binSize = (nodeDedu2Old.size() * 3) *
sizeof(
double);
869 std::vector<uint8_t> dataOutBytes;
870 dataOutBytes.resize(binSize +
sizeof(binSize), 0);
872 *
reinterpret_cast<uint64_t *
>(dataOutBytes.data() + top) = binSize, top +=
sizeof(uint64_t);
873 for (
auto iN : nodeDedu2Old)
877 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(coordOut[iN](0)), top +=
sizeof(
double);
878 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(coordOut[iN](1)), top +=
sizeof(
double);
879 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(coordOut[iN](2)), top +=
sizeof(
double);
883 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(nodesExtra.at(iN -
nNode)(0)), top +=
sizeof(double);
884 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(nodesExtra.at(iN -
nNode)(1)), top +=
sizeof(double);
885 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(nodesExtra.at(iN -
nNode)(2)), top +=
sizeof(double);
888 out << cppcodec::base64_rfc4648::encode(dataOutBytes);
890 else if (vtuFloatEncodeMode ==
"ascii")
892 std::vector<double> coordsOutData(nodeDedu2Old.size() * 3);
893 for (
index i = 0;
i < nodeDedu2Old.size();
i++)
895 index iN = nodeDedu2Old.at(
i);
898 coordsOutData[
i * 3 + 0LL] = coordOut[iN](0);
899 coordsOutData[
i * 3 + 1LL] = coordOut[iN](1);
900 coordsOutData[
i * 3 + 2LL] = coordOut[iN](2);
904 coordsOutData[
i * 3 + 0LL] = nodesExtra.at(iN -
nNode)(0);
905 coordsOutData[
i * 3 + 1LL] = nodesExtra.at(iN -
nNode)(1);
906 coordsOutData[
i * 3 + 2LL] = nodesExtra.at(iN -
nNode)(2);
912 for (
auto v : coordsOutData)
913 out << std::setprecision(ascii_precision) <<
v <<
" ";
922 auto vtkTopo = BuildVTKCellTopology(
924 cellElemInfoOut, nodeOld2Dedu,
mesh->isPeriodic);
925 auto &cell2nodeOutData = vtkTopo.connectivity;
926 auto &cell2nodeOffsetData = vtkTopo.offsets;
927 auto &cellTypeData = vtkTopo.cellTypes;
929 auto writeCells = [&](
auto &out,
int level)
934 [&](
auto &out,
int level)
937 out, level,
"DataArray",
939 {
"Name",
"connectivity"},
940 {
"format",
"ascii"}},
941 [&](
auto &out,
int level)
946 for (
auto v : cell2nodeOutData)
951 out, level,
"DataArray",
954 {
"format",
"ascii"}},
955 [&](
auto &out,
int level)
960 for (
auto v : cell2nodeOffsetData)
965 out, level,
"DataArray",
968 {
"format",
"ascii"}},
969 [&](
auto &out,
int level)
974 for (
int v : cellTypeData)
981 auto writeCellData = [&](
auto &out,
int level)
983 std::string namesAll;
984 for (
int i = 0;
i < arraySiz;
i++)
985 namesAll.append(names(
i) +
" ");
986 std::string vectorsNameAll;
987 for (
int i = 0;
i < vecArraySiz;
i++)
988 vectorsNameAll.append(vectorNames(
i) +
" ");
991 out, level,
"CellData",
992 {{
"Scalars", namesAll},
993 {
"Vectors", vectorsNameAll}},
994 [&](
auto &out,
int level)
996 for (
int i = 0;
i < arraySiz;
i++)
999 out, level,
"DataArray",
1000 {{
"type",
"Float64"},
1002 {
"format", vtuFloatEncodeMode}},
1003 [&](
auto &out,
int level)
1005 if (vtuFloatEncodeMode ==
"binary")
1009 uint64_t binSize =
nCell *
sizeof(double);
1010 std::vector<uint8_t> dataOutBytes;
1011 dataOutBytes.resize(binSize +
sizeof(binSize), 0);
1013 *
reinterpret_cast<uint64_t *
>(dataOutBytes.data() + top) = binSize, top +=
sizeof(uint64_t);
1014 for (
index iCell = 0; iCell <
nCell; iCell++)
1015 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) =
double(data(
i, iCell)), top +=
sizeof(
double);
1016 out << cppcodec::base64_rfc4648::encode(dataOutBytes);
1018 else if (vtuFloatEncodeMode ==
"ascii")
1022 std::vector<double> dataOutC(
nCell);
1023 for (
index iCell = 0; iCell <
nCell; iCell++)
1024 dataOutC[iCell] = data(
i, iCell);
1027 out << std::setprecision(ascii_precision);
1028 for (
auto v : dataOutC)
1037 out, level,
"DataArray",
1040 {
"format",
"ascii"}},
1041 [&](
auto &out,
int level)
1043 std::vector<double> dataOutC(
nCell);
1044 for (
index iCell = 0; iCell <
nCell; iCell++)
1054 r =
mesh->getMPI().rank;
1055 dataOutC[iCell] =
r;
1057 out << std::setprecision(ascii_precision);
1058 for (
auto v : dataOutC)
1062 for (
int i = 0;
i < vecArraySiz;
i++)
1065 out, level,
"DataArray",
1066 {{
"type",
"Float64"},
1067 {
"Name", vectorNames(
i)},
1068 {
"NumberOfComponents",
"3"},
1069 {
"format", vtuFloatEncodeMode}},
1070 [&](
auto &out,
int level)
1072 if (vtuFloatEncodeMode ==
"binary")
1076 uint64_t binSize = (
nCell * 3) *
sizeof(
double);
1077 std::vector<uint8_t> dataOutBytes;
1078 dataOutBytes.resize(binSize +
sizeof(binSize), 0);
1080 *
reinterpret_cast<uint64_t *
>(dataOutBytes.data() + top) = binSize, top +=
sizeof(uint64_t);
1081 for (
index iCell = 0; iCell <
nCell; iCell++)
1083 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorData(
i, iCell, 0), top +=
sizeof(double);
1084 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorData(
i, iCell, 1), top +=
sizeof(double);
1085 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorData(
i, iCell, 2), top +=
sizeof(double);
1087 out << cppcodec::base64_rfc4648::encode(dataOutBytes);
1089 else if (vtuFloatEncodeMode ==
"ascii")
1093 std::vector<double> dataOutC(
nCell * 3);
1094 for (
index iCell = 0; iCell <
nCell; iCell++)
1096 dataOutC[iCell * 3 + 0LL] = vectorData(
i, iCell, 0);
1097 dataOutC[iCell * 3 + 1] = vectorData(
i, iCell, 1);
1098 dataOutC[iCell * 3 + 2] = vectorData(
i, iCell, 2);
1103 for (
auto v : dataOutC)
1104 out << std::setprecision(ascii_precision) <<
v <<
" ";
1114 auto writePointData = [&](
auto &out,
int level)
1116 std::string namesAll;
1117 for (
int i = 0;
i < arraySizPoint;
i++)
1118 namesAll.append(namesPoint(
i) +
" ");
1119 std::string vectorsNameAll;
1120 for (
int i = 0;
i < vecArraySizPoint;
i++)
1121 vectorsNameAll.append(vectorNamesPoint(
i) +
" ");
1124 out, level,
"PointData",
1125 {{
"Scalars", namesAll},
1126 {
"Vectors", vectorsNameAll}},
1127 [&](
auto &out,
int level)
1129 for (
int i = 0;
i < arraySizPoint;
i++)
1132 out, level,
"DataArray",
1133 {{
"type",
"Float64"},
1134 {
"Name", namesPoint(
i)},
1135 {
"format", vtuFloatEncodeMode}},
1136 [&](
auto &out,
int level)
1138 if (vtuFloatEncodeMode ==
"binary")
1142 uint64_t binSize = (nodeDedu2Old.size()) *
sizeof(
double);
1143 std::vector<uint8_t> dataOutBytes;
1144 dataOutBytes.resize(binSize +
sizeof(binSize), 0);
1146 *
reinterpret_cast<uint64_t *
>(dataOutBytes.data() + top) = binSize, top +=
sizeof(uint64_t);
1147 for (
auto iN : nodeDedu2Old)
1150 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = dataPoint(
i, iN), top +=
sizeof(double);
1152 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = dataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode)), top +=
sizeof(
double);
1154 out << cppcodec::base64_rfc4648::encode(dataOutBytes);
1156 else if (vtuFloatEncodeMode ==
"ascii")
1160 out << std::setprecision(ascii_precision);
1161 for (
auto iN : nodeDedu2Old)
1164 out << dataPoint(
i, iN) <<
" ";
1166 out << dataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode)) <<
" ";
1174 for (
int i = 0;
i < vecArraySizPoint;
i++)
1177 out, level,
"DataArray",
1178 {{
"type",
"Float64"},
1179 {
"Name", vectorNamesPoint(
i)},
1180 {
"NumberOfComponents",
"3"},
1181 {
"format", vtuFloatEncodeMode}},
1182 [&](
auto &out,
int level)
1184 if (vtuFloatEncodeMode ==
"binary")
1188 uint64_t binSize = (nodeDedu2Old.size()) * 3 *
sizeof(
double);
1189 std::vector<uint8_t> dataOutBytes;
1190 dataOutBytes.resize(binSize +
sizeof(binSize), 0);
1192 *
reinterpret_cast<uint64_t *
>(dataOutBytes.data() + top) = binSize, top +=
sizeof(uint64_t);
1193 for (
auto iN : nodeDedu2Old)
1197 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorDataPoint(
i, iN, 0), top +=
sizeof(double);
1198 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorDataPoint(
i, iN, 1), top +=
sizeof(double);
1199 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorDataPoint(
i, iN, 2), top +=
sizeof(double);
1203 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorDataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode), 0), top +=
sizeof(
double);
1204 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorDataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode), 1), top +=
sizeof(
double);
1205 *
reinterpret_cast<double *
>(dataOutBytes.data() + top) = vectorDataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode), 2), top +=
sizeof(
double);
1208 out << cppcodec::base64_rfc4648::encode(dataOutBytes);
1210 else if (vtuFloatEncodeMode ==
"ascii")
1214 out << std::setprecision(ascii_precision);
1215 for (
auto iN : nodeDedu2Old)
1219 out << vectorDataPoint(
i, iN, 0) <<
" ";
1220 out << vectorDataPoint(
i, iN, 1) <<
" ";
1221 out << vectorDataPoint(
i, iN, 2) <<
" ";
1225 out << vectorDataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode), 0) <<
" ";
1226 out << vectorDataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode), 1) <<
" ";
1227 out << vectorDataPoint(
i, nodesExtraAtOriginal.at(iN -
nNode), 2) <<
" ";
1239 std::string endianName{
"BigEndian"};
1240 uint32_t beTest = 1;
1241 uint8_t beTestS = *
reinterpret_cast<uint8_t *
>(&beTest);
1243 endianName =
"LittleEndian";
1248 {
"type",
"UnstructuredGrid"},
1249 {
"byte_order", endianName},
1250 {
"header_type",
"UInt64"},
1253 [&](
auto &out,
int level)
1256 out, level,
"UnstructuredGrid",
1258 [&](
auto &out,
int level)
1261 out, level,
"FieldData",
1263 [&](
auto &out,
int level)
1266 out, level,
"DataArray",
1267 {{
"type",
"Float64"},
1269 {
"NumberOfTuples",
"1"},
1270 {
"format",
"ascii"}},
1271 [&](
auto &out,
int level)
1273 out << std::setprecision(16);
1278 out, level,
"Piece",
1279 {{
"NumberOfPoints", std::to_string(nodeDedu2Old.size())},
1280 {
"NumberOfCells", std::to_string(
nCell)}},
1281 [&](
auto &out,
int level)
1285 writeCoords(out, level);
1287 writeCells(out, level);
1289 writeCellData(out, level);
1291 writePointData(out, level);
1297 if (mpi.rank ==
mRank && flag == 1)
1299 WritePVTUMasterFile(
1300 fnameIN, outPath, endianName, seriesName, t, mpi.size,
1301 arraySiz, vecArraySiz, arraySizPoint, vecArraySizPoint,
1302 names, vectorNames, namesPoint, vectorNamesPoint,
1307 static void H5_WriteDataset(hid_t loc,
const char *name,
index nGlobal,
index nOffset,
index nLocal,
1308 hid_t file_dataType, hid_t mem_dataType, hid_t plist_id, hid_t dcpl_id,
void *buf,
int dim2 = -1)
1312 fmt::format(
"{},{},{}", nGlobal,
nLocal, nOffset));
1313 int rank = dim2 >= 0 ? 2 : 1;
1314 std::array<hsize_t, 2> ranksFull{hsize_t(nGlobal), hsize_t(dim2)};
1315 std::array<hsize_t, 2> ranksFullUnlim{H5S_UNLIMITED, hsize_t(dim2)};
1316 std::array<hsize_t, 2> offset{hsize_t(nOffset), 0};
1317 std::array<hsize_t, 2> siz{hsize_t(
nLocal), hsize_t(dim2)};
1318 hid_t memSpace = H5Screate_simple(rank, siz.data(),
nullptr);
1319 hid_t fileSpace = H5Screate_simple(rank, ranksFull.data(), ranksFullUnlim.data());
1320 hid_t dset_id = H5Dcreate(loc, name, file_dataType, fileSpace, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
1322 herr = H5Sclose(fileSpace);
1323 fileSpace = H5Dget_space(dset_id);
1324 herr |= H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, offset.data(),
nullptr, siz.data(),
nullptr);
1325 herr |= H5Dwrite(dset_id, mem_dataType, memSpace, fileSpace, plist_id, buf);
1326 herr |= H5Dclose(dset_id);
1327 herr |= H5Sclose(fileSpace);
1328 herr |= H5Sclose(memSpace);
1330 "h5 error " + fmt::format(
1331 "nGlobal {}, nOffset {}, nLocal {}",
1332 nGlobal, nOffset,
nLocal));
1349 std::filesystem::path
outFile{fname};
1351 std::filesystem::create_directories(
outFile.parent_path() /
".");
1391#define H5SS DNDS_assert_info(herr >= 0, "H5 setting err")
1392#define H5S_Close DNDS_assert_info(herr >= 0, "H5 closing err")
1419 std::array<long long, 2>
version{1, 0};
1422 std::array<hsize_t, 2>
dims{2, 1};
1448#ifdef H5_HAVE_FILTER_DEFLATE
1498 for (
int iRow = 0; iRow < 3; iRow++)
1532 for (
int iRow = 0; iRow < 3; iRow++)
1611 std::map<std::string, std::vector<cgsize_t>>
bocoLists;
1613 bocoLists.insert({name, std::vector<cgsize_t>()});
1614 for (
index iBnd = 0; iBnd <
nBnd; iBnd++)
1617 std::string bcName = fbcid2name(this->bndElemInfo(iBnd, 0).zone);
1618 bocoLists[bcName].push_back(iBnd + nBndCellProcOffset + 1);
1620 std::vector<index> bocoListLengths(allNames.size());
1621 for (
size_t i = 0;
i < allNames.size();
i++)
1622 bocoListLengths[
i] = bocoLists[allNames[
i]].size();
1623 std::vector<index> bocoListLengthsGlobal{bocoListLengths};
1626 this->AdjGlobal2LocalPrimary();
1631 std::filesystem::path outFile{fname};
1632 std::filesystem::create_directories(outFile.parent_path() /
".");
1640 std::array<cgsize_t, 3> zone_sizes{nNodeGlobal, nCellGlobal, 0};
1641 DNDS_CGNS_CALL_EXIT(cg_zone_write(cgns_file, iBase,
"Zone_0", zone_sizes.data(), Unstructured, &iZone));
1642 std::array<int, 3> iCoords{};
1643 DNDS_CGNS_CALL_EXIT(cgp_coord_write(cgns_file, iBase, iZone, RealDouble,
"CoordinateX", iCoords.data()));
1644 DNDS_CGNS_CALL_EXIT(cgp_coord_write(cgns_file, iBase, iZone, RealDouble,
"CoordinateY", &iCoords[1]));
1645 DNDS_CGNS_CALL_EXIT(cgp_coord_write(cgns_file, iBase, iZone, RealDouble,
"CoordinateZ", &iCoords[2]));
1646 std::array<cgsize_t, 1> rmin{nNodeProcOffset + 1};
1647 std::array<cgsize_t, 1> rmax{nNodeProcOffset +
nNode};
1649 DNDS_CGNS_CALL_EXIT(cgp_coord_write_data(cgns_file, iBase, iZone, iCoords[0], rmin.data(), rmax.data(), coordsX.data()));
1650 DNDS_CGNS_CALL_EXIT(cgp_coord_write_data(cgns_file, iBase, iZone, iCoords[1], rmin.data(), rmax.data(), coordsY.data()));
1651 DNDS_CGNS_CALL_EXIT(cgp_coord_write_data(cgns_file, iBase, iZone, iCoords[2], rmin.data(), rmax.data(), coordsZ.data()));
1654 DNDS_CGNS_CALL_EXIT(cgp_poly_section_write(cgns_file, iBase, iZone,
"all_elements", ElementType_t::MIXED, 1, nCellGlobal + nBndGlobal,
1655 bndCellOffsetsGlobalMax, 0, &iSec));
1658 nBndCellProcOffset + 1, nBndCellProcOffset + nBndCell,
1659 elementPolyData.data(), bndCellOffsets.data()));
1661 static_assert(CGNS_VERSION >= 4500,
"Need at least CGNS 4.5.0");
1662 for (
size_t i = 0;
i < allNames.size();
i++)
1663 if (bocoListLengthsGlobal[
i] > 0)
1666 DNDS_CGNS_CALL_EXIT(cg_boco_write(cgns_file, iBase, iZone, allNames[
i].data(), BCType_t::BCTypeNull, PointList,
1667 bocoListLengthsGlobal[
i],
nullptr, &iBC));
1668 DNDS_CGNS_CALL_EXIT(cg_boco_gridlocation_write(cgns_file, iBase, iZone, iBC, this->dim == 3 ? GridLocation_t::FaceCenter : GridLocation_t::EdgeCenter));
1669 DNDS_CGNS_CALL_EXIT(cg_goto(cgns_file, iBase,
"Zone_t", iZone,
"ZoneBC_t", 1,
"BC_t", iBC,
"PointList", 0,
""));
1670 index nBCLocal = bocoListLengths[
i];
1671 index nBCLocalProcOffSet{0};
1673 nBCLocalProcOffSet -= nBCLocal;
1674 DNDS_CGNS_CALL_EXIT(cgp_ptlist_write_data(cgns_file, nBCLocalProcOffSet + 1, nBCLocalProcOffSet + nBCLocal, bocoLists.at(allNames[
i]).data()));
1677 if (cgp_close(cgns_file))
#define DNDS_CGNS_CALL_EXIT(call)
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
std::vector< int64_t > connectivity
Flat node-index list for all cells.
std::vector< int64_t > offsets
Per-cell cumulative offset into connectivity.
std::vector< uint8_t > cellTypes
VTK cell type per cell.
std::pair< int, std::vector< index > > ToVTKVertsAndData(Element e, const TIn &vin)
std::function< std::string(int)> tFGetName
ArrayPair< ArrayNodePeriodicBits< DNDS::NonUniformSize > > tPbiPair
decltype(tAdjPair::father) tAdj
std::function< DNDS::real(int, DNDS::index)> tFGetData
std::function< DNDS::real(int, DNDS::index, DNDS::rowsize)> tFGetVecData
DNDS::ArrayPair< DNDS::ParArray< ElemInfo > > tElemInfoArrayPair
DNDS::ssp< DNDS::ParArray< ElemInfo > > tElemInfoArray
std::function< std::string(t_index)> t_FBCID_2_Name
decltype(tPbiPair::father) tPbi
DNDS::ArrayAdjacencyPair< DNDS::NonUniformSize > tAdjPair
constexpr ElementType_t _getCGNSTypeFromElemType(Elem::ElemType et)
decltype(tCoordPair::father) tCoord
MPI_int Bcast(void *buf, MPI_int num, MPI_Datatype type, MPI_int source_rank, MPI_Comm comm)
dumb wrapper
MPI_int Scan(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Scan (inclusive prefix reduction).
MPI_int Allreduce(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Allreduce.
const MPI_Datatype DNDS_MPI_INDEX
MPI datatype matching index (= MPI_INT64_T).
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
std::string getStringForcePath(const std::filesystem::path::string_type &v)
Portable conversion of a platform-native path string to std::string.
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
DNDS_CONSTANT const real veryLargeReal
Catch-all upper bound ("practically infinity") for physical scalars.
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
DNDS_DEVICE_CALLABLE index Size() const
Combined father + son row count.
ssp< TArray > father
Owned-side array (must be resized before ghost setup).
index Size() const
Combined row count (father->Size() + son->Size()).
ssp< TArray > son
Ghost-side array (sized automatically by createMPITypes / BorrowAndPull).
auto RowSize() const
Uniform row width (delegates to father).
static MPI_Datatype CommType()
static MPI_Datatype CommType()
void GetCurrentOutputArrays(int flag, tCoordPair &coordOut, tAdjPair &cell2nodeOut, tPbiPair &cell2nodePbiOut, tElemInfoArrayPair &cellElemInfoOut, index &nCell, index &nNode)
DNDS::ArrayTransformerType< tAdj::element_type >::Type cell2nodeSerialOutTrans
DNDS::ssp< UnstructuredMesh > mesh
void PrintSerialPartVTKDataArray(std::string fname, std::string seriesName, int arraySiz, int vecArraySiz, int arraySizPoint, int vecArraySizPoint, const tFGetName &names, const tFGetData &data, const tFGetName &vectorNames, const tFGetVecData &vectorData, const tFGetName &namesPoint, const tFGetData &dataPoint, const tFGetName &vectorNamesPoint, const tFGetVecData &vectorDataPoint, double t, int flag=0)
names(idata) data(idata, ivolume)
void PrintSerialPartPltBinaryDataArray(std::string fname, int arraySiz, int arraySizPoint, const tFGetName &names, const tFGetData &data, const tFGetName &namesPoint, const tFGetData &dataPoint, double t, int flag)
names(idata) data(idata, ivolume) https://tecplot.azureedge.net/products/360/current/360_data_format_...
tElemInfoArray cellElemInfoSerial
UnstructuredMeshDeviceView< B > t_deviceView
tCoordPair coordsPeriodicRecreated
std::vector< uint8_t > vtkCellType
std::vector< index > vtkCell2nodeOffsets
for parallel out
struct DNDS::Geom::UnstructuredMesh::HDF5OutSetting hdf5OutSetting
void PrintParallelVTKHDFDataArray(std::string fname, std::string seriesName, int arraySiz, int vecArraySiz, int arraySizPoint, int vecArraySizPoint, const tFGetName &names, const tFGetData &data, const tFGetName &vectorNames, const tFGetVecData &vectorData, const tFGetName &namesPoint, const tFGetData &dataPoint, const tFGetName &vectorNamesPoint, const tFGetVecData &vectorDataPoint, double t, MPI_Comm commDup)
AdjPairTracked< tAdjPair > cell2cell
void AdjLocal2GlobalPrimary()
MeshAdjState adjPrimaryState
AdjPairTracked< tAdjPair > cell2node
tElemInfoArrayPair cellElemInfo
void PrintMeshCGNS(std::string fname, const t_FBCID_2_Name &fbcid2name, const std::vector< std::string > &allNames)
index vtkCell2NodeGlobalSiz
AdjPairTracked< tAdjPair > bnd2node
tElemInfoArrayPair bndElemInfo
std::vector< index > vtkCell2node
std::vector< index > nodeRecreated2nodeLocal
AdjPairTracked< tAdj2Pair > bnd2cell
int size
Number of ranks in comm (-1 until initialised).
int rank
This rank's 0-based index within comm (-1 until initialised).
MPI_Comm comm
The underlying MPI communicator handle.
Tag type for naming objects created via make_ssp.
Eigen::Matrix< real, 5, 1 > v
input explicitMaps push_back(EntityReorderMap{EntityKind::Cell, cellPartition})