86 static void createVectors(std::array<std::vector<Scalar>, dim> &polarCoordinates,
87 Dune::FieldVector<int, dim> &indices,
88 const std::string& modelParamGroup,
92 std::array<std::vector<Scalar>, dim> positions;
94 for (
int i = 0; i < dim; ++i)
96 const bool hasRadial =
hasParamInGroup(modelParamGroup,
"Grid.Radial" + std::to_string(i));
97 const bool hasAngular =
hasParamInGroup(modelParamGroup,
"Grid.Angular" + std::to_string(i));
98 const bool hasAxial = (dim == 3) &&
hasParamInGroup(modelParamGroup,
"Grid.Axial" + std::to_string(i));
99 if (
static_cast<int>(hasRadial) +
static_cast<int>(hasAngular) +
static_cast<int>(hasAxial) != 1)
100 DUNE_THROW(Dune::RangeError,
"Multiple or no position vectors (radial, angular, axial) specified in coord direction: " << i << std::endl);
118 if (!std::is_sorted(positions[i].begin(), positions[i].end()))
119 DUNE_THROW(Dune::GridError,
"Make sure to specify a monotone increasing \"Positions\" array");
121 if(positions[i].size() < 2)
122 DUNE_THROW(Dune::GridError,
"Make sure to specify position arrays with at least two entries (min and max value).");
126 for (
int i = 0; i < dim; ++i)
128 DUNE_THROW(Dune::RangeError,
"Please specify Positions Angular and Radial and Axial correctly and unambiguously!" << std::endl);
131 std::array<std::vector<int>, dim> cells;
132 for (
int i = 0; i < dim; ++i)
134 cells[i].resize(positions[i].size()-1, 1.0);
136 if (cells[i].size() + 1 != positions[i].size())
137 DUNE_THROW(Dune::RangeError,
"Make sure to specify the correct length of \"Cells\" and \"Positions\" arrays");
141 std::array<std::vector<Scalar>, dim> grading;
142 for (
int i = 0; i < dim; ++i)
144 grading[i].resize(positions[i].size()-1, 1.0);
146 if (grading[i].size() + 1 != positions[i].size())
147 DUNE_THROW(Dune::RangeError,
"Make sure to specify the correct length of \"Grading\" and \"Positions\" arrays");
151 std::array<std::vector<Scalar>, dim> globalPositions;
154 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
157 std::size_t numGlobalPositions = 1;
158 for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
159 numGlobalPositions += cells[dimIdx][zoneIdx];
161 globalPositions[dimIdx].resize(numGlobalPositions);
162 std::size_t posIdx = 0;
163 for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
165 const Scalar lower = positions[dimIdx][zoneIdx];
166 const Scalar upper = positions[dimIdx][zoneIdx+1];
167 const int numCells = cells[dimIdx][zoneIdx];
168 Scalar gradingFactor = grading[dimIdx][zoneIdx];
169 const Scalar length = upper - lower;
171 bool increasingCellSize =
false;
175 std::cout <<
"dim " << dimIdx
176 <<
" lower " << lower
177 <<
" upper " << upper
178 <<
" numCells " << numCells
179 <<
" grading " << gradingFactor;
182 if (gradingFactor > 1.0)
183 increasingCellSize =
true;
187 if (gradingFactor < 0.0)
190 gradingFactor = abs(gradingFactor);
192 if (gradingFactor < 1.0)
193 increasingCellSize =
true;
196 const bool useGrading = Dune::FloatCmp::eq(gradingFactor, 1.0) ? false :
true;
201 height = 1.0 / numCells;
203 std::cout <<
" -> h " << height * length << std::endl;
208 height = (1.0 - gradingFactor) / (1.0 - power(gradingFactor, numCells));
212 std::cout <<
" -> grading_eff " << gradingFactor
213 <<
" h_min " << height * power(gradingFactor, 0) * length
214 <<
" h_max " << height * power(gradingFactor, numCells-1) * length
220 Dune::DynamicVector<Scalar> localPositions(numCells, 0.0);
221 for (
int i = 1; i < numCells; i++)
226 if (increasingCellSize)
227 hI *= power(gradingFactor, i-1);
230 hI *= power(gradingFactor, numCells-i);
232 localPositions[i] = localPositions[i-1] + hI;
235 localPositions *= length;
236 localPositions += lower;
238 for (
int i = 0; i < numCells; ++i)
239 globalPositions[dimIdx][posIdx++] = localPositions[i];
242 globalPositions[dimIdx][posIdx] = positions[dimIdx].back();
245 polarCoordinates[0] = globalPositions[indices[0]];
246 polarCoordinates[1] = globalPositions[indices[1]];
248 polarCoordinates[2] = globalPositions[dim - indices[0] - indices[1]];
251 std::transform(polarCoordinates[1].begin(), polarCoordinates[1].end(),
252 polarCoordinates[1].begin(),
253 [](Scalar s){
return s*M_PI/180; });
264 std::unique_ptr<Grid>
createCakeGrid(std::array<std::vector<Scalar>, dim> &polarCoordinates,
265 Dune::FieldVector<int, dim> &indices,
266 const std::string& modelParamGroup,
267 bool verbose =
false)
269 GridFactory gridFactory;
272 if (gridFactory.comm().rank() != 0)
273 return std::unique_ptr<Grid>(gridFactory.createGrid());
275 const auto& dR = polarCoordinates[0];
276 const auto& dA = polarCoordinates[1];
282 const int dAMax = Dune::FloatCmp::eq(dA[dA.size()-1], 2*M_PI) ? dA.size() - 2 : dA.size() - 1;
283 constexpr auto type = Dune::GeometryTypes::cube(dim);
284 const bool hasHole = dR[0] >= 1.0e-8*dR.back();
287 if constexpr (dim == 3)
289 constexpr auto prismType = Dune::GeometryTypes::prism;
290 std::vector<Scalar> dZ = polarCoordinates[2];
291 for (
int j = 0; j <= dAMax; ++j)
293 for (
int l = 0; l <= dZ.size() - 1; ++l)
295 for (
int i = hasHole ? 0 : 1; i <= dR.size()- 1; ++i)
300 Dune::FieldVector <double, dim> v(0.0);
301 v[indices[2]] = dZ[l];
302 v[indices[0]] = cos(dA[j])*dR[i];
303 v[indices[1]] = sin(dA[j])*dR[i];
306 gridFactory.insertVertex(v);
315 for (
int l = 0; l <= dZ.size() - 1; ++l)
317 Dune::FieldVector <double, dim> v(0.0);
318 v[indices[2]] = dZ[l];
324 gridFactory.insertVertex(v);
329 std::cout <<
"Filled node vector" << std::endl;
334 unsigned int rSize = hasHole ? dR.size() : dR.size()-1;
335 unsigned int zSize = dZ.size();
336 for (
int j = 0; j < dA.size() - 1; ++j)
338 for (
int l = 0; l < dZ.size() - 1; ++l)
342 for (
int i = 0; i < dR.size() - 1; ++i)
346 std::vector<unsigned int> vid({rSize*zSize*(dAMax+1) + l, z, z+rSize*zSize,
347 rSize*zSize*(dAMax+1) + l+1, z+rSize, z+rSize*zSize+rSize});
352 gridFactory.insertElement(prismType, vid);
356 std::vector<unsigned int> vid({z, z+1,
357 z+rSize*zSize, z+rSize*zSize+1,
359 z+rSize*zSize+rSize, z+rSize*zSize+rSize+1});
364 gridFactory.insertElement(type, vid);
374 for (
int i = 0; i < dR.size() - 1; ++i)
378 std::vector<unsigned int> vid({rSize*zSize*(dAMax+1) + l, z, t,
379 rSize*zSize*(dAMax+1) + l+1, z+rSize, t+rSize});
384 gridFactory.insertElement(prismType, vid);
388 std::vector<unsigned int> vid({z, z+1,
391 t+rSize, t+rSize+1});
396 gridFactory.insertElement(type, vid);
405 std::cout <<
"assign nodes 360° ends..." << std::endl;
415 constexpr auto triangleType = Dune::GeometryTypes::simplex(dim);
416 for (
int j = 0; j <= dAMax; ++j)
418 for (
int i = hasHole ? 0 : 1; i <= dR.size()- 1; ++i)
421 Dune::FieldVector <double, dim> v(0.0);
423 v[indices[0]] = cos(dA[j])*dR[i];
424 v[indices[1]] = sin(dA[j])*dR[i];
427 gridFactory.insertVertex(v);
435 Dune::FieldVector <double, dim> v(0.0);
441 gridFactory.insertVertex(v);
444 std::cout <<
"Filled node vector" << std::endl;
449 unsigned int rSize = hasHole ? dR.size() : dR.size()-1;
450 for (
int j = 0; j < dA.size() - 1; ++j)
454 for (
int i = 0; i < dR.size() - 1; ++i)
458 std::vector<unsigned int> vid({rSize*(dAMax+1), z, z+rSize});
463 gridFactory.insertElement(triangleType, vid);
467 std::vector<unsigned int> vid({z, z+1, z+rSize, z+rSize+1});
472 gridFactory.insertElement(type, vid);
481 for (
int i = 0; i < dR.size() - 1; ++i)
485 std::vector<unsigned int> vid({rSize*(dAMax+1), z, t});
490 gridFactory.insertElement(triangleType, vid);
494 std::vector<unsigned int> vid({z, z+1, t, t+1});
499 gridFactory.insertElement(type, vid);
508 std::cout <<
"assign nodes 360 ends..." << std::endl;
514 return std::unique_ptr<Grid>(gridFactory.createGrid());