1#ifndef DUNE_GRID_UTILITY_TENSORGRIDFACTORY_HH
2#define DUNE_GRID_UTILITY_TENSORGRIDFACTORY_HH
31 template<
typename Gr
id>
32 class TensorGridFactoryCreator;
38 template<
typename Gr
id>
42 typedef typename Grid::Traits::CollectiveCommunication Comm;
46 std::unique_ptr<Grid> createGrid(Comm comm = Comm())
48 TensorGridFactoryCreator<Grid> creator(*
this);
49 return creator.createGrid(comm);
52 std::array<std::vector<ctype> , dim> coords()
const
64 const std::vector<ctype>&
operator[](std::size_t d)
const
80 _coords[d][0] = value;
94 for (
int i = 0; i < n; i++)
95 _coords[d].push_back (_coords[d].back () + h);
109 const ctype h = (end - _coords[d].back ()) / n;
110 for (
int i = 0; i < n - 1; i++)
111 _coords[d].push_back (_coords[d].back () + h);
112 _coords[d].push_back (end);
126 while (_coords[d].back () < end)
127 _coords[d].push_back (_coords[d].back () + h);
143 static_cast<ctype
> (0))
147 if (h0 ==
static_cast<ctype
>(0))
148 h = lastInterval (d) * ratio;
149 for (
int i = 0; i < n; i++)
151 _coords[d].push_back (_coords[d].back () + h);
172 if (h0 ==
static_cast<ctype
>(0))
173 h = lastInterval (d) * ratio;
174 while (_coords[d].back () < end)
176 _coords[d].push_back (_coords[d].back () + h);
196 static_cast<ctype
> (0),
201 h = lastInterval (d);
202 ctype ratio = newton (n, _coords[d].back (), end, h);
205 h = h * pow (ratio, n - 1);
208 for (
int i = 0; i < n - 1; i++)
210 _coords[d].push_back (_coords[d].back () + h);
213 _coords[d].push_back (end);
219 for (
int i=0; i<dim; i++)
221 std::cout <<
"Container in direction " << i <<
":" << std::endl <<
"Coordinates: ";
222 for (
auto it = _coords[i].begin(); it != _coords[i].end(); ++it)
223 std::cout << *it <<
" ";
224 std::cout << std::endl <<
"Interval lengths: ";
226 std::vector<ctype> meshsize;
227 for (
auto it = _coords[i].begin(); it != _coords[i].end()-1;)
229 meshsize.push_back(-1.*(*it));
231 meshsize.back() += *it;
234 for (
auto it = meshsize.begin(); it != meshsize.end(); ++it)
235 std::cout << *it <<
" ";
236 std::cout << std::endl <<
"Ratios between interval lengths: ";
238 std::vector<ctype> ratios;
239 for (
auto it = meshsize.begin(); it != meshsize.end() - 1 ;)
240 ratios.push_back((1./(*it)) * *(++it));
242 for (
auto it = ratios.begin(); it != ratios.end(); ++it)
243 std::cout << *it <<
" ";
244 std::cout << std::endl << std::endl << std::endl;
250 void emptyCheck (
int i)
252 if (_coords[i].empty ())
253 _coords[i].push_back (
static_cast<ctype
> (0));
257 ctype lastInterval (
int d)
259 if (_coords[d].size () < 2)
262 "Not enough elements in coordinate container to deduce interval length in TensorYaspFactory");
264 return _coords[d].back () - _coords[d][_coords[d].size () - 2];
270 ctype newton (
int n, ctype x_s, ctype x_e, ctype h)
272 ctype m = (x_e - x_s) / h;
274 ctype xnew = x_e - x_s;
275 while (std::abs (xnew - xold) > 1E-8)
279 - (-pow (xold, n) + m * xold - m + 1)
280 / (-n * pow (xold, n - 1) + m);
282 if (std::abs (xnew - 1) < 1E-6)
286 while (std::abs (xnew - xold) > 1E-8)
290 - (-pow (xold, n) + m * xold - m + 1)
291 / (-n * pow (xold, n - 1) + m);
297 std::array<std::vector<ctype>, dim> _coords;
302 template<
typename Gr
id>
303 class TensorGridFactoryCreator
306 typedef typename Grid::Traits::CollectiveCommunication Comm;
310 TensorGridFactoryCreator(
const TensorGridFactory<Grid>& factory) : _factory(factory) {}
312 std::unique_ptr<Grid> createGrid(Comm comm)
315 GridFactory<Grid> fac;
317 if (comm.rank() == 0)
320 std::array<unsigned int, dim> vsizes, esizes;
321 std::size_t size = 1;
322 for (std::size_t i = 0; i<dim; ++i)
324 vsizes[i] = _factory[i].size();
325 esizes[i] = vsizes[i] - 1;
330 FactoryUtilities::MultiIndex<dim> index(vsizes);
331 for (std::size_t i=0; i<size; ++i, ++index)
334 for (std::size_t j = 0; j<dim; ++j)
335 position[j] = _factory[j][index[j]];
336 fac.insertVertex(position);
340 std::array<std::size_t, dim> offsets;
342 for (std::size_t i=1; i<dim; i++)
343 offsets[i] = offsets[i-1] * vsizes[i-1];
347 unsigned int nCorners = 1<<dim;
349 std::vector<unsigned int> cornersTemplate(nCorners,0);
351 for (
size_t i=0; i<nCorners; i++)
352 for (
int j=0; j<dim; j++)
354 cornersTemplate[i] += offsets[j];
357 FactoryUtilities::MultiIndex<dim> eindex(esizes);
360 int numElements = eindex.cycle();
362 for (
int i=0; i<numElements; i++, ++eindex)
365 unsigned int base = 0;
366 for (
int j=0; j<dim; j++)
367 base += eindex[j] * offsets[j];
370 std::vector<unsigned int> corners = cornersTemplate;
371 for (
size_t j=0; j<corners.size(); j++)
378 return std::unique_ptr<Grid>(fac.createGrid());
382 const TensorGridFactory<Grid>& _factory;
385 template<
typename ctype,
int dim>
386 class TensorGridFactoryCreator<YaspGrid<dim, TensorProductCoordinates<ctype, dim> > >
389 typedef YaspGrid<dim, TensorProductCoordinates<ctype, dim> > Grid;
392 TensorGridFactoryCreator(
const TensorGridFactory<Grid>& factory) : _factory(factory) {}
394 std::unique_ptr<Grid> createGrid(Comm comm)
396 return std::make_unique<Grid>(_factory.coords(), std::bitset<dim>(0ULL), 1, comm);
399 const TensorGridFactory<Grid>& _factory;
GridFamily::Traits::CollectiveCommunication CollectiveCommunication
A type that is a model of Dune::CollectiveCommunication. It provides a portable way for collective co...
Definition: grid.hh:519
@ dimension
The dimension of the grid.
Definition: grid.hh:387
ct ctype
Define type used for coordinates in grid module.
Definition: grid.hh:522
A factory class for conveniently creating tensorproduct grids.
Definition: tensorgridfactory.hh:40
void fillRange(int d, int n, ctype end)
fills the range to end with n intervals in direction d
Definition: tensorgridfactory.hh:106
void geometricFillRange(int d, int n, ctype end, ctype h=static_cast< ctype >(0), bool first=true)
fills a coordinate range in direction d with n intervals according to a geometric series
Definition: tensorgridfactory.hh:195
void fillUntil(int d, ctype h, ctype end)
adds intervals in direction d until a given coordinate is reached
Definition: tensorgridfactory.hh:123
void geometricFillUntil(int d, ctype ratio, ctype end, ctype h0=static_cast< ctype >(0))
adds intervals in direction d according with a given length ratio until a given coordinate is reached
Definition: tensorgridfactory.hh:168
void print()
print the coordinate information given to the factory so far
Definition: tensorgridfactory.hh:217
void fillIntervals(int d, int n, ctype h)
pushs n intervals of length h in direction d
Definition: tensorgridfactory.hh:91
void setStart(int d, ctype value)
set a starting value in a given direction d
Definition: tensorgridfactory.hh:77
void geometricFillIntervals(int d, int n, ctype ratio, ctype h0=static_cast< ctype >(0))
adds n intervals in direction d with a given length ratio and a given starting interval length.
Definition: tensorgridfactory.hh:142
std::vector< ctype > & operator[](std::size_t d)
allow to manually tune the factory by overloading operator[] to export the coordinate vectors in the ...
Definition: tensorgridfactory.hh:58
const std::vector< ctype > & operator[](std::size_t d) const
allow to manually tune the factory by overloading operator[] to export the coordinate vectors in the ...
Definition: tensorgridfactory.hh:64
Provide a generic factory class for unstructured grids.
Implements a multiindex with arbitrary dimension and fixed index ranges This is used by various facto...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:705
Dune namespace.
Definition: alignedallocator.hh:10