216 MPI_Topo_test(comm, &comm_type);
217 if (comm_type == MPI_CART) {
219 balancer->setCommunicator(communicator);
221 const int dimension = balancer->getDimension();
222 int location[dimension];
224 int periodicity[dimension];
225 MPI_Cart_get(communicator, dimension, size, periodicity, location);
226 procGridLoc.assign(location, location + dimension);
227 procGridDim.assign(size, size + dimension);
231 MPI_Comm_rank(comm, &rank);
236 switch (balancer->getDimension()) {
238 idx = procGridLoc.at(2) + procGridLoc.at(1) * procGridDim.at(2) +
239 procGridLoc.at(0) * procGridDim.at(2) * procGridDim.at(1);
242 idx = procGridLoc.at(1) + procGridLoc.at(0) * procGridDim.at(1);
245 idx = procGridLoc.at(0);
249 __FILE__, __func__, __LINE__,
250 "ALL cannot deal with more then three dimensions (or less then "
257 MPI_Comm_split(comm, 0, idx, &temp_comm);
259 std::vector<int> periods(3, 1);
262 MPI_Cart_create(temp_comm, balancer->getDimension(), procGridDim.data(),
263 periods.data(), 0, &communicator);
264 balancer->setCommunicator(communicator);
267 __FILE__, __func__, __LINE__,
268 "When using a non-cartesian communicator process grid parameters "
269 "required (not set).");
532 auto points = vtkSmartPointer<vtkPoints>::New();
534 points->Allocate(8 * balancer->getDimension());
540 controller = vtkMPIController::New();
541 controller->Initialize();
542 controller->SetGlobalController(controller);
546 MPI_Comm_rank(communicator, &local_rank);
547 MPI_Comm_size(communicator, &n_ranks);
549 std::vector<Point<W>> tmp_outline(2);
550 std::vector<W> tmp_0(
551 {outline.at(0)[0], outline.at(0)[1], outline.at(0)[2]});
552 std::vector<W> tmp_1(
553 {outline.at(1)[0], outline.at(1)[1], outline.at(1)[2]});
554 tmp_outline.at(0) =
Point<W>(tmp_0);
555 tmp_outline.at(1) =
Point<W>(tmp_1);
557 for (
auto z = 0; z <= 1; ++z)
558 for (
auto y = 0; y <= 1; ++y)
559 for (
auto x = 0; x <= 1; ++x) {
560 points->InsertPoint(x + 2 * y + 4 * z, tmp_outline.at(x)[0],
561 tmp_outline.at(y)[1], tmp_outline.at(z)[2]);
564 auto hexa = vtkSmartPointer<vtkVoxel>::New();
565 for (
int i = 0; i < 8; ++i)
566 hexa->GetPointIds()->SetId(i, i);
568 auto cellArray = vtkSmartPointer<vtkCellArray>::New();
569 cellArray->InsertNextCell(hexa);
572 auto work = vtkSmartPointer<vtkFloatArray>::New();
573 work->SetNumberOfComponents(1);
574 work->SetNumberOfTuples(1);
575 work->SetName(
"work");
576 W total_work = std::accumulate(balancer->getWork().begin(),
577 balancer->getWork().end(), (W)0);
578 work->SetValue(0, total_work);
582 MPI_Comm_rank(communicator, &rank);
583 auto coords = vtkSmartPointer<vtkFloatArray>::New();
584 coords->SetNumberOfComponents(3);
585 coords->SetNumberOfTuples(1);
586 coords->SetName(
"coords");
587 coords->SetValue(0, procGridLoc.at(0));
588 coords->SetValue(1, procGridLoc.at(1));
589 coords->SetValue(2, procGridLoc.at(2));
591 auto rnk = vtkSmartPointer<vtkFloatArray>::New();
592 rnk->SetNumberOfComponents(1);
593 rnk->SetNumberOfTuples(1);
594 rnk->SetName(
"MPI rank");
595 rnk->SetValue(0, rank);
598 auto tag = vtkSmartPointer<vtkIntArray>::New();
599 tag->SetNumberOfComponents(1);
600 tag->SetNumberOfTuples(1);
602 tag->SetValue(0, procTag);
613 for (
int i = 0; i < 3; ++i) {
614 local_min[i] = outline.at(0)[i];
615 local_max[i] = outline.at(1)[i];
616 width[i] = local_max[i] - local_min[i];
620 W surface = (W)2.0 * width[0] * width[1] + (W)2.0 * width[1] * width[2] +
621 (W)2.0 * width[0] * width[2];
623 auto expanse = vtkSmartPointer<vtkFloatArray>::New();
624 expanse->SetNumberOfComponents(6);
625 expanse->SetNumberOfTuples(1);
626 expanse->SetName(
"expanse");
627 expanse->SetValue(0, width[0]);
628 expanse->SetValue(1, width[0]);
629 expanse->SetValue(2, width[0]);
630 expanse->SetValue(3, volume);
631 expanse->SetValue(4, surface);
632 expanse->SetValue(5, surface / volume);
634 MPI_Allreduce(&local_min, &global_min, 3, MPIDataTypeW, MPI_MIN,
636 MPI_Allreduce(&local_max, &global_max, 3, MPIDataTypeW, MPI_MAX,
639 for (
int i = 0; i < 3; ++i) {
640 global_extent[2 * i] = global_min[i];
641 global_extent[2 * i + 1] = global_max[i];
645 auto unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
646 unstructuredGrid->SetPoints(points);
647 unstructuredGrid->SetCells(VTK_VOXEL, cellArray);
648 unstructuredGrid->GetCellData()->AddArray(work);
649 unstructuredGrid->GetCellData()->AddArray(expanse);
650 unstructuredGrid->GetCellData()->AddArray(rnk);
651 unstructuredGrid->GetCellData()->AddArray(coords);
652 unstructuredGrid->GetCellData()->AddArray(tag);
668 createDirectory(
"vtk_outline");
669 std::ostringstream ss_local;
670 ss_local <<
"vtk_outline/ALL_vtk_outline_" << std::setw(7)
671 << std::setfill(
'0') << step <<
"_" << local_rank <<
".vtu";
687 auto writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
688 writer->SetInputData(unstructuredGrid);
689 writer->SetFileName(ss_local.str().c_str());
691 writer->SetDataModeToBinary();
696 std::ostringstream ss_para;
697 ss_para <<
"vtk_outline/ALL_vtk_outline_" << std::setw(7)
698 << std::setfill(
'0') << step <<
".pvtu";
701 auto parallel_writer =
702 vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New();
703 parallel_writer->SetFileName(ss_para.str().c_str());
704 parallel_writer->SetNumberOfPieces(n_ranks);
705 parallel_writer->SetStartPiece(local_rank);
706 parallel_writer->SetEndPiece(local_rank);
707 parallel_writer->SetInputData(unstructuredGrid);
709 parallel_writer->SetDataModeToBinary();
710 parallel_writer->Write();
722 MPI_Comm_rank(communicator, &local_rank);
723 MPI_Comm_size(communicator, &n_ranks);
727 T local_vertices[nVertices * balancer->getDimension() + 1];
729 for (
int v = 0; v < nVertices; ++v) {
730 for (
int d = 0; d < balancer->getDimension(); ++d) {
731 local_vertices[v * balancer->getDimension() + d] =
732 balancer->getVertices().at(v)[d];
735 local_vertices[nVertices * balancer->getDimension()] =
736 (T)balancer->getWork().at(0);
745 T global_vertices[n_ranks * (nVertices * balancer->getDimension() + 1)];
748 MPI_Gather(local_vertices, nVertices * balancer->getDimension() + 1,
749 MPIDataTypeT, global_vertices,
750 nVertices * balancer->getDimension() + 1, MPIDataTypeT, 0,
753 if (local_rank == 0) {
754 auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
755#ifdef VTK_CELL_ARRAY_V2
756 vtkNew<vtkUnstructuredGrid> unstructuredGrid;
757 unstructuredGrid->Allocate(n_ranks + 10);
759 auto unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
763 for (
int i = 0; i < n_ranks; ++i) {
764 for (
int v = 0; v < nVertices; ++v) {
765 vtkpoints->InsertNextPoint(
766 global_vertices[i * (nVertices * balancer->getDimension() + 1) +
767 v * balancer->getDimension() + 0],
768 global_vertices[i * (nVertices * balancer->getDimension() + 1) +
769 v * balancer->getDimension() + 1],
770 global_vertices[i * (nVertices * balancer->getDimension() + 1) +
771 v * balancer->getDimension() + 2]);
774 unstructuredGrid->SetPoints(vtkpoints);
777 auto work = vtkSmartPointer<vtkFloatArray>::New();
778 auto cell = vtkSmartPointer<vtkFloatArray>::New();
779 work->SetNumberOfComponents(1);
780 work->SetNumberOfTuples(n_ranks);
781 work->SetName(
"work");
782 cell->SetNumberOfComponents(1);
783 cell->SetNumberOfTuples(n_ranks);
784 cell->SetName(
"cell id");
786 for (
int n = 0; n < n_ranks; ++n) {
788#ifdef VTK_CELL_ARRAY_V2
790 vtkIdType pointIds[8] = {8 * n + 0, 8 * n + 1, 8 * n + 2, 8 * n + 3,
791 8 * n + 4, 8 * n + 5, 8 * n + 6, 8 * n + 7};
793 vtkIdType faces[48] = {
794 3, 8 * n + 0, 8 * n + 2, 8 * n + 1,
795 3, 8 * n + 1, 8 * n + 2, 8 * n + 3,
796 3, 8 * n + 0, 8 * n + 4, 8 * n + 2,
797 3, 8 * n + 2, 8 * n + 4, 8 * n + 6,
798 3, 8 * n + 2, 8 * n + 6, 8 * n + 3,
799 3, 8 * n + 3, 8 * n + 6, 8 * n + 7,
800 3, 8 * n + 1, 8 * n + 5, 8 * n + 3,
801 3, 8 * n + 3, 8 * n + 5, 8 * n + 7,
802 3, 8 * n + 0, 8 * n + 4, 8 * n + 1,
803 3, 8 * n + 1, 8 * n + 4, 8 * n + 5,
804 3, 8 * n + 4, 8 * n + 6, 8 * n + 5,
805 3, 8 * n + 5, 8 * n + 6, 8 * n + 7};
807 unstructuredGrid->InsertNextCell(VTK_POLYHEDRON, 8, pointIds, 12,
811 vtkIdType pointIds[8] = {8 * n + 0, 8 * n + 1, 8 * n + 2, 8 * n + 3,
812 8 * n + 4, 8 * n + 5, 8 * n + 6, 8 * n + 7};
814 auto faces = vtkSmartPointer<vtkCellArray>::New();
816 vtkIdType f0[3] = {8 * n + 0, 8 * n + 2, 8 * n + 1};
817 vtkIdType f1[3] = {8 * n + 1, 8 * n + 2, 8 * n + 3};
819 vtkIdType f2[3] = {8 * n + 0, 8 * n + 4, 8 * n + 2};
820 vtkIdType f3[3] = {8 * n + 2, 8 * n + 4, 8 * n + 6};
822 vtkIdType f4[3] = {8 * n + 2, 8 * n + 6, 8 * n + 3};
823 vtkIdType f5[3] = {8 * n + 3, 8 * n + 6, 8 * n + 7};
825 vtkIdType f6[3] = {8 * n + 1, 8 * n + 5, 8 * n + 3};
826 vtkIdType f7[3] = {8 * n + 3, 8 * n + 5, 8 * n + 7};
828 vtkIdType f8[3] = {8 * n + 0, 8 * n + 4, 8 * n + 1};
829 vtkIdType f9[3] = {8 * n + 1, 8 * n + 4, 8 * n + 5};
831 vtkIdType fa[3] = {8 * n + 4, 8 * n + 6, 8 * n + 5};
832 vtkIdType fb[3] = {8 * n + 5, 8 * n + 6, 8 * n + 7};
834 faces->InsertNextCell(3, f0);
835 faces->InsertNextCell(3, f1);
836 faces->InsertNextCell(3, f2);
837 faces->InsertNextCell(3, f3);
838 faces->InsertNextCell(3, f4);
839 faces->InsertNextCell(3, f5);
840 faces->InsertNextCell(3, f6);
841 faces->InsertNextCell(3, f7);
842 faces->InsertNextCell(3, f8);
843 faces->InsertNextCell(3, f9);
844 faces->InsertNextCell(3, fa);
845 faces->InsertNextCell(3, fb);
847 unstructuredGrid->InsertNextCell(VTK_POLYHEDRON, 8, pointIds, 12,
848 faces->GetPointer());
851 n, global_vertices[n * (nVertices * balancer->getDimension() + 1) +
852 8 * balancer->getDimension()]);
853 cell->SetValue(n, (T)n);
855 unstructuredGrid->GetCellData()->AddArray(work);
856 unstructuredGrid->GetCellData()->AddArray(cell);
858 createDirectory(
"vtk_vertices");
859 std::ostringstream filename;
860 filename <<
"vtk_vertices/ALL_vtk_vertices_" << std::setw(7)
861 << std::setfill(
'0') << step <<
".vtu";
862 auto writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
863 writer->SetInputData(unstructuredGrid);
864 writer->SetFileName(filename.str().c_str());
865 writer->SetDataModeToAscii();