84    static void createVectors(std::array<std::vector<Scalar>, dim> &polarCoordinates,
 
   85                              Dune::FieldVector<int, dim> &indices,
 
   86                              const std::string& modelParamGroup,
 
   90        std::array<std::vector<Scalar>, dim> positions;
 
   92        for (
int i = 0; i < dim; ++i)
 
   94            const bool hasRadial = 
hasParamInGroup(modelParamGroup, 
"Grid.Radial" + std::to_string(i));
 
   95            const bool hasAngular = 
hasParamInGroup(modelParamGroup, 
"Grid.Angular" + std::to_string(i));
 
   96            const bool hasAxial = (dim == 3) && 
hasParamInGroup(modelParamGroup, 
"Grid.Axial" + std::to_string(i));
 
   97            if (
static_cast<int>(hasRadial) + 
static_cast<int>(hasAngular) + 
static_cast<int>(hasAxial) != 1)
 
   98                DUNE_THROW(Dune::RangeError, 
"Multiple or no position vectors (radial, angular, axial) specified in coord direction: " << i << std::endl);
 
  116            if (!std::is_sorted(positions[i].begin(), positions[i].end()))
 
  117                DUNE_THROW(Dune::GridError, 
"Make sure to specify a monotone increasing \"Positions\" array");
 
  119            if(positions[i].size() < 2)
 
  120                DUNE_THROW(Dune::GridError, 
"Make sure to specify position arrays with at least two entries (min and max value).");
 
  124        for (
int i = 0; i < dim; ++i)
 
  126                DUNE_THROW(Dune::RangeError, 
"Please specify Positions Angular and Radial and Axial correctly and unambiguously!" << std::endl);
 
  129        std::array<std::vector<int>, dim> cells;
 
  130        for (
int i = 0; i < dim; ++i)
 
  132            cells[i].resize(positions[i].size()-1, 1.0);
 
  134            if (cells[i].size() + 1 != positions[i].size())
 
  135                DUNE_THROW(Dune::RangeError, 
"Make sure to specify the correct length of \"Cells\" and \"Positions\" arrays");
 
  139        std::array<std::vector<Scalar>, dim> grading;
 
  140        for (
int i = 0; i < dim; ++i)
 
  142            grading[i].resize(positions[i].size()-1, 1.0);
 
  144            if (grading[i].size() + 1 != positions[i].size())
 
  145                DUNE_THROW(Dune::RangeError, 
"Make sure to specify the correct length of \"Grading\" and \"Positions\" arrays");
 
  149        std::array<std::vector<Scalar>, dim> globalPositions;
 
  152        for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
 
  155            std::size_t numGlobalPositions = 1;
 
  156            for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
 
  157                numGlobalPositions += cells[dimIdx][zoneIdx];
 
  159            globalPositions[dimIdx].resize(numGlobalPositions);
 
  160            std::size_t posIdx = 0;
 
  161            for (
int zoneIdx = 0; zoneIdx < cells[dimIdx].size(); ++zoneIdx)
 
  163                const Scalar lower = positions[dimIdx][zoneIdx];
 
  164                const Scalar upper = positions[dimIdx][zoneIdx+1];
 
  165                const int numCells = cells[dimIdx][zoneIdx];
 
  166                Scalar gradingFactor = grading[dimIdx][zoneIdx];
 
  167                const Scalar length = upper - lower;
 
  169                bool increasingCellSize = 
false;
 
  173                    std::cout << 
"dim " << dimIdx
 
  174                              << 
" lower "  << lower
 
  175                              << 
" upper "  << upper
 
  176                              << 
" numCells "  << numCells
 
  177                              << 
" grading "  << gradingFactor;
 
  180                if (gradingFactor > 1.0)
 
  181                    increasingCellSize = 
true;
 
  185                if (gradingFactor < 0.0)
 
  188                    gradingFactor = abs(gradingFactor);
 
  190                    if (gradingFactor < 1.0)
 
  191                        increasingCellSize = 
true;
 
  194                const bool useGrading = Dune::FloatCmp::eq(gradingFactor, 1.0) ? false : 
true;
 
  199                    height = 1.0 / numCells;
 
  201                        std::cout << 
" -> h "  << height * length << std::endl;
 
  206                    height = (1.0 - gradingFactor) / (1.0 - power(gradingFactor, numCells));
 
  210                        std::cout << 
" -> grading_eff "  << gradingFactor
 
  211                                  << 
" h_min "  << height * power(gradingFactor, 0) * length
 
  212                                  << 
" h_max "  << height * power(gradingFactor, numCells-1) * length
 
  218                Dune::DynamicVector<Scalar> localPositions(numCells, 0.0);
 
  219                for (
int i = 1; i < numCells; i++)
 
  224                        if (increasingCellSize)
 
  225                            hI *= power(gradingFactor, i-1);
 
  228                            hI *= power(gradingFactor, numCells-i);
 
  230                    localPositions[i] = localPositions[i-1] + hI;
 
  233                localPositions *= length;
 
  234                localPositions += lower;
 
  236                for (
int i = 0; i < numCells; ++i)
 
  237                    globalPositions[dimIdx][posIdx++] = localPositions[i];
 
  240            globalPositions[dimIdx][posIdx] = positions[dimIdx].back();
 
  243        polarCoordinates[0] = globalPositions[indices[0]];
 
  244        polarCoordinates[1] = globalPositions[indices[1]];
 
  246            polarCoordinates[2] = globalPositions[dim - indices[0] - indices[1]];
 
  249        std::transform(polarCoordinates[1].begin(), polarCoordinates[1].end(),
 
  250                       polarCoordinates[1].begin(),
 
  251                       [](Scalar s){ 
return s*M_PI/180; });
 
 
  262    std::unique_ptr<Grid> 
createCakeGrid(std::array<std::vector<Scalar>, dim> &polarCoordinates,
 
  263                                         Dune::FieldVector<int, dim> &indices,
 
  264                                         const std::string& modelParamGroup,
 
  265                                         bool verbose = 
false)
 
  267        GridFactory gridFactory;
 
  270        if (gridFactory.comm().rank() != 0)
 
  271            return std::unique_ptr<Grid>(gridFactory.createGrid());
 
  273        const auto& dR = polarCoordinates[0];
 
  274        const auto& dA = polarCoordinates[1];
 
  280        const int dAMax = Dune::FloatCmp::eq(dA[dA.size()-1], 2*M_PI) ? dA.size() - 2 : dA.size() - 1;
 
  281        constexpr auto type = Dune::GeometryTypes::cube(dim);
 
  282        const bool hasHole = dR[0] >= 1.0e-8*dR.back();
 
  285        if constexpr (dim == 3)
 
  287            constexpr auto prismType = Dune::GeometryTypes::prism;
 
  288            std::vector<Scalar> dZ = polarCoordinates[2];
 
  289            for (
int j = 0; j <= dAMax; ++j)
 
  291                for (
int l = 0; l <= dZ.size() - 1; ++l)
 
  293                    for (
int i = hasHole ? 0 : 1; i <= dR.size()- 1; ++i)
 
  298                        Dune::FieldVector <double, dim> v(0.0);
 
  299                        v[indices[2]] = dZ[l];
 
  300                        v[indices[0]] = cos(dA[j])*dR[i];
 
  301                        v[indices[1]] = sin(dA[j])*dR[i];
 
  304                        gridFactory.insertVertex(v);
 
  313                for (
int l = 0; l <= dZ.size() - 1; ++l)
 
  315                    Dune::FieldVector <double, dim> v(0.0);
 
  316                    v[indices[2]] = dZ[l];
 
  322                    gridFactory.insertVertex(v);
 
  327                std::cout << 
"Filled node vector" << std::endl;
 
  332            unsigned int rSize = hasHole ? dR.size() : dR.size()-1;
 
  333            unsigned int zSize = dZ.size();
 
  334            for (
int j = 0; j < dA.size() - 1; ++j)
 
  336                for (
int l = 0; l < dZ.size() - 1; ++l)
 
  340                        for (
int i = 0; i < dR.size() - 1; ++i)
 
  344                                std::vector<unsigned int> vid({rSize*zSize*(dAMax+1) + l, z, z+rSize*zSize,
 
  345                                                               rSize*zSize*(dAMax+1) + l+1, z+rSize, z+rSize*zSize+rSize});
 
  350                                gridFactory.insertElement(prismType, vid);
 
  354                                std::vector<unsigned int> vid({z, z+1,
 
  355                                                               z+rSize*zSize, z+rSize*zSize+1,
 
  357                                                               z+rSize*zSize+rSize, z+rSize*zSize+rSize+1});
 
  362                                gridFactory.insertElement(type, vid);
 
  372                        for (
int i = 0; i < dR.size() - 1; ++i)
 
  376                                std::vector<unsigned int> vid({rSize*zSize*(dAMax+1) + l, z, t,
 
  377                                                               rSize*zSize*(dAMax+1) + l+1, z+rSize, t+rSize});
 
  382                                gridFactory.insertElement(prismType, vid);
 
  386                                std::vector<unsigned int> vid({z, z+1,
 
  389                                                               t+rSize, t+rSize+1});
 
  394                                gridFactory.insertElement(type, vid);
 
  403                            std::cout << 
"assign nodes 360° ends..." << std::endl;
 
  413            constexpr auto triangleType = Dune::GeometryTypes::simplex(dim);
 
  414            for (
int j = 0; j <= dAMax; ++j)
 
  416                for (
int i = hasHole ? 0 : 1; i <= dR.size()- 1; ++i)
 
  419                    Dune::FieldVector <double, dim> v(0.0);
 
  421                    v[indices[0]] = cos(dA[j])*dR[i];
 
  422                    v[indices[1]] = sin(dA[j])*dR[i];
 
  425                    gridFactory.insertVertex(v);
 
  433                Dune::FieldVector <double, dim> v(0.0);
 
  439                gridFactory.insertVertex(v);
 
  442            std::cout << 
"Filled node vector" << std::endl;
 
  447            unsigned int rSize = hasHole ? dR.size() : dR.size()-1;
 
  448            for (
int j = 0; j < dA.size() - 1; ++j)
 
  452                    for (
int i = 0; i < dR.size() - 1; ++i)
 
  456                            std::vector<unsigned int> vid({rSize*(dAMax+1), z, z+rSize});
 
  461                            gridFactory.insertElement(triangleType, vid);
 
  465                            std::vector<unsigned int> vid({z, z+1, z+rSize, z+rSize+1});
 
  470                            gridFactory.insertElement(type, vid);
 
  479                    for (
int i = 0; i < dR.size() - 1; ++i)
 
  483                            std::vector<unsigned int> vid({rSize*(dAMax+1), z, t});
 
  488                            gridFactory.insertElement(triangleType, vid);
 
  492                            std::vector<unsigned int> vid({z, z+1, t, t+1});
 
  497                            gridFactory.insertElement(type, vid);
 
  506                        std::cout << 
"assign nodes 360 ends..." << std::endl;
 
  512        return std::unique_ptr<Grid>(gridFactory.createGrid());