parallel_reader_writer_test.cc 6.25 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1
2
3
4
5
6
7
8
9
10
11
12
13
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <cstring>
#include <iostream>
#include <vector>

#include <dune/common/parallel/mpihelper.hh> // An initializer of MPI
#include <dune/common/filledarray.hh>
14
#include <dune/common/std/type_traits.hh>
Praetorius, Simon's avatar
Praetorius, Simon committed
15
16
#include <dune/common/test/testsuite.hh>

Praetorius, Simon's avatar
Praetorius, Simon committed
17
#if HAVE_DUNE_UGGRID
Praetorius, Simon's avatar
Praetorius, Simon committed
18
#include <dune/grid/uggrid.hh>
19
20
#endif

Praetorius, Simon's avatar
Praetorius, Simon committed
21
22
23
24
25
26
27
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/utility/structuredgridfactory.hh>

#if HAVE_DUNE_ALUGRID
#include <dune/alugrid/grid.hh>
#endif

28
29
#include <dune/vtk/vtkreader.hh>
#include <dune/vtk/writers/vtkunstructuredgridwriter.hh>
Praetorius, Simon's avatar
Praetorius, Simon committed
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <dune/vtk/gridcreators/parallelgridcreator.hh>
#include <dune/vtk/gridcreators/serialgridcreator.hh>

using namespace Dune;

// see https://stackoverflow.com/questions/6163611/compare-two-files
bool compare_files (std::string const& fn1, std::string const& fn2)
{
  std::ifstream in1(fn1, std::ios::binary);
  std::ifstream in2(fn2, std::ios::binary);
  if (!in1 || !in2) {
    std::cout << "can not find file " << fn1 << " or file " << fn2 << "\n";
    return false;
  }

  std::ifstream::pos_type size1 = in1.seekg(0, std::ifstream::end).tellg();
  in1.seekg(0, std::ifstream::beg);

  std::ifstream::pos_type size2 = in2.seekg(0, std::ifstream::end).tellg();
  in2.seekg(0, std::ifstream::beg);

  if (size1 != size2)
    return false;

  static const std::size_t BLOCKSIZE = 4096;
  std::size_t remaining = size1;

  while (remaining) {
    char buffer1[BLOCKSIZE], buffer2[BLOCKSIZE];
    std::size_t size = std::min(BLOCKSIZE, remaining);

    in1.read(buffer1, size);
    in2.read(buffer2, size);

    if (0 != std::memcmp(buffer1, buffer2, size))
      return false;

    remaining -= size;
  }

  return true;
}

73

74
75
76
77
78
template <class GF>
using HasParallelGridFactoryImpl = decltype(std::declval<GF>().createGrid(true,true,std::string(""),true));

template <class G>
using HasParallelGridFactory = Std::is_detected<HasParallelGridFactoryImpl, GridFactory<G>>;
79

Praetorius, Simon's avatar
Praetorius, Simon committed
80
81

template <class Test>
82
void compare (Test& test, Vtk::Path const& dir, Vtk::Path const& name)
Praetorius, Simon's avatar
Praetorius, Simon committed
83
84
85
86
87
88
{
  test.check(compare_files(dir.string() + '/' + name.string() + ".vtu",
                           dir.string() + '/' + name.string() + "_2.vtu"));
}

template <class GridView>
89
void writer_test (GridView const& gridView, std::string base_name)
Praetorius, Simon's avatar
Praetorius, Simon committed
90
{
91
92
  VtkUnstructuredGridWriter<GridView> vtkWriter(gridView, Vtk::ASCII, Vtk::FLOAT32);
  vtkWriter.write(base_name + ".vtu");
Praetorius, Simon's avatar
Praetorius, Simon committed
93
94
95
}

