215 MPI_Topo_test(comm, &comm_type);
216 if (comm_type == MPI_CART) {
218 balancer->setCommunicator(communicator);
220 const int dimension = balancer->getDimension();
221 int location[dimension];
223 int periodicity[dimension];
224 MPI_Cart_get(communicator, dimension, size, periodicity, location);
225 procGridLoc.assign(location, location + dimension);
226 procGridDim.assign(size, size + dimension);
230 MPI_Comm_rank(comm, &rank);
235 switch (balancer->getDimension()) {
237 idx = procGridLoc.at(2) + procGridLoc.at(1) * procGridDim.at(2) +
238 procGridLoc.at(0) * procGridDim.at(2) * procGridDim.at(1);
241 idx = procGridLoc.at(1) + procGridLoc.at(0) * procGridDim.at(1);
244 idx = procGridLoc.at(0);
248 __FILE__, __func__, __LINE__,
249 "ALL cannot deal with more then three dimensions (or less then "
256 MPI_Comm_split(comm, 0, idx, &temp_comm);
258 std::vector<int> periods(3, 1);
261 MPI_Cart_create(temp_comm, balancer->getDimension(), procGridDim.data(),
262 periods.data(), 0, &communicator);
263 balancer->setCommunicator(communicator);
266 __FILE__, __func__, __LINE__,
267 "When using a non-cartesian communicator process grid parameters "
268 "required (not set).");
523 auto points = vtkSmartPointer<vtkPoints>::New();
525 points->Allocate(8 * balancer->getDimension());
531 controller = vtkMPIController::New();
532 controller->Initialize();
533 controller->SetGlobalController(controller);
537 MPI_Comm_rank(communicator, &local_rank);
538 MPI_Comm_size(communicator, &n_ranks);
540 std::vector<Point<W>> tmp_outline(2);
541 std::vector<W> tmp_0(
542 {outline.at(0)[0], outline.at(0)[1], outline.at(0)[2]});
543 std::vector<W> tmp_1(
544 {outline.at(1)[0], outline.at(1)[1], outline.at(1)[2]});
545 tmp_outline.at(0) =
Point<W>(tmp_0);
546 tmp_outline.at(1) =
Point<W>(tmp_1);
548 for (
auto z = 0; z <= 1; ++z)
549 for (
auto y = 0; y <= 1; ++y)
550 for (
auto x = 0; x <= 1; ++x) {
551 points->InsertPoint(x + 2 * y + 4 * z, tmp_outline.at(x)[0],
552 tmp_outline.at(y)[1], tmp_outline.at(z)[2]);
555 auto hexa = vtkSmartPointer<vtkVoxel>::New();
556 for (
int i = 0; i < 8; ++i)
557 hexa->GetPointIds()->SetId(i, i);
559 auto cellArray = vtkSmartPointer<vtkCellArray>::New();
560 cellArray->InsertNextCell(hexa);
563 auto work = vtkSmartPointer<vtkFloatArray>::New();
564 work->SetNumberOfComponents(1);
565 work->SetNumberOfTuples(1);
566 work->SetName(
"work");
567 W total_work = std::accumulate(balancer->getWork().begin(),
568 balancer->getWork().end(), (W)0);
569 work->SetValue(0, total_work);
573 MPI_Comm_rank(communicator, &rank);
574 auto coords = vtkSmartPointer<vtkFloatArray>::New();
575 coords->SetNumberOfComponents(3);
576 coords->SetNumberOfTuples(1);
577 coords->SetName(
"coords");
578 coords->SetValue(0, procGridLoc.at(0));
579 coords->SetValue(1, procGridLoc.at(1));
580 coords->SetValue(2, procGridLoc.at(2));
582 auto rnk = vtkSmartPointer<vtkFloatArray>::New();
583 rnk->SetNumberOfComponents(1);
584 rnk->SetNumberOfTuples(1);
585 rnk->SetName(
"MPI rank");
586 rnk->SetValue(0, rank);
589 auto tag = vtkSmartPointer<vtkIntArray>::New();
590 tag->SetNumberOfComponents(1);
591 tag->SetNumberOfTuples(1);
593 tag->SetValue(0, procTag);
604 for (
int i = 0; i < 3; ++i) {
605 local_min[i] = outline.at(0)[i];
606 local_max[i] = outline.at(1)[i];
607 width[i] = local_max[i] - local_min[i];
611 W surface = (W)2.0 * width[0] * width[1] + (W)2.0 * width[1] * width[2] +
612 (W)2.0 * width[0] * width[2];
614 auto expanse = vtkSmartPointer<vtkFloatArray>::New();
615 expanse->SetNumberOfComponents(6);
616 expanse->SetNumberOfTuples(1);
617 expanse->SetName(
"expanse");
618 expanse->SetValue(0, width[0]);
619 expanse->SetValue(1, width[0]);
620 expanse->SetValue(2, width[0]);
621 expanse->SetValue(3, volume);
622 expanse->SetValue(4, surface);
623 expanse->SetValue(5, surface / volume);
625 MPI_Allreduce(&local_min, &global_min, 3, MPIDataTypeW, MPI_MIN,
627 MPI_Allreduce(&local_max, &global_max, 3, MPIDataTypeW, MPI_MAX,
630 for (
int i = 0; i < 3; ++i) {
631 global_extent[2 * i] = global_min[i];
632 global_extent[2 * i + 1] = global_max[i];
636 auto unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
637 unstructuredGrid->SetPoints(points);
638 unstructuredGrid->SetCells(VTK_VOXEL, cellArray);
639 unstructuredGrid->GetCellData()->AddArray(work);
640 unstructuredGrid->GetCellData()->AddArray(expanse);
641 unstructuredGrid->GetCellData()->AddArray(rnk);
642 unstructuredGrid->GetCellData()->AddArray(coords);
643 unstructuredGrid->GetCellData()->AddArray(tag);
659 createDirectory(
"vtk_outline");
660 std::ostringstream ss_local;
661 ss_local <<
"vtk_outline/ALL_vtk_outline_" << std::setw(7)
662 << std::setfill(
'0') << step <<
"_" << local_rank <<
".vtu";
664 auto writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
665 writer->SetInputData(unstructuredGrid);
666 writer->SetFileName(ss_local.str().c_str());
668 writer->SetDataModeToBinary();
673 std::ostringstream ss_para;
674 ss_para <<
"vtk_outline/ALL_vtk_outline_" << std::setw(7)
675 << std::setfill(
'0') << step <<
".pvtu";
677 auto parallel_writer =
678 vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New();
679 parallel_writer->SetFileName(ss_para.str().c_str());
680 parallel_writer->SetNumberOfPieces(n_ranks);
681 parallel_writer->SetStartPiece(local_rank);
682 parallel_writer->SetEndPiece(local_rank);
683 parallel_writer->SetInputData(unstructuredGrid);
685 parallel_writer->SetDataModeToBinary();
686 parallel_writer->Write();
698 MPI_Comm_rank(communicator, &local_rank);
699 MPI_Comm_size(communicator, &n_ranks);
703 T local_vertices[nVertices * balancer->getDimension() + 1];
705 for (
int v = 0; v < nVertices; ++v) {
706 for (
int d = 0; d < balancer->getDimension(); ++d) {
707 local_vertices[v * balancer->getDimension() + d] =
708 balancer->getVertices().at(v)[d];
711 local_vertices[nVertices * balancer->getDimension()] =
712 (T)balancer->getWork().at(0);
721 T global_vertices[n_ranks * (nVertices * balancer->getDimension() + 1)];
724 MPI_Gather(local_vertices, nVertices * balancer->getDimension() + 1,
725 MPIDataTypeT, global_vertices,
726 nVertices * balancer->getDimension() + 1, MPIDataTypeT, 0,
729 if (local_rank == 0) {
730 auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
731#ifdef VTK_CELL_ARRAY_V2
732 vtkNew<vtkUnstructuredGrid> unstructuredGrid;
733 unstructuredGrid->Allocate(n_ranks + 10);
735 auto unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
739 for (
int i = 0; i < n_ranks; ++i) {
740 for (
int v = 0; v < nVertices; ++v) {
741 vtkpoints->InsertNextPoint(
742 global_vertices[i * (nVertices * balancer->getDimension() + 1) +
743 v * balancer->getDimension() + 0],
744 global_vertices[i * (nVertices * balancer->getDimension() + 1) +
745 v * balancer->getDimension() + 1],
746 global_vertices[i * (nVertices * balancer->getDimension() + 1) +
747 v * balancer->getDimension() + 2]);
750 unstructuredGrid->SetPoints(vtkpoints);
753 auto work = vtkSmartPointer<vtkFloatArray>::New();
754 auto cell = vtkSmartPointer<vtkFloatArray>::New();
755 work->SetNumberOfComponents(1);
756 work->SetNumberOfTuples(n_ranks);
757 work->SetName(
"work");
758 cell->SetNumberOfComponents(1);
759 cell->SetNumberOfTuples(n_ranks);
760 cell->SetName(
"cell id");
762 for (
int n = 0; n < n_ranks; ++n) {
764#ifdef VTK_CELL_ARRAY_V2
766 vtkIdType pointIds[8] = {8 * n + 0, 8 * n + 1, 8 * n + 2, 8 * n + 3,
767 8 * n + 4, 8 * n + 5, 8 * n + 6, 8 * n + 7};
769 vtkIdType faces[48] = {
770 3, 8 * n + 0, 8 * n + 2, 8 * n + 1,
771 3, 8 * n + 1, 8 * n + 2, 8 * n + 3,
772 3, 8 * n + 0, 8 * n + 4, 8 * n + 2,
773 3, 8 * n + 2, 8 * n + 4, 8 * n + 6,
774 3, 8 * n + 2, 8 * n + 6, 8 * n + 3,
775 3, 8 * n + 3, 8 * n + 6, 8 * n + 7,
776 3, 8 * n + 1, 8 * n + 5, 8 * n + 3,
777 3, 8 * n + 3, 8 * n + 5, 8 * n + 7,
778 3, 8 * n + 0, 8 * n + 4, 8 * n + 1,
779 3, 8 * n + 1, 8 * n + 4, 8 * n + 5,
780 3, 8 * n + 4, 8 * n + 6, 8 * n + 5,
781 3, 8 * n + 5, 8 * n + 6, 8 * n + 7};
783 unstructuredGrid->InsertNextCell(VTK_POLYHEDRON, 8, pointIds, 12,
787 vtkIdType pointIds[8] = {8 * n + 0, 8 * n + 1, 8 * n + 2, 8 * n + 3,
788 8 * n + 4, 8 * n + 5, 8 * n + 6, 8 * n + 7};
790 auto faces = vtkSmartPointer<vtkCellArray>::New();
792 vtkIdType f0[3] = {8 * n + 0, 8 * n + 2, 8 * n + 1};
793 vtkIdType f1[3] = {8 * n + 1, 8 * n + 2, 8 * n + 3};
795 vtkIdType f2[3] = {8 * n + 0, 8 * n + 4, 8 * n + 2};
796 vtkIdType f3[3] = {8 * n + 2, 8 * n + 4, 8 * n + 6};
798 vtkIdType f4[3] = {8 * n + 2, 8 * n + 6, 8 * n + 3};
799 vtkIdType f5[3] = {8 * n + 3, 8 * n + 6, 8 * n + 7};
801 vtkIdType f6[3] = {8 * n + 1, 8 * n + 5, 8 * n + 3};
802 vtkIdType f7[3] = {8 * n + 3, 8 * n + 5, 8 * n + 7};
804 vtkIdType f8[3] = {8 * n + 0, 8 * n + 4, 8 * n + 1};
805 vtkIdType f9[3] = {8 * n + 1, 8 * n + 4, 8 * n + 5};
807 vtkIdType fa[3] = {8 * n + 4, 8 * n + 6, 8 * n + 5};
808 vtkIdType fb[3] = {8 * n + 5, 8 * n + 6, 8 * n + 7};
810 faces->InsertNextCell(3, f0);
811 faces->InsertNextCell(3, f1);
812 faces->InsertNextCell(3, f2);
813 faces->InsertNextCell(3, f3);
814 faces->InsertNextCell(3, f4);
815 faces->InsertNextCell(3, f5);
816 faces->InsertNextCell(3, f6);
817 faces->InsertNextCell(3, f7);
818 faces->InsertNextCell(3, f8);
819 faces->InsertNextCell(3, f9);
820 faces->InsertNextCell(3, fa);
821 faces->InsertNextCell(3, fb);
823 unstructuredGrid->InsertNextCell(VTK_POLYHEDRON, 8, pointIds, 12,
824 faces->GetPointer());
827 n, global_vertices[n * (nVertices * balancer->getDimension() + 1) +
828 8 * balancer->getDimension()]);
829 cell->SetValue(n, (T)n);
831 unstructuredGrid->GetCellData()->AddArray(work);
832 unstructuredGrid->GetCellData()->AddArray(cell);
834 createDirectory(
"vtk_vertices");
835 std::ostringstream filename;
836 filename <<
"vtk_vertices/ALL_vtk_vertices_" << std::setw(7)
837 << std::setfill(
'0') << step <<
".vtu";
838 auto writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
839 writer->SetInputData(unstructuredGrid);
840 writer->SetFileName(filename.str().c_str());
841 writer->SetDataModeToAscii();