24#ifndef DUMUX_CAKE_GRID_MANAGER_HH
25#define DUMUX_CAKE_GRID_MANAGER_HH
32#include <dune/common/dynvector.hh>
33#include <dune/common/float_cmp.hh>
34#include <dune/grid/common/gridfactory.hh>
48 using Scalar =
typename Grid::ctype;
50 using GridFactory = Dune::GridFactory<Grid>;
51 using GridPointer = std::shared_ptr<Grid>;
53 enum { dim = Grid::dimension,
54 dimWorld = Grid::dimensionworld };
60 void init(
const std::string& modelParamGroup =
"")
62 static_assert(dim == 2 || dim == 3,
"The CakeGridManager is only implemented for 2D and 3D.");
64 const bool verbose = getParamFromGroup<bool>(modelParamGroup,
"Grid.Verbosity",
false);
66 std::array<std::vector<Scalar>, dim> polarCoordinates;
68 Dune::FieldVector<int, dim> indices(-1);
69 createVectors(polarCoordinates, indices, modelParamGroup, verbose);
95 static void createVectors(std::array<std::vector<Scalar>, dim> &polarCoordinates,
96 Dune::FieldVector<int, dim> &indices,
97 const std::string& modelParamGroup,
101 std::array<std::vector<Scalar>, dim> positions;
103 for (
int i = 0; i < dim; ++i)
105 const bool hasRadial =
hasParamInGroup(modelParamGroup,
"Grid.Radial" + std::to_string(i));
106 const bool hasAngular =
hasParamInGroup(modelParamGroup,
"Grid.Angular" + std::to_string(i));
107 const bool hasAxial = (dim == 3) &&
hasParamInGroup(modelParamGroup,
"Grid.Axial" + std::to_string(i));
108 if (
static_cast<int>(hasRadial) +
static_cast<int>(hasAngular) +
static_cast<int>(hasAxial) != 1)
109 DUNE_THROW(Dune::RangeError,
"Multiple or no position vectors (radial, angular, axial) specified in coord direction: " << i << std::endl);
113 positions[i] = getParamFromGroup<std::vector<Scalar>>(modelParamGroup,
"Grid.Radial" + std::to_string(i));
119 positions[i] = getParamFromGroup<std::vector<Scalar>>(modelParamGroup,
"Grid.Angular" + std::to_string(i));
125 positions[i] = getParamFromGroup<std::vector<Scalar>>(modelParamGroup,
"Grid.Axial" + std::to_string(i));
129 if (!std::is_sorted(positions[i].begin(), positions[i].end()))
130 DUNE_THROW(Dune::GridError,
"Make sure to specify a monotone increasing \"Positions\" array");
134 for (
int i = 0; i < dim; ++i)
136 DUNE_THROW(Dune::RangeError,
"Please specify Positions Angular and Radial and Axial correctly and unambiguously!" << std::endl);
139 std::array<std::vector<int>, dim> cells;
140 for (
int i = 0; i < dim; ++i)
142 cells[i].resize(positions[i].size()-1, 1.0);
143 cells[i] = getParamFromGroup<std::vector<int>>(modelParamGroup,
"Grid.Cells" + std::to_string(i), cells[i]);
144 if (cells[i].size() + 1 != positions[i].size())
145 DUNE_THROW(Dune::RangeError,
"Make sure to specify the correct length of \"Cells\" and \"Positions\" arrays");
149 std::array<std::vector<Scalar>, dim> grading;
150 for (
int i = 0; i < dim; ++i)
152 grading[i].resize(positions[i].size()-1, 1.0);
153 grading[i] = getParamFromGroup<std::vector<Scalar>>(modelParamGroup,
"Grid.Grading" + std::to_string(i), grading[i]);
154 if (grading[i].size() + 1 != positions[i].size())
155 DUNE_THROW(Dune::RangeError,
"Make sure to specify the correct length of \"Grading\" and \"Positions\" arrays");
159 std::array<std::vector<Scalar>, dim> globalPositions;
161 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
163 std::size_t numGlobalPositions = 0;
164 for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
165 numGlobalPositions += cells[dimIdx][zoneIdx] + 1;
167 globalPositions[dimIdx].resize(numGlobalPositions);
168 std::size_t posIdx = 0;
169 for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
171 const Scalar lower = positions[dimIdx][zoneIdx];
172 const Scalar upper = positions[dimIdx][zoneIdx+1];
173 const int numCells = cells[dimIdx][zoneIdx];
174 Scalar gradingFactor = grading[dimIdx][zoneIdx];
175 const Scalar length = upper - lower;
177 bool increasingCellSize =
false;
181 std::cout <<
"dim " << dimIdx
182 <<
" lower " << lower
183 <<
" upper " << upper
184 <<
" numCells " << numCells
185 <<
" grading " << gradingFactor;
188 if (gradingFactor > 1.0)
189 increasingCellSize =
true;
193 if (gradingFactor < 0.0)
196 gradingFactor = abs(gradingFactor);
198 if (gradingFactor < 1.0)
199 increasingCellSize =
true;
203 if (gradingFactor > 1.0 - 1e-7 && gradingFactor < 1.0 + 1e-7)
205 height = 1.0 / numCells;
207 std::cout <<
" -> h " << height * length << std::endl;
213 height = (1.0 - gradingFactor) / (1.0 - pow(gradingFactor, numCells));
217 std::cout <<
" -> grading_eff " << gradingFactor
218 <<
" h_min " << height * pow(gradingFactor, 0) * length
219 <<
" h_max " << height * pow(gradingFactor, numCells-1) * length
225 Dune::DynamicVector<Scalar> localPositions(numCells, 0.0);
226 for (
int i = 1; i < numCells; i++)
229 if (!(gradingFactor < 1.0 + 1e-7 && gradingFactor > 1.0 - 1e-7))
231 if (increasingCellSize)
232 hI *= pow(gradingFactor, i-1);
235 hI *= pow(gradingFactor, numCells-i);
237 localPositions[i] = localPositions[i-1] + hI;
240 localPositions *= length;
241 localPositions += lower;
243 for (
int i = 0; i < numCells; ++i)
244 globalPositions[dimIdx][posIdx++] = localPositions[i];
247 globalPositions[dimIdx][posIdx] = positions[dimIdx].back();
250 polarCoordinates[0] = globalPositions[indices[0]];
251 polarCoordinates[1] = globalPositions[indices[1]];
253 polarCoordinates[2] = globalPositions[dim - indices[0] - indices[1]];
256 std::transform(polarCoordinates[1].begin(), polarCoordinates[1].end(),
257 polarCoordinates[1].begin(),
258 [](Scalar s){
return s*M_PI/180; });
269 std::unique_ptr<Grid>
createCakeGrid(std::array<std::vector<Scalar>, dim> &polarCoordinates,
270 Dune::FieldVector<int, dim> &indices,
271 const std::string& modelParamGroup,
272 bool verbose =
false)
274 std::vector<Scalar> dR = polarCoordinates[0];
275 std::vector<Scalar> dA = polarCoordinates[1];
281 int maxdA = dA.size() - 1;
282 if (Dune::FloatCmp::eq(polarCoordinates[1][polarCoordinates[1].size()-1], 360.0))
284 maxdA = dA.size() - 2;
287 GridFactory gridFactory;
288 constexpr auto type = Dune::GeometryTypes::cube(dim);
293 std::vector<Scalar> dZ = polarCoordinates[2];
294 for (
int j = 0; j <= dA.size() - 1; ++j)
296 for (
int l = 0; l <= dZ.size() - 1; ++l)
298 for (
int i = 0; i <= dR.size()- 1; ++i)
301 const auto wellRadius = getParamFromGroup<Scalar>(modelParamGroup,
"Grid.WellRadius");
306 Dune::FieldVector <double, dim> v(0.0);
307 v[indices[2]] = dZ[l];
308 v[indices[0]] = cos(dA[j])*wellRadius + cos(dA[j])*dR[i];
309 v[indices[1]] = sin(dA[j])*wellRadius + sin(dA[j])*dR[i];
312 std::cout <<
"Coordinates of : "
313 << v[0] <<
" " << v[1] <<
" " << v[2] << std::endl;
315 gridFactory.insertVertex(v);
321 std::cout <<
"Filled node vector" << std::endl;
326 for (
int j = 0; j < dA.size() - 1; ++j)
328 for (
int l = 0; l < dZ.size() - 1; ++l)
332 for (
int i = 0; i < dR.size() - 1; ++i)
334 unsigned int rSize = dR.size();
335 unsigned int zSize = dZ.size();
336 std::vector<unsigned int> vid({z, z+1, z+rSize*zSize,
337 z+rSize*zSize+1, z+rSize, z+rSize+1,
338 z+rSize*zSize+rSize, z+rSize*zSize+rSize+1});
342 std::cout <<
"element vertex ids: ";
343 for (
int k = 0; k < vid.size(); ++k)
344 std::cout << vid[k] <<
" ";
345 std::cout << std::endl;
348 gridFactory.insertElement(type, vid);
357 for (
int i = 0; i < dR.size() - 1; ++i)
360 unsigned int rSize = dR.size();
361 std::vector<unsigned int> vid({z, z+1, t,
362 t+1, z+rSize, z+rSize+1,
363 t+rSize, t+rSize+1});
367 std::cout <<
"element vertex ids: ";
368 for (
int k = 0; k < vid.size(); ++k)
369 std::cout << vid[k] <<
" ";
370 std::cout << std::endl;
373 gridFactory.insertElement(type, vid);
381 std::cout <<
"assign nodes 360° ends..." << std::endl;
391 for (
int j = 0; j <= dA.size() - 1; ++j)
393 for (
int i = 0; i <= dR.size()- 1; ++i)
396 const Scalar wellRadius = getParamFromGroup<Scalar>(modelParamGroup,
"Grid.WellRadius");
399 Dune::FieldVector <double, dim> v(0.0);
401 v[indices[0]] = cos(dA[j])*wellRadius + cos(dA[j])*dR[i];
402 v[indices[1]] = sin(dA[j])*wellRadius + sin(dA[j])*dR[i];
403 if(verbose) std::cout <<
"Coordinates of : " << v[0] <<
" " << v[1] << std::endl;
404 gridFactory.insertVertex(v);
407 std::cout <<
"Filled node vector" << std::endl;
412 for (
int j = 0; j < dA.size() - 1; ++j)
416 for (
int i = 0; i < dR.size() - 1; ++i)
418 unsigned int rSize = dR.size();
419 std::vector<unsigned int> vid({z, z+1, z+rSize, z+rSize+1});
423 std::cout <<
"element vertex ids: ";
424 for (
int k = 0; k < vid.size(); ++k)
425 std::cout << vid[k] <<
" ";
426 std::cout << std::endl;
429 gridFactory.insertElement(type, vid);
437 for (
int i = 0; i < dR.size() - 1; ++i)
440 std::vector<unsigned int> vid({z, z+1, t, t+1});
444 std::cout <<
"element vertex ids: ";
445 for (
int k = 0; k < vid.size(); ++k)
446 std::cout << vid[k] <<
" ";
447 std::cout << std::endl;
450 gridFactory.insertElement(type, vid);
457 std::cout <<
"assign nodes 360 ends..." << std::endl;
461 return std::unique_ptr<Grid>(gridFactory.createGrid());
492 GridPointer cakeGrid_;
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
bool hasParamInGroup(const std::string ¶mGroup, const std::string ¶m)
Check whether a key exists in the parameter tree with a model group prefix.
Definition: parameters.hh:454
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Provides a grid manager with a method for creating creating vectors with polar Coordinates and one fo...
Definition: cakegridmanager.hh:47
void init(const std::string &modelParamGroup="")
Make the grid.
Definition: cakegridmanager.hh:60
void loadBalance()
Distributes the grid on all processes of a parallel computation.
Definition: cakegridmanager.hh:476
GridPointer & gridPtr()
Returns a reference to the shared pointer to the grid.
Definition: cakegridmanager.hh:486
Grid & grid()
Returns a reference to the grid.
Definition: cakegridmanager.hh:467
static void createVectors(std::array< std::vector< Scalar >, dim > &polarCoordinates, Dune::FieldVector< int, dim > &indices, const std::string &modelParamGroup, bool verbose=false)
Create vectors containing polar coordinates of all points.
Definition: cakegridmanager.hh:95
std::unique_ptr< Grid > createCakeGrid(std::array< std::vector< Scalar >, dim > &polarCoordinates, Dune::FieldVector< int, dim > &indices, const std::string &modelParamGroup, bool verbose=false)
Creates cartesian grid from polar coordinates.
Definition: cakegridmanager.hh:269