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);
127 if (!std::is_sorted(positions[i].begin(), positions[i].end()))
128 DUNE_THROW(Dune::GridError,
"Make sure to specify a monotone increasing \"Positions\" array");
130 if(positions[i].size() < 2)
131 DUNE_THROW(Dune::GridError,
"Make sure to specify position arrays with at least two entries (min and max value).");
135 for (
int i = 0; i < dim; ++i)
137 DUNE_THROW(Dune::RangeError,
"Please specify Positions Angular and Radial and Axial correctly and unambiguously!" << std::endl);
141 std::cerr <<
"Deprecation warning: parameter Grid.WellRadius is deprecated. "
142 <<
"Specify the WellRadius as the first radial coordinate." << std::endl;
148 std::array<std::vector<int>, dim> cells;
149 for (
int i = 0; i < dim; ++i)
151 cells[i].resize(positions[i].size()-1, 1.0);
153 if (cells[i].size() + 1 != positions[i].size())
154 DUNE_THROW(Dune::RangeError,
"Make sure to specify the correct length of \"Cells\" and \"Positions\" arrays");
158 std::array<std::vector<Scalar>, dim> grading;
159 for (
int i = 0; i < dim; ++i)
161 grading[i].resize(positions[i].size()-1, 1.0);
163 if (grading[i].size() + 1 != positions[i].size())
164 DUNE_THROW(Dune::RangeError,
"Make sure to specify the correct length of \"Grading\" and \"Positions\" arrays");
168 std::array<std::vector<Scalar>, dim> globalPositions;
170 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
173 std::size_t numGlobalPositions = 1;
174 for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
175 numGlobalPositions += cells[dimIdx][zoneIdx];
177 globalPositions[dimIdx].resize(numGlobalPositions);
178 std::size_t posIdx = 0;
179 for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
181 const Scalar lower = positions[dimIdx][zoneIdx];
182 const Scalar upper = positions[dimIdx][zoneIdx+1];
183 const int numCells = cells[dimIdx][zoneIdx];
184 Scalar gradingFactor = grading[dimIdx][zoneIdx];
185 const Scalar length = upper - lower;
187 bool increasingCellSize =
false;
191 std::cout <<
"dim " << dimIdx
192 <<
" lower " << lower
193 <<
" upper " << upper
194 <<
" numCells " << numCells
195 <<
" grading " << gradingFactor;
198 if (gradingFactor > 1.0)
199 increasingCellSize =
true;
203 if (gradingFactor < 0.0)
206 gradingFactor = abs(gradingFactor);
208 if (gradingFactor < 1.0)
209 increasingCellSize =
true;
212 const bool useGrading = Dune::FloatCmp::eq(gradingFactor, 1.0) ? false :
true;
217 height = 1.0 / numCells;
219 std::cout <<
" -> h " << height * length << std::endl;
224 height = (1.0 - gradingFactor) / (1.0 - pow(gradingFactor, numCells));
228 std::cout <<
" -> grading_eff " << gradingFactor
229 <<
" h_min " << height * pow(gradingFactor, 0) * length
230 <<
" h_max " << height * pow(gradingFactor, numCells-1) * length
236 Dune::DynamicVector<Scalar> localPositions(numCells, 0.0);
237 for (
int i = 1; i < numCells; i++)
242 if (increasingCellSize)
243 hI *= pow(gradingFactor, i-1);
246 hI *= pow(gradingFactor, numCells-i);
248 localPositions[i] = localPositions[i-1] + hI;
251 localPositions *= length;
252 localPositions += lower;
254 for (
int i = 0; i < numCells; ++i)
255 globalPositions[dimIdx][posIdx++] = localPositions[i];
258 globalPositions[dimIdx][posIdx] = positions[dimIdx].back();
261 polarCoordinates[0] = globalPositions[indices[0]];
262 polarCoordinates[1] = globalPositions[indices[1]];
264 polarCoordinates[2] = globalPositions[dim - indices[0] - indices[1]];
267 std::transform(polarCoordinates[1].begin(), polarCoordinates[1].end(),
268 polarCoordinates[1].begin(),
269 [](Scalar s){
return s*M_PI/180; });
280 std::unique_ptr<Grid>
createCakeGrid(std::array<std::vector<Scalar>, dim> &polarCoordinates,
281 Dune::FieldVector<int, dim> &indices,
282 const std::string& modelParamGroup,
283 bool verbose =
false)
285 std::vector<Scalar> dR = polarCoordinates[0];
286 std::vector<Scalar> dA = polarCoordinates[1];
292 int maxdA = dA.size() - 1;
293 if (Dune::FloatCmp::eq(dA[dA.size()-1], 2*M_PI))
295 maxdA = dA.size() - 2;
298 GridFactory gridFactory;
299 constexpr auto type = Dune::GeometryTypes::cube(dim);
302 if(dR[0] < 1.0e-8*dR.back())
308 constexpr auto prismType = Dune::GeometryTypes::prism;
309 std::vector<Scalar> dZ = polarCoordinates[2];
310 for (
int j = 0; j <= maxdA; ++j)
312 for (
int l = 0; l <= dZ.size() - 1; ++l)
314 for (
int i = hasHole ? 0 : 1; i <= dR.size()- 1; ++i)
319 Dune::FieldVector <double, dim> v(0.0);
320 v[indices[2]] = dZ[l];
321 v[indices[0]] = cos(dA[j])*dR[i];
322 v[indices[1]] = sin(dA[j])*dR[i];
325 gridFactory.insertVertex(v);
334 for (
int l = 0; l <= dZ.size() - 1; ++l)
336 Dune::FieldVector <double, dim> v(0.0);
337 v[indices[2]] = dZ[l];
343 gridFactory.insertVertex(v);
348 std::cout <<
"Filled node vector" << std::endl;
353 unsigned int rSize = hasHole ? dR.size() : dR.size()-1;
354 unsigned int zSize = dZ.size();
355 for (
int j = 0; j < dA.size() - 1; ++j)
357 for (
int l = 0; l < dZ.size() - 1; ++l)
361 for (
int i = 0; i < dR.size() - 1; ++i)
365 std::vector<unsigned int> vid({rSize*zSize*(maxdA+1) + l, z, z+rSize*zSize,
366 rSize*zSize*(maxdA+1) + l+1, z+rSize, z+rSize*zSize+rSize});
371 gridFactory.insertElement(prismType, vid);
375 std::vector<unsigned int> vid({z, z+1,
376 z+rSize*zSize, z+rSize*zSize+1,
378 z+rSize*zSize+rSize, z+rSize*zSize+rSize+1});
383 gridFactory.insertElement(type, vid);
393 for (
int i = 0; i < dR.size() - 1; ++i)
397 std::vector<unsigned int> vid({rSize*zSize*(maxdA+1) + l, z, t,
398 rSize*zSize*(maxdA+1) + l+1, z+rSize, t+rSize});
403 gridFactory.insertElement(prismType, vid);
407 std::vector<unsigned int> vid({z, z+1,
410 t+rSize, t+rSize+1});
415 gridFactory.insertElement(type, vid);
424 std::cout <<
"assign nodes 360° ends..." << std::endl;
433 constexpr auto triangleType = Dune::GeometryTypes::simplex(dim);
434 for (
int j = 0; j <= maxdA; ++j)
436 for (
int i = hasHole ? 0 : 1; i <= dR.size()- 1; ++i)
439 Dune::FieldVector <double, dim> v(0.0);
441 v[indices[0]] = cos(dA[j])*dR[i];
442 v[indices[1]] = sin(dA[j])*dR[i];
445 gridFactory.insertVertex(v);
453 Dune::FieldVector <double, dim> v(0.0);
459 gridFactory.insertVertex(v);
462 std::cout <<
"Filled node vector" << std::endl;
467 unsigned int rSize = hasHole ? dR.size() : dR.size()-1;
468 for (
int j = 0; j < dA.size() - 1; ++j)
472 for (
int i = 0; i < dR.size() - 1; ++i)
476 std::vector<unsigned int> vid({rSize*(maxdA+1), z, z+rSize});
481 gridFactory.insertElement(triangleType, vid);
485 std::vector<unsigned int> vid({z, z+1, z+rSize, z+rSize+1});
490 gridFactory.insertElement(type, vid);
499 for (
int i = 0; i < dR.size() - 1; ++i)
503 std::vector<unsigned int> vid({rSize*(maxdA+1), z, t});
508 gridFactory.insertElement(triangleType, vid);
512 std::vector<unsigned int> vid({z, z+1, t, t+1});
517 gridFactory.insertElement(type, vid);
526 std::cout <<
"assign nodes 360 ends..." << std::endl;
531 return std::unique_ptr<Grid>(gridFactory.createGrid());