template <class Grid, class Creator>
96
void reader_writer_test(MPIHelper& mpi, TestSuite& test, std::string const& testName, bool doLoadBalance = true)
Praetorius, Simon's avatar
Praetorius, Simon committed
97
{
98
99
100
101
  std::cout << "== " << testName << "\n";
  std::string base_name = "parallel_rw_dim" + std::to_string(Grid::dimension);
  std::vector<std::string> pieces1, pieces2;

Praetorius, Simon's avatar
Praetorius, Simon committed
102
103
104
105
  std::string ext = ".vtu";
  if (mpi.size() > 1)
    ext = ".pvtu";

106
107
108
109
110
111
112
113
114
115
  // Step 1: create a new grid and write it to file1
  const int dim = Grid::dimension;
  {
    FieldVector<double,dim> lowerLeft; lowerLeft = 0.0;
    FieldVector<double,dim> upperRight; upperRight = 1.0;
    auto numElements = filledArray<dim,unsigned int>(4);
    auto gridPtr = StructuredGridFactory<Grid>::createSimplexGrid(lowerLeft, upperRight, numElements);
    gridPtr->loadBalance();
    writer_test(gridPtr->leafGridView(), base_name);
  }
Praetorius, Simon's avatar
Praetorius, Simon committed
116

117
  mpi.getCollectiveCommunication().barrier(); // need a barrier between write and read
Praetorius, Simon's avatar
Praetorius, Simon committed
118

119
120
121
  // Step 2: read the grid from file1 and write it back to file2
  { GridFactory<Grid> factory;
    VtkReader<Grid, Creator> reader{factory};
122
    reader.read(base_name + ext);
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

    std::unique_ptr<Grid> grid{ Hybrid::ifElse(HasParallelGridFactory<Grid>{},
      [&](auto id) { return id(factory).createGrid(std::true_type{}); },
      [&](auto id) { return id(factory).createGrid(); }) };
    if (doLoadBalance)
      grid->loadBalance();

    writer_test(grid->leafGridView(), base_name + "_1");
  }

  mpi.getCollectiveCommunication().barrier();

  // Step 3: read the (parallel) file1 to get the piece filenames
  { GridFactory<Grid> factory;
    VtkReader<Grid, Creator> reader{factory};
138
    reader.read(base_name + "_1" + ext);
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

    std::unique_ptr<Grid> grid{ Hybrid::ifElse(HasParallelGridFactory<Grid>{},
      [&](auto id) { return id(factory).createGrid(std::true_type{}); },
      [&](auto id) { return id(factory).createGrid(); }) };
    if (doLoadBalance)
      grid->loadBalance();
    pieces1 = reader.pieces();

    writer_test(grid->leafGridView(), base_name + "_2");
  }

  mpi.getCollectiveCommunication().barrier();

  // Step 4: read the (parallel) file2 to get the piece filenames
  { GridFactory<Grid> factory;
    VtkReader<Grid, Creator> reader{factory};
155
    reader.read(base_name + "_2" + ext, false);
156
157
158
159
160
161
162
163
164
165
166
167

    pieces2 = reader.pieces();
  }

  mpi.getCollectiveCommunication().barrier();

  // Step 4: compare the pieces
  if (mpi.rank() == 0) {
    test.check(pieces1.size() == pieces2.size(), "pieces1.size == pieces2.size");
    for (std::size_t i = 0; i < pieces1.size(); ++i)
      test.check(compare_files(pieces1[i], pieces2[i]), "compare(" + pieces1[i] + ", " + pieces2[i] + ")");
  }
Praetorius, Simon's avatar
Praetorius, Simon committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
}

#if HAVE_DUNE_ALUGRID
  template <int dim>
  using ALUGridType = Dune::ALUGrid<dim, dim, Dune::simplex, Dune::conforming>;
#endif

template <int I>
using int_ = std::integral_constant<int,I>;

int main (int argc, char** argv)
{
  auto& mpi = Dune::MPIHelper::instance(argc, argv);

  TestSuite test{};

Praetorius, Simon's avatar
Praetorius, Simon committed
184
#if HAVE_DUNE_UGGRID
Stenger, Florian's avatar
Stenger, Florian committed
185
186
  reader_writer_test<UGGrid<2>, Vtk::SerialGridCreator<UGGrid<2>>>(mpi, test, "UGGrid<2>");
  reader_writer_test<UGGrid<3>, Vtk::SerialGridCreator<UGGrid<3>>>(mpi, test, "UGGrid<3>");
Praetorius, Simon's avatar
Praetorius, Simon committed
187
188
189
#endif

#if HAVE_DUNE_ALUGRID
190
  // Test VtkWriter for ALUGrid.
Stenger, Florian's avatar
Stenger, Florian committed
191
192
  reader_writer_test<ALUGridType<2>, Vtk::SerialGridCreator<ALUGridType<2>>>(mpi, test, "ALUGridType<2>");
  reader_writer_test<ALUGridType<2>, Vtk::ParallelGridCreator<ALUGridType<2>>>(mpi, test, "ALUGridType<2, Parallel>", false);
Praetorius, Simon's avatar
Praetorius, Simon committed
193

Stenger, Florian's avatar
Stenger, Florian committed
194
  reader_writer_test<ALUGridType<3>, Vtk::SerialGridCreator<ALUGridType<3>>>(mpi, test, "ALUGridType<3>");
195
196
  #if DUNE_VERSION_LT(DUNE_GRID,2,7)
  // Currently the 2.7 branch is not working, due to a new bisection compatibility check in 3d
Stenger, Florian's avatar
Stenger, Florian committed
197
  reader_writer_test<ALUGridType<3>, Vtk::ParallelGridCreator<ALUGridType<3>>>(mpi, test, "ALUGridType<3, Parallel>", false);
198
  #endif
Praetorius, Simon's avatar
Praetorius, Simon committed
199
200
201
202
#endif

  return test.exit();
}