From c44c3229d41dac2c970e449e1729558659a50837 Mon Sep 17 00:00:00 2001 From: podlesny <podlesny@zedat.fu-berlin.de> Date: Fri, 19 Mar 2021 15:33:20 +0100 Subject: [PATCH] new gridConstructor for cuboids, uniform refinement, towards foam production --- dune/tectonic/factories/twoblocksfactory.cc | 41 ++- dune/tectonic/factories/twoblocksfactory.hh | 4 +- .../tectonic/problem-data/grid/CMakeLists.txt | 2 + .../grid/cuboidgridconstructor.hh | 234 ++++++++++++++++++ .../problem-data/grid/gridconstructor.hh | 9 +- src/foam/CMakeLists.txt | 2 +- src/foam/foam-2D.cfg | 8 +- src/foam/foam.cc | 4 +- 8 files changed, 266 insertions(+), 38 deletions(-) create mode 100644 dune/tectonic/problem-data/grid/cuboidgridconstructor.hh diff --git a/dune/tectonic/factories/twoblocksfactory.cc b/dune/tectonic/factories/twoblocksfactory.cc index a60ace65..9b7834c9 100644 --- a/dune/tectonic/factories/twoblocksfactory.cc +++ b/dune/tectonic/factories/twoblocksfactory.cc @@ -2,6 +2,8 @@ #include "config.h" #endif +#include <string> + #include <dune/fufem/geometry/convexpolyhedron.hh> #include <dune/contact/projections/normalprojection.hh> @@ -48,39 +50,23 @@ void TwoBlocksFactory<HostGridType, VectorTEMPLATE>::setBodies() { #error CuboidGeometry only supports 2D and 3D!" #endif - // set up reference grids - gridConstructor_ = std::make_unique<GridsConstructor<HostGridType>>(cuboidGeometries_); - auto& grids = gridConstructor_->getGrids(); - - std::array<double, 2> smallestDiameter = {this->parset_.template get<double>("body0.smallestDiameter"), this->parset_.template get<double>("body1.smallestDiameter")}; + const auto gravity = this->parset_.template get<double>("general.gravity"); for (size_t i=0; i<this->bodyCount_; i++) { + std::string body_str = "body" + std::to_string(i); const auto& cuboidGeometry = *cuboidGeometries_[i]; - // define weak patch and refine grid - const auto& weakeningRegions = cuboidGeometry.weakeningRegions(); - for (size_t j=0; j<weakeningRegions.size(); j++) { - refine(*grids[i], weakeningRegions[j], smallestDiameter[i], CuboidGeometry::lengthScale()); - } + std::array<unsigned int, 2> initialElements = { + { this->parset_.template get<size_t>("body" + std::to_string(i) + ".initialXElements"), + this->parset_.template get<size_t>("body" + std::to_string(i) + ".initialYElements") } }; - // determine minDiameter and maxDiameter - double minDiameter = std::numeric_limits<double>::infinity(); - double maxDiameter = 0.0; - for (auto &&e : elements(grids[i]->leafGridView())) { - auto const geometry = e.geometry(); - auto const diam = diameter(geometry); - minDiameter = std::min(minDiameter, diam); - maxDiameter = std::max(maxDiameter, diam); - } - std::cout << "Grid" << i << " min diameter: " << minDiameter << std::endl; - std::cout << "Grid" << i << " max diameter: " << maxDiameter << std::endl; - } - - bodyData_[0] = std::make_shared<MyBodyData<dim>>(this->parset_.sub("body0"), this->parset_.template get<double>("general.gravity"), zenith_()); - this->bodies_[0] = std::make_shared<typename Base::LeafBody>(bodyData_[0], grids[0]); + // set up reference grid + DefaultCuboidGridConstructor<HostGridType> gridConstructor(cuboidGeometry, initialElements); + gridConstructor.refine(this->parset_.template get<size_t>(body_str + ".refinements")); - bodyData_[1] = std::make_shared<MyBodyData<dim>>(this->parset_.sub("body1"), this->parset_.template get<double>("general.gravity"), zenith_()); - this->bodies_[1] = std::make_shared<typename Base::LeafBody>(bodyData_[1], grids[1]); + bodyData_[i] = std::make_shared<MyBodyData<dim>>(this->parset_.sub(body_str), gravity, zenith_()); + this->bodies_[i] = std::make_shared<typename Base::LeafBody>(bodyData_[i], gridConstructor.grid()); + } } template <class HostGridType, class VectorTEMPLATE> @@ -121,6 +107,7 @@ void TwoBlocksFactory<HostGridType, VectorTEMPLATE>::setBoundaryConditions() { using Function = Dune::VirtualFunction<double, double>; std::shared_ptr<Function> neumannFunction = std::make_shared<NeumannCondition>(); + //std::shared_ptr<Function> velocityDirichletFunction = std::make_shared<VelocityDirichletConditionLinearLoading>(this->parset_.template get<double>("boundary.dirichlet.finalVelocity"), 0.25); std::shared_ptr<Function> velocityDirichletFunction = std::make_shared<VelocityDirichletCondition>(this->parset_.template get<double>("boundary.dirichlet.finalVelocity"), 0.25); //std::shared_ptr<Function> velocityDirichletFunction = std::make_shared<VelocityStepDirichletCondition>(this->parset_.template get<double>("boundary.dirichlet.finalVelocity"), 10*this->parset_.template get<double>("boundary.dirichlet.finalVelocity"), 0.25, 0.5); diff --git a/dune/tectonic/factories/twoblocksfactory.hh b/dune/tectonic/factories/twoblocksfactory.hh index a02cd74a..39447a4a 100644 --- a/dune/tectonic/factories/twoblocksfactory.hh +++ b/dune/tectonic/factories/twoblocksfactory.hh @@ -10,8 +10,8 @@ #include "contactnetworkfactory.hh" #include "../problem-data/mybody.hh" -#include "../problem-data/grid/mygrids.hh" #include "../problem-data/grid/cuboidgeometry.hh" +#include "../problem-data/grid/cuboidgridconstructor.hh" template <class HostGridType, class VectorType> class TwoBlocksFactory : public ContactNetworkFactory<HostGridType, VectorType>{ private: @@ -39,8 +39,6 @@ template <class HostGridType, class VectorType> class TwoBlocksFactory : public std::vector<std::shared_ptr<MyBodyData<dim>>> bodyData_; // material properties of bodies - std::unique_ptr<GridsConstructor<HostGridType>> gridConstructor_; - std::vector<std::shared_ptr<CuboidGeometry>> cuboidGeometries_; std::vector<std::shared_ptr<LeafFaces>> leafFaces_; diff --git a/dune/tectonic/problem-data/grid/CMakeLists.txt b/dune/tectonic/problem-data/grid/CMakeLists.txt index b7abfed5..6effa5a3 100644 --- a/dune/tectonic/problem-data/grid/CMakeLists.txt +++ b/dune/tectonic/problem-data/grid/CMakeLists.txt @@ -6,6 +6,7 @@ add_custom_target(tectonic_dune_problem-data_grid SOURCES cubegridconstructor.hh cuboidgeometry.hh cuboidgeometry.cc + cuboidgridconstructor.hh gridconstructor.hh mygrids.hh mygrids.cc @@ -23,6 +24,7 @@ install(FILES cubefaces.hh cubegridconstructor.hh cuboidgeometry.hh + cuboidgridconstructor.hh gridconstructor.hh mygrids.hh simplexmanager.hh diff --git a/dune/tectonic/problem-data/grid/cuboidgridconstructor.hh b/dune/tectonic/problem-data/grid/cuboidgridconstructor.hh new file mode 100644 index 00000000..ac2c09c2 --- /dev/null +++ b/dune/tectonic/problem-data/grid/cuboidgridconstructor.hh @@ -0,0 +1,234 @@ +#ifndef SRC_CUBOIDGRIDCONSTRUCTOR_HH +#define SRC_CUBOIDGRIDCONSTRUCTOR_HH + +#include <dune/common/fmatrix.hh> +#include <dune/grid/common/gridfactory.hh> +#include <dune/grid/utility/structuredgridfactory.hh> + +#include <dune/fufem/boundarypatch.hh> +#include <dune/fufem/geometry/convexpolyhedron.hh> + +#include "cuboidgeometry.hh" +#include "gridconstructor.hh" +#include "simplexmanager.hh" + +// ------------------------------------------------- +// MyFaces +// ------------------------------------------------- + +template <class GridView> struct MyFaces { + BoundaryPatch<GridView> lower; + BoundaryPatch<GridView> right; + BoundaryPatch<GridView> upper; + BoundaryPatch<GridView> left; + +#if MY_DIM == 3 + BoundaryPatch<GridView> front; + BoundaryPatch<GridView> back; +#endif + + MyFaces(GridView const &gridView, const CuboidGeometry<typename GridView::ctype>& cuboidGeometry_) : + #if MY_DIM == 3 + lower(gridView), + right(gridView), + upper(gridView), + left(gridView), + front(gridView), + back(gridView), + #else + lower(gridView), + right(gridView), + upper(gridView), + left(gridView), + #endif + cuboidGeometry(cuboidGeometry_) + { + lower.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.lowerLeft(), cuboidGeometry.lowerRight(), in.geometry().center()); + }); + + right.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.lowerRight(), cuboidGeometry.upperRight(), in.geometry().center()); + }); + + upper.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.upperLeft(), cuboidGeometry.upperRight(), in.geometry().center()); + }); + + left.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.lowerLeft(), cuboidGeometry.upperLeft(), in.geometry().center()); + }); + + #if MY_DIM == 3 + front.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return isClose(cuboidGeometry.depth() / 2.0, in.geometry().center()[2]); + }); + + back.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return isClose(-cuboidGeometry.depth() / 2.0, in.geometry().center()[2]); + }); + #endif + } + +private: + const CuboidGeometry<typename GridView::ctype>& cuboidGeometry; + + bool isClose(double a, double b) { + return std::abs(a - b) < 1e-14 * cuboidGeometry.lengthScale(); + } + + bool isClose2(double a, double b) { + return std::abs(a - b) < + 1e-14 * cuboidGeometry.lengthScale() * cuboidGeometry.lengthScale(); + } + + template <class Vector> + bool xyBoxed(Vector const &v1, Vector const &v2, Vector const &x) { + auto const minmax0 = std::minmax(v1[0], v2[0]); + auto const minmax1 = std::minmax(v1[1], v2[1]); + + if (minmax0.first - 1e-14 * cuboidGeometry.lengthScale() > x[0] or + x[0] > minmax0.second + 1e-14 * cuboidGeometry.lengthScale()) + return false; + if (minmax1.first - 1e-14 * cuboidGeometry.lengthScale() > x[1] or + x[1] > minmax1.second + 1e-14 * cuboidGeometry.lengthScale()) + return false; + + return true; + } + + template <class Vector> + bool xyCollinear(Vector const &a, Vector const &b, Vector const &c) { + return isClose2((b[0] - a[0]) * (c[1] - a[1]), (b[1] - a[1]) * (c[0] - a[0])); + } + + template <class Vector> + bool xyBetween(Vector const &v1, Vector const &v2, Vector const &x) { + return xyCollinear(v1, v2, x) && xyBoxed(v1, v2, x); + } +}; + + +template <class GridView> +MyFaces<GridView> constructFaces(const GridView& gridView, const CuboidGeometry<typename GridView::ctype>& cuboidGeometry) { + return MyFaces<GridView>(gridView, cuboidGeometry); +} + +// ------------------------------------------------- +// CuboidGridConstructor +// ------------------------------------------------- + +template <class Grid> +class CuboidGridConstructor : public GridConstructor<Grid> { +public: + CuboidGridConstructor(const CuboidGeometry<typename Grid::ctype>& cuboidGeometry) : + cuboidGeometry_(cuboidGeometry) { + + createGrid(); + } + +protected: + void createGrid() { + Dune::GridFactory<Grid> gridFactory; + + const auto& A = cuboidGeometry_.lowerLeft(); + const auto& B = cuboidGeometry_.lowerRight(); + const auto& C = cuboidGeometry_.upperRight(); + const auto& D = cuboidGeometry_.upperLeft(); + + unsigned int const vc = 4; + + #if MY_DIM == 3 + Dune::FieldMatrix<double, 2 * vc, MY_DIM> vertices; + #else + Dune::FieldMatrix<double, vc, MY_DIM> vertices; + #endif + for (size_t i = 0; i < 2; ++i) { + #if MY_DIM == 3 + size_t numXYplanes = 2; + #else + size_t numXYplanes = 1; + #endif + size_t k = 0; + for (size_t j = 1; j <= numXYplanes; ++j) { + vertices[k++][i] = A[i]; + vertices[k++][i] = B[i]; + vertices[k++][i] = C[i]; + vertices[k++][i] = D[i]; + assert(k == j * vc); + } + } + + #if MY_DIM == 3 + for (size_t k = 0; k < vc; ++k) { + vertices[k][2] = -cuboidGeometry_.depth() / 2.0; + vertices[k + vc][2] = cuboidGeometry_.depth() / 2.0; + } + #endif + + for (size_t i = 0; i < vertices.N(); ++i) + gridFactory.insertVertex(vertices[i]); + + Dune::GeometryType cell; + #if MY_DIM == 3 + cell = Dune::GeometryTypes::tetrahedron; + #else + cell = Dune::GeometryTypes::triangle; + #endif + + #if MY_DIM == 3 + SimplexManager sm(vc); + #else + SimplexManager sm; + #endif + sm.addFromVerticesFFB(1, 2, 0); + sm.addFromVerticesFFB(2, 3, 0); + auto const &simplices = sm.getSimplices(); + + // sanity-check choices of simplices + for (size_t i = 0; i < simplices.size(); ++i) { + Dune::FieldMatrix<double, MY_DIM, MY_DIM> check; + for (size_t j = 0; j < MY_DIM; ++j) + check[j] = vertices[simplices[i][j + 1]] - vertices[simplices[i][j]]; + assert(check.determinant() > 0); + gridFactory.insertElement(cell, simplices[i]); + } + + this->grid_ = std::shared_ptr<Grid>(gridFactory.createGrid()); + this->grid_->setRefinementType(Grid::RefinementType::COPY); + } + + protected: + const CuboidGeometry<typename Grid::ctype>& cuboidGeometry_; +}; + + +// ------------------------------------------------- +// DefaultCuboidGridConstructor +// ------------------------------------------------- +template <class Grid> +class DefaultCuboidGridConstructor : public GridConstructor<Grid> { + static const int dim = Grid::dimension; + +public: + DefaultCuboidGridConstructor(const CuboidGeometry<typename Grid::ctype>& cuboidGeometry, std::array<unsigned int, dim> elements) : + cuboidGeometry_(cuboidGeometry), + elements_(elements) { + + createGrid(); + } + +protected: + void createGrid() { + this->grid_ = Dune::StructuredGridFactory<Grid>::createSimplexGrid( + cuboidGeometry_.lowerLeft(), cuboidGeometry_.upperRight(), elements_); + } + + protected: + const CuboidGeometry<typename Grid::ctype>& cuboidGeometry_; + std::array<unsigned int, dim> elements_; +}; + +#endif + + diff --git a/dune/tectonic/problem-data/grid/gridconstructor.hh b/dune/tectonic/problem-data/grid/gridconstructor.hh index e93d3c01..85f97a21 100644 --- a/dune/tectonic/problem-data/grid/gridconstructor.hh +++ b/dune/tectonic/problem-data/grid/gridconstructor.hh @@ -8,6 +8,7 @@ #include "../../utils/diameter.hh" + template <class GridType> class GridConstructor { private: @@ -50,10 +51,14 @@ class GridConstructor { } } + void refine(size_t globalRefinements) { + grid_->globalRefine(globalRefinements); + } + + protected: virtual void createGrid() = 0; - private: - Dune::GridFactory<GridType> gridFactory_; + protected: std::shared_ptr<GridType> grid_; }; diff --git a/src/foam/CMakeLists.txt b/src/foam/CMakeLists.txt index b38552f3..c228fda9 100644 --- a/src/foam/CMakeLists.txt +++ b/src/foam/CMakeLists.txt @@ -18,7 +18,7 @@ set(FOAM_SOURCE_FILES #../../dune/tectonic/io/hdf5/surface-writer.cc #../../dune/tectonic/io/hdf5/time-writer.cc ../../dune/tectonic/problem-data/grid/cuboidgeometry.cc - ../../dune/tectonic/problem-data/grid/mygrids.cc + #../../dune/tectonic/problem-data/grid/mygrids.cc ../../dune/tectonic/problem-data/grid/simplexmanager.cc ../../dune/tectonic/spatial-solving/solverfactory.cc ../../dune/tectonic/spatial-solving/fixedpointiterator.cc diff --git a/src/foam/foam-2D.cfg b/src/foam/foam-2D.cfg index d5028e7f..c7e12533 100644 --- a/src/foam/foam-2D.cfg +++ b/src/foam/foam-2D.cfg @@ -1,9 +1,13 @@ # -*- mode:conf -*- [body0] -smallestDiameter = 6.25e-2 # 2e-3 [m] +refinements = 4 # 2e-3 [m] +initialXElements = 5 +initialYElements = 1 [body1] -smallestDiameter = 6.25e-2 # 2e-3 [m] +refinements = 4 # 2e-3 [m] +initialXElements = 5 +initialYElements = 1 [timeSteps] refinementTolerance = 1e-5 # 1e-5 diff --git a/src/foam/foam.cc b/src/foam/foam.cc index 21dc1cec..b606d65b 100644 --- a/src/foam/foam.cc +++ b/src/foam/foam.cc @@ -66,7 +66,7 @@ #include <dune/tectonic/problem-data/bc.hh> #include <dune/tectonic/problem-data/mybody.hh> -#include <dune/tectonic/problem-data/grid/mygrids.hh> +//#include <dune/tectonic/problem-data/grid/mygrids.hh> #include <dune/tectonic/spatial-solving/tnnmg/functional.hh> //#include <dune/tectonic/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh> @@ -473,8 +473,6 @@ int main(int argc, char *argv[]) { typename ContactNetwork::ExternalForces externalForces; contactNetwork.externalForces(externalForces); - auto&& noFriction = ZeroNonlinearity(); - StepBase<NonlinearFactory, std::decay_t<decltype(contactNetwork)>, Updaters, std::decay_t<decltype(stateEnergyNorms)>> stepBase(parset, contactNetwork, totalDirichletNodes, globalFriction, frictionNodes, externalForces, stateEnergyNorms); -- GitLab