OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
convergence_test.cpp
1 //
2 // Created by jstark on 27.05.21.
3 //
4 #define BOOST_TEST_DYN_LINK
5 //#define BOOST_TEST_MAIN // in only one cpp file
6 #include <boost/test/unit_test.hpp>
7 
8 // Include redistancing files
9 #include "util/PathsAndFiles.hpp"
12 // Include header files for testing
13 #include "Draw/DrawSphere.hpp"
14 #include "l_norms/LNorms.hpp"
16 
17 
18 
19 BOOST_AUTO_TEST_SUITE(ConvergenceTestSuite)
20  typedef double phi_type;
21  typedef double space_type;
22  const phi_type EPSILON = std::numeric_limits<phi_type>::epsilon();
23 
24  space_type get_min_required_time_step(size_t Nmax, space_type b_low, space_type b_up, int dims)
25  {
26  space_type dx = (b_up - b_low) / (space_type) Nmax;
27  space_type sum = 0;
28  for (int d = 0; d < dims; d++)
29  {
30  sum += 1 / (dx * dx);
31  }
32  return 0.5 / sum;
33  }
34 
35  BOOST_AUTO_TEST_CASE(RedistancingSussman_convergence_test_1D)
36  {
37  // CFL dt in 1D for N=64 and c=1 is 0.000503905
38 
39  const size_t grid_dim = 1;
40  // some indices
41  const size_t x = 0;
42 
43  const size_t Phi_0_grid = 0;
44  const size_t SDF_sussman_grid = 1;
45  const size_t SDF_exact_grid = 2;
46  const size_t Error_grid = 3;
47 
48  const space_type box_lower = -1.0;
49  const space_type box_upper = 1.0;
50  Box<grid_dim, space_type> box({box_lower}, {box_upper});
53  typedef grid_dist_id<grid_dim, space_type, props> grid_in_type;
54 
55 // space_type dt = 0.000503905;
56  size_t Nmin = 32;
57  size_t Nmax = 4096;
58  space_type dt = get_min_required_time_step(Nmax, box_lower, box_upper, grid_dim);
59  for (size_t N = Nmin; N <= Nmax; N*=2)
60  {
61  const size_t sz[grid_dim] = {N};
62  grid_in_type g_dist(sz, box, ghost);
63  g_dist.setPropNames({"Phi_0", "SDF_sussman", "SDF_exact", "Relative error"});
64 
65  // Now we initialize the grid with the indicator function and the analytical solution
66  auto dom = g_dist.getDomainIterator();
67  while(dom.isNext())
68  {
69  auto key = dom.get();
70  Point<grid_dim, space_type> coords = g_dist.getPos(key);
71  g_dist.template get<Phi_0_grid>(key) = sgn(coords.get(x));
72  g_dist.template get<SDF_exact_grid>(key) = coords.get(x);
73  ++dom;
74  }
75 
76  {
77  Redist_options<phi_type> redist_options;
78  redist_options.min_iter = 1e3;
79  redist_options.max_iter = 1e16;
80 
81  // set both convergence criteria to false s.t. termination only when max_iterations reached
82  redist_options.convTolChange.check = true; // define here which of the convergence criteria above should
83  // be used. If both are true, termination only occurs when both are fulfilled or when iter > max_iter
84  redist_options.convTolChange.value = EPSILON;
85 
86  redist_options.convTolResidual.check = false; // (default: false)
87  redist_options.interval_check_convergence = 1000; // interval of #iterations at which
88  // convergence is checked (default: 100)
89  redist_options.width_NB_in_grid_points = 10; // width of narrow band in number of grid points.
90  // Must
91  // be at least 4, in order to have at least 2 grid points on each side of the interface. (default: 4)
92  redist_options.print_current_iterChangeResidual = true; // if true, prints out every current iteration + corresponding change from the previous iteration + residual from SDF (default: false)
93  redist_options.print_steadyState_iter = true; // if true, prints out the final iteration number when steady state was reached + final change + residual (default: true)
94 
96  redist_options); // Instantiation of Sussman-redistancing class
97  std::cout << "CFL dt = " << redist_obj.get_time_step() << std::endl;
98  redist_obj.set_user_time_step(dt);
99  std::cout << "dt set to = " << dt << std::endl;
100  // Run the redistancing. in the <> brackets provide property-index where 1.) your initial Phi is stored and 2.) where the resulting SDF should be written to.
101  redist_obj.run_redistancing<Phi_0_grid, SDF_sussman_grid>();
102 
103  // Compute the absolute error between analytical and numerical solution at each grid point
104  get_absolute_error<SDF_sussman_grid, SDF_exact_grid, Error_grid>(g_dist);
105 // g_dist.write("grid_postRedistancing", FORMAT_BINARY);
107  // Get narrow band: Place particles on interface (narrow band width e.g. 4 grid points on each side of the
108  // interface)
109  size_t bc[grid_dim] = {NON_PERIODIC};
110  typedef aggregate<phi_type> props_nb;
112  Ghost<grid_dim, space_type> ghost_vd(0);
113  vd_type vd_narrow_band(0, box, bc, ghost_vd);
114  vd_narrow_band.setPropNames({"error"});
115  const size_t Error_vd = 0;
116  // Compute the L_2- and L_infinity-norm and save to file
117  size_t narrow_band_width = redist_options.width_NB_in_grid_points - 2;
118  NarrowBand<grid_in_type, phi_type> narrowBand_points(g_dist, narrow_band_width); // Instantiation of
119  // NarrowBand class
120  narrowBand_points.get_narrow_band_copy_specific_property<SDF_sussman_grid, Error_grid, Error_vd>(g_dist,
121  vd_narrow_band);
122 // vd_narrow_band.write("vd_error_N" + std::to_string(N), FORMAT_BINARY);
123 // vd_narrow_band.save("test_data/output/vd_nb8p_error" + std::to_string(N) + ".bin");
124  // Compute the L_2- and L_infinity-norm and save to file
125  LNorms<phi_type> lNorms_vd;
126  lNorms_vd.get_l_norms_vector<Error_vd>(vd_narrow_band);
127  lNorms_vd.write_to_file(N, 6, "l_norms_", "./");
128  }
129 
130  }
131  }
132 
133  BOOST_AUTO_TEST_CASE(RedistancingSussman_convergence_test_3D)
134  {
135  const size_t grid_dim = 3;
136  // some indices
137  const size_t x = 0;
138  const size_t y = 1;
139  const size_t z = 2;
140 
141  const size_t Phi_0_grid = 0;
142  const size_t SDF_sussman_grid = 1;
143  const size_t SDF_exact_grid = 2;
144  const size_t Error_grid = 3;
145 
146  for (size_t N=32; N <=128; N*=2)
147  {
148  const space_type dt = 0.000165334;
149  const size_t sz[grid_dim] = {N, N, N};
150  const space_type radius = 1.0;
151  const space_type box_lower = 0.0;
152  const space_type box_upper = 4.0 * radius;
153  Box<grid_dim, space_type> box({box_lower, box_lower, box_lower}, {box_upper, box_upper, box_upper});
154  Ghost<grid_dim, long int> ghost(0);
156  typedef grid_dist_id<grid_dim, space_type, props > grid_in_type;
157  grid_in_type g_dist(sz, box, ghost);
158  g_dist.setPropNames({"Phi_0", "SDF_sussman", "SDF_exact", "Relative error"});
159 
160  const space_type center[grid_dim] = {0.5*(box_upper+box_lower), 0.5*(box_upper+box_lower), 0.5*(box_upper+box_lower)};
161  init_grid_with_sphere<Phi_0_grid>(g_dist, radius, center[x], center[y], center[z]); // Initialize sphere onto grid
162 
163  int order = 1;
164  {
165  Redist_options<phi_type> redist_options;
166  redist_options.min_iter = 1e4;
167  redist_options.max_iter = 1e4;
168 
169  // set both convergence criteria to false s.t. termination only when max_iterations reached
170  redist_options.convTolChange.check = false; // define here which of the convergence criteria above should be used. If both are true, termination only occurs when both are fulfilled or when iter > max_iter
171  redist_options.convTolResidual.check = false; // (default: false)
172 
173  redist_options.interval_check_convergence = 100; // interval of #iterations at which
174  // convergence is checked (default: 100)
175  redist_options.width_NB_in_grid_points = 8; // width of narrow band in number of grid points. Must be at least 4, in order to have at least 2 grid points on each side of the interface. (default: 4)
176  redist_options.print_current_iterChangeResidual = true; // if true, prints out every current iteration + corresponding change from the previous iteration + residual from SDF (default: false)
177  redist_options.print_steadyState_iter = true; // if true, prints out the final iteration number when steady state was reached + final change + residual (default: true)
178 
179  RedistancingSussman<grid_in_type, phi_type> redist_obj(g_dist, redist_options); // Instantiation of
180  // Sussman-redistancing class
181  redist_obj.set_user_time_step(dt);
182  std::cout << "dt set to = " << dt << std::endl;
183  // Run the redistancing. in the <> brackets provide property-index where 1.) your initial Phi is stored and 2.) where the resulting SDF should be written to.
184  redist_obj.run_redistancing<Phi_0_grid, SDF_sussman_grid>();
185 
186  // Compute exact signed distance function at each grid point
187  init_analytic_sdf_sphere<SDF_exact_grid>(g_dist, radius, center[x], center[y], center[z]);
188 
189  // Compute the absolute error between analytical and numerical solution at each grid point
190  get_absolute_error<SDF_sussman_grid, SDF_exact_grid, Error_grid>(g_dist);
191 
192 
194  // Get narrow band: Place particles on interface (narrow band width e.g. 4 grid points on each side of the
195  // interface)
196  size_t bc[grid_dim] = {PERIODIC, PERIODIC, PERIODIC};
197  typedef aggregate<phi_type> props_nb;
199  Ghost<grid_dim, space_type> ghost_vd(0);
200  vd_type vd_narrow_band(0, box, bc, ghost_vd);
201  vd_narrow_band.setPropNames({"error"});
202  const size_t Error_vd = 0;
203  // Compute the L_2- and L_infinity-norm and save to file
204  size_t narrow_band_width = 8;
205  NarrowBand<grid_in_type, phi_type> narrowBand_points(g_dist, narrow_band_width); // Instantiation of NarrowBand class
206  narrowBand_points.get_narrow_band_copy_specific_property<SDF_sussman_grid, Error_grid, Error_vd>(g_dist,
207  vd_narrow_band);
208 // vd_narrow_band.write("vd_nb8p_error_N" + std::to_string(N) + "_order" +
209 // std::to_string(order), FORMAT_BINARY);
210 // vd_narrow_band.save("test_data/output/vd_nb8p_error" + std::to_string(N) + ".bin");
211  // Compute the L_2- and L_infinity-norm and save to file
212  LNorms<phi_type> lNorms_vd;
213  lNorms_vd.get_l_norms_vector<Error_vd>(vd_narrow_band);
214  lNorms_vd.write_to_file(N, 6, "l_norms_vd_absError_8p_order" + std::to_string(order), "./");
215 
216 // switch(order)
217 // {
218 // case 1:
219 // BOOST_CHECK(lNorms_vd.l2 < 0.03369 + EPSILON);
220 // BOOST_CHECK(lNorms_vd.linf < 0.06307 + EPSILON);
221 // break;
222 // case 3:
223 // BOOST_CHECK(lNorms_vd.l2 < 0.02794 + EPSILON);
224 // BOOST_CHECK(lNorms_vd.linf < 0.0586704 + EPSILON);
225 // break;
226 // case 5:
227 // BOOST_CHECK(lNorms_vd.l2 < 0.0187199 + EPSILON);
228 // BOOST_CHECK(lNorms_vd.linf < 0.0367638 + EPSILON);
229 // break;
230 // }
231 
232  }
233  }
234  }
235 
236 BOOST_AUTO_TEST_SUITE_END()
237 
238 
Class for getting the narrow band around the interface.
Definition: NarrowBand.hpp:42
Class for reinitializing a level-set function into a signed distance function using Sussman redistanc...
Header file containing functions for computing the error and the L_2 / L_infinity norm.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
Structure to bundle options for redistancing.
Definition: Ghost.hpp:39
int sgn(T val)
Gets the sign of a variable.
Class for reinitializing a level-set function into a signed distance function using Sussman redistanc...
This is a distributed grid.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
This class represent an N-dimensional box.
Definition: Box.hpp:60
void get_l_norms_vector(vectortype &vd)
Computes the L_2 and L_infinity norm on the basis of the precomputed error on a particle vector.
Definition: LNorms.hpp:153
Distributed vector.
Header file containing functions for creating files and folders.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:214
It model an expression expr1 + ... exprn.
Definition: sum.hpp:92
Class for getting the narrow band around the interface.
Header file containing functions that compute the analytical solution of the signed distance function...
Class for computing the l2/l_infinity norm for distributed grids and vectors based on given errors.
Definition: LNorms.hpp:103