diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fbd99d9fe11f61a3ea84653dbbf8cb71bf7ee551..d86dde2a5b076bb28e0578c31c69df606c69ca8f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory("tests") + set(SW_SOURCE_FILES assemblers.cc data-structures/body.cc @@ -24,10 +26,10 @@ set(SW_SOURCE_FILES set(MSW_SOURCE_FILES assemblers.cc data-structures/body.cc - data-structures/contactnetwork.cc + #data-structures/contactnetwork.cc data-structures/enumparser.cc data-structures/levelcontactnetwork.cc - factories/cantorfactory.cc + #factories/cantorfactory.cc factories/stackedblocksfactory.cc io/vtk.cc io/hdf5/frictionalboundary-writer.cc @@ -36,8 +38,11 @@ set(MSW_SOURCE_FILES io/hdf5/restart-io.cc io/hdf5/surface-writer.cc io/hdf5/time-writer.cc - multi-body-problem-data/cuboidgeometry.cc - multi-body-problem-data/mygrids.cc + #multi-body-problem-data/grid/cube.cc + #multi-body-problem-data/grid/cubefaces.cc + multi-body-problem-data/grid/cuboidgeometry.cc + multi-body-problem-data/grid/mygrids.cc + multi-body-problem-data/grid/simplexmanager.cc multi-body-problem.cc spatial-solving/fixedpointiterator.cc spatial-solving/solverfactory.cc diff --git a/src/assemblers.cc b/src/assemblers.cc index 1097625fbd3055c9b7d68720d93b5fbc3952c2c1..d19b8e32f1f77790ad491479fadb4f97dba28634 100644 --- a/src/assemblers.cc +++ b/src/assemblers.cc @@ -24,8 +24,8 @@ #include "assemblers.hh" template <class GridView, int dimension> -MyAssembler<GridView, dimension>::MyAssembler(GridView const &_gridView) - : cellBasis(_gridView), +MyAssembler<GridView, dimension>::MyAssembler(GridView const &_gridView) : + cellBasis(_gridView), vertexBasis(_gridView), gridView(_gridView), cellAssembler(cellBasis, cellBasis), @@ -33,8 +33,9 @@ MyAssembler<GridView, dimension>::MyAssembler(GridView const &_gridView) template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleFrictionalBoundaryMass( - BoundaryPatch<GridView> const &frictionalBoundary, - ScalarMatrix &frictionalBoundaryMass) const { + BoundaryPatch<GridView> const &frictionalBoundary, + ScalarMatrix &frictionalBoundaryMass) const { + BoundaryMassAssembler<Grid, BoundaryPatch<GridView>, LocalVertexBasis, LocalVertexBasis, Dune::FieldMatrix<double, 1, 1>> const frictionalBoundaryMassAssembler(frictionalBoundary); @@ -44,9 +45,9 @@ void MyAssembler<GridView, dimension>::assembleFrictionalBoundaryMass( template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleMass( - Dune::VirtualFunction<LocalVector, LocalScalarVector> const & - densityFunction, - Matrix &M) const { + Dune::VirtualFunction<LocalVector, LocalScalarVector> const & densityFunction, + Matrix &M) const { + // NOTE: We treat the weight as a constant function QuadratureRuleKey quadKey(dimension, 0); @@ -58,8 +59,11 @@ void MyAssembler<GridView, dimension>::assembleMass( } template <class GridView, int dimension> -void MyAssembler<GridView, dimension>::assembleElasticity(double E, double nu, - Matrix &A) const { +void MyAssembler<GridView, dimension>::assembleElasticity( + double E, + double nu, + Matrix &A) const { + StVenantKirchhoffAssembler<Grid, LocalVertexBasis, LocalVertexBasis> const localStiffness(E, nu); vertexAssembler.assembleOperator(localStiffness, A); @@ -67,9 +71,10 @@ void MyAssembler<GridView, dimension>::assembleElasticity(double E, double nu, template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleViscosity( - Dune::VirtualFunction<LocalVector, LocalScalarVector> const &shearViscosity, - Dune::VirtualFunction<LocalVector, LocalScalarVector> const &bulkViscosity, - Matrix &C) const { + Dune::VirtualFunction<LocalVector, LocalScalarVector> const &shearViscosity, + Dune::VirtualFunction<LocalVector, LocalScalarVector> const &bulkViscosity, + Matrix &C) const { + // NOTE: We treat the weights as constant functions QuadratureRuleKey shearViscosityKey(dimension, 0); QuadratureRuleKey bulkViscosityKey(dimension, 0); @@ -83,8 +88,9 @@ void MyAssembler<GridView, dimension>::assembleViscosity( template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleBodyForce( - Dune::VirtualFunction<LocalVector, LocalVector> const &gravityField, - Vector &f) const { + Dune::VirtualFunction<LocalVector, LocalVector> const &gravityField, + Vector &f) const { + L2FunctionalAssembler<Grid, LocalVertexBasis, LocalVector> gravityFunctionalAssembler(gravityField); vertexAssembler.assembleFunctional(gravityFunctionalAssembler, f); @@ -92,9 +98,11 @@ void MyAssembler<GridView, dimension>::assembleBodyForce( template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleNeumann( - BoundaryPatch<GridView> const &neumannBoundary, Vector &f, - Dune::VirtualFunction<double, double> const &neumann, - double relativeTime) const { + BoundaryPatch<GridView> const &neumannBoundary, + Vector &f, + Dune::VirtualFunction<double, double> const &neumann, + double relativeTime) const { + LocalVector localNeumann(0); neumann.evaluate(relativeTime, localNeumann[0]); NeumannBoundaryAssembler<Grid, LocalVector> neumannBoundaryAssembler( @@ -106,9 +114,11 @@ void MyAssembler<GridView, dimension>::assembleNeumann( template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleWeightedNormalStress( - BoundaryPatch<GridView> const &frictionalBoundary, - ScalarVector &weightedNormalStress, double youngModulus, - double poissonRatio, Vector const &displacement) const { + BoundaryPatch<GridView> const &frictionalBoundary, + ScalarVector &weightedNormalStress, + double youngModulus, + double poissonRatio, + Vector const &displacement) const { BasisGridFunction<VertexBasis, Vector> displacementFunction(vertexBasis, displacement); @@ -138,11 +148,12 @@ void MyAssembler<GridView, dimension>::assembleWeightedNormalStress( template <class GridView, int dimension> auto MyAssembler<GridView, dimension>::assembleFrictionNonlinearity( - Config::FrictionModel frictionModel, - BoundaryPatch<GridView> const &frictionalBoundary, - GlobalFrictionData<dimension> const &frictionInfo, - ScalarVector const &weightedNormalStress) const - -> std::shared_ptr<GlobalFriction<Matrix, Vector>> { + Config::FrictionModel frictionModel, + BoundaryPatch<GridView> const &frictionalBoundary, + GlobalFrictionData<dimension> const &frictionInfo, + ScalarVector const &weightedNormalStress) const +-> std::shared_ptr<GlobalFriction<Matrix, Vector>> { + // Lumping of the nonlinearity ScalarVector weights; { @@ -169,8 +180,11 @@ auto MyAssembler<GridView, dimension>::assembleFrictionNonlinearity( template <class GridView, int dimension> void MyAssembler<GridView, dimension>::assembleVonMisesStress( - double youngModulus, double poissonRatio, Vector const &u, - ScalarVector &stress) const { + double youngModulus, + double poissonRatio, + Vector const &u, + ScalarVector &stress) const { + auto const gridDisplacement = std::make_shared<BasisGridFunction<VertexBasis, Vector> const>( vertexBasis, u); diff --git a/src/assemblers.hh b/src/assemblers.hh index 195370d454400ba28d9a20ca9dc5630db916c124..a32870a9d25159d8d00420323e002d4f75b0607c 100644 --- a/src/assemblers.hh +++ b/src/assemblers.hh @@ -18,73 +18,83 @@ #include "data-structures/enums.hh" -template <class GridView, int dimension> class MyAssembler { +template <class GridView, int dimension> +class MyAssembler { public: - using ScalarMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1>>; - using Matrix = + using ScalarMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1>>; + using Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, dimension, dimension>>; - using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>; - using Vector = Dune::BlockVector<Dune::FieldVector<double, dimension>>; + using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>; + using Vector = Dune::BlockVector<Dune::FieldVector<double, dimension>>; - using CellBasis = P0Basis<GridView, double>; - using VertexBasis = P1NodalBasis<GridView, double>; + using CellBasis = P0Basis<GridView, double>; + using VertexBasis = P1NodalBasis<GridView, double>; - CellBasis const cellBasis; - VertexBasis const vertexBasis; - GridView const &gridView; + CellBasis const cellBasis; + VertexBasis const vertexBasis; + GridView const &gridView; private: - using Grid = typename GridView::Grid; - using LocalVector = typename Vector::block_type; - using LocalScalarVector = typename ScalarVector::block_type; + using Grid = typename GridView::Grid; + using LocalVector = typename Vector::block_type; + using LocalScalarVector = typename ScalarVector::block_type; - using LocalCellBasis = typename CellBasis::LocalFiniteElement; - using LocalVertexBasis = typename VertexBasis::LocalFiniteElement; + using LocalCellBasis = typename CellBasis::LocalFiniteElement; + using LocalVertexBasis = typename VertexBasis::LocalFiniteElement; - Assembler<CellBasis, CellBasis> cellAssembler; - Assembler<VertexBasis, VertexBasis> vertexAssembler; + Assembler<CellBasis, CellBasis> cellAssembler; + Assembler<VertexBasis, VertexBasis> vertexAssembler; public: - MyAssembler(GridView const &gridView); - - void assembleFrictionalBoundaryMass( - BoundaryPatch<GridView> const &frictionalBoundary, - ScalarMatrix &frictionalBoundaryMass) const; - - void assembleMass(Dune::VirtualFunction< - LocalVector, LocalScalarVector> const &densityFunction, - Matrix &M) const; - - void assembleElasticity(double E, double nu, Matrix &A) const; - - void assembleViscosity( - Dune::VirtualFunction<LocalVector, LocalScalarVector> const & - shearViscosity, - Dune::VirtualFunction<LocalVector, LocalScalarVector> const & - bulkViscosity, - Matrix &C) const; - - void assembleBodyForce( - Dune::VirtualFunction<LocalVector, LocalVector> const &gravityField, - Vector &f) const; - - void assembleNeumann(BoundaryPatch<GridView> const &neumannBoundary, - Vector &f, - Dune::VirtualFunction<double, double> const &neumann, - double relativeTime) const; - - void assembleWeightedNormalStress( - BoundaryPatch<GridView> const &frictionalBoundary, - ScalarVector &weightedNormalStress, double youngModulus, - double poissonRatio, Vector const &displacement) const; - - std::shared_ptr<GlobalFriction<Matrix, Vector>> assembleFrictionNonlinearity( - Config::FrictionModel frictionModel, - BoundaryPatch<GridView> const &frictionalBoundary, - GlobalFrictionData<dimension> const &frictionInfo, - ScalarVector const &weightedNormalStress) const; - - void assembleVonMisesStress(double youngModulus, double poissonRatio, - Vector const &u, ScalarVector &stress) const; + MyAssembler(GridView const &gridView); + + void assembleFrictionalBoundaryMass( + BoundaryPatch<GridView> const &frictionalBoundary, + ScalarMatrix &frictionalBoundaryMass) const; + + void assembleMass( + Dune::VirtualFunction< + LocalVector, LocalScalarVector> const &densityFunction, + Matrix &M) const; + + void assembleElasticity( + double E, + double nu, + Matrix &A) const; + + void assembleViscosity( + Dune::VirtualFunction<LocalVector, LocalScalarVector> const & shearViscosity, + Dune::VirtualFunction<LocalVector, LocalScalarVector> const & bulkViscosity, + Matrix &C) const; + + void assembleBodyForce( + Dune::VirtualFunction<LocalVector, LocalVector> const &gravityField, + Vector &f) const; + + void assembleNeumann( + BoundaryPatch<GridView> const &neumannBoundary, + Vector &f, + Dune::VirtualFunction<double, double> const &neumann, + double relativeTime) const; + + void assembleWeightedNormalStress( + BoundaryPatch<GridView> const &frictionalBoundary, + ScalarVector &weightedNormalStress, + double youngModulus, + double poissonRatio, + Vector const &displacement) const; + + auto assembleFrictionNonlinearity( + Config::FrictionModel frictionModel, + BoundaryPatch<GridView> const &frictionalBoundary, + GlobalFrictionData<dimension> const &frictionInfo, + ScalarVector const &weightedNormalStress) const + -> std::shared_ptr<GlobalFriction<Matrix, Vector>>; + + void assembleVonMisesStress( + double youngModulus, + double poissonRatio, + Vector const &u, + ScalarVector &stress) const; }; #endif diff --git a/src/data-structures/body.cc b/src/data-structures/body.cc index f110eec13b143b1b619a35c5ac4f248cef133785..b72f396b28523faf0e48e46fe63510e2edb835f2 100644 --- a/src/data-structures/body.cc +++ b/src/data-structures/body.cc @@ -6,7 +6,9 @@ #include "body.hh" template <class GridTEMPLATE, class VectorTEMPLATE, int dims> -Body<GridTEMPLATE, VectorTEMPLATE, dims>::Body(const std::shared_ptr<BodyData<dims>>& bodyData, const std::shared_ptr<GridType>& grid) : +Body<GridTEMPLATE, VectorTEMPLATE, dims>::Body( + const std::shared_ptr<BodyData<dims>>& bodyData, + const std::shared_ptr<GridType>& grid) : bodyData_(bodyData), grid_(grid), deformation_(std::make_shared<DeformationFunction>(grid_->leafGridView())), @@ -22,6 +24,23 @@ Body<GridTEMPLATE, VectorTEMPLATE, dims>::Body(const std::shared_ptr<BodyData<di for (size_t i=0; i<levelBoundaryConditions_.size(); i++) { levelBoundaryConditions_[i].resize(0); } + + externalForce_ = [&](double relativeTime, VectorType &ell) { + // Problem formulation: right-hand side + std::vector<std::shared_ptr<LeafBoundaryCondition>> leafNeumannConditions; + leafBoundaryConditions("neumann", leafNeumannConditions); + ell.resize(gravityFunctional_.size()); + ell = gravityFunctional_; + + for (size_t i=0; i<leafNeumannConditions.size(); i++) { + const auto& leafNeumannCondition = leafNeumannConditions[i]; + + VectorType b; + assembler_->assembleNeumann(*leafNeumannCondition->boundaryPatch(), b, *leafNeumannCondition->boundaryFunction(), + relativeTime); + ell += b; + } + }; } @@ -51,8 +70,11 @@ void Body<GridTEMPLATE, VectorTEMPLATE, dims>::assemble() { } template <class GridTEMPLATE, class VectorTEMPLATE, int dims> -void Body<GridTEMPLATE, VectorTEMPLATE, dims>::assembleFriction(const Config::FrictionModel& frictionModel, const ScalarVector& weightedNormalStress) { - globalFriction_.resize(frictionBoundaryConditions_.size()); +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::assembleFriction( + const Config::FrictionModel& frictionModel, + const ScalarVector& weightedNormalStress) { + + globalFriction_.resize({frictionBoundaryConditions_.size()}); for (size_t i=0; i<globalFriction_.size(); i++) { const auto& frictionBoundaryCondition = frictionBoundaryConditions_[i]; @@ -60,21 +82,241 @@ void Body<GridTEMPLATE, VectorTEMPLATE, dims>::assembleFriction(const Config::Fr } } +// setter and getter + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::data() const +-> const std::shared_ptr<BodyData<dims>>& { + + return bodyData_; +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::setDeformation(const VectorType& def) { + deformation_->setDeformation(def); +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::deformation() const +-> DeformationFunction& { + + return *deformation_; +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::deformedGrid() const +-> const DeformedGridType* { + + return deformedGrid_.get(); +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::leafView() const +-> const DeformedLeafGridView& { + + return leafView_; +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::leafVertexCount() const +-> int { + + return leafVertexCount_; +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::assembler() const +-> const std::shared_ptr<Assembler>& { + + return assembler_; +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::matrices() const +-> const Matrices<Matrix,1>& { + + return matrices_; +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::externalForce() const +-> const ExternalForce& { + + return externalForce_; +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::stateEnergyNorm() const +-> const std::shared_ptr<const StateEnergyNorm>& { + + return stateEnergyNorm_; +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::addBoundaryCondition(std::shared_ptr<LeafBoundaryCondition> leafBoundaryCondition) { + leafBoundaryConditions_.emplace_back(leafBoundaryCondition); +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::leafBoundaryConditions( + const std::string& tag, + std::vector<std::shared_ptr<LeafBoundaryCondition>>& selectedConditions) const { + + if (tag == "friction") { + selectedConditions.resize(frictionBoundaryConditions_.size()); + for (size_t i=0; i<frictionBoundaryConditions_.size(); i++) { + selectedConditions[i] = frictionBoundaryConditions_[i]; + } + + } else { + selectedConditions.resize(0); + for (size_t i=0; i<leafBoundaryConditions_.size(); i++) { + if (leafBoundaryConditions_[i]->tag() == tag) + selectedConditions.emplace_back(leafBoundaryConditions_[i]); + } + } +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::leafBoundaryConditions() const +-> const std::vector<std::shared_ptr<LeafBoundaryCondition>>& { + + return leafBoundaryConditions_; +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::addBoundaryCondition( + std::shared_ptr<LevelBoundaryCondition> levelBoundaryCondition, + int level) { + + levelBoundaryConditions_[level].push_back(levelBoundaryCondition); +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::levelBoundaryConditions( + const std::string& tag, + std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>>& selectedConditions) const { + + selectedConditions.resize(levelBoundaryConditions_.size()); + for (size_t level=0; level<levelBoundaryConditions_.size(); level++) { + const std::vector<std::shared_ptr<LevelBoundaryCondition>>& levelBoundaryConditions = levelBoundaryConditions_[level]; + for (size_t i=0; i<levelBoundaryConditions.size(); i++) { + if (levelBoundaryConditions[i]->tag() == tag) + selectedConditions[level].push_back(levelBoundaryConditions[i]); + } + } +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::levelBoundaryConditions( + const std::string& tag, + int level, + std::vector<std::shared_ptr<LevelBoundaryCondition>>& selectedConditions) const { + + selectedConditions.resize(0); + const std::vector<std::shared_ptr<LevelBoundaryCondition>>& levelBoundaryConditions = levelBoundaryConditions_[level]; + for (size_t i=0; i<levelBoundaryConditions.size(); i++) { + if (levelBoundaryConditions[i]->tag() == tag) + selectedConditions.push_back(levelBoundaryConditions[i]); + } +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::levelBoundaryConditions(int level) const +-> const std::vector<std::shared_ptr<LevelBoundaryCondition>>& { + + return levelBoundaryConditions_[level]; +} + template <class GridTEMPLATE, class VectorTEMPLATE, int dims> -void Body<GridTEMPLATE, VectorTEMPLATE, dims>::externalForce(double relativeTime, VectorType& ell) const { - // Problem formulation: right-hand side - std::vector<std::shared_ptr<LeafBoundaryCondition>> leafNeumannConditions; - leafBoundaryConditions("neumann", leafNeumannConditions); - ell.resize(gravityFunctional_.size()); - ell = gravityFunctional_; +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::levelBoundaryConditions() const +-> const std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>>& { + + return levelBoundaryConditions_; +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::addBoundaryCondition(std::shared_ptr<FrictionBoundaryCondition> frictionBoundaryCondition) { + frictionBoundaryConditions_.emplace_back(frictionBoundaryCondition); +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::frictionBoundaryConditions() const +-> const std::vector<std::shared_ptr<FrictionBoundaryCondition>>& { + + return frictionBoundaryConditions_; +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +auto Body<GridTEMPLATE, VectorTEMPLATE, dims>::globalFriction() +-> GlobalFrictionContainer& { + return globalFriction_; +} + + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::boundaryPatchNodes( + const std::string& tag, + BoundaryPatchNodes& nodes) const { + + std::vector<std::shared_ptr<typename Body::LeafBoundaryCondition>> boundaryConditions; + this->leafBoundaryConditions(tag, boundaryConditions); + + nodes.resize(boundaryConditions.size()); + + for (size_t i=0; i<nodes.size(); i++) { + nodes[i] = boundaryConditions[i]->boundaryPatch()->getVertices(); + } +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::boundaryNodes( + const std::string& tag, + BoundaryNodes& nodes) const { + + std::vector<std::shared_ptr<typename Body::LeafBoundaryCondition>> boundaryConditions; + this->leafBoundaryConditions(tag, boundaryConditions); + + nodes.resize(boundaryConditions.size()); + + for (size_t i=0; i<nodes.size(); i++) { + nodes[i] = boundaryConditions[i]->boundaryNodes().get(); + } +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::boundaryFunctions( + const std::string& tag, + BoundaryFunctions& functions) const { + + std::vector<std::shared_ptr<typename Body::LeafBoundaryCondition>> boundaryConditions; + this->leafBoundaryConditions(tag, boundaryConditions); + + functions.resize(boundaryConditions.size()); + + for (size_t i=0; i<functions.size(); i++) { + functions[i] = boundaryConditions[i]->boundaryFunction().get(); + } +} + +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +void Body<GridTEMPLATE, VectorTEMPLATE, dims>::boundaryPatches( + const std::string& tag, + BoundaryPatches& patches) const { + + std::vector<std::shared_ptr<typename Body::LeafBoundaryCondition>> boundaryConditions; + this->leafBoundaryConditions(tag, boundaryConditions); - for (size_t i=0; i<leafNeumannConditions.size(); i++) { - const auto& leafNeumannCondition = leafNeumannConditions[i]; + patches.resize(boundaryConditions.size()); - VectorType b; - assembler_->assembleNeumann(*leafNeumannCondition->boundaryPatch(), b, *leafNeumannCondition->boundaryFunction(), - relativeTime); - ell += b; + for (size_t i=0; i<patches.size(); i++) { + patches[i] = boundaryConditions[i]->boundaryPatch().get(); } } diff --git a/src/data-structures/body.hh b/src/data-structures/body.hh index 5359fbd096bb701967f70b319a0de6bc395c051a..6a254e4ccb1e92e75216bf3db6b8166f4a3a2490 100644 --- a/src/data-structures/body.hh +++ b/src/data-structures/body.hh @@ -1,5 +1,5 @@ -#ifndef SRC_BODY_HH -#define SRC_BODY_HH +#ifndef SRC_DATA_STRUCTURES_BODY_HH +#define SRC_DATA_STRUCTURES_BODY_HH #include <functional> @@ -29,152 +29,136 @@ #include "../assemblers.hh" #include "../boundarycondition.hh" +#include "globalfrictioncontainer.hh" #include "enums.hh" #include "matrices.hh" -template <class GridTEMPLATE, class VectorTEMPLATE, int dims> class Body { +template <class GridTEMPLATE, class VectorTEMPLATE, int dims> +class Body { public: - using GridType = GridTEMPLATE; - using VectorType = VectorTEMPLATE; + using GridType = GridTEMPLATE; + using VectorType = VectorTEMPLATE; - using DeformationFunction = DeformationFunction<typename GridType::LeafGridView, VectorType>; - using DeformedGridType = Dune::GeometryGrid<GridType, DeformationFunction>; - using DeformedLeafGridView = typename DeformedGridType::LeafGridView; - using DeformedLevelGridView = typename DeformedGridType::LevelGridView; + using DeformationFunction = DeformationFunction<typename GridType::LeafGridView, VectorType>; + using DeformedGridType = Dune::GeometryGrid<GridType, DeformationFunction>; + using DeformedLeafGridView = typename DeformedGridType::LeafGridView; + using DeformedLevelGridView = typename DeformedGridType::LevelGridView; - using Assembler = MyAssembler<DeformedLeafGridView, dims>; - using Matrix = typename Assembler::Matrix; - using LocalVector = typename VectorType::block_type; + using Assembler = MyAssembler<DeformedLeafGridView, dims>; + using Matrix = typename Assembler::Matrix; + using LocalVector = typename VectorType::block_type; - using ScalarMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1>>; - using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>; + using ScalarMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1>>; + using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>; - using Function = Dune::VirtualFunction<double, double>; + using Function = Dune::VirtualFunction<double, double>; + using ExternalForce = std::function<void(double, VectorType &)>; - using LeafBoundaryCondition = BoundaryCondition<DeformedLeafGridView, dims>; - using FrictionBoundaryCondition = FrictionBoundaryCondition<DeformedLeafGridView, LocalVector, dims>; - using LevelBoundaryCondition = BoundaryCondition<DeformedLevelGridView, dims>; + using LeafBoundaryCondition = BoundaryCondition<DeformedLeafGridView, dims>; + using FrictionBoundaryCondition = FrictionBoundaryCondition<DeformedLeafGridView, LocalVector, dims>; + using LevelBoundaryCondition = BoundaryCondition<DeformedLevelGridView, dims>; + + using BoundaryFunctions = std::vector<const Function* >; + using BoundaryNodes = std::vector<const Dune::BitSetVector<dims>* >; + using BoundaryPatchNodes = std::vector<const Dune::BitSetVector<1>* >; + using BoundaryPatches = std::vector<const typename LeafBoundaryCondition::BoundaryPatch* >; + + using GlobalFriction = GlobalFriction<Matrix, VectorType>; + using GlobalFrictionContainer = GlobalFrictionContainer<GlobalFriction, 1>; + + using StateEnergyNorm = EnergyNorm<ScalarMatrix, ScalarVector>; private: - std::shared_ptr<BodyData<dims>> bodyData_; + std::shared_ptr<Body<GridType, VectorType, dims>> parent_; + std::vector<std::shared_ptr<Body<GridType, VectorType, dims>>> children_; + + std::shared_ptr<BodyData<dims>> bodyData_; + + std::shared_ptr<GridType> grid_; + std::shared_ptr<DeformationFunction> deformation_; + std::shared_ptr<DeformedGridType> deformedGrid_; - std::shared_ptr<GridType> grid_; - std::shared_ptr<DeformationFunction> deformation_; - std::shared_ptr<DeformedGridType> deformedGrid_; + DeformedLeafGridView leafView_; + int leafVertexCount_; - DeformedLeafGridView leafView_; - int leafVertexCount_; + std::shared_ptr<Assembler> assembler_; + Matrices<Matrix,1> matrices_; - std::shared_ptr<Assembler> assembler_; - Matrices<Matrix,1> matrices_; + ExternalForce externalForce_; - VectorType gravityFunctional_; - std::shared_ptr<const EnergyNorm<ScalarMatrix, ScalarVector>> stateEnergyNorm_; + VectorType gravityFunctional_; + std::shared_ptr<const StateEnergyNorm> stateEnergyNorm_; - // boundary conditions - std::vector<std::shared_ptr<LeafBoundaryCondition>> leafBoundaryConditions_; - std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>> levelBoundaryConditions_; // first index: level, second index: bc on lvl + // boundary conditions + std::vector<std::shared_ptr<LeafBoundaryCondition>> leafBoundaryConditions_; + std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>> levelBoundaryConditions_; // first index: level, second index: bc on lvl - // friction boundary conditions - std::vector<std::shared_ptr<FrictionBoundaryCondition>> frictionBoundaryConditions_; - std::vector<std::shared_ptr<GlobalFriction<Matrix, VectorType>>> globalFriction_; + // friction boundary conditions + std::vector<std::shared_ptr<FrictionBoundaryCondition>> frictionBoundaryConditions_; + GlobalFrictionContainer globalFriction_; public: - Body(const std::shared_ptr<BodyData<dims>>& bodyData, const std::shared_ptr<GridType>& grid); - - void assemble(); - void assembleFriction(const Config::FrictionModel& frictionModel, const ScalarVector& weightedNormalStress); - - const std::shared_ptr<Assembler>& assembler() const { - return assembler_; - } - - const std::shared_ptr<BodyData<dims>>& data() const { - return bodyData_; - } - - void addBoundaryCondition(std::shared_ptr<LeafBoundaryCondition> leafBoundaryCondition) { - leafBoundaryConditions_.push_back(leafBoundaryCondition); - } - - const std::vector<std::shared_ptr<LeafBoundaryCondition>>& leafBoundaryConditions() const { - return leafBoundaryConditions_; - } - - void leafBoundaryConditions(const std::string& tag, std::vector<std::shared_ptr<LeafBoundaryCondition>>& selectedConditions) const { - selectedConditions.resize(0); - for (size_t i=0; i<leafBoundaryConditions_.size(); i++) { - if (leafBoundaryConditions_[i]->tag() == tag) - selectedConditions.push_back(leafBoundaryConditions_[i]); - } - } - - void addBoundaryCondition(std::shared_ptr<FrictionBoundaryCondition> frictionBoundaryCondition) { - frictionBoundaryConditions_.push_back(frictionBoundaryCondition); - } - - const std::vector<std::shared_ptr<FrictionBoundaryCondition>>& frictionBoundaryConditions() const { - return frictionBoundaryConditions_; - } - - void addBoundaryCondition(std::shared_ptr<LevelBoundaryCondition> levelBoundaryCondition, int level) { - levelBoundaryConditions_[level].push_back(levelBoundaryCondition); - } - - const std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>>& levelBoundaryConditions() const { - return levelBoundaryConditions_; - } - - void levelBoundaryConditions(const std::string& tag, std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>>& selectedConditions) const { - selectedConditions.resize(levelBoundaryConditions_.size()); - for (size_t level=0; level<levelBoundaryConditions_.size(); level++) { - const std::vector<std::shared_ptr<LevelBoundaryCondition>>& levelBoundaryConditions = levelBoundaryConditions_[level]; - for (size_t i=0; i<levelBoundaryConditions.size(); i++) { - if (levelBoundaryConditions[i]->tag() == tag) - selectedConditions[level].push_back(levelBoundaryConditions[i]); - } - } - } - - const std::vector<std::shared_ptr<LevelBoundaryCondition>>& levelBoundaryConditions(int level) const { - return levelBoundaryConditions_[level]; - } - - void levelBoundaryConditions(const std::string& tag, int level, std::vector<std::shared_ptr<LevelBoundaryCondition>>& selectedConditions) const { - selectedConditions.resize(0); - const std::vector<std::shared_ptr<LevelBoundaryCondition>>& levelBoundaryConditions = levelBoundaryConditions_[level]; - for (size_t i=0; i<levelBoundaryConditions.size(); i++) { - if (levelBoundaryConditions[i]->tag() == tag) - selectedConditions.push_back(levelBoundaryConditions[i]); - } - } - - const DeformedGridType* deformedGrid() const { - return deformedGrid_.get(); - } - - DeformationFunction& deformation() { - return *deformation_; - } - - void setDeformation(const VectorType& def) { - deformation_->setDeformation(def); - } - - const DeformedLeafGridView& leafView() const { - return leafView_; - } - - int leafVertexCount() const { - return leafVertexCount_; - } - - const Matrices<Matrix,1>& matrices() const { - return matrices_; - } - - void externalForce(double relativeTime, VectorType& ell) const; + Body( + const std::shared_ptr<BodyData<dims>>& bodyData, + const std::shared_ptr<GridType>& grid); + + void assemble(); + void assembleFriction( + const Config::FrictionModel& frictionModel, + const ScalarVector& weightedNormalStress); + + // setter and getter + auto data() const -> const std::shared_ptr<BodyData<dims>>&; + + void setDeformation(const VectorType& def); + auto deformation() const -> DeformationFunction&; + auto deformedGrid() const -> const DeformedGridType*; + + auto leafView() const -> const DeformedLeafGridView&; + auto leafVertexCount() const -> int; + + auto assembler() const -> const std::shared_ptr<Assembler>&; + auto matrices() const -> const Matrices<Matrix,1>&; + + auto externalForce() const -> const ExternalForce&; + + auto stateEnergyNorm() const -> const std::shared_ptr<const StateEnergyNorm>&; + + void addBoundaryCondition(std::shared_ptr<LeafBoundaryCondition> leafBoundaryCondition); + void leafBoundaryConditions( + const std::string& tag, + std::vector<std::shared_ptr<LeafBoundaryCondition>>& selectedConditions) const; + auto leafBoundaryConditions() const -> const std::vector<std::shared_ptr<LeafBoundaryCondition>>&; + + void addBoundaryCondition(std::shared_ptr<LevelBoundaryCondition> levelBoundaryCondition, int level); + void levelBoundaryConditions( + const std::string& tag, + std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>>& selectedConditions) const; + void levelBoundaryConditions( + const std::string& tag, + int level, + std::vector<std::shared_ptr<LevelBoundaryCondition>>& selectedConditions) const; + auto levelBoundaryConditions(int level) const -> const std::vector<std::shared_ptr<LevelBoundaryCondition>>&; + auto levelBoundaryConditions() const -> const std::vector<std::vector<std::shared_ptr<LevelBoundaryCondition>>>&; + + void addBoundaryCondition(std::shared_ptr<FrictionBoundaryCondition> frictionBoundaryCondition); + auto frictionBoundaryConditions() const -> const std::vector<std::shared_ptr<FrictionBoundaryCondition>>&; + + auto globalFriction() -> GlobalFrictionContainer&; + + void boundaryPatchNodes( + const std::string& tag, + BoundaryPatchNodes& nodes) const; + void boundaryNodes( + const std::string& tag, + BoundaryNodes& nodes) const; + void boundaryFunctions( + const std::string& tag, + BoundaryFunctions& functions) const; + void boundaryPatches( + const std::string& tag, + BoundaryPatches& patches) const; }; #endif diff --git a/src/data-structures/contactnetwork.cc b/src/data-structures/contactnetwork.cc index 93708d26cf42da834ba82861cf69a8570c80ce23..ac118a1ec8f5e443e70bac28a756c84a5491cd03 100644 --- a/src/data-structures/contactnetwork.cc +++ b/src/data-structures/contactnetwork.cc @@ -2,124 +2,30 @@ #include "config.h" #endif -#include <dune/contact/projections/normalprojection.hh> #include "contactnetwork.hh" -template <class GridType, int dimension> -ContactNetwork<GridType, dimension>::ContactNetwork(int nBodies, int nCouplings, int level) : - level_(level), - bodies_(nBodies), - couplings_(nCouplings), - deformedGrids_(nBodies), - leafViews_(nBodies), - levelViews_(nBodies), - leafVertexCounts_(nBodies), - nBodyAssembler_(nBodies, nCouplings) -{} - -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::assemble() { - for (size_t i=0; i<nBodies(); i++) { - bodies_[i]->assemble(); - } - - totalNodes("dirichlet", totalDirichletNodes_); - - // set up dune-contact nBodyAssembler - nBodyAssembler_.setGrids(deformedGrids_); - - for (size_t i=0; i<nCouplings(); i++) { - nBodyAssembler_.setCoupling(*couplings_[i], i); - } - - nBodyAssembler_.assembleTransferOperator(); - nBodyAssembler_.assembleObstacle(); -} - -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::assembleFriction(const Config::FrictionModel& frictionModel, const std::vector<ScalarVector>& weightedNormalStress) { - for (size_t i=0; i<nBodies(); i++) { - bodies_[i]->assembleFriction(frictionModel, weightedNormalStress[i]); - } -} - -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::setBodies(const std::vector<std::shared_ptr<Body>>& bodies) { - assert(nBodies()==bodies.size()); - bodies_ = bodies; - - matrices_.elasticity.resize(nBodies()); - matrices_.damping.resize(nBodies()); - matrices_.mass.resize(nBodies()); - - for (size_t i=0; i<nBodies(); i++) { - deformedGrids_[i] = bodies_[i]->deformedGrid(); - - leafViews_[i] = std::make_unique<DeformedLeafGridView>(deformedGrids_[i]->leafGridView()); - levelViews_[i] = std::make_unique<DeformedLevelGridView>(deformedGrids_[i]->levelGridView(0)); - - leafVertexCounts_[i] = leafViews_[i]->size(dimension); - - matrices_.elasticity[i] = bodies_[i]->matrices().elasticity; - matrices_.damping[i] = bodies_[i]->matrices().damping; - matrices_.mass[i] = bodies_[i]->matrices().mass; +template <class GridType, int dim> +void ContactNetwork<GridType, dim>::assemble() { + for (size_t i=0; i<levelContactNetworks_.size(); i++) { + levelContactNetworks_[i]->assemble(); } } -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::setCouplings(const std::vector<std::shared_ptr<CouplingPair>>& couplings) { - assert(this->nCouplings()==couplings.size()); - couplings_ = couplings; -} +template <class GridType, int dim> +void ContactNetwork<GridType, dim>::addLevelContactNetwork(std::shared_ptr<LevelContactNetwork> levelContactNetwork) { + size_t level = levelContactNetwork->level(); + assert(level < this->size()); -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::constructBody(const std::shared_ptr<BodyData<dimension>>& bodyData, - const std::shared_ptr<GridType>& grid, - std::shared_ptr<Body>& body) const -{ - body = std::make_shared<Body>(bodyData, grid); + levelContactNetworks_[level] = levelContactNetwork; } -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::constructCoupling(int nonMortarBodyIdx, int mortarBodyIdx, - const std::shared_ptr<DeformedLevelBoundaryPatch>& nonmortarPatch, - const std::shared_ptr<DeformedLevelBoundaryPatch>& mortarPatch, - std::shared_ptr<CouplingPair>& coupling) const -{ - coupling = std::make_shared<CouplingPair>(); - - auto contactProjection = std::make_shared<Dune::Contact::NormalProjection<DeformedLeafBoundaryPatch>>(); - std::shared_ptr<typename CouplingPair::BackEndType> backend = nullptr; - coupling->set(nonMortarBodyIdx, mortarBodyIdx, nonmortarPatch, mortarPatch, 0.1, Dune::Contact::CouplingPairBase::STICK_SLIP, contactProjection, backend); -} +template <class GridType, int dim> +const std::shared_ptr<typename ContactNetwork<GridType, dim>::LevelContactNetwork>& ContactNetwork<GridType, dim>::addLevelContactNetwork(int nBodies, int nCouplings, int level) { + assert(level < this->size()); -// collects all leaf boundary nodes from the different bodies identified by "tag" in a single BitSetVector -template <class GridType, int dimension> -void ContactNetwork<GridType, dimension>::totalNodes(const std::string& tag, Dune::BitSetVector<dimension>& totalNodes) { - - int totalSize = 0; - for (size_t i=0; i<nBodies(); i++) { - totalSize += this->body(i)->leafVertexCount(); - } - - totalNodes.resize(totalSize); - - int idx=0; - for (size_t i=0; i<nBodies(); i++) { - const auto& body = this->body(i); - std::vector<std::shared_ptr<typename Body::LeafBoundaryCondition>> boundaryConditions; - body->leafBoundaryConditions(tag, boundaryConditions); - - const int idxBackup = idx; - for (size_t bc = 0; bc<boundaryConditions.size(); bc++) { - const auto& nodes = boundaryConditions[bc]->boundaryNodes(); - for (size_t j=0; j<nodes->size(); j++, idx++) - for (int k=0; k<dimension; k++) - totalNodes[idx][k] = (*nodes)[j][k]; - idx = (bc==boundaryConditions.size()-1 ? idx : idxBackup); - } - } + levelContactNetworks_[level] = std::make_shared<LevelContactNetwork>(nBodies, nCouplings, level); + return levelContactNetworks_[level]; } #include "contactnetwork_tmpl.cc" diff --git a/src/data-structures/contactnetwork.hh b/src/data-structures/contactnetwork.hh index 1a29a90b8eb61004e865194306830f09f1365042..25baf45b74620318079a66894fac23b4703a6948 100644 --- a/src/data-structures/contactnetwork.hh +++ b/src/data-structures/contactnetwork.hh @@ -1,145 +1,37 @@ -#ifndef SRC_LEVELCONTACTNETWORK_HH -#define SRC_LEVELCONTACTNETWORK_HH +#ifndef SRC_CONTACTNETWORK_HH +#define SRC_CONTACTNETWORK_HH -#include <dune/common/fvector.hh> -#include <dune/common/bitsetvector.hh> - -#include <dune/istl/bvector.hh> - -#include <dune/contact/common/deformedcontinuacomplex.hh> -#include <dune/contact/common/couplingpair.hh> -#include <dune/contact/assemblers/nbodyassembler.hh> -//#include <dune/contact/assemblers/dualmortarcoupling.hh> -#include <dune/contact/projections/normalprojection.hh> - -#include <dune/tectonic/bodydata.hh> -#include <dune/tectonic/globalfriction.hh> - -#include "../assemblers.hh" -#include "body.hh" -#include "enums.hh" -#include "matrices.hh" -//#include "multi-body-problem-data/myglobalfrictiondata.hh" - -template <class GridType, int dimension> class ContactNetwork { - private: - using Vector = Dune::BlockVector<Dune::FieldVector<double, dimension>>; +#include "levelcontactnetwork.hh" +template <class GridType, int dim> class ContactNetwork { public: - using Body = Body<GridType, Vector, dimension>; - - using DeformedGridType = typename Body::DeformedGridType; - using DeformedLeafGridView = typename Body::DeformedLeafGridView; - using DeformedLevelGridView = typename Body::DeformedLevelGridView; - - using DeformedLeafBoundaryPatch = BoundaryPatch<DeformedLeafGridView>; - using DeformedLevelBoundaryPatch = BoundaryPatch<DeformedLevelGridView>; - - - - - using Assembler = typename Body::Assembler; - using Matrix = typename Assembler::Matrix; - using LocalVector = typename Vector::block_type; - using ScalarMatrix = typename Assembler::ScalarMatrix; - using ScalarVector = typename Assembler::ScalarVector; - using field_type = typename Matrix::field_type; - - using CouplingPair = Dune::Contact::CouplingPair<DeformedGridType, DeformedGridType, field_type>; - - using Function = Dune::VirtualFunction<double, double>; + using LevelContactNetwork = LevelContactNetwork<GridType, dim>; private: - const int level_; - - std::vector<std::shared_ptr<Body>> bodies_; - std::vector<std::shared_ptr<CouplingPair>> couplings_; - - std::vector<const DeformedGridType*> deformedGrids_; - std::vector<std::unique_ptr<const DeformedLeafGridView>> leafViews_; - std::vector<std::unique_ptr<const DeformedLevelGridView>> levelViews_; - std::vector<size_t> leafVertexCounts_; - - Dune::Contact::NBodyAssembler<DeformedGridType, Vector> nBodyAssembler_; - Dune::BitSetVector<dimension> totalDirichletNodes_; + std::vector<std::shared_ptr<LevelContactNetwork>> levelContactNetworks_; - Matrices<Matrix,2> matrices_; - // std::vector<std::shared_ptr<MyGlobalFrictionData<LocalVector>>> frictionData_; - std::vector<std::shared_ptr<GlobalFriction<Matrix, Vector>>> globalFriction_; + public: + ContactNetwork() {} - public: - ContactNetwork(int nBodies, int nCouplings, int level = 0); + void addLevelContactNetwork(std::shared_ptr<LevelContactNetwork> levelContactNetwork); + const std::shared_ptr<LevelContactNetwork>& addLevelContactNetwork(int nBodies, int nCouplings, int level); void assemble(); - void assembleFriction(const Config::FrictionModel& frictionModel, const std::vector<ScalarVector>& weightedNormalStress); - - int level() const { - return level_; - } - - void setBodies(const std::vector<std::shared_ptr<Body>>& bodies); - void setCouplings(const std::vector<std::shared_ptr<CouplingPair>>& couplings); - - void constructBody(const std::shared_ptr<BodyData<dimension>>& bodyData, - const std::shared_ptr<GridType>& grid, - std::shared_ptr<Body>& body) const; - void constructCoupling(int nonMortarBodyIdx, int mortarBodyIdx, - const std::shared_ptr<DeformedLevelBoundaryPatch>& nonmortarPatch, - const std::shared_ptr<DeformedLevelBoundaryPatch>& mortarPatch, - std::shared_ptr<CouplingPair>& coupling) const; - - void totalNodes(const std::string& tag, Dune::BitSetVector<dimension>& totalNodes); - - size_t nBodies() const { - return bodies_.size(); - } - - size_t nCouplings() const { - return couplings_.size(); - } - - const std::vector<size_t>& leafVertexCounts() const { - return leafVertexCounts_; - } - const std::shared_ptr<Body>& body(int i) const { - return bodies_[i]; + const std::shared_ptr<LevelContactNetwork>& levelContactNetwork(size_t level) const { + return levelContactNetworks_[level]; } - const std::vector<const DeformedGridType*>& deformedGrids() const { - return deformedGrids_; + void resize(size_t size) { + levelContactNetworks_.resize(size); } - const DeformedLeafGridView& leafView(int i) const { - return *leafViews_[i]; + size_t size() const { + return levelContactNetworks_.size(); } - const DeformedLevelGridView& levelView(int i) const { - return *levelViews_[i]; - } - - int leafVertexCount(int i) const { - return leafVertexCounts_[i]; - } - - Dune::Contact::NBodyAssembler<DeformedGridType, Vector>& nBodyAssembler() { - return nBodyAssembler_; - } - - const Dune::Contact::NBodyAssembler<DeformedGridType, Vector>& nBodyAssembler() const { - return nBodyAssembler_; - } - - const Matrices<Matrix,2>& matrices() const { - return matrices_; - } - - const std::vector<std::shared_ptr<GlobalFriction<Matrix, Vector>>>& globalFriction() const { - return globalFriction_; - } - - const Dune::BitSetVector<dimension>& totalDirichletNodes() const { - return totalDirichletNodes_; - } + size_t maxLevel() const { + return size()-1; + } }; #endif diff --git a/src/data-structures/enumparser.hh b/src/data-structures/enumparser.hh index 34f1c5830f6063d144d6a58dfd092b8cf2896122..47a73f78d0b82e304ef55e99b602d57f3ba0283e 100644 --- a/src/data-structures/enumparser.hh +++ b/src/data-structures/enumparser.hh @@ -1,5 +1,5 @@ -#ifndef SRC_ENUMPARSER_HH -#define SRC_ENUMPARSER_HH +#ifndef SRC_DATA_STRUCTURES_ENUMPARSER_HH +#define SRC_DATA_STRUCTURES_ENUMPARSER_HH // Copyright Carsten Graeser 2012 diff --git a/src/data-structures/globalfrictioncontainer.cc b/src/data-structures/globalfrictioncontainer.cc new file mode 100644 index 0000000000000000000000000000000000000000..37843c46c76e6c6d0a56c3f6bcba3c6ef9d62af3 --- /dev/null +++ b/src/data-structures/globalfrictioncontainer.cc @@ -0,0 +1,114 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* +#include "globalfrictioncontainer.hh" + +template <class BaseGlobalFriction, size_t depth> +auto GlobalFrictionContainer<BaseGlobalFriction, depth>::operator[](std::size_t i) +-> IndexObject& { + return globalFriction_[i]; +} + +template <class BaseGlobalFriction, size_t depth> +auto GlobalFrictionContainer<BaseGlobalFriction, depth>::operator[](std::size_t i) const +-> const IndexObject& { + return globalFriction_[i]; +} + +template <class BaseGlobalFriction, size_t depth> +auto GlobalFrictionContainer<BaseGlobalFriction, depth>::size() const +-> size_t { + return globalFriction_.size(); +} + +template <class BaseGlobalFriction, size_t depth> +void GlobalFrictionContainer<BaseGlobalFriction, depth>::resize(std::list<size_t> list) { + assert(list.size() <= depth); + + if (list.size() == 0) { + globalFriction_.resize(0); + } else { + globalFriction_.resize(list.front()); + list.pop_front(); + + for (size_t i=0; i<size(); i++) { + globalFriction_[i].resize(list); + } + } +} + +template <class BaseGlobalFriction, size_t depth> +template <class VectorContainer> +void GlobalFrictionContainer<BaseGlobalFriction, depth>::updateAlpha(const VectorContainer& newAlpha) { + assert(newAlpha.size() == size()); + + for (size_t i=0; i<size(); i++) { + globalFriction_[i].updateAlpha(newAlpha[i]); + } +} + +template <class BaseGlobalFriction, size_t depth> +auto GlobalFrictionContainer<BaseGlobalFriction, depth>::globalFriction() +-> GlobalFriction& { + return globalFriction_; +} + +template <class BaseGlobalFriction, size_t depth> +auto GlobalFrictionContainer<BaseGlobalFriction, depth>::globalFriction() const +-> const GlobalFriction& { + return globalFriction_; +} + + +template <class BaseGlobalFriction> +auto GlobalFrictionContainer<BaseGlobalFriction, 1>::operator[](std::size_t i) +-> IndexObject& { + return globalFriction_[i]; +} + +template <class BaseGlobalFriction> +auto GlobalFrictionContainer<BaseGlobalFriction, 1>::operator[](std::size_t i) const +-> const IndexObject& { + return globalFriction_[i]; +} + +template <class BaseGlobalFriction> +auto GlobalFrictionContainer<BaseGlobalFriction, 1>::size() const +-> size_t { + return globalFriction_.size(); +} + +template <class BaseGlobalFriction> +void GlobalFrictionContainer<BaseGlobalFriction, 1>::resize(std::list<size_t> newSize) { + if (newSize.size() > 0) { + globalFriction_.resize(newSize.front(), nullptr); + } else { + globalFriction_.resize(0); + } +} + +template <class BaseGlobalFriction> +template <class Vector> +void GlobalFrictionContainer<BaseGlobalFriction, 1>::updateAlpha(const Vector& newAlpha) { + for (size_t i=0; i<size(); i++) { + globalFriction_[i]->updateAlpha(newAlpha); + } +} + +template <class BaseGlobalFriction> +auto GlobalFrictionContainer<BaseGlobalFriction, 1>::globalFriction() +-> GlobalFriction& { + return globalFriction_; +} + +template <class BaseGlobalFriction> +auto GlobalFrictionContainer<BaseGlobalFriction, 1>::globalFriction() const +-> const GlobalFriction& { + return globalFriction_; +} + + +#include "globalfrictioncontainer_tmpl.cc" +*/ diff --git a/src/data-structures/globalfrictioncontainer.hh b/src/data-structures/globalfrictioncontainer.hh new file mode 100644 index 0000000000000000000000000000000000000000..fd2c058b750c041afb01461a313cff9fa5f28979 --- /dev/null +++ b/src/data-structures/globalfrictioncontainer.hh @@ -0,0 +1,114 @@ +#ifndef SRC_DATA_STRUCTURES_GLOBALFRICTIONCONTAINER_HH +#define SRC_DATA_STRUCTURES_GLOBALFRICTIONCONTAINER_HH + +#include <vector> +#include <cstddef> +#include <list> +#include <cassert> +#include <memory> + +template <class BaseGlobalFriction, size_t depth> +class GlobalFrictionContainer { +public: + using IndexObject = GlobalFrictionContainer<BaseGlobalFriction, depth-1>; + using GlobalFriction = std::vector<IndexObject>; + + GlobalFrictionContainer() {} + + auto operator[](std::size_t i) -> IndexObject& { + return globalFriction_[i]; + } + + auto operator[](std::size_t i) const -> const IndexObject& { + return globalFriction_[i]; + } + + auto size() const -> size_t { + return globalFriction_.size(); + } + + void resize(std::list<size_t> list) { + assert(list.size() <= depth); + + if (list.size() == 0) { + globalFriction_.resize(0); + } else { + globalFriction_.resize(list.front()); + list.pop_front(); + + for (size_t i=0; i<size(); i++) { + globalFriction_[i].resize(list); + } + } + } + + template <class VectorContainer> + void updateAlpha(const VectorContainer& newAlpha) { + assert(newAlpha.size() == size()); + + for (size_t i=0; i<size(); i++) { + globalFriction_[i].updateAlpha(newAlpha[i]); + } + } + + auto globalFriction() -> GlobalFriction& { + return globalFriction_; + } + + auto globalFriction() const -> const GlobalFriction& { + return globalFriction_; + } + +private: + GlobalFriction globalFriction_; +}; + + +template <class BaseGlobalFriction> +class GlobalFrictionContainer<BaseGlobalFriction, 1> { +public: + using IndexObject = std::shared_ptr<BaseGlobalFriction>; + using GlobalFriction = std::vector<IndexObject>; + + GlobalFrictionContainer() {} + + auto operator[](std::size_t i) -> IndexObject& { + return globalFriction_[i]; + } + + auto operator[](std::size_t i) const -> const IndexObject& { + return globalFriction_[i]; + } + + auto size() const -> size_t { + return globalFriction_.size(); + } + + void resize(std::list<size_t> newSize) { + if (newSize.size() > 0) { + globalFriction_.resize(newSize.front(), nullptr); + } else { + globalFriction_.resize(0); + } + } + + template <class Vector> + void updateAlpha(const Vector& newAlpha) { + for (size_t i=0; i<size(); i++) { + globalFriction_[i]->updateAlpha(newAlpha); + } + } + + auto globalFriction() -> GlobalFriction& { + return globalFriction_; + } + + auto globalFriction() const -> const GlobalFriction& { + return globalFriction_; + } + +private: + GlobalFriction globalFriction_; +}; + +#endif diff --git a/src/data-structures/levelcontactnetwork.cc b/src/data-structures/levelcontactnetwork.cc index 8f58d4d250fa29abe3c268667db81a1fd9da675a..bf3ca67689f6f15e418261f185462aef33d661ab 100644 --- a/src/data-structures/levelcontactnetwork.cc +++ b/src/data-structures/levelcontactnetwork.cc @@ -6,8 +6,14 @@ #include "levelcontactnetwork.hh" +#include "../utils/tobool.hh" +#include "../utils/debugutils.hh" + template <class GridType, int dimension> -LevelContactNetwork<GridType, dimension>::LevelContactNetwork(int nBodies, int nCouplings, int level) : +LevelContactNetwork<GridType, dimension>::LevelContactNetwork( + int nBodies, + int nCouplings, + int level) : level_(level), bodies_(nBodies), couplings_(nCouplings), @@ -22,10 +28,9 @@ template <class GridType, int dimension> void LevelContactNetwork<GridType, dimension>::assemble() { for (size_t i=0; i<nBodies(); i++) { bodies_[i]->assemble(); + //printBasisDofLocation(bodies_[i]->assembler()->vertexBasis); //TODO remove after debugging } - totalNodes("dirichlet", totalDirichletNodes_); - // set up dune-contact nBodyAssembler nBodyAssembler_.setGrids(deformedGrids_); @@ -38,7 +43,10 @@ void LevelContactNetwork<GridType, dimension>::assemble() { } template <class GridType, int dimension> -void LevelContactNetwork<GridType, dimension>::assembleFriction(const Config::FrictionModel& frictionModel, const std::vector<ScalarVector>& weightedNormalStress) { +void LevelContactNetwork<GridType, dimension>::assembleFriction( + const Config::FrictionModel& frictionModel, + const std::vector<ScalarVector>& weightedNormalStress) { + for (size_t i=0; i<nBodies(); i++) { bodies_[i]->assembleFriction(frictionModel, weightedNormalStress[i]); } @@ -57,7 +65,11 @@ void LevelContactNetwork<GridType, dimension>::setBodies(const std::vector<std:: deformedGrids_[i] = bodies_[i]->deformedGrid(); leafViews_[i] = std::make_unique<DeformedLeafGridView>(deformedGrids_[i]->leafGridView()); - levelViews_[i] = std::make_unique<DeformedLevelGridView>(deformedGrids_[i]->levelGridView(0)); + + levelViews_[i].resize(deformedGrids_[i]->maxLevel()+1); + for (size_t j=0; j<levelViews_[i].size(); j++) { + levelViews_[i][j] = std::make_unique<DeformedLevelGridView>(deformedGrids_[i]->levelGridView(j)); + } leafVertexCounts_[i] = leafViews_[i]->size(dimension); @@ -74,19 +86,21 @@ void LevelContactNetwork<GridType, dimension>::setCouplings(const std::vector<st } template <class GridType, int dimension> -void LevelContactNetwork<GridType, dimension>::constructBody(const std::shared_ptr<BodyData<dimension>>& bodyData, - const std::shared_ptr<GridType>& grid, - std::shared_ptr<Body>& body) const -{ +void LevelContactNetwork<GridType, dimension>::constructBody( + const std::shared_ptr<BodyData<dimension>>& bodyData, + const std::shared_ptr<GridType>& grid, + std::shared_ptr<Body>& body) const { + body = std::make_shared<Body>(bodyData, grid); } template <class GridType, int dimension> -void LevelContactNetwork<GridType, dimension>::constructCoupling(int nonMortarBodyIdx, int mortarBodyIdx, - const std::shared_ptr<DeformedLevelBoundaryPatch>& nonmortarPatch, - const std::shared_ptr<DeformedLevelBoundaryPatch>& mortarPatch, - std::shared_ptr<CouplingPair>& coupling) const -{ +void LevelContactNetwork<GridType, dimension>::constructCoupling( + int nonMortarBodyIdx, int mortarBodyIdx, + const std::shared_ptr<DeformedLevelBoundaryPatch>& nonmortarPatch, + const std::shared_ptr<DeformedLevelBoundaryPatch>& mortarPatch, + std::shared_ptr<CouplingPair>& coupling) const { + coupling = std::make_shared<CouplingPair>(); auto contactProjection = std::make_shared<Dune::Contact::NormalProjection<DeformedLeafBoundaryPatch>>(); @@ -96,7 +110,9 @@ void LevelContactNetwork<GridType, dimension>::constructCoupling(int nonMortarBo // collects all leaf boundary nodes from the different bodies identified by "tag" in a single BitSetVector template <class GridType, int dimension> -void LevelContactNetwork<GridType, dimension>::totalNodes(const std::string& tag, Dune::BitSetVector<dimension>& totalNodes) { +void LevelContactNetwork<GridType, dimension>::totalNodes( + const std::string& tag, + Dune::BitSetVector<dimension>& totalNodes) const { int totalSize = 0; for (size_t i=0; i<nBodies(); i++) { @@ -122,4 +138,174 @@ void LevelContactNetwork<GridType, dimension>::totalNodes(const std::string& tag } } +// collects all leaf boundary nodes from the different bodies identified by "tag" in a vector of BitSetVector +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::boundaryPatchNodes( + const std::string& tag, + BoundaryPatchNodes& nodes) const { + + nodes.resize(nBodies()); + + for (size_t i=0; i<nBodies(); i++) { + this->body(i)->boundaryPatchNodes(tag, nodes[i]); + } +} + +// collects all leaf boundary nodes from the different bodies identified by "tag" in a vector of BitSetVector +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::boundaryNodes( + const std::string& tag, + BoundaryNodes& nodes) const { + + nodes.resize(nBodies()); + + for (size_t i=0; i<nBodies(); i++) { + this->body(i)->boundaryNodes(tag, nodes[i]); + } +} + +// collects all leaf boundary functions from the different bodies identified by "tag" +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::boundaryFunctions( + const std::string& tag, + BoundaryFunctions& functions) const { + + functions.resize(nBodies()); + + for (size_t i=0; i<nBodies(); i++) { + this->body(i)->boundaryFunctions(tag, functions[i]); + } +} + +// collects all leaf boundary patches from the different bodies identified by "tag" +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::boundaryPatches( + const std::string& tag, + BoundaryPatches& patches) const { + + patches.resize(nBodies()); + + for (size_t i=0; i<nBodies(); i++) { + this->body(i)->boundaryPatches(tag, patches[i]); + } +} + +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::stateEnergyNorms(StateEnergyNorms& stateEnergyNorms) const { + stateEnergyNorms.resize(nBodies()); + for (size_t i=0; i<stateEnergyNorms.size(); i++) { + stateEnergyNorms[i] = body(i)->stateEnergyNorm().get(); + } +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::level() const +-> int { + + return level_; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::nBodies() const +-> size_t { + + return bodies_.size(); +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::nCouplings() const +-> size_t { + + return couplings_.size(); +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::leafVertexCounts() const +-> const std::vector<size_t>& { + + return leafVertexCounts_; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::body(int i) const +-> const std::shared_ptr<Body>& { + + return bodies_[i]; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::deformedGrids() const +-> const std::vector<const DeformedGridType*>& { + + return deformedGrids_; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::leafView(int bodyID) const +-> const DeformedLeafGridView& { + + return *leafViews_[bodyID]; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::levelViews(int bodyID) const +-> const std::vector<std::unique_ptr<const DeformedLevelGridView>>& { + + return levelViews_[bodyID]; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::levelView(int bodyID, int level) const +-> const DeformedLevelGridView& { + + return *levelViews_[bodyID][level]; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::leafVertexCount(int bodyID) const +-> int { + + return leafVertexCounts_[bodyID]; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::nBodyAssembler() +-> Dune::Contact::NBodyAssembler<DeformedGridType, Vector>& { + + return nBodyAssembler_; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::nBodyAssembler() const +-> const Dune::Contact::NBodyAssembler<DeformedGridType, Vector>& { + + return nBodyAssembler_; +} + +template <class GridType, int dimension> +auto LevelContactNetwork<GridType, dimension>::matrices() const +-> const Matrices<Matrix,2>& { + + return matrices_; +} + +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::globalFriction(GlobalFrictionContainer& globalFriction) const { + globalFriction.resize({nBodies()}); + + for (size_t i=0; i<nBodies(); i++) { + globalFriction[i] = bodies_[i]->globalFriction(); + } +} + +template <class GridType, int dimension> +void LevelContactNetwork<GridType, dimension>::externalForces(ExternalForces& externalForces) const { + externalForces.resize(nBodies()); + + for (size_t i=0; i<nBodies(); i++) { + externalForces[i] = &bodies_[i]->externalForce(); + } +} + + #include "levelcontactnetwork_tmpl.cc" diff --git a/src/data-structures/levelcontactnetwork.hh b/src/data-structures/levelcontactnetwork.hh index ea47b6efdd690c45732ab4096ec4c09483f10c13..f6c1bf194f3889ff2effa0a446f317df4e09621f 100644 --- a/src/data-structures/levelcontactnetwork.hh +++ b/src/data-structures/levelcontactnetwork.hh @@ -1,5 +1,5 @@ -#ifndef SRC_LEVELCONTACTNETWORK_HH -#define SRC_LEVELCONTACTNETWORK_HH +#ifndef SRC_DATA_STRUCTURES_LEVELCONTACTNETWORK_HH +#define SRC_DATA_STRUCTURES_LEVELCONTACTNETWORK_HH #include <dune/common/fvector.hh> #include <dune/common/bitsetvector.hh> @@ -13,133 +13,128 @@ #include <dune/contact/projections/normalprojection.hh> #include <dune/tectonic/bodydata.hh> -#include <dune/tectonic/globalfriction.hh> #include "../assemblers.hh" #include "body.hh" #include "enums.hh" +#include "globalfrictioncontainer.hh" #include "matrices.hh" //#include "multi-body-problem-data/myglobalfrictiondata.hh" template <class GridType, int dimension> class LevelContactNetwork { - private: - using Vector = Dune::BlockVector<Dune::FieldVector<double, dimension>>; + private: + using Vector = Dune::BlockVector<Dune::FieldVector<double, dimension>>; - public: - using Body = Body<GridType, Vector, dimension>; + public: + using Body = Body<GridType, Vector, dimension>; - using DeformedGridType = typename Body::DeformedGridType; - using DeformedLeafGridView = typename Body::DeformedLeafGridView; - using DeformedLevelGridView = typename Body::DeformedLevelGridView; + using DeformedGridType = typename Body::DeformedGridType; + using DeformedLeafGridView = typename Body::DeformedLeafGridView; + using DeformedLevelGridView = typename Body::DeformedLevelGridView; - using DeformedLeafBoundaryPatch = BoundaryPatch<DeformedLeafGridView>; - using DeformedLevelBoundaryPatch = BoundaryPatch<DeformedLevelGridView>; + using DeformedLeafBoundaryPatch = BoundaryPatch<DeformedLeafGridView>; + using DeformedLevelBoundaryPatch = BoundaryPatch<DeformedLevelGridView>; + using Assembler = typename Body::Assembler; + using Matrix = typename Assembler::Matrix; + using LocalVector = typename Vector::block_type; + using ScalarMatrix = typename Assembler::ScalarMatrix; + using ScalarVector = typename Assembler::ScalarVector; + using field_type = typename Matrix::field_type; + + using CouplingPair = Dune::Contact::CouplingPair<DeformedGridType, DeformedGridType, field_type>; + + using Function = Dune::VirtualFunction<double, double>; + using BoundaryFunctions = std::vector<typename Body::BoundaryFunctions>; + using BoundaryNodes = std::vector<typename Body::BoundaryNodes>; + using BoundaryPatchNodes = std::vector<typename Body::BoundaryPatchNodes>; + using BoundaryPatches = std::vector<typename Body::BoundaryPatches>; + using GlobalFrictionContainer = GlobalFrictionContainer<typename Body::GlobalFriction, 2>; - using Assembler = typename Body::Assembler; - using Matrix = typename Assembler::Matrix; - using LocalVector = typename Vector::block_type; - using ScalarMatrix = typename Assembler::ScalarMatrix; - using ScalarVector = typename Assembler::ScalarVector; - using field_type = typename Matrix::field_type; - - using CouplingPair = Dune::Contact::CouplingPair<DeformedGridType, DeformedGridType, field_type>; - - using Function = Dune::VirtualFunction<double, double>; - - private: - const int level_; - - std::vector<std::shared_ptr<Body>> bodies_; - std::vector<std::shared_ptr<CouplingPair>> couplings_; - - std::vector<const DeformedGridType*> deformedGrids_; - std::vector<std::unique_ptr<const DeformedLeafGridView>> leafViews_; - std::vector<std::unique_ptr<const DeformedLevelGridView>> levelViews_; - std::vector<size_t> leafVertexCounts_; - - Dune::Contact::NBodyAssembler<DeformedGridType, Vector> nBodyAssembler_; - Dune::BitSetVector<dimension> totalDirichletNodes_; - - Matrices<Matrix,2> matrices_; - // std::vector<std::shared_ptr<MyGlobalFrictionData<LocalVector>>> frictionData_; - std::vector<std::shared_ptr<GlobalFriction<Matrix, Vector>>> globalFriction_; - - public: + using StateEnergyNorms = std::vector<const typename Body::StateEnergyNorm *>; + using ExternalForces = std::vector<const typename Body::ExternalForce *>; + + public: LevelContactNetwork(int nBodies, int nCouplings, int level = 0); void assemble(); - void assembleFriction(const Config::FrictionModel& frictionModel, const std::vector<ScalarVector>& weightedNormalStress); - - int level() const { - return level_; - } + void assembleFriction( + const Config::FrictionModel& frictionModel, + const std::vector<ScalarVector>& weightedNormalStress); void setBodies(const std::vector<std::shared_ptr<Body>>& bodies); void setCouplings(const std::vector<std::shared_ptr<CouplingPair>>& couplings); - void constructBody(const std::shared_ptr<BodyData<dimension>>& bodyData, - const std::shared_ptr<GridType>& grid, - std::shared_ptr<Body>& body) const; - void constructCoupling(int nonMortarBodyIdx, int mortarBodyIdx, - const std::shared_ptr<DeformedLevelBoundaryPatch>& nonmortarPatch, - const std::shared_ptr<DeformedLevelBoundaryPatch>& mortarPatch, - std::shared_ptr<CouplingPair>& coupling) const; + void constructBody( + const std::shared_ptr<BodyData<dimension>>& bodyData, + const std::shared_ptr<GridType>& grid, + std::shared_ptr<Body>& body) const; + void constructCoupling( + int nonMortarBodyIdx, + int mortarBodyIdx, + const std::shared_ptr<DeformedLevelBoundaryPatch>& nonmortarPatch, + const std::shared_ptr<DeformedLevelBoundaryPatch>& mortarPatch, + std::shared_ptr<CouplingPair>& coupling) const; + + // getter + void totalNodes( + const std::string& tag, + Dune::BitSetVector<dimension>& totalNodes) const; + void boundaryPatches( + const std::string& tag, + BoundaryPatches& patches) const; + void boundaryPatchNodes( + const std::string& tag, + BoundaryPatchNodes& nodes) const; + void boundaryNodes( + const std::string& tag, + BoundaryNodes& nodes) const; + void boundaryFunctions( + const std::string& tag, + BoundaryFunctions& functions) const; + + void stateEnergyNorms(StateEnergyNorms& stateEnergyNorms) const; + void globalFriction(GlobalFrictionContainer& globalFriction) const; + void externalForces(ExternalForces& externalForces) const; + + auto level() const -> int; - void totalNodes(const std::string& tag, Dune::BitSetVector<dimension>& totalNodes); + auto nBodies() const -> size_t; + auto nCouplings() const -> size_t; - size_t nBodies() const { - return bodies_.size(); - } + auto body(int i) const -> const std::shared_ptr<Body>&; - size_t nCouplings() const { - return couplings_.size(); - } + auto deformedGrids() const -> const std::vector<const DeformedGridType*>& ; - const std::vector<size_t>& leafVertexCounts() const { - return leafVertexCounts_; - } + auto leafVertexCounts() const -> const std::vector<size_t>&; + auto leafVertexCount(int bodyID) const -> int; - const std::shared_ptr<Body>& body(int i) const { - return bodies_[i]; - } + auto leafView(int bodyID) const -> const DeformedLeafGridView&; + auto levelView(int bodyID, int level = 0) const -> const DeformedLevelGridView&; + auto levelViews(int bodyID) const -> const std::vector<std::unique_ptr<const DeformedLevelGridView>>&; - const std::vector<const DeformedGridType*>& deformedGrids() const { - return deformedGrids_; - } + auto nBodyAssembler() -> Dune::Contact::NBodyAssembler<DeformedGridType, Vector>&; + auto nBodyAssembler() const -> const Dune::Contact::NBodyAssembler<DeformedGridType, Vector>&; - const DeformedLeafGridView& leafView(int i) const { - return *leafViews_[i]; - } + auto matrices() const -> const Matrices<Matrix,2>&; - const DeformedLevelGridView& levelView(int i) const { - return *levelViews_[i]; - } - int leafVertexCount(int i) const { - return leafVertexCounts_[i]; - } - Dune::Contact::NBodyAssembler<DeformedGridType, Vector>& nBodyAssembler() { - return nBodyAssembler_; - } + private: + const int level_; - const Dune::Contact::NBodyAssembler<DeformedGridType, Vector>& nBodyAssembler() const { - return nBodyAssembler_; - } + std::vector<std::shared_ptr<Body>> bodies_; + std::vector<std::shared_ptr<CouplingPair>> couplings_; - const Matrices<Matrix,2>& matrices() const { - return matrices_; - } + std::vector<const DeformedGridType*> deformedGrids_; + std::vector<std::unique_ptr<const DeformedLeafGridView>> leafViews_; + std::vector<std::vector<std::unique_ptr<const DeformedLevelGridView>>> levelViews_; + std::vector<size_t> leafVertexCounts_; - const std::vector<std::shared_ptr<GlobalFriction<Matrix, Vector>>>& globalFriction() const { - return globalFriction_; - } + Dune::Contact::NBodyAssembler<DeformedGridType, Vector> nBodyAssembler_; - const Dune::BitSetVector<dimension>& totalDirichletNodes() const { - return totalDirichletNodes_; - } + Matrices<Matrix,2> matrices_; }; #endif diff --git a/src/data-structures/levelcontactnetwork_tmpl.cc b/src/data-structures/levelcontactnetwork_tmpl.cc index b0c5200f198c29fe30a2407919ad55b94b36f461..1a4be09fc127345d24d54b09e9baef4f3b1f7e83 100644 --- a/src/data-structures/levelcontactnetwork_tmpl.cc +++ b/src/data-structures/levelcontactnetwork_tmpl.cc @@ -3,5 +3,6 @@ #endif #include "../explicitgrid.hh" +#include "levelcontactnetwork.hh" template class LevelContactNetwork<Grid, MY_DIM>; diff --git a/src/data-structures/program_state.hh b/src/data-structures/program_state.hh index 44b84f91086a1f35f01dd2e973c4c11cc3c088ea..275697da77effe110850f77c239a4d1981b9a41c 100644 --- a/src/data-structures/program_state.hh +++ b/src/data-structures/program_state.hh @@ -99,7 +99,6 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { std::vector<const Matrix*> matrices_ptr(_matrices.size()); for (size_t i=0; i<matrices_ptr.size(); i++) { matrices_ptr[i] = _matrices[i].get(); - print(*matrices_ptr[i], "matrix " + std::to_string(i)); } /*std::vector<Matrix> matrices(velocityMatrices.size()); @@ -129,10 +128,15 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { using LinearFactory = SolverFactory<DeformedGridType, GlobalFriction<Matrix, Vector>, Matrix, Vector>; LinearFactory factory(parset.sub("solver.tnnmg"), nBodyAssembler, _dirichletNodes); - print(_dirichletNodes, "dirichletNodes: "); - print(bilinearForm, "matrix: "); + /* std::vector<Dune::BitSetVector<dims>> bodyDirichletNodes; + nBodyAssembler.postprocess(_dirichletNodes, bodyDirichletNodes); + for (size_t i=0; i<bodyDirichletNodes.size(); i++) { + print(bodyDirichletNodes[i], "bodyDirichletNodes_" + std::to_string(i) + ": "); + }*/ + + /* print(bilinearForm, "matrix: "); print(totalX, "totalX: "); - print(totalRhs, "totalRhs: "); + print(totalRhs, "totalRhs: ");*/ auto multigridStep = factory.getStep(); multigridStep->setProblem(bilinearForm, totalX, totalRhs); @@ -163,13 +167,14 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { ell0[i].resize(u[i].size()); ell0[i] = 0.0; - levelContactNetwork.body(i)->externalForce(relativeTime, ell0[i]); + levelContactNetwork.body(i)->externalForce()(relativeTime, ell0[i]); } // Initial displacement: Start from a situation of minimal stress, // which is automatically attained in the case [v = 0 = a]. // Assuming dPhi(v = 0) = 0, we thus only have to solve Au = ell0 - Dune::BitSetVector<dims> dirichletNodes = levelContactNetwork.totalDirichletNodes(); + Dune::BitSetVector<dims> dirichletNodes; + levelContactNetwork.totalNodes("dirichlet", dirichletNodes); for (size_t i=0; i<dirichletNodes.size(); i++) { bool val = false; for (size_t d=0; d<dims; d++) { @@ -210,7 +215,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { Dune::MatrixVector::subtractProduct(accelerationRHS[i], *body->matrices().elasticity, u[i]); } - Dune::BitSetVector<dims> noNodes(levelContactNetwork.totalDirichletNodes().size()); + Dune::BitSetVector<dims> noNodes(dirichletNodes.size(), false); solveLinearProblem(noNodes, levelContactNetwork.matrices().mass, accelerationRHS, a, parset.sub("a0.solver")); } diff --git a/src/factories/cantorfactory.cc b/src/factories/cantorfactory.cc index 4c30f26697f55681df4663adafd5238e90e76492..4df27f770be9ceb4e6de4a7454ab847978d2e2f1 100644 --- a/src/factories/cantorfactory.cc +++ b/src/factories/cantorfactory.cc @@ -8,69 +8,32 @@ #include <dune/contact/projections/normalprojection.hh> +#include "../utils/almostequal.hh" + #include "cantorfactory.hh" #include "../multi-body-problem-data/bc.hh" #include "../multi-body-problem-data/cuboidgeometry.hh" #include "../multi-body-problem-data/myglobalfrictiondata.hh" #include "../multi-body-problem-data/weakpatch.hh" +#include "../multi-body-problem-data/cubegridconstructor.hh" #include "../utils/diameter.hh" -template <int dim> -class Cube { -private: - using Vector = Dune::FieldVector<double, dim>; - - Vector A_; // two corners that are diagonal define cube in any space dimension - Vector B_; - - bool invariant_; // flag to set if Cube can be split() - - /* bool isDiagonal(const Vector& A, const Vector& B) const { - Vector diff = A; - diff -= B; +template <class GridType, int dim> +void CantorFactory<GridType, dim>::setBodies() { - for (size_t d=0; d<dim; d++) { - if (std::abs(diff[d])< 1e-14) - return false; - } - return true; - } */ -public: - Cube(bool invariant = false) { - invariant_ = invariant; - } - Cube(const Vector& A, const Vector& B, bool invariant = false) { - setCorners(A, B); - invariant_ = invariant; - } + for (size_t level=0; level<=maxLevel_; level++) { + const LevelCubes& levelCubes = cubes_[level]; - void setCorners(const Vector& A, const Vector& B) { - //assert(isDiagonal(corners[0], corners[1])); - A_ = A; - B_ = B; - } + for (size_t i=0; i<levelCubes.size(); i++) { + const std::shared_ptr<Cube>& cube = levelCubes[i]; - void split(std::vector<Cube>& newCubes) const { - assert(!invariant_); - - Vector midPoint = A_; - midPoint += 1/2*(B_ - A_); - - newCubes.push_back(); + CubeGridConstructor + } } -}; - -template <class GridType, int dims> -void CantorFactory<GridType, dims>::setBodies() { - // set up cuboid geometries - - double const length = 1.00; - double const width = 0.27; - double const weakLength = 0.20; std::vector<LocalVector> origins(this->bodyCount_); std::vector<LocalVector> lowerWeakOrigins(this->bodyCount_); @@ -133,18 +96,6 @@ void CantorFactory<GridType, dims>::setBodies() { getWeakPatch<LocalVector>(this->parset_.sub("boundary.friction.weakening"), cuboidGeometry, *lowerWeakPatch, *upperWeakPatch); refine(*grids[i], *lowerWeakPatch, this->parset_.template get<double>("boundary.friction.smallestDiameter"), cuboidGeometry.lengthScale); refine(*grids[i], *upperWeakPatch, this->parset_.template get<double>("boundary.friction.smallestDiameter"), cuboidGeometry.lengthScale); - - // 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; } for (size_t i=0; i<this->bodyCount_; i++) { @@ -152,8 +103,8 @@ void CantorFactory<GridType, dims>::setBodies() { } } -template <class GridType, int dims> -void CantorFactory<GridType, dims>::setCouplings() { +template <class GridType, int dim> +void CantorFactory<GridType, dim>::setCouplings() { const auto deformedGrids = this->contactNetwork_.deformedGrids(); for (size_t i=0; i<this->bodyCount_; i++) { @@ -175,10 +126,10 @@ void CantorFactory<GridType, dims>::setCouplings() { } } -template <class GridType, int dims> -void CantorFactory<GridType, dims>::setBoundaryConditions() { - using LeafBoundaryCondition = BoundaryCondition<DeformedLeafGridView, dims>; - using FrictionBoundaryCondition = FrictionBoundaryCondition<DeformedLeafGridView, LocalVector, dims>; +template <class GridType, int dim> +void CantorFactory<GridType, dim>::setBoundaryConditions() { + using LeafBoundaryCondition = BoundaryCondition<DeformedLeafGridView, dim>; + using FrictionBoundaryCondition = FrictionBoundaryCondition<DeformedLeafGridView, LocalVector, dim>; using Function = Dune::VirtualFunction<double, double>; std::shared_ptr<Function> neumannFunction = std::make_shared<NeumannCondition>(); @@ -214,7 +165,7 @@ void CantorFactory<GridType, dims>::setBoundaryConditions() { // Dirichlet Boundary // identify Dirichlet nodes on leaf level - std::shared_ptr<Dune::BitSetVector<dims>> dirichletNodes = std::make_shared<Dune::BitSetVector<dims>>(leafVertexCount); + std::shared_ptr<Dune::BitSetVector<dim>> dirichletNodes = std::make_shared<Dune::BitSetVector<dim>>(leafVertexCount); for (int j=0; j<leafVertexCount; j++) { if (leafFaces_[i]->right.containsVertex(j)) (*dirichletNodes)[j][0] = true; @@ -235,4 +186,219 @@ void CantorFactory<GridType, dims>::setBoundaryConditions() { } } + +class CantorIndexHierarchy { + public: + typedef std::map<std::pair<int,int>, bool> LevelCantorIndices; + + private: + const size_t maxLevel_; + std::vector<size_t> levelN_; + std::vector<LevelCantorIndices> cantorIndexHierarchy_; + + void prolongIndices(size_t currentLevel, size_t newLevel) { + const LevelCantorIndices& indices = cantorIndexHierarchy_[currentLevel]; + LevelCantorIndices& newIndices = cantorIndexHierarchy_[newLevel]; + + size_t offset = levelN_[currentLevel]; + + std::map<std::pair<int,int>, bool>::const_iterator it = indices.begin(); + std::map<std::pair<int,int>, bool>::const_iterator endIt = indices.end(); + for (; it!=endIt; ++it) { + int xID = it->first.first; + int yID = it->first.second; + newIndices[std::make_pair(xID, yID)] = true; + newIndices[std::make_pair(xID+offset, yID)] = true; + newIndices[std::make_pair(xID, yID+offset)] = true; + } + + size_t doubleOffset = 2*offset; + for (size_t i=offset+1; i<=doubleOffset; i=i+2) { + newIndices[std::make_pair(doubleOffset, i)] = true; + newIndices[std::make_pair(i, doubleOffset)] = true; + } + } + + void print(const LevelCantorIndices& indices) const { + std::cout << "LevelCantorIndices: " << std::endl; + + std::map<std::pair<int,int>, bool>::const_iterator it = indices.begin(); + std::map<std::pair<int,int>, bool>::const_iterator endIt = indices.end(); + for (; it!=endIt; ++it) { + std::cout << "(" << it->first.first << ", " << it->first.second << ")"<< std::endl; + } + } + + public: + CantorIndexHierarchy(size_t maxLevel) : + maxLevel_(maxLevel) + { + levelN_.resize(maxLevel_+1); + cantorIndexHierarchy_.resize(maxLevel_+1); + + // init levelCantorIndices on level 0 + LevelCantorIndices& initCantorIndices = cantorIndexHierarchy_[0]; + initCantorIndices[std::make_pair(0, 1)] = true; + initCantorIndices[std::make_pair(1, 0)] = true; + initCantorIndices[std::make_pair(1, 2)] = true; + initCantorIndices[std::make_pair(2, 1)] = true; + + for (size_t i=0; i<maxLevel_; i++) { + levelN_[i] = std::pow(2, i+1); + prolongIndices(i, i+1); + } + + levelN_[maxLevel_] = std::pow(2, maxLevel_+1); + } + + const LevelCantorIndices& levelCantorIndices(size_t i) const { + return cantorIndexHierarchy_[i]; + } + + size_t levelN(const size_t i) const { + return levelN_[i]; + } +}; + + +template <class GridType> +class CantorFaultFactory +{ + //! Parameter for mapper class + template<int dim> + struct FaceMapperLayout + { + bool contains (Dune::GeometryType gt) + { + return gt.dim() == dim-1; + } + }; + + protected: + typedef OscUnitCube<GridType, 2> GridOb; + static const int dimworld = GridType::dimensionworld; + static const int dim = GridType::dimension; + typedef typename GridType::ctype ctype; + typedef typename GridType::LevelGridView GV; + + typedef typename Dune::MultipleCodimMultipleGeomTypeMapper<GV, FaceMapperLayout > FaceMapper; + + private: + const std::map<size_t, size_t>& levelToCantorLevel_; + const int coarseResolution_; + const size_t maxLevel_; + const size_t maxCantorLevel_; + const CantorIndexHierarchy cantorIndexHierarchy_; + const int coarseGridN_; + + std::shared_ptr<GridType> grid_; + std::vector<double> levelResolutions_; + + std::shared_ptr<InterfaceNetwork<GridType>> interfaceNetwork_; + +private: + + + bool computeID(Dune::FieldVector<ctype, dimworld> vertex, const size_t gridN, std::pair<size_t, size_t>& IDs) const { + ctype xID = vertex[0]*gridN; + ctype yID = vertex[1]*gridN; + + ctype x = 0; + ctype y = 0; + + bool xIsInt = almost_equal(std::modf(xID, &x), 0.0, 2); + bool yIsInt = almost_equal(std::modf(yID, &y), 0.0, 2); + + if (xIsInt && yIsInt) { + IDs = std::make_pair((size_t) x, (size_t) y); + return true; + } + + if (xIsInt) { + y = std::ceil(yID); + if ((size_t) y % 2==0) + y = y-1; + IDs = std::make_pair((size_t) x, (size_t) y); + return true; + } + + if (yIsInt) { + x = std::ceil(xID); + if ((size_t) x % 2==0) + x = x-1; + IDs = std::make_pair((size_t) x, (size_t) y); + return true; + } + + return false; + } + +public: + //setup + CantorFaultFactory(const std::map<size_t, size_t>& levelToCantorLevel, const int coarseResolution, const size_t maxLevel, const size_t maxCantorLevel) : + levelToCantorLevel_(levelToCantorLevel), + coarseResolution_(coarseResolution), + maxLevel_(maxLevel), + maxCantorLevel_(maxCantorLevel), + cantorIndexHierarchy_(maxCantorLevel_), + coarseGridN_(std::pow(2, coarseResolution_)), + interfaceNetwork_(nullptr) + { + Dune::UGGrid<dim>::setDefaultHeapSize(4000); + GridOb unitCube(coarseGridN_); + grid_ = unitCube.grid(); + + grid_->globalRefine(maxLevel_); + + levelResolutions_.resize(maxLevel_+1); + + // init interface network + interfaceNetwork_ = std::make_shared<InterfaceNetwork<GridType>>(*grid_); + + for (size_t i=0; i<=maxLevel_; i++) { + if (i>0) { + interfaceNetwork_->prolongLevel(i-1, i); + } + + if (levelToCantorLevel_.count(i)) { + + levelResolutions_[i] = std::pow(2, coarseResolution_+i); + const size_t levelResolution = levelResolutions_[i]; + const size_t cantorResolution = cantorIndexHierarchy_.levelN(levelToCantorLevel_.at(i)); + + if (2*levelResolution<cantorResolution) + DUNE_THROW(Dune::Exception, "Level " + std::to_string(i) + " does not support cantor set with resolution " + std::to_string(cantorResolution)); + + const typename CantorIndexHierarchy::LevelCantorIndices& levelCantorIndices = cantorIndexHierarchy_.levelCantorIndices(levelToCantorLevel_.at(i)); + std::shared_ptr<LevelInterfaceNetwork<GV>> levelInterfaceNetwork = interfaceNetwork_->levelInterfaceNetworkPtr(i); + + const GV& gridView = levelInterfaceNetwork->levelGridView(); + FaceMapper intersectionMapper(gridView); + std::vector<bool> intersectionHandled(intersectionMapper.size(),false); + + for (const auto& elem:elements(gridView)) { + for (const auto& isect:intersections(gridView, elem)) { + + if (intersectionHandled[intersectionMapper.subIndex(elem, isect.indexInInside(),1)]) + continue; + + intersectionHandled[intersectionMapper.subIndex(elem, isect.indexInInside(),1)]=true; + + if (isect.boundary()) + continue; + + std::pair<size_t, size_t> intersectionID; + bool isAdmissibleID = computeID(isect.geometry().center(), cantorResolution, intersectionID); + + if (isAdmissibleID && levelCantorIndices.count(intersectionID)) { + levelInterfaceNetwork->addIntersection(isect, i); + } + } + } + } + } + } + + + #include "cantorfactory_tmpl.cc" diff --git a/src/factories/cantorfactory.hh b/src/factories/cantorfactory.hh index 8818fed94c60ab15da62d023a4e8ee166b404886..7e58c9ad159cdab9168a53eaf62311c55d165578 100644 --- a/src/factories/cantorfactory.hh +++ b/src/factories/cantorfactory.hh @@ -10,11 +10,16 @@ #include "contactnetworkfactory.hh" #include "../multi-body-problem-data/mybody.hh" -#include "../multi-body-problem-data/mygrids.hh" +#include "../multi-body-problem-data/grid/mygrids.hh" -template <class GridType, int dims> class CantorFactory : public ContactNetworkFactory<GridType, dims>{ + + + +template <class GridType, int dim> class CantorFactory : public ContactNetworkFactory<GridType, dim>{ private: - using Base = ContactNetworkFactory<GridType, dims>; + using Base = ContactNetworkFactory<GridType, dim>; + + using LevelCubes = std::vector<std::shared_ptr<Cube>>; using LocalVector = typename Base::ContactNetwork::LocalVector; @@ -28,11 +33,11 @@ template <class GridType, int dims> class CantorFactory : public ContactNetworkF using LevelFaces = MyFaces<DeformedLevelGridView>; private: - const std::shared_ptr<MyBodyData<dims>> bodyData_; // material properties of bodies + const std::shared_ptr<MyBodyData<dim>> bodyData_; // material properties of bodies GridsConstructor<GridType>* gridConstructor_; - std::vector<std::shared_ptr<CuboidGeometry>> cuboidGeometries_; + std::vector<LevelCubes> cubes_; std::vector<std::shared_ptr<LeafFaces>> leafFaces_; std::vector<std::shared_ptr<LevelFaces>> levelFaces_; @@ -46,7 +51,7 @@ template <class GridType, int dims> class CantorFactory : public ContactNetworkF public: CantorFactory(const Dune::ParameterTree& parset) : Base(parset, parset.get<size_t>("problem.bodyCount"), parset.get<size_t>("problem.bodyCount")-1), - bodyData_(std::make_shared<MyBodyData<dims>>(this->parset_, zenith_())), + bodyData_(std::make_shared<MyBodyData<dim>>(this->parset_, zenith_())), cuboidGeometries_(this->bodyCount_), leafFaces_(this->bodyCount_), levelFaces_(this->bodyCount_), diff --git a/src/factories/contactnetworkfactory.hh b/src/factories/contactnetworkfactory.hh index bee811e7ed717428a93d5c0bdb56cc8bd782401a..90298ad6803b98a8a7cd6053d4b805e3128207bc 100644 --- a/src/factories/contactnetworkfactory.hh +++ b/src/factories/contactnetworkfactory.hh @@ -4,22 +4,21 @@ #include <dune/common/parametertree.hh> #include "../data-structures/contactnetwork.hh" +#include "../data-structures/levelcontactnetwork.hh" -template <class GridType, int dims> +#include "levelcontactnetworkfactory.hh" + +template <class GridType, int dim> class ContactNetworkFactory { public: - using ContactNetwork = ContactNetwork<GridType, dims>; + using ContactNetwork = ContactNetwork<GridType, dim>; protected: - using Body = typename ContactNetwork::Body; - using CouplingPair = typename ContactNetwork::CouplingPair; + using LevelContactNetworkFactory = LevelContactNetworkFactory<GridType, dim>; const Dune::ParameterTree& parset_; - const size_t bodyCount_; - const size_t couplingCount_; - std::vector<std::shared_ptr<Body>> bodies_; - std::vector<std::shared_ptr<CouplingPair>> couplings_; + std::vector<std::shared_ptr<LevelContactNetworkFactory>> levelContactNetworkFactories_; ContactNetwork contactNetwork_; @@ -29,20 +28,16 @@ class ContactNetworkFactory { virtual void setBoundaryConditions() = 0; public: - ContactNetworkFactory(const Dune::ParameterTree& parset, size_t bodyCount, size_t couplingCount) : + ContactNetworkFactory(const Dune::ParameterTree& parset) : parset_(parset), - bodyCount_(bodyCount), - couplingCount_(couplingCount), - bodies_(bodyCount_), - couplings_(couplingCount_), - contactNetwork_(bodyCount_, couplingCount_) {} + contactNetwork_() {} void build() { setBodies(); - contactNetwork_.setBodies(bodies_); + contactNetwork_.setBodies(); setCouplings(); - contactNetwork_.setCouplings(couplings_); + contactNetwork_.setCouplings(); setBoundaryConditions(); } diff --git a/src/factories/stackedblocksfactory.cc b/src/factories/stackedblocksfactory.cc index 504ddff81aa9df3cce6434af4c1e9445890976c5..0891faeed91b05c974393734c48b20442ca01a2c 100644 --- a/src/factories/stackedblocksfactory.cc +++ b/src/factories/stackedblocksfactory.cc @@ -7,7 +7,7 @@ #include <dune/contact/projections/normalprojection.hh> #include "../multi-body-problem-data/bc.hh" -#include "../multi-body-problem-data/cuboidgeometry.hh" +#include "../multi-body-problem-data/grid/cuboidgeometry.hh" #include "../multi-body-problem-data/myglobalfrictiondata.hh" #include "../multi-body-problem-data/weakpatch.hh" diff --git a/src/factories/stackedblocksfactory.hh b/src/factories/stackedblocksfactory.hh index cf486808766bd42e7b9fdc0c606fa753630ba6f4..ed38c0ff4a01b9564a9e297f4e393d52eb36e83b 100644 --- a/src/factories/stackedblocksfactory.hh +++ b/src/factories/stackedblocksfactory.hh @@ -10,7 +10,7 @@ #include "levelcontactnetworkfactory.hh" #include "../multi-body-problem-data/mybody.hh" -#include "../multi-body-problem-data/mygrids.hh" +#include "../multi-body-problem-data/grid/mygrids.hh" template <class GridType, int dims> class StackedBlocksFactory : public LevelContactNetworkFactory<GridType, dims>{ private: diff --git a/src/io/hdf5-writer.hh b/src/io/hdf5-writer.hh index 211cb8ef12b5e0a2bac29e851c4ee1e7924cf538..d0351be71cdc9e4e61c82fa32520ef81b5ba1707 100644 --- a/src/io/hdf5-writer.hh +++ b/src/io/hdf5-writer.hh @@ -23,7 +23,6 @@ class HDF5Writer { HDF5Writer(HDF5::Grouplike &file, const std::vector<Vector>& vertexCoordinates, const std::vector<const VertexBasis* >& vertexBases, - const std::vector<Patch>& surfaces, const std::vector<Patch>& frictionalBoundaries, const std::vector<ConvexPolyhedron<LocalVector>>& weakPatches) : bodyCount_(vertexCoordinates.size()), @@ -33,14 +32,12 @@ class HDF5Writer { #if MY_DIM == 3 patchInfoWriters_(bodyCount_), #endif - surfaceWriters_(bodyCount_), frictionalBoundaryWriters_(bodyCount_) { for (size_t i=0; i<bodyCount_; i++) { #if MY_DIM == 3 patchInfoWriters_[i] = new PatchInfoWriter<ProgramState, VertexBasis, GridView>(file_, *vertexBases[i], frictionalBoundaries[i], weakPatches[i], i); #endif - surfaceWriters_[i] = new SurfaceWriter<ProgramState, GridView>(file_, vertexCoordinates[i], surfaces[i], i); frictionalBoundaryWriters_[i] = new FrictionalBoundaryWriter<ProgramState, GridView>(file_, vertexCoordinates[i], frictionalBoundaries[i], i); } } @@ -50,7 +47,6 @@ class HDF5Writer { #if MY_DIM == 3 delete patchInfoWriters_[i]; #endif - delete surfaceWriters_[i]; delete frictionalBoundaryWriters_[i]; } } @@ -65,7 +61,6 @@ class HDF5Writer { #if MY_DIM == 3 patchInfoWriters_[i]->write(programState); #endif - surfaceWriters_[i]->write(programState); frictionalBoundaryWriters_[i]->write(programState, *friction[i]); } } @@ -85,7 +80,6 @@ class HDF5Writer { #if MY_DIM == 3 std::vector<PatchInfoWriter<ProgramState, VertexBasis, GridView>* > patchInfoWriters_; #endif - std::vector<SurfaceWriter<ProgramState, GridView>* > surfaceWriters_; std::vector<FrictionalBoundaryWriter<ProgramState, GridView>* > frictionalBoundaryWriters_; }; #endif diff --git a/src/multi-body-problem-2D.cfg b/src/multi-body-problem-2D.cfg index c98e933debf34bae0af1a0707a3eda16887a9035..8212c5812d2a6e871c051438b06893b8b91cf11b 100644 --- a/src/multi-body-problem-2D.cfg +++ b/src/multi-body-problem-2D.cfg @@ -1,6 +1,6 @@ # -*- mode:conf -*- [boundary.friction] -smallestDiameter = 1 # 2e-3 [m] +smallestDiameter = 0.5 # 2e-3 [m] [timeSteps] refinementTolerance = 1e-5 diff --git a/src/multi-body-problem-data/grid/cube.cc b/src/multi-body-problem-data/grid/cube.cc new file mode 100644 index 0000000000000000000000000000000000000000..e3161f49ee94b46be4a0e2e0089310bf29c589b0 --- /dev/null +++ b/src/multi-body-problem-data/grid/cube.cc @@ -0,0 +1,72 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "cube.hh" + +template <int dim> +Cube<dim>::Cube(bool invariant = false) : invariant_(invariant) { + if (invariant_) { + nChildren_ = 1; + } else { + nChildren_ = std::pow(2, dim); + } + children_.resize(nChildren_, nullptr); +} + +template <int dim> +Cube<dim>::Cube(const Vector& A, const Vector& B, bool invariant = false) : invariant_(invariant) { + setCorners(A, B); + + if (invariant_) { + nChildren_ = 1; + } else { + nChildren_ = std::pow(2, dim); + } + children_.resize(nChildren_, nullptr); +} + +// generate a combination of unit basis vectors from binary number +template <int dim> +void Cube<dim>::parseBinary(int binary, Vector& shift) const { + + shift = 0; + for (int d=0; d<dim; d++) { + // yields true, if d-th digit of binary is a 1 + if (binary & std::pow(2, d)) { + // use d-th basis vector + shift[d] = 1; + } + } +} + +// constructs child cubes and sets children_ +template <int dim> +void Cube<dim>::split() { + if (invariant_) { + children_[0] = this; + } else { + const int nNewCubes = std::pow(2, dim); + newCubes.resize(nNewCubes); + + Vector midPoint = A_; + midPoint += 1/2*(B_ - A_); + + const double h = std::pow(2.0, std::round(std::log(midPoint[0]-A_[0])/std::log(2))); + + newCubes[0] = new Cube(A_, midPoint, false); + newCubes[nNewCubes-1] = new Cube(midPoint, B_, true); + + for (int i=1; i<nNewCubes-1; i++) { + Vector shift; + parseBinary(i, shift); + shift *= h; + + newCubes[i] = new Cube(A_+shift, midPoint+shift); + } + } else { + children_.resize(1); + } +} + +#include "cube_tmpl.cc" diff --git a/src/multi-body-problem-data/grid/cube.hh b/src/multi-body-problem-data/grid/cube.hh new file mode 100644 index 0000000000000000000000000000000000000000..56ecafe8f736e3b729a8887d2d5778061a49f838 --- /dev/null +++ b/src/multi-body-problem-data/grid/cube.hh @@ -0,0 +1,49 @@ +#ifndef SRC_MULTI_BODY_PROBLEM_DATA_CUBE_HH +#define SRC_MULTI_BODY_PROBLEM_DATA_CUBE_HH + + +// works in any space dimension +template <int dim> +class Cube { +private: + using Vector = Dune::FieldVector<double, dim>; + + // generate a combination of unit basis vectors from binary number + void parseBinary(int binary, Vector& shift) const; + +public: + Cube(bool invariant = false); + Cube(const Vector& A, const Vector& B, bool invariant = false); + + void setCorners(const Vector& A, const Vector& B) { + A_ = A; + B_ = B; + } + + void setParent(Cube* parent) { + parent_ = parent; + } + + const std::vector<std::shared_ptr<Cube>>& children() const { + return children_; + } + + // constructs child cubes and sets children_ + void split(); + +private: + using Vector = Dune::FieldVector<double, dim>; + + Vector A_; // two corners that are diagonal define dim-cube in any space dimension + Vector B_; + + const bool invariant_; // flag to set if Cube can be split() + + std::shared_ptr<Cube<dim>> parent_ = nullptr; + std::vector<std::shared_ptr<Cube<dim>>> children_; + int nChildren_; +}; + +#endif + + diff --git a/src/multi-body-problem-data/grid/cube_tmpl.cc b/src/multi-body-problem-data/grid/cube_tmpl.cc new file mode 100644 index 0000000000000000000000000000000000000000..d7aa099e3a1f7052805726d5ff74b6bc650a4c15 --- /dev/null +++ b/src/multi-body-problem-data/grid/cube_tmpl.cc @@ -0,0 +1,5 @@ +#ifndef MY_DIM +#error MY_DIM unset +#endif + +template class Cube<MY_DIM>; diff --git a/src/multi-body-problem-data/grid/cubefaces.cc b/src/multi-body-problem-data/grid/cubefaces.cc new file mode 100644 index 0000000000000000000000000000000000000000..255057c8d44aefce6b2f041be2e3ab650d858dcf --- /dev/null +++ b/src/multi-body-problem-data/grid/cubefaces.cc @@ -0,0 +1,84 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "cubefaces.hh" + +template <class GridView> +template <class Vector> +bool CubeFaces<GridView>::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 GridView> +template <class Vector> +bool CubeFaces<GridView>::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 * lengthScale_ > x[0] or + x[0] > minmax0.second + 1e-14 * lengthScale_) + return false; + if (minmax1.first - 1e-14 * lengthScale_ > x[1] or + x[1] > minmax1.second + 1e-14 * lengthScale_) + return false; + + return true; +} + +template <class GridView> +template <class Vector> +bool CubeFaces<GridView>::xyBetween(Vector const &v1, Vector const &v2, + Vector const &x) { + return xyCollinear(v1, v2, x) && xyBoxed(v1, v2, x); +} + +template <class GridView> +CubeFaces<GridView>::CubeFaces(const GridView& gridView, const Cube& cube, double lengthScale) + : + #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 + cube_(cube), + lengthScale_(lengthScale) + { + lower.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.A, cuboidGeometry.B, in.geometry().center()); + }); + + right.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.B, cuboidGeometry.C, in.geometry().center()); + }); + + upper.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.D, cuboidGeometry.C, in.geometry().center()); + }); + + left.insertFacesByProperty([&](typename GridView::Intersection const &in) { + return xyBetween(cuboidGeometry.A, cuboidGeometry.D, 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 + } + +#include "cubefaces_tmpl.cc" diff --git a/src/multi-body-problem-data/grid/cubefaces.hh b/src/multi-body-problem-data/grid/cubefaces.hh new file mode 100644 index 0000000000000000000000000000000000000000..4262f24f9d444585e9fde1c0f4807888eb5f0edf --- /dev/null +++ b/src/multi-body-problem-data/grid/cubefaces.hh @@ -0,0 +1,76 @@ +#ifndef SRC_MULTI_BODY_PROBLEM_DATA_CUBEFACES_HH +#define SRC_MULTI_BODY_PROBLEM_DATA_CUBEFACES_HH + +#include <dune/fufem/boundarypatch.hh> + +#include "cube.hh" + +template <class GridView> +class CubeFaces { +private: + using Cube = Cube<GridView::dimensionworld>; + + bool isClose(double a, double b) { + return std::abs(a - b) < 1e-14 * lengthScale_; + } + + bool isClose2(double a, double b) { + return std::abs(a - b) < + 1e-14 * lengthScale_ * lengthScale_; + } + + template <class Vector> + bool xyBoxed(Vector const &v1, Vector const &v2, Vector const &x); + + template <class Vector> + bool xyCollinear(Vector const &a, Vector const &b, Vector const &c); + + template <class Vector> + bool xyBetween(Vector const &v1, Vector const &v2, Vector const &x); + +public: + CubeFaces(const GridView& gridView, const Cube<GridView::dimensionworld>& cube, double lengthScale); + + const BoundaryPatch<GridView>& lower() const { + return lower_; + } + + const BoundaryPatch<GridView>& right() const { + return right_; + } + + const BoundaryPatch<GridView>& upper() const { + return upper_; + } + + const BoundaryPatch<GridView>& left() const { + return left_; + } + +#if MY_DIM == 3 + const BoundaryPatch<GridView>& front() const { + return front_; + } + const BoundaryPatch<GridView>& back() const { + return back_; + } +#endif + +private: + BoundaryPatch<GridView> lower_; + BoundaryPatch<GridView> right_; + BoundaryPatch<GridView> upper_; + BoundaryPatch<GridView> left_; + +#if MY_DIM == 3 + BoundaryPatch<GridView> front_; + BoundaryPatch<GridView> back_; +#endif + + const Cube& cube_; + const double lengthScale_; +}; + +#endif + + diff --git a/src/multi-body-problem-data/grid/cubefaces_tmpl.cc b/src/multi-body-problem-data/grid/cubefaces_tmpl.cc new file mode 100644 index 0000000000000000000000000000000000000000..aea2ea22b7b3b8bb8e398ca507b0a5ce6c3bd06f --- /dev/null +++ b/src/multi-body-problem-data/grid/cubefaces_tmpl.cc @@ -0,0 +1,8 @@ +#ifndef MY_DIM +#error MY_DIM unset +#endif + +#include "../../explicitgrid.hh" + +template struct CubeFaces<DeformedGrid::LeafGridView>; +template struct CubeFaces<DeformedGrid::LevelGridView>; diff --git a/src/multi-body-problem-data/grid/cubegridconstructor.hh b/src/multi-body-problem-data/grid/cubegridconstructor.hh new file mode 100644 index 0000000000000000000000000000000000000000..7cb6b6a30211b4fc9196d1419f57cf73f940a54d --- /dev/null +++ b/src/multi-body-problem-data/grid/cubegridconstructor.hh @@ -0,0 +1,28 @@ +#ifndef SRC_MULTI_BODY_PROBLEM_DATA_CUBEGRIDCONSTRUCTOR_HH +#define SRC_MULTI_BODY_PROBLEM_DATA_CUBEGRIDCONSTRUCTOR_HH + +#include "gridconstructor.hh" + +#include <dune/common/fmatrix.hh> + +#include <dune/fufem/boundarypatch.hh> + + +template <class GridType> +class CubeGridConstructor : public GridConstructor { +public: + using Cube = Cube<GridType::dimensionworld>; + + CubeGridConstructor(std::vector<std::shared_ptr<CuboidGeometry>> const &cuboidGeometries_); + + template <class GridView> + void constructFaces(const GridView& gridView, CuboidGeometry const &cuboidGeometry, CubeFaces<GridView>& cubeFaces); + +private: + std::vector<std::shared_ptr<CuboidGeometry>> const &cuboidGeometries; +}; + + +#endif + + diff --git a/src/multi-body-problem-data/cuboidgeometry.cc b/src/multi-body-problem-data/grid/cuboidgeometry.cc similarity index 100% rename from src/multi-body-problem-data/cuboidgeometry.cc rename to src/multi-body-problem-data/grid/cuboidgeometry.cc diff --git a/src/multi-body-problem-data/cuboidgeometry.hh b/src/multi-body-problem-data/grid/cuboidgeometry.hh similarity index 98% rename from src/multi-body-problem-data/cuboidgeometry.hh rename to src/multi-body-problem-data/grid/cuboidgeometry.hh index d189502eda9e007c7ebab67697c2e8a3eaba4eb7..834f3f4d330f92d77b498dbef42ab3194a64c02b 100644 --- a/src/multi-body-problem-data/cuboidgeometry.hh +++ b/src/multi-body-problem-data/grid/cuboidgeometry.hh @@ -3,7 +3,7 @@ #include <dune/common/fvector.hh> -#include "midpoint.hh" +#include "../midpoint.hh" class CuboidGeometry { public: diff --git a/src/multi-body-problem-data/grid/gridconstructor.hh b/src/multi-body-problem-data/grid/gridconstructor.hh new file mode 100644 index 0000000000000000000000000000000000000000..4faa6fe1254c0745eff55850217d562b1e4ceb7b --- /dev/null +++ b/src/multi-body-problem-data/grid/gridconstructor.hh @@ -0,0 +1,65 @@ +#ifndef SRC_GRIDCONSTRUCTOR_HH +#define SRC_GRIDCONSTRUCTOR_HH + +#include <dune/grid/common/gridfactory.hh> + +#include <dune/fufem/geometry/convexpolyhedron.hh> +#include <dune/fufem/geometry/polyhedrondistance.hh> + +#include "../utils/diameter.hh" + +template <class GridType> +class GridConstructor { + private: + double computeAdmissibleDiameter(double distance, double smallestDiameter, double lengthScale) { + return (distance / 0.0125 / lengthScale + 1.0) * smallestDiameter; + } + + public: + GridConstructor() {} + + std::shared_ptr<GridType> grid() { + return grid_; + } + + template <class LocalVector> + void refine(const ConvexPolyhedron<LocalVector>& weakPatch, double smallestDiameter, double lengthScale) { + bool needRefine = true; + while (true) { + needRefine = false; + for (auto &&e : elements(grid_->leafGridView())) { + auto const geometry = e.geometry(); + + auto const weakeningRegionDistance = + distance(weakPatch, geometry, 1e-6 * lengthScale); + auto const admissibleDiameter = + computeAdmissibleDiameter(weakeningRegionDistance, smallestDiameter, lengthScale); + + if (diameter(geometry) <= admissibleDiameter) + continue; + + needRefine = true; + grid_->mark(1, e); + } + if (!needRefine) + break; + + grid_->preAdapt(); + grid_->adapt(); + grid_->postAdapt(); + } + } + + virtual void createGrid() = 0; + + private: + Dune::GridFactory<GridType> gridFactory_; + std::shared_ptr<GridType> grid_; +}; + + + + +#endif + + diff --git a/src/multi-body-problem-data/mygrids.cc b/src/multi-body-problem-data/grid/mygrids.cc similarity index 83% rename from src/multi-body-problem-data/mygrids.cc rename to src/multi-body-problem-data/grid/mygrids.cc index a754ee56ce8f229196fa25fd9e3849bc4ef1284b..3d2fafda4cdf9ec5fce0a216ec63c85be52f6ec9 100644 --- a/src/multi-body-problem-data/mygrids.cc +++ b/src/multi-body-problem-data/grid/mygrids.cc @@ -5,48 +5,10 @@ #include <dune/fufem/geometry/polyhedrondistance.hh> #include "mygrids.hh" -#include "midpoint.hh" -#include "../utils/diameter.hh" +#include "../midpoint.hh" +#include "../../utils/diameter.hh" -#if MY_DIM == 3 -SimplexManager::SimplexManager(unsigned int shift) : shift_(shift) {} -#endif - -// back-to-front, front-to-back, front-to-back -void SimplexManager::addFromVerticesFBB(unsigned int U, unsigned int V, - unsigned int W) { -#if MY_DIM == 3 - unsigned int const U2 = U + shift_; - unsigned int const V2 = V + shift_; - unsigned int const W2 = W + shift_; - - simplices_.push_back({ U, V, W, U2 }); - simplices_.push_back({ V, V2, W2, U2 }); - simplices_.push_back({ W, W2, U2, V }); -#else - simplices_.push_back({ U, V, W }); -#endif -} - -// back-to-front, back-to-front, front-to-back -void SimplexManager::addFromVerticesFFB(unsigned int U, unsigned int V, - unsigned int W) { -#if MY_DIM == 3 - unsigned int const U2 = U + shift_; - unsigned int const V2 = V + shift_; - unsigned int const W2 = W + shift_; - - simplices_.push_back({ U, V, W, U2 }); - simplices_.push_back({ V, V2, W, U2 }); - simplices_.push_back({ V2, W, U2, W2 }); -#else - simplices_.push_back({ U, V, W }); -#endif -} - -auto SimplexManager::getSimplices() -> SimplexList const & { - return simplices_; -} +#include "simplexmanager.hh" // Fix: 3D case (still Elias code) template <class Grid> GridsConstructor<Grid>::GridsConstructor(std::vector<std::shared_ptr<CuboidGeometry>> const &cuboidGeometries_) : diff --git a/src/multi-body-problem-data/mygrids.hh b/src/multi-body-problem-data/grid/mygrids.hh similarity index 81% rename from src/multi-body-problem-data/mygrids.hh rename to src/multi-body-problem-data/grid/mygrids.hh index aa62f7f8dc4789e121e84208fca9ce26c768979c..f37716ebb57f3f51656f747e8fdf5696e1f4aa69 100644 --- a/src/multi-body-problem-data/mygrids.hh +++ b/src/multi-body-problem-data/grid/mygrids.hh @@ -27,12 +27,12 @@ template <class GridView> struct MyFaces { 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); @@ -44,27 +44,6 @@ template <class GridView> struct MyFaces { bool xyBetween(Vector const &v1, Vector const &v2, Vector const &x); }; -class SimplexManager { -public: - using SimplexList = std::vector<std::vector<unsigned int>>; - -#if MY_DIM == 3 - SimplexManager(unsigned int shift); -#endif - - void addFromVerticesFBB(unsigned int U, unsigned int V, unsigned int W); - void addFromVerticesFFB(unsigned int U, unsigned int V, unsigned int W); - - SimplexList const &getSimplices(); - -private: - SimplexList simplices_; - -#if MY_DIM == 3 - unsigned int const shift_; -#endif -}; - template <class Grid> class GridsConstructor { public: GridsConstructor(std::vector<std::shared_ptr<CuboidGeometry>> const &cuboidGeometries_); diff --git a/src/multi-body-problem-data/mygrids_tmpl.cc b/src/multi-body-problem-data/grid/mygrids_tmpl.cc similarity index 91% rename from src/multi-body-problem-data/mygrids_tmpl.cc rename to src/multi-body-problem-data/grid/mygrids_tmpl.cc index fc8ccba75f356ab8e8cebd2041693f868ccf3fb9..32a1975979054b67089c8940a51a8762327f0927 100644 --- a/src/multi-body-problem-data/mygrids_tmpl.cc +++ b/src/multi-body-problem-data/grid/mygrids_tmpl.cc @@ -2,8 +2,8 @@ #error MY_DIM unset #endif -#include "../explicitgrid.hh" -#include "../explicitvectors.hh" +#include "../../explicitgrid.hh" +#include "../../explicitvectors.hh" #include "cuboidgeometry.hh" template class GridsConstructor<Grid>; diff --git a/src/multi-body-problem-data/grid/simplexmanager.cc b/src/multi-body-problem-data/grid/simplexmanager.cc new file mode 100644 index 0000000000000000000000000000000000000000..4e4a3aaf7e07d37b106a0c464331989f7c071dc7 --- /dev/null +++ b/src/multi-body-problem-data/grid/simplexmanager.cc @@ -0,0 +1,45 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "simplexmanager.hh" + +#if MY_DIM == 3 +SimplexManager::SimplexManager(unsigned int shift) : shift_(shift) {} +#endif + +// back-to-front, front-to-back, front-to-back +void SimplexManager::addFromVerticesFBB(unsigned int U, unsigned int V, + unsigned int W) { +#if MY_DIM == 3 + unsigned int const U2 = U + shift_; + unsigned int const V2 = V + shift_; + unsigned int const W2 = W + shift_; + + simplices_.push_back({ U, V, W, U2 }); + simplices_.push_back({ V, V2, W2, U2 }); + simplices_.push_back({ W, W2, U2, V }); +#else + simplices_.push_back({ U, V, W }); +#endif +} + +// back-to-front, back-to-front, front-to-back +void SimplexManager::addFromVerticesFFB(unsigned int U, unsigned int V, + unsigned int W) { +#if MY_DIM == 3 + unsigned int const U2 = U + shift_; + unsigned int const V2 = V + shift_; + unsigned int const W2 = W + shift_; + + simplices_.push_back({ U, V, W, U2 }); + simplices_.push_back({ V, V2, W, U2 }); + simplices_.push_back({ V2, W, U2, W2 }); +#else + simplices_.push_back({ U, V, W }); +#endif +} + +auto SimplexManager::getSimplices() -> SimplexList const & { + return simplices_; +} diff --git a/src/multi-body-problem-data/grid/simplexmanager.hh b/src/multi-body-problem-data/grid/simplexmanager.hh new file mode 100644 index 0000000000000000000000000000000000000000..74217833e98af9c0bc7f2a571c9e5fa0391769e0 --- /dev/null +++ b/src/multi-body-problem-data/grid/simplexmanager.hh @@ -0,0 +1,29 @@ +#ifndef SRC_MULTI_BODY_PROBLEM_DATA_SIMPLEXMANAGER_HH +#define SRC_MULTI_BODY_PROBLEM_DATA_SIMPLEXMANAGER_HH + +#include <vector> + +class SimplexManager { +public: + using SimplexList = std::vector<std::vector<unsigned int>>; + +#if MY_DIM == 3 + SimplexManager(unsigned int shift); +#endif + + void addFromVerticesFBB(unsigned int U, unsigned int V, unsigned int W); + void addFromVerticesFFB(unsigned int U, unsigned int V, unsigned int W); + + auto getSimplices() -> SimplexList const &; + +private: + SimplexList simplices_; + +#if MY_DIM == 3 + unsigned int const shift_; +#endif +}; + +#endif + + diff --git a/src/multi-body-problem-data/mybody.hh b/src/multi-body-problem-data/mybody.hh index a79e359ee7e6670fed506bd4a64c2885cad7e5e8..c0160dde33964101263ba0b70cd13ac7f4ce55d4 100644 --- a/src/multi-body-problem-data/mybody.hh +++ b/src/multi-body-problem-data/mybody.hh @@ -8,7 +8,7 @@ #include <dune/tectonic/bodydata.hh> #include <dune/tectonic/gravity.hh> -#include "cuboidgeometry.hh" +#include "grid/cuboidgeometry.hh" #include "segmented-function.hh" template <int dimension> class MyBodyData : public BodyData<dimension> { diff --git a/src/multi-body-problem-data/segmented-function.hh b/src/multi-body-problem-data/segmented-function.hh index a75a7199559a5a47c8b8527a9a9fef13a6e842f0..866415af358cfb19939af139b70e33b4f652e92b 100644 --- a/src/multi-body-problem-data/segmented-function.hh +++ b/src/multi-body-problem-data/segmented-function.hh @@ -5,7 +5,7 @@ #include <dune/common/fvector.hh> #include <dune/common/parametertree.hh> -#include "cuboidgeometry.hh" +#include "grid/cuboidgeometry.hh" class SegmentedFunction : public Dune::VirtualFunction<Dune::FieldVector<double, MY_DIM>, diff --git a/src/multi-body-problem-data/weakpatch.hh b/src/multi-body-problem-data/weakpatch.hh index 4e54105bc293a3142033c1e34b04f58ad58c9540..a1fde1cb46c1e7351e650b061ae6ca584199c9d3 100644 --- a/src/multi-body-problem-data/weakpatch.hh +++ b/src/multi-body-problem-data/weakpatch.hh @@ -5,7 +5,7 @@ #include <dune/fufem/geometry/convexpolyhedron.hh> -#include "cuboidgeometry.hh" +#include "grid/cuboidgeometry.hh" template <class LocalVector> void getWeakPatch(Dune::ParameterTree const &parset, CuboidGeometry const &cuboidGeometry, ConvexPolyhedron<LocalVector>& lowerWeakPatch, ConvexPolyhedron<LocalVector>& upperWeakPatch) { diff --git a/src/multi-body-problem.cc b/src/multi-body-problem.cc index f02c02aaffff5563a256630e307ed5e709159865..de02c49787df22f05ef2cc28ec4b38749533d36d 100644 --- a/src/multi-body-problem.cc +++ b/src/multi-body-problem.cc @@ -67,7 +67,7 @@ #include "multi-body-problem-data/bc.hh" #include "multi-body-problem-data/mybody.hh" -#include "multi-body-problem-data/mygrids.hh" +#include "multi-body-problem-data/grid/mygrids.hh" //#include "spatial-solving/solverfactory.hh" @@ -144,8 +144,13 @@ int main(int argc, char *argv[]) { /* Vector def(levelContactNetwork.deformedGrids()[i]->size(dims)); def = 1; deformedGridComplex.setDeformation(def, i);*/ + auto& levelViews = levelContactNetwork.levelViews(i); - writeToVTK(levelContactNetwork.leafView(i), "", "deformedGrid" + std::to_string(i)); + for (size_t j=0; j<levelViews.size(); j++) { + writeToVTK(*levelViews[j], "", "body_" + std::to_string(i) + "_level_" + std::to_string(j)); + } + + writeToVTK(levelContactNetwork.leafView(i), "", "body_" + std::to_string(i) + "_leaf"); } // ---------------------------- @@ -193,7 +198,10 @@ int main(int argc, char *argv[]) { // ------------------------ levelContactNetwork.assembleFriction(parset.get<Config::FrictionModel>("boundary.friction.frictionModel"), programState.weightedNormalStress); - /* + typename LevelContactNetwork::GlobalFrictionContainer globalFriction; + levelContactNetwork.globalFriction(globalFriction); + globalFriction.updateAlpha(programState.alpha); + using MyVertexBasis = typename Assembler::VertexBasis; using MyCellBasis = typename Assembler::CellBasis; std::vector<Vector> vertexCoordinates(bodyCount); @@ -214,14 +222,16 @@ int main(int argc, char *argv[]) { vertexCoords[vertexMapper.index(v)] = geoToPoint(v.geometry()); } + typename LevelContactNetwork::BoundaryPatches frictionBoundaries; + levelContactNetwork.boundaryPatches("friction", frictionBoundaries); auto dataWriter = writeData ? std::make_unique< HDF5Writer<MyProgramState, MyVertexBasis, DefLeafGridView>>( *dataFile, vertexCoordinates, vertexBases, - surfaces, frictionalBoundaries, weakPatches) + frictionBoundaries, weakPatches) : nullptr; - +/* const MyVTKWriter<MyVertexBasis, MyCellBasis> vtkWriter(cellBases, vertexBases, "body"); IterationRegister iterationCount; @@ -261,34 +271,58 @@ int main(int argc, char *argv[]) { } }; report(true); - - +*/ // ------------------- // Set up TNNMG solver // ------------------- auto& nBodyAssembler = levelContactNetwork.nBodyAssembler(); - const auto& totalDirichletNodes = levelContactNetwork.totalDirichletNodes(); + + Dune::BitSetVector<dims> totalDirichletNodes; + levelContactNetwork.totalNodes("dirichlet", totalDirichletNodes); using NonlinearFactory = SolverFactory<DeformedGrid, GlobalFriction<Matrix, Vector>, Matrix, Vector>; NonlinearFactory factory(parset.sub("solver.tnnmg"), nBodyAssembler, totalDirichletNodes); - using MyUpdater = Updaters<RateUpdater<Vector, Matrix, typename LevelContactNetwork::Body::Function, dims>, + using BoundaryFunctions = typename LevelContactNetwork::BoundaryFunctions; + using BoundaryNodes = typename LevelContactNetwork::BoundaryNodes; + using Updaters = Updaters<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>, StateUpdater<ScalarVector, Vector>>; -/* + std::vector<double> L(bodyCount, parset.get<double>("boundary.friction.L")); std::vector<double> V0(bodyCount, parset.get<double>("boundary.friction.V0")); - MyUpdater current( - initRateUpdater(parset.get<Config::scheme>("timeSteps.scheme"), - velocityDirichletFunctions, dirichletNodes, matrices, - programState.u, programState.v, programState.a), - initStateUpdater<ScalarVector, Vector>( + + BoundaryFunctions velocityDirichletFunctions; + levelContactNetwork.boundaryFunctions("dirichlet", velocityDirichletFunctions); + + BoundaryNodes dirichletNodes; + levelContactNetwork.boundaryNodes("dirichlet", dirichletNodes); + + typename LevelContactNetwork::BoundaryPatchNodes frictionNodes; + levelContactNetwork.boundaryPatchNodes("friction", frictionNodes); + + Updaters current( + initRateUpdater( + parset.get<Config::scheme>("timeSteps.scheme"), + velocityDirichletFunctions, + dirichletNodes, + levelContactNetwork.matrices(), + programState.u, + programState.v, + programState.a), + initStateUpdater<ScalarVector, Vector, typename LevelContactNetwork::BoundaryPatchNodes>( parset.get<Config::stateModel>("boundary.friction.stateModel"), - programState.alpha, frictionalNodes, - L, V0)); + programState.alpha, + frictionNodes, + L, + V0)); auto const refinementTolerance = parset.get<double>("timeSteps.refinementTolerance"); - auto const mustRefine = [&](MyUpdater &coarseUpdater, - MyUpdater &fineUpdater) { + + typename LevelContactNetwork::StateEnergyNorms stateEnergyNorms; + levelContactNetwork.stateEnergyNorms(stateEnergyNorms); + + auto const mustRefine = [&](Updaters &coarseUpdater, + Updaters &fineUpdater) { std::vector<ScalarVector> coarseAlpha; coarseUpdater.state_->extractAlpha(coarseAlpha); @@ -307,11 +341,14 @@ int main(int argc, char *argv[]) { std::signal(SIGINT, handleSignal); std::signal(SIGTERM, handleSignal); - AdaptiveTimeStepper<NonlinearFactory, MyUpdater, EnergyNorm<ScalarMatrix, ScalarVector>> + typename LevelContactNetwork::ExternalForces externalForces; + levelContactNetwork.externalForces(externalForces); + + AdaptiveTimeStepper<NonlinearFactory, Updaters, EnergyNorm<ScalarMatrix, ScalarVector>> adaptiveTimeStepper(factory, parset, globalFriction, current, programState.relativeTime, programState.relativeTau, externalForces, stateEnergyNorms, mustRefine); - +/* while (!adaptiveTimeStepper.reachedEnd()) { programState.timeStep++; diff --git a/src/multi-body-problem.cfg b/src/multi-body-problem.cfg index 03c7084ae23e1d8d4a14c76f78504531efe42000..b850b5cc829734e50342d1e812254778f74ad97b 100644 --- a/src/multi-body-problem.cfg +++ b/src/multi-body-problem.cfg @@ -11,7 +11,7 @@ vtk.write = false [problem] finalTime = 1000 # [s] -bodyCount = 3 +bodyCount = 2 [body] bulkModulus = 0.5e5 # [Pa] diff --git a/src/spatial-solving/fixedpointiterator.cc b/src/spatial-solving/fixedpointiterator.cc index c3e90842cc708f2375e613b71e53f70eed241a8d..6b776feb982debaca743bd3bb6598d4a8ebdd8ca 100644 --- a/src/spatial-solving/fixedpointiterator.cc +++ b/src/spatial-solving/fixedpointiterator.cc @@ -36,7 +36,7 @@ void FixedPointIterationCounter::operator+=( template <class Factory, class Updaters, class ErrorNorm> FixedPointIterator<Factory, Updaters, ErrorNorm>::FixedPointIterator( Factory &factory, Dune::ParameterTree const &parset, - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction, const std::vector<const ErrorNorm* >& errorNorms) + GlobalFrictionContainer& globalFriction, const std::vector<const ErrorNorm* >& errorNorms) : factory_(factory), step_(factory_.getStep()), parset_(parset), @@ -81,9 +81,8 @@ FixedPointIterator<Factory, Updaters, ErrorNorm>::run( relativeVelocities(velocityIterates, v_rel); // contribution from nonlinearity - for (size_t i=0; i<alpha.size(); i++) { - globalFriction_[i]->updateAlpha(alpha[i]); - } + globalFriction_.updateAlpha(alpha); + std::vector<Matrix> matrices(velocityMatrices.size()); std::vector<Vector> rhs(velocityRHSs.size()); @@ -91,8 +90,11 @@ FixedPointIterator<Factory, Updaters, ErrorNorm>::run( matrices[i] = velocityMatrices[i]; rhs[i] = velocityRHSs[i]; - globalFriction_[i]->addHessian(v_rel[i], matrices[i]); - globalFriction_[i]->addGradient(v_rel[i], rhs[i]); + auto& globalFriction = globalFriction_[i]; + for (size_t j=0; j<globalFriction.size(); j++) { + globalFriction[j]->addHessian(v_rel[i], matrices[i]); + globalFriction[j]->addGradient(v_rel[i], rhs[i]); + } matrices_ptr[i] = &matrices[i]; } diff --git a/src/spatial-solving/fixedpointiterator.hh b/src/spatial-solving/fixedpointiterator.hh index bae4624f1dc8f8c04e7de03ac4165ac2bf438aae..688a80b516c3a8dfe4e34764a9a48688477118a7 100644 --- a/src/spatial-solving/fixedpointiterator.hh +++ b/src/spatial-solving/fixedpointiterator.hh @@ -10,6 +10,8 @@ #include <dune/contact/assemblers/nbodyassembler.hh> +#include "../data-structures/globalfrictioncontainer.hh" + struct FixedPointIterationCounter { size_t iterations = 0; size_t multigridIterations = 0; @@ -28,15 +30,17 @@ class FixedPointIterator { using Nonlinearity = typename Factory::Nonlinearity; // using Nonlinearity = typename ConvexProblem::NonlinearityType; + using DeformedGrid = typename Factory::DeformedGrid; - using DeformedGrid = typename Factory::DeformedGrid; +public: + using GlobalFrictionContainer = GlobalFrictionContainer<Nonlinearity, 2>; private: void relativeVelocities(const std::vector<Vector>& v, std::vector<Vector>& v_rel) const; public: FixedPointIterator(Factory& factory, const Dune::ParameterTree& parset, - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction, + GlobalFrictionContainer& globalFriction, const std::vector<const ErrorNorm* >& errorNorms); FixedPointIterationCounter run(Updaters updaters, @@ -48,7 +52,7 @@ class FixedPointIterator { Factory& factory_; std::shared_ptr<typename Factory::Step> step_; Dune::ParameterTree const &parset_; - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction_; + GlobalFrictionContainer& globalFriction_; size_t fixedPointMaxIterations_; double fixedPointTolerance_; diff --git a/src/spatial-solving/fixedpointiterator_tmpl.cc b/src/spatial-solving/fixedpointiterator_tmpl.cc index 97dfe8341850194d93d6cba4dca335331c3342d6..eec3461083148f6a5b8b372dcd7abe3cd655e61a 100644 --- a/src/spatial-solving/fixedpointiterator_tmpl.cc +++ b/src/spatial-solving/fixedpointiterator_tmpl.cc @@ -15,16 +15,21 @@ #include <dune/tectonic/globalfriction.hh> #include <dune/tectonic/myblockproblem.hh> +#include "../data-structures/levelcontactnetwork.hh" #include "../time-stepping/rate/rateupdater.hh" #include "../time-stepping/state/stateupdater.hh" #include "../time-stepping/updaters.hh" #include "solverfactory.hh" -using Function = Dune::VirtualFunction<double, double>; + + +using BoundaryNodes = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryNodes; +using BoundaryFunctions = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryFunctions; + using Factory = SolverFactory<DeformedGrid, GlobalFriction<Matrix, Vector>, Matrix, Vector>; using MyStateUpdater = StateUpdater<ScalarVector, Vector>; -using MyRateUpdater = RateUpdater<Vector, Matrix, Function, MY_DIM>; +using MyRateUpdater = RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>; using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>; using ErrorNorm = EnergyNorm<ScalarMatrix, ScalarVector>; diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc index 2d83a0c13aa36ce8c2c5ea006cec0cdc7a4b7730..0bba4b88001d23557b8608aaef3f7f40f02fd42f 100644 --- a/src/spatial-solving/solverfactory.cc +++ b/src/spatial-solving/solverfactory.cc @@ -26,6 +26,11 @@ SolverFactory<DeformedGrid, Nonlinearity, MatrixType, VectorType>::SolverFactory Solver::QUIET), transferOperators_(nBodyAssembler.getGrids().at(0)->maxLevel()) { + /* baseSolverStep_.obstacles_ = using HasObstacle = Dune::BitSetVector<BlockSize>; + using Obstacle = BoxConstraint<Field, BlockSize>; + const HasObstacle* hasObstacle_; + const std::vector<Obstacle>* obstacles_;*/ + multigridStep_ = std::make_shared<Step>(); // tnnmg iteration step multigridStep_->setMGType(parset.get<int>("main.multi"), parset.get<int>("main.pre"), parset.get<int>("main.post")); @@ -34,7 +39,7 @@ SolverFactory<DeformedGrid, Nonlinearity, MatrixType, VectorType>::SolverFactory multigridStep_->setSmoother(&presmoother_, &postsmoother_); multigridStep_->setHasObstacle(nBodyAssembler_.totalHasObstacle_); multigridStep_->setObstacles(nBodyAssembler_.totalObstacles_); - + multigridStep_->setVerbosity(NumProc::QUIET); // create the transfer operators const int nCouplings = nBodyAssembler_.nCouplings(); diff --git a/src/spatial-solving/solverfactory.hh b/src/spatial-solving/solverfactory.hh index 9e982c90b3367e1cb5a1e84410d2e4367145a0b0..5e87ea27d7920dbab7b044a485c5a7d4f8f159e7 100644 --- a/src/spatial-solving/solverfactory.hh +++ b/src/spatial-solving/solverfactory.hh @@ -6,8 +6,10 @@ #include <dune/solvers/iterationsteps/multigridstep.hh> #include <dune/solvers/iterationsteps/projectedblockgsstep.hh> +#include <dune/solvers/iterationsteps/blockgsstep.hh> #include <dune/solvers/norms/energynorm.hh> #include <dune/solvers/solvers/loopsolver.hh> + //#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh> //#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh> //#include <dune/tnnmg/iterationsteps/tnnmgstep.hh> @@ -50,7 +52,8 @@ class SolverFactory { private: const Dune::Contact::NBodyAssembler<DeformedGrid, VectorType>& nBodyAssembler_; - ProjectedBlockGSStep<MatrixType, VectorType> baseSolverStep_; + //ProjectedBlockGSStep<MatrixType, VectorType> baseSolverStep_; + BlockGSStep<MatrixType, VectorType> baseSolverStep_; EnergyNorm<MatrixType, VectorType> baseEnergyNorm_; LoopSolver<VectorType> baseSolver_; diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4109f1b97ceead8006cffc009c8ee1cbd2817826 --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1 @@ +dune_add_test(SOURCES globalfrictioncontainertest.cc) diff --git a/src/tests/globalfrictioncontainertest.cc b/src/tests/globalfrictioncontainertest.cc new file mode 100644 index 0000000000000000000000000000000000000000..7439c584284f180e22313407c4d142fb0ea9c877 --- /dev/null +++ b/src/tests/globalfrictioncontainertest.cc @@ -0,0 +1,120 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <iostream> +#include <vector> + +#include <exception> + +#include <dune/common/exceptions.hh> +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/stdstreams.hh> + +#include "../data-structures/globalfrictioncontainer.hh" + +struct Body { + size_t id; + size_t localAlpha; + + void updateAlpha(size_t lAlpha) { + localAlpha = lAlpha; + } +}; + +int main(int argc, char *argv[]) { + try { + Dune::MPIHelper::instance(argc, argv); + + std::cout << "--------------------------" << std::endl; + std::cout << "-- GlobalFriction Test: --" << std::endl; + std::cout << "--------------------------" << std::endl << std::endl; + + // have to be <10 + size_t n = 5; + size_t m = 3; + size_t l = 2; + + std::vector<std::vector<int>> ref; + ref.resize(n); + for (size_t i=0; i<n; i++) { + ref[i].resize(m); + for (size_t j=0; j<m; j++) { + ref[i][j] = 10*i + j; + } + } + + // resize() test + bool resizeTest = true; + { + GlobalFrictionContainer<Body,1> globalFriction1; + globalFriction1.resize({n}); + resizeTest = resizeTest & (globalFriction1.size() == n); + + GlobalFrictionContainer<Body,2> globalFriction2; + globalFriction2.resize({n}); + resizeTest = resizeTest & (globalFriction2.size() == n); + + for (size_t i=0; i<globalFriction2.size(); i++) { + resizeTest = resizeTest & (globalFriction2[i].size() == 0); + } + } + + // operator[] test + bool operatorTest = true; + { + GlobalFrictionContainer<Body,2> globalFriction; + globalFriction.resize({n, m}); + operatorTest = operatorTest & (globalFriction.size() == n); + + for (size_t i=0; i<n; i++) { + for (size_t j=0; j<m; j++) { + operatorTest = operatorTest & (globalFriction[i][j] == nullptr); + } + } + } + + // updateAlpha() test + bool updateTest = true; + { + GlobalFrictionContainer<Body,3> globalFriction; + globalFriction.resize({n,m,l}); + + for (size_t i=0; i<n; i++) { + for (size_t j=0; j<m; j++) { + for (size_t k=0; k<l; k++) { + globalFriction[i][j][k] = std::make_shared<Body>(); + globalFriction[i][j][k]->id = 10*i + j; + } + } + } + + globalFriction.updateAlpha(ref); + + for (size_t i=0; i<n; i++) { + for (size_t j=0; j<m; j++) { + for (size_t k=0; k<l; k++) { + updateTest = updateTest & (globalFriction[i][j][k]->id == globalFriction[i][j][k]->localAlpha); + } + } + } + + } + + std::cout << "resize(): " << resizeTest << std::endl; + std::cout << "operator[]: " << operatorTest << std::endl; + std::cout << "updateAlpha(): " << updateTest << std::endl; + std::cout << "-------------------------" << std::endl << std::endl; + + bool passed = resizeTest & operatorTest & updateTest; + + std::cout << "Overall the test " << (passed ? "was successful!" : "failed!") << std::endl; + + return passed ? 0 : 1; + + } catch (Dune::Exception &e) { + Dune::derr << "Dune reported error: " << e << std::endl; + } catch (std::exception &e) { + std::cerr << "Standard exception: " << e.what() << std::endl; + } +} diff --git a/src/time-stepping/adaptivetimestepper.cc b/src/time-stepping/adaptivetimestepper.cc index 1c36768ee8fb049be3a357b57d053c5a58e6a61c..cde9e81d81cb6d445e4acdc8aec166be90c56d45 100644 --- a/src/time-stepping/adaptivetimestepper.cc +++ b/src/time-stepping/adaptivetimestepper.cc @@ -20,9 +20,9 @@ void IterationRegister::reset() { template <class Factory, class Updaters, class ErrorNorm> AdaptiveTimeStepper<Factory, Updaters, ErrorNorm>::AdaptiveTimeStepper( Factory &factory, Dune::ParameterTree const &parset, - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction, Updaters ¤t, + GlobalFrictionContainer& globalFriction, Updaters ¤t, double relativeTime, double relativeTau, - std::vector<std::function<void(double, Vector &)>>& externalForces, + ExternalForces& externalForces, const std::vector<const ErrorNorm* >& errorNorms, std::function<bool(Updaters &, Updaters &)> mustRefine) : relativeTime_(relativeTime), diff --git a/src/time-stepping/adaptivetimestepper.hh b/src/time-stepping/adaptivetimestepper.hh index f7897a2906dbf22d53cc5bf334abb329cc437ddc..7b251fade0bb1709a209bacae861c696593a6050 100644 --- a/src/time-stepping/adaptivetimestepper.hh +++ b/src/time-stepping/adaptivetimestepper.hh @@ -24,16 +24,19 @@ class AdaptiveTimeStepper { using Vector = typename Factory::Vector; //using ConvexProblem = typename Factory::ConvexProblem; - using Nonlinearity = typename Factory::Nonlinearity; + //using Nonlinearity = typename Factory::Nonlinearity; using MyCoupledTimeStepper = CoupledTimeStepper<Factory, Updaters, ErrorNorm>; + using GlobalFrictionContainer = typename MyCoupledTimeStepper::GlobalFrictionContainer; + using ExternalForces = typename MyCoupledTimeStepper::ExternalForces; + public: AdaptiveTimeStepper(Factory &factory, Dune::ParameterTree const &parset, - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction, + GlobalFrictionContainer& globalFriction, Updaters ¤t, double relativeTime, double relativeTau, - std::vector<std::function<void(double, Vector &)>>& externalForces, + ExternalForces& externalForces, const std::vector<const ErrorNorm* >& errorNorms, std::function<bool(Updaters &, Updaters &)> mustRefine); @@ -50,10 +53,10 @@ class AdaptiveTimeStepper { double finalTime_; Factory &factory_; Dune::ParameterTree const &parset_; - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction_; + GlobalFrictionContainer& globalFriction_; Updaters ¤t_; UpdatersWithCount R1_; - std::vector<std::function<void(double, Vector &)>>& externalForces_; + ExternalForces& externalForces_; std::function<bool(Updaters &, Updaters &)> mustRefine_; const std::vector<const ErrorNorm* >& errorNorms_; diff --git a/src/time-stepping/adaptivetimestepper_tmpl.cc b/src/time-stepping/adaptivetimestepper_tmpl.cc index 97c383edff112abcd9c782cc6d50bc2860cf3e33..4f11f38799fb9caa92e811342a2ac15da900a5e5 100644 --- a/src/time-stepping/adaptivetimestepper_tmpl.cc +++ b/src/time-stepping/adaptivetimestepper_tmpl.cc @@ -13,15 +13,18 @@ #include <dune/tectonic/globalfriction.hh> #include <dune/tectonic/myblockproblem.hh> +#include "../data-structures/levelcontactnetwork.hh" #include "../spatial-solving/solverfactory.hh" #include "rate/rateupdater.hh" #include "state/stateupdater.hh" #include "updaters.hh" -using Function = Dune::VirtualFunction<double, double>; +using BoundaryNodes = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryNodes; +using BoundaryFunctions = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryFunctions; + using Factory = SolverFactory<DeformedGrid, GlobalFriction<Matrix, Vector>, Matrix, Vector>; using MyStateUpdater = StateUpdater<ScalarVector, Vector>; -using MyRateUpdater = RateUpdater<Vector, Matrix, Function, MY_DIM>; +using MyRateUpdater = RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>; using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>; using ErrorNorm = EnergyNorm<ScalarMatrix, ScalarVector>; diff --git a/src/time-stepping/coupledtimestepper.cc b/src/time-stepping/coupledtimestepper.cc index 74e66fc80594a18a69db83932038372c538882b0..e06ce73233e419f737b8455c354b3fe3ad5e0c61 100644 --- a/src/time-stepping/coupledtimestepper.cc +++ b/src/time-stepping/coupledtimestepper.cc @@ -7,9 +7,9 @@ template <class Factory, class Updaters, class ErrorNorm> CoupledTimeStepper<Factory, Updaters, ErrorNorm>::CoupledTimeStepper( double finalTime, Factory &factory, Dune::ParameterTree const &parset, - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction, Updaters updaters, + GlobalFrictionContainer& globalFriction, Updaters updaters, const std::vector<const ErrorNorm* >& errorNorms, - std::vector<std::function<void(double, Vector &)>>& externalForces) + ExternalForces& externalForces) : finalTime_(finalTime), factory_(factory), parset_(parset), @@ -28,7 +28,7 @@ CoupledTimeStepper<Factory, Updaters, ErrorNorm>::step(double relativeTime, auto const newRelativeTime = relativeTime + relativeTau; std::vector<Vector> ell(externalForces_.size()); for (size_t i=0; i<externalForces_.size(); i++) { - externalForces_[i](newRelativeTime, ell[i]); + (*externalForces_[i])(newRelativeTime, ell[i]); } std::vector<Matrix> velocityMatrix; diff --git a/src/time-stepping/coupledtimestepper.hh b/src/time-stepping/coupledtimestepper.hh index 97c0128243e64a9431c7a80ea9ce9dc1eab1342c..81a53c6fd5bd286dee6951a4eb6a64fbae9fb923 100644 --- a/src/time-stepping/coupledtimestepper.hh +++ b/src/time-stepping/coupledtimestepper.hh @@ -12,14 +12,17 @@ template <class Factory, class Updaters, class ErrorNorm> class CoupledTimeStepper { using Vector = typename Factory::Vector; using Matrix = typename Factory::Matrix; - using Nonlinearity = typename Factory::Nonlinearity; + //using Nonlinearity = typename Factory::Nonlinearity; +public: + using GlobalFrictionContainer = typename FixedPointIterator<Factory, Updaters, ErrorNorm>::GlobalFrictionContainer; + using ExternalForces = std::vector<const std::function<void(double, Vector &)>*>; public: CoupledTimeStepper(double finalTime, Factory &factory, Dune::ParameterTree const &parset, - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction, + GlobalFrictionContainer& globalFriction, Updaters updaters, const std::vector<const ErrorNorm* >& errorNorms, - std::vector<std::function<void(double, Vector &)>>& externalForces); + ExternalForces& externalForces); FixedPointIterationCounter step(double relativeTime, double relativeTau); @@ -27,9 +30,9 @@ class CoupledTimeStepper { double finalTime_; Factory &factory_; Dune::ParameterTree const &parset_; - std::vector<std::shared_ptr<Nonlinearity>>& globalFriction_; + GlobalFrictionContainer& globalFriction_; Updaters updaters_; - std::vector<std::function<void(double, Vector &)>>& externalForces_; + ExternalForces& externalForces_; const std::vector<const ErrorNorm* >& errorNorms_; }; #endif diff --git a/src/time-stepping/coupledtimestepper_tmpl.cc b/src/time-stepping/coupledtimestepper_tmpl.cc index a2bd2dfa43a144219f95c7793de0520f85fea1c5..e16e9df9c948a02153eb818a75334410cd1fd88b 100644 --- a/src/time-stepping/coupledtimestepper_tmpl.cc +++ b/src/time-stepping/coupledtimestepper_tmpl.cc @@ -13,16 +13,19 @@ #include <dune/tectonic/globalfriction.hh> #include <dune/tectonic/myblockproblem.hh> +#include "../data-structures/levelcontactnetwork.hh" #include "../spatial-solving/solverfactory.hh" #include "rate/rateupdater.hh" #include "state/stateupdater.hh" #include "updaters.hh" -using Function = Dune::VirtualFunction<double, double>; +using BoundaryNodes = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryNodes; +using BoundaryFunctions = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryFunctions; + using Factory = SolverFactory<DeformedGrid, GlobalFriction<Matrix, Vector>, Matrix, Vector>; using MyStateUpdater = StateUpdater<ScalarVector, Vector>; -using MyRateUpdater = RateUpdater<Vector, Matrix, Function, MY_DIM>; +using MyRateUpdater = RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>; using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>; using ErrorNorm = EnergyNorm<ScalarMatrix, ScalarVector>; diff --git a/src/time-stepping/rate.cc b/src/time-stepping/rate.cc index b94a2a353cef977101784289a2a88633119a65eb..5ff412aac0f72b4b9b81315e2b8e72716ebe8435 100644 --- a/src/time-stepping/rate.cc +++ b/src/time-stepping/rate.cc @@ -6,23 +6,24 @@ #include "rate/backward_euler.hh" #include "rate/newmark.hh" -template <class Vector, class Matrix, class Function, int dimension> -std::shared_ptr<RateUpdater<Vector, Matrix, Function, dimension>> -initRateUpdater(Config::scheme scheme, - const std::vector<const Function*>& velocityDirichletFunctions, - const std::vector<Dune::BitSetVector<dimension>>& velocityDirichletNodes, +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +auto initRateUpdater(Config::scheme scheme, + const BoundaryFunctions& velocityDirichletFunctions, + const BoundaryNodes& velocityDirichletNodes, const Matrices<Matrix,2>& matrices, const std::vector<Vector>& u_initial, const std::vector<Vector>& v_initial, - const std::vector<Vector>& a_initial) { + const std::vector<Vector>& a_initial) +-> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>> { + switch (scheme) { case Config::Newmark: - return std::make_shared<Newmark<Vector, Matrix, Function, dimension>>( + return std::make_shared<Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>>( matrices, u_initial, v_initial, a_initial, velocityDirichletNodes, velocityDirichletFunctions); case Config::BackwardEuler: return std::make_shared< - BackwardEuler<Vector, Matrix, Function, dimension>>( + BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>>( matrices, u_initial, v_initial, a_initial, velocityDirichletNodes, velocityDirichletFunctions); default: diff --git a/src/time-stepping/rate.hh b/src/time-stepping/rate.hh index 8a3cc285779d0918bc93c25066eb4a924039e99e..4497a4e1e4c598182402d8d00a46c00c7910cbcf 100644 --- a/src/time-stepping/rate.hh +++ b/src/time-stepping/rate.hh @@ -6,13 +6,13 @@ #include "../data-structures/enums.hh" #include "rate/rateupdater.hh" -template <class Vector, class Matrix, class Function, int dimension> -std::shared_ptr<RateUpdater<Vector, Matrix, Function, dimension>> -initRateUpdater(Config::scheme scheme, - const std::vector<const Function* >& velocityDirichletFunctions, - const std::vector<std::vector<Dune::BitSetVector<dimension>>>& velocityDirichletNodes, +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +auto initRateUpdater(Config::scheme scheme, + const BoundaryFunctions& velocityDirichletFunctions, + const BoundaryNodes& velocityDirichletNodes, const Matrices<Matrix,2>& matrices, const std::vector<Vector>& u_initial, const std::vector<Vector>& v_initial, - const std::vector<Vector>& a_initial); + const std::vector<Vector>& a_initial) +-> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>>; #endif diff --git a/src/time-stepping/rate/backward_euler.cc b/src/time-stepping/rate/backward_euler.cc index c4845782846180f98dabf1283415bef265ec6ad3..b7a915f9c1e38b9252543e72af4de1384198b94f 100644 --- a/src/time-stepping/rate/backward_euler.cc +++ b/src/time-stepping/rate/backward_euler.cc @@ -3,102 +3,121 @@ #include "backward_euler.hh" -template <class Vector, class Matrix, class Function, size_t dim> -BackwardEuler<Vector, Matrix, Function, dim>::BackwardEuler( - const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, - const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, - const std::vector<Dune::BitSetVector<dim>>& _dirichletNodes, - const std::vector<const Function*>& _dirichletFunctions) - : RateUpdater<Vector, Matrix, Function, dim>( - _matrices, _u_initial, _v_initial, _a_initial, _dirichletNodes, - _dirichletFunctions) {} - -template <class Vector, class Matrix, class Function, size_t dim> -void BackwardEuler<Vector, Matrix, Function, dim>::setup(const std::vector<Vector>& ell, - double _tau, - double relativeTime, - std::vector<Vector>& rhs, std::vector<Vector>& iterate, - std::vector<Matrix>& AM) { - for (size_t i=0; i<this->u.size(); i++) { - this->dirichletFunctions[i]->evaluate(relativeTime, this->dirichletValue); - this->tau = _tau; - - /* We start out with the formulation - - M a + C v + A u = ell - - Backward Euler means - - a1 = 1.0/tau ( v1 - v0 ) - u1 = tau v1 + u0 - - in summary, we get at time t=1 - - M [1.0/tau ( v1 - v0 )] + C v1 - + A [tau v1 + u0] = ell - - or - - 1.0/tau M v1 + C v1 + tau A v1 - = [1.0/tau M + C + tau A] v1 - = ell + 1.0/tau M v0 - A u0 - */ - - // set up LHS (for fixed tau, we'd only really have to do this once) - Matrix& LHS = AM[i]; - { - Dune::MatrixIndexSet indices(this->matrices.elasticity[i]->N(), - this->matrices.elasticity[i]->M()); - indices.import(*this->matrices.elasticity[i]); - indices.import(*this->matrices.mass[i]); - indices.import(*this->matrices.damping[i]); - indices.exportIdx(LHS); - } - LHS = 0.0; - Dune::MatrixVector::addProduct(LHS, 1.0 / this->tau, *this->matrices.mass[i]); - Dune::MatrixVector::addProduct(LHS, 1.0, *this->matrices.damping[i]); - Dune::MatrixVector::addProduct(LHS, this->tau, *this->matrices.elasticity[i]); - - // set up RHS - { - Vector& rhss = rhs[i]; - rhss = ell[i]; - Dune::MatrixVector::addProduct(rhss, 1.0 / this->tau, *this->matrices.mass[i], +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::BackwardEuler( + const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, + const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, + const BoundaryNodes& _dirichletNodes, + const BoundaryFunctions& _dirichletFunctions) : + RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>( + _matrices, _u_initial, _v_initial, _a_initial, _dirichletNodes, + _dirichletFunctions) {} + +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::setup( + const std::vector<Vector>& ell, + double _tau, + double relativeTime, + std::vector<Vector>& rhs, std::vector<Vector>& iterate, + std::vector<Matrix>& AM) { + + for (size_t i=0; i<this->u.size(); i++) { + this->tau = _tau; + + /* We start out with the formulation + + M a + C v + A u = ell + + Backward Euler means + + a1 = 1.0/tau ( v1 - v0 ) + u1 = tau v1 + u0 + + in summary, we get at time t=1 + + M [1.0/tau ( v1 - v0 )] + C v1 + + A [tau v1 + u0] = ell + + or + + 1.0/tau M v1 + C v1 + tau A v1 + = [1.0/tau M + C + tau A] v1 + = ell + 1.0/tau M v0 - A u0 + */ + + // set up LHS (for fixed tau, we'd only really have to do this once) + Matrix& LHS = AM[i]; + { + Dune::MatrixIndexSet indices( + this->matrices.elasticity[i]->N(), + this->matrices.elasticity[i]->M()); + indices.import(*this->matrices.elasticity[i]); + indices.import(*this->matrices.mass[i]); + indices.import(*this->matrices.damping[i]); + indices.exportIdx(LHS); + } + LHS = 0.0; + Dune::MatrixVector::addProduct(LHS, 1.0 / this->tau, *this->matrices.mass[i]); + Dune::MatrixVector::addProduct(LHS, 1.0, *this->matrices.damping[i]); + Dune::MatrixVector::addProduct(LHS, this->tau, *this->matrices.elasticity[i]); + + // set up RHS + { + Vector& rhss = rhs[i]; + rhss = ell[i]; + Dune::MatrixVector::addProduct(rhss, 1.0 / this->tau, *this->matrices.mass[i], this->v_o[i]); - Dune::MatrixVector::subtractProduct(rhss, *this->matrices.elasticity[i], this->u_o[i]); + Dune::MatrixVector::subtractProduct(rhss, *this->matrices.elasticity[i], this->u_o[i]); + } + } iterate = this->v_o; - const Dune::BitSetVector<dim>& dirichletNodess = this->dirichletNodes[i]; - for (size_t k = 0; k < dirichletNodess.size(); ++k) - for (size_t j = 0; j < dim; ++j) - if (dirichletNodess[k][j]) - iterate[k][j] = (j == 0) ? this->dirichletValue : 0; - } + for (size_t i=0; i<iterate.size(); i++) { + auto& bodyIterate = iterate[i]; + + const auto& bodyDirichletNodes = this->dirichletNodes[i]; + const auto& bodyDirichletFunctions = this->dirichletFunctions[i]; + for (size_t bc=0; bc<bodyDirichletNodes.size(); ++bc) { + const auto& bcDirichletNodes = *bodyDirichletNodes[bc]; + size_t dim = bcDirichletNodes[0].size(); + + double dirichletValue; + bodyDirichletFunctions[bc]->evaluate(relativeTime, dirichletValue); + + for (size_t k=0; k<bcDirichletNodes.size() ; ++k) { + for (size_t j=0; j<dim; ++j) { + if (bcDirichletNodes[k][j]) { + iterate[k][j] = dirichletValue; + } + } + } + } + } } -template <class Vector, class Matrix, class Function, size_t dim> -void BackwardEuler<Vector, Matrix, Function, dim>::postProcess( - const std::vector<Vector>& iterate) { - this->postProcessCalled = true; +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::postProcess(const std::vector<Vector>& iterate) { + this->postProcessCalled = true; - this->v = iterate; + this->v = iterate; - this->u = this->u_o; + this->u = this->u_o; - for (size_t i=0; i<this->u.size(); i++) { - Dune::MatrixVector::addProduct(this->u[i], this->tau, this->v[i]); + for (size_t i=0; i<this->u.size(); i++) { + Dune::MatrixVector::addProduct(this->u[i], this->tau, this->v[i]); - Vector& ai = this->a[i]; - ai = this->v[i]; - ai -= this->v_o[i]; - ai /= this->tau; - } + Vector& ai = this->a[i]; + ai = this->v[i]; + ai -= this->v_o[i]; + ai /= this->tau; + } } -template <class Vector, class Matrix, class Function, size_t dim> -std::shared_ptr<RateUpdater<Vector, Matrix, Function, dim>> -BackwardEuler<Vector, Matrix, Function, dim>::clone() const { - return std::make_shared<BackwardEuler<Vector, Matrix, Function, dim>>(*this); +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +auto BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::clone() const +-> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>> { + + return std::make_shared<BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>>(*this); } diff --git a/src/time-stepping/rate/backward_euler.hh b/src/time-stepping/rate/backward_euler.hh index 26e5831d26a184a51d17af729837225294dca122..bb48a2550bb64672b4ab0092b91764e46346477b 100644 --- a/src/time-stepping/rate/backward_euler.hh +++ b/src/time-stepping/rate/backward_euler.hh @@ -1,22 +1,27 @@ #ifndef SRC_TIME_STEPPING_RATE_BACKWARD_EULER_HH #define SRC_TIME_STEPPING_RATE_BACKWARD_EULER_HH -template <class Vector, class Matrix, class Function, size_t dim> -class BackwardEuler : public RateUpdater<Vector, Matrix, Function, dim> { +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +class BackwardEuler : public RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes> { public: - BackwardEuler(const Matrices<Matrix,2> &_matrices, const std::vector<Vector> &_u_initial, - const std::vector<Vector> &_v_initial, const std::vector<Vector> &_a_initial, - const std::vector<Dune::BitSetVector<dim> > &_dirichletNodes, - const std::vector<const Function*> &_dirichletFunctions); + BackwardEuler( + const Matrices<Matrix,2> &_matrices, + const std::vector<Vector> &_u_initial, + const std::vector<Vector> &_v_initial, + const std::vector<Vector> &_a_initial, + const BoundaryNodes& _dirichletNodes, + const BoundaryFunctions& _dirichletFunctions); - void setup(const std::vector<Vector>&, double, double, std::vector<Vector>&, std::vector<Vector>&, - std::vector<Matrix>&) override; + virtual void setup( + const std::vector<Vector>&, + double, + double, + std::vector<Vector>&, + std::vector<Vector>&, + std::vector<Matrix>&) override; - void postProcess(const std::vector<Vector>&) override; + virtual void postProcess(const std::vector<Vector>&) override; - std::shared_ptr<RateUpdater<Vector, Matrix, Function, dim>> clone() - const override; - -private: + virtual auto clone() const -> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>> override; }; #endif diff --git a/src/time-stepping/rate/newmark.cc b/src/time-stepping/rate/newmark.cc index b3fb46699fb58f959a6e0ef891ffc0cdca3bae06..2961e7e8885a92681c35fe0b8f48aa7d76d2cee4 100644 --- a/src/time-stepping/rate/newmark.cc +++ b/src/time-stepping/rate/newmark.cc @@ -3,108 +3,127 @@ #include "newmark.hh" -template <class Vector, class Matrix, class Function, size_t dim> -Newmark<Vector, Matrix, Function, dim>::Newmark( - const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, - const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, - const std::vector<Dune::BitSetVector<dim>>& _dirichletNodes, - const std::vector<const Function*>& _dirichletFunctions) - : RateUpdater<Vector, Matrix, Function, dim>( - _matrices, _u_initial, _v_initial, _a_initial, _dirichletNodes, - _dirichletFunctions) {} - -template <class Vector, class Matrix, class Function, size_t dim> -void Newmark<Vector, Matrix, Function, dim>::setup(const std::vector<Vector>& ell, - double _tau, - double relativeTime, - std::vector<Vector>& rhs, std::vector<Vector>& iterate, - std::vector<Matrix>& AM) { - for (size_t i=0; i<this->u.size(); i++) { - this->dirichletFunctions[i]->evaluate(relativeTime, this->dirichletValue); - this->tau = _tau; - - /* We start out with the formulation - - M a + C v + A u = ell - - Newmark means - - a1 = 2/tau ( v1 - v0 ) - a0 - u1 = tau/2 ( v1 + v0 ) + u0 - - in summary, we get at time t=1 - - M [2/tau ( u1 - u0 ) - a0] + C v1 - + A [tau/2 ( v1 + v0 ) + u0] = ell - - or - - 2/tau M v1 + C v1 + tau/2 A v1 - = [2/tau M + C + tau/2 A] v1 - = ell + 2/tau M v0 + M a0 - - tau/2 A v0 - A u0 - */ - - // set up LHS (for fixed tau, we'd only really have to do this once) - Matrix& LHS = AM[i]; - { - Dune::MatrixIndexSet indices(this->matrices.elasticity[i]->N(), - this->matrices.elasticity[i]->M()); - indices.import(*this->matrices.elasticity[i]); - indices.import(*this->matrices.mass[i]); - indices.import(*this->matrices.damping[i]); - indices.exportIdx(LHS); - } - LHS = 0.0; - Dune::MatrixVector::addProduct(LHS, 2.0 / this->tau, *this->matrices.mass[i]); - Dune::MatrixVector::addProduct(LHS, 1.0, *this->matrices.damping[i]); - Dune::MatrixVector::addProduct(LHS, this->tau / 2.0, *this->matrices.elasticity[i]); - - // set up RHS - { - Vector& rhss = rhs[i]; - rhss = ell[i]; - Dune::MatrixVector::addProduct(rhss, 2.0 / this->tau, *this->matrices.mass[i], +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::Newmark( + const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, + const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, + const BoundaryNodes& _dirichletNodes, + const BoundaryFunctions& _dirichletFunctions) : + RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>( + _matrices, _u_initial, _v_initial, _a_initial, _dirichletNodes, + _dirichletFunctions) {} + +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::setup( + const std::vector<Vector>& ell, + double _tau, + double relativeTime, + std::vector<Vector>& rhs, std::vector<Vector>& iterate, + std::vector<Matrix>& AM) { + + for (size_t i=0; i<this->u.size(); i++) { + this->tau = _tau; + + /* We start out with the formulation + + M a + C v + A u = ell + + Newmark means + + a1 = 2/tau ( v1 - v0 ) - a0 + u1 = tau/2 ( v1 + v0 ) + u0 + + in summary, we get at time t=1 + + M [2/tau ( u1 - u0 ) - a0] + C v1 + + A [tau/2 ( v1 + v0 ) + u0] = ell + + or + + 2/tau M v1 + C v1 + tau/2 A v1 + = [2/tau M + C + tau/2 A] v1 + = ell + 2/tau M v0 + M a0 + - tau/2 A v0 - A u0 + */ + + // set up LHS (for fixed tau, we'd only really have to do this once) + Matrix& LHS = AM[i]; + { + Dune::MatrixIndexSet indices( + this->matrices.elasticity[i]->N(), + this->matrices.elasticity[i]->M()); + indices.import(*this->matrices.elasticity[i]); + indices.import(*this->matrices.mass[i]); + indices.import(*this->matrices.damping[i]); + indices.exportIdx(LHS); + } + LHS = 0.0; + Dune::MatrixVector::addProduct(LHS, 2.0 / this->tau, *this->matrices.mass[i]); + Dune::MatrixVector::addProduct(LHS, 1.0, *this->matrices.damping[i]); + Dune::MatrixVector::addProduct(LHS, this->tau / 2.0, *this->matrices.elasticity[i]); + + // set up RHS + { + Vector& rhss = rhs[i]; + rhss = ell[i]; + Dune::MatrixVector::addProduct(rhss, 2.0 / this->tau, *this->matrices.mass[i], + this->v_o[i]); + Dune::MatrixVector::addProduct(rhss, *this->matrices.mass[i], this->a_o[i]); + Dune::MatrixVector::subtractProduct(rhss, this->tau / 2.0, *this->matrices.elasticity[i], this->v_o[i]); - Dune::MatrixVector::addProduct(rhss, *this->matrices.mass[i], this->a_o[i]); - Dune::MatrixVector::subtractProduct(rhss, this->tau / 2.0, *this->matrices.elasticity[i], - this->v_o[i]); - Dune::MatrixVector::subtractProduct(rhss, *this->matrices.elasticity[i], this->u_o[i]); + Dune::MatrixVector::subtractProduct(rhss, *this->matrices.elasticity[i], this->u_o[i]); + } } iterate = this->v_o; - const Dune::BitSetVector<dim>& dirichletNodess = this->dirichletNodes[i]; - for (size_t k = 0; k < dirichletNodess.size(); ++k) - for (size_t j = 0; j < dim; ++j) - if (dirichletNodess[k][j]) - iterate[k][j] = (j == 0) ? this->dirichletValue : 0; - } + for (size_t i=0; i<iterate.size(); i++) { + auto& bodyIterate = iterate[i]; + + const auto& bodyDirichletNodes = this->dirichletNodes[i]; + const auto& bodyDirichletFunctions = this->dirichletFunctions[i]; + for (size_t bc=0; bc<bodyDirichletNodes.size(); ++bc) { + const auto& bcDirichletNodes = *bodyDirichletNodes[bc]; + size_t dim = bcDirichletNodes[0].size(); + + double dirichletValue; + bodyDirichletFunctions[bc]->evaluate(relativeTime, dirichletValue); + + for (size_t k=0; k<bcDirichletNodes.size() ; ++k) { + for (size_t j=0; j<dim; ++j) { + if (bcDirichletNodes[k][j]) { + iterate[k][j] = dirichletValue; + } + } + } + } + } } -template <class Vector, class Matrix, class Function, size_t dim> -void Newmark<Vector, Matrix, Function, dim>::postProcess(const std::vector<Vector>& iterate) { - this->postProcessCalled = true; +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::postProcess(const std::vector<Vector>& iterate) { + this->postProcessCalled = true; - this->v = iterate; + this->v = iterate; - // u1 = tau/2 ( v1 + v0 ) + u0 - this->u = this->u_o; + // u1 = tau/2 ( v1 + v0 ) + u0 + this->u = this->u_o; - for (size_t i=0; i<this->u.size(); i++) { - Dune::MatrixVector::addProduct(this->u[i], this->tau / 2.0, this->v[i]); - Dune::MatrixVector::addProduct(this->u[i], this->tau / 2.0, this->v_o[i]); + for (size_t i=0; i<this->u.size(); i++) { + Dune::MatrixVector::addProduct(this->u[i], this->tau / 2.0, this->v[i]); + Dune::MatrixVector::addProduct(this->u[i], this->tau / 2.0, this->v_o[i]); - // a1 = 2/tau ( v1 - v0 ) - a0 - this->a[i] = 0.0; - Dune::MatrixVector::addProduct(this->a[i], 2.0 / this->tau, this->v[i]); - Dune::MatrixVector::subtractProduct(this->a[i], 2.0 / this->tau, this->v_o[i]); - Dune::MatrixVector::subtractProduct(this->a[i], 1.0, this->a_o[i]); - } + // a1 = 2/tau ( v1 - v0 ) - a0 + this->a[i] = 0.0; + Dune::MatrixVector::addProduct(this->a[i], 2.0 / this->tau, this->v[i]); + Dune::MatrixVector::subtractProduct(this->a[i], 2.0 / this->tau, this->v_o[i]); + Dune::MatrixVector::subtractProduct(this->a[i], 1.0, this->a_o[i]); + } } -template <class Vector, class Matrix, class Function, size_t dim> -std::shared_ptr<RateUpdater<Vector, Matrix, Function, dim>> -Newmark<Vector, Matrix, Function, dim>::clone() const { - return std::make_shared<Newmark<Vector, Matrix, Function, dim>>(*this); +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +auto Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::clone() const +-> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>> { + + return std::make_shared<Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>>(*this); } diff --git a/src/time-stepping/rate/newmark.hh b/src/time-stepping/rate/newmark.hh index 9041e01dc066dde3a03b9285930aaf595598af95..4aef6caf6b2c24ac36754c647350e1f68f641c60 100644 --- a/src/time-stepping/rate/newmark.hh +++ b/src/time-stepping/rate/newmark.hh @@ -1,20 +1,27 @@ #ifndef SRC_TIME_STEPPING_RATE_NEWMARK_HH #define SRC_TIME_STEPPING_RATE_NEWMARK_HH -template <class Vector, class Matrix, class Function, size_t dim> -class Newmark : public RateUpdater<Vector, Matrix, Function, dim> { +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +class Newmark : public RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes> { public: - Newmark(const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, - const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, - const std::vector<Dune::BitSetVector<dim>>& _dirichletNodes, - const std::vector<const Function*>& _dirichletFunctions); + Newmark( + const Matrices<Matrix,2>& _matrices, + const std::vector<Vector>& _u_initial, + const std::vector<Vector>& _v_initial, + const std::vector<Vector>& _a_initial, + const BoundaryNodes& _dirichletNodes, + const BoundaryFunctions& _dirichletFunctions); - void setup(const std::vector<Vector>&, double, double, std::vector<Vector>&, std::vector<Vector>&, - std::vector<Matrix>&) override; + virtual void setup( + const std::vector<Vector>&, + double, + double, + std::vector<Vector>&, + std::vector<Vector>&, + std::vector<Matrix>&) override; - void postProcess(const std::vector<Vector>&) override; + virtual void postProcess(const std::vector<Vector>&) override; - std::shared_ptr<RateUpdater<Vector, Matrix, Function, dim>> clone() - const override; + virtual auto clone() const -> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>> override; }; #endif diff --git a/src/time-stepping/rate/rateupdater.cc b/src/time-stepping/rate/rateupdater.cc index fb2e22a2d78caa630774df09d9d1aa79cd1b52c2..aa29295b7b8e6d8ac8c209e5d484beb624ad3531 100644 --- a/src/time-stepping/rate/rateupdater.cc +++ b/src/time-stepping/rate/rateupdater.cc @@ -4,12 +4,12 @@ #include "rateupdater.hh" -template <class Vector, class Matrix, class Function, size_t dim> -RateUpdater<Vector, Matrix, Function, dim>::RateUpdater( +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::RateUpdater( const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, - const std::vector<Dune::BitSetVector<dim>>& _dirichletNodes, - const std::vector<const Function*>& _dirichletFunctions) + const BoundaryNodes& _dirichletNodes, + const BoundaryFunctions& _dirichletFunctions) : matrices(_matrices), u(_u_initial), v(_v_initial), @@ -17,41 +17,41 @@ RateUpdater<Vector, Matrix, Function, dim>::RateUpdater( dirichletNodes(_dirichletNodes), dirichletFunctions(_dirichletFunctions) {} -template <class Vector, class Matrix, class Function, size_t dim> -void RateUpdater<Vector, Matrix, Function, dim>::nextTimeStep() { - u_o = u; - v_o = v; - a_o = a; - postProcessCalled = false; +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::nextTimeStep() { + u_o = u; + v_o = v; + a_o = a; + postProcessCalled = false; } -template <class Vector, class Matrix, class Function, size_t dim> -void RateUpdater<Vector, Matrix, Function, dim>::extractDisplacement(std::vector<Vector>& displacements) const { - if (!postProcessCalled) - DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!"); +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::extractDisplacement(std::vector<Vector>& displacements) const { + if (!postProcessCalled) + DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!"); - displacements = u; + displacements = u; } -template <class Vector, class Matrix, class Function, size_t dim> -void RateUpdater<Vector, Matrix, Function, dim>::extractVelocity(std::vector<Vector>& velocity) const { - if (!postProcessCalled) - DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!"); +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::extractVelocity(std::vector<Vector>& velocity) const { + if (!postProcessCalled) + DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!"); - velocity = v; + velocity = v; } -template <class Vector, class Matrix, class Function, size_t dim> -void RateUpdater<Vector, Matrix, Function, dim>::extractOldVelocity(std::vector<Vector>& oldVelocity) const { - oldVelocity = v_o; +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::extractOldVelocity(std::vector<Vector>& oldVelocity) const { + oldVelocity = v_o; } -template <class Vector, class Matrix, class Function, size_t dim> -void RateUpdater<Vector, Matrix, Function, dim>::extractAcceleration(std::vector<Vector>& acceleration) const { - if (!postProcessCalled) - DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!"); +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> +void RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::extractAcceleration(std::vector<Vector>& acceleration) const { + if (!postProcessCalled) + DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!"); - acceleration = a; + acceleration = a; } #include "backward_euler.cc" diff --git a/src/time-stepping/rate/rateupdater.hh b/src/time-stepping/rate/rateupdater.hh index a9819ff5894f14673cc944451b774676426ce227..5c06af42f058a98912699ecbf3b99b4b772499f0 100644 --- a/src/time-stepping/rate/rateupdater.hh +++ b/src/time-stepping/rate/rateupdater.hh @@ -7,18 +7,26 @@ #include "../../data-structures/matrices.hh" -template <class Vector, class Matrix, class Function, size_t dim> +template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes> class RateUpdater { protected: - RateUpdater(const Matrices<Matrix,2>& _matrices, const std::vector<Vector>& _u_initial, - const std::vector<Vector>& _v_initial, const std::vector<Vector>& _a_initial, - const std::vector<Dune::BitSetVector<dim>>& _dirichletNodes, - const std::vector<const Function*>& _dirichletFunctions); + RateUpdater( + const Matrices<Matrix,2>& _matrices, + const std::vector<Vector>& _u_initial, + const std::vector<Vector>& _v_initial, + const std::vector<Vector>& _a_initial, + const BoundaryNodes& _dirichletNodes, + const BoundaryFunctions& _dirichletFunctions); public: - void nextTimeStep(); - void virtual setup(const std::vector<Vector>& ell, double _tau, double relativeTime, - std::vector<Vector>& rhs, std::vector<Vector>& iterate, std::vector<Matrix>& AB) = 0; + void nextTimeStep(); + void virtual setup( + const std::vector<Vector>& ell, + double _tau, + double relativeTime, + std::vector<Vector>& rhs, + std::vector<Vector>& iterate, + std::vector<Matrix>& AB) = 0; void virtual postProcess(const std::vector<Vector>& iterate) = 0; void extractDisplacement(std::vector<Vector>& displacements) const; @@ -26,15 +34,13 @@ class RateUpdater { void extractOldVelocity(std::vector<Vector>& velocity) const; void extractAcceleration(std::vector<Vector>& acceleration) const; - std::shared_ptr<RateUpdater<Vector, Matrix, Function, dim>> virtual clone() - const = 0; + std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>> virtual clone() const = 0; protected: const Matrices<Matrix,2>& matrices; std::vector<Vector> u, v, a; - const std::vector<Dune::BitSetVector<dim>>& dirichletNodes; - const std::vector<const Function*>& dirichletFunctions; - double dirichletValue; + const BoundaryNodes& dirichletNodes; + const BoundaryFunctions& dirichletFunctions; std::vector<Vector> u_o, v_o, a_o; double tau; diff --git a/src/time-stepping/rate/rateupdater_tmpl.cc b/src/time-stepping/rate/rateupdater_tmpl.cc index 0af5138618c73ba1fba451fe77a6b8cd6f555472..273c261198849795ad1fd0d9f39b316b80f256b2 100644 --- a/src/time-stepping/rate/rateupdater_tmpl.cc +++ b/src/time-stepping/rate/rateupdater_tmpl.cc @@ -2,12 +2,14 @@ #error MY_DIM unset #endif -#include <dune/common/function.hh> - +#include "../../explicitgrid.hh" #include "../../explicitvectors.hh" -using Function = Dune::VirtualFunction<double, double>; +#include "../../data-structures/levelcontactnetwork.hh" + +using BoundaryNodes = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryNodes; +using BoundaryFunctions = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryFunctions; -template class RateUpdater<Vector, Matrix, Function, MY_DIM>; -template class Newmark<Vector, Matrix, Function, MY_DIM>; -template class BackwardEuler<Vector, Matrix, Function, MY_DIM>; +template class RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>; +template class Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>; +template class BackwardEuler<Vector, Matrix, BoundaryFunctions, BoundaryNodes>; diff --git a/src/time-stepping/rate_tmpl.cc b/src/time-stepping/rate_tmpl.cc index b71b59eb3e85b3e0255f0bff47bcbd5a92adba37..0d1271ed0e11cf146900a568c435c6716ce521da 100644 --- a/src/time-stepping/rate_tmpl.cc +++ b/src/time-stepping/rate_tmpl.cc @@ -1,15 +1,16 @@ +#include "../data-structures/levelcontactnetwork_tmpl.cc" #include "../explicitvectors.hh" -#include <dune/common/function.hh> +using BoundaryFunctions = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryFunctions; +using BoundaryNodes = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryNodes; -using Function = Dune::VirtualFunction<double, double>; - -template std::shared_ptr<RateUpdater<Vector, Matrix, Function, MY_DIM>> -initRateUpdater<Vector, Matrix, Function, MY_DIM>( +template +auto initRateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>( Config::scheme scheme, - const std::vector<const Function* >& velocityDirichletFunctions, - const std::vector<Dune::BitSetVector<MY_DIM>>& velocityDirichletNodes, + const BoundaryFunctions& velocityDirichletFunctions, + const BoundaryNodes& velocityDirichletNodes, const Matrices<Matrix, 2>& matrices, const std::vector<Vector>& u_initial, const std::vector<Vector>& v_initial, - const std::vector<Vector>& a_initial); + const std::vector<Vector>& a_initial) +-> std::shared_ptr<RateUpdater<Vector, Matrix, BoundaryFunctions, BoundaryNodes>>; diff --git a/src/time-stepping/state.cc b/src/time-stepping/state.cc index b8e4349eae5dead583fede83ed929845b018e186..02233a4468bb254cf8d41117c30c2e02dab31403 100644 --- a/src/time-stepping/state.cc +++ b/src/time-stepping/state.cc @@ -6,16 +6,22 @@ #include "state/ageinglawstateupdater.cc" #include "state/sliplawstateupdater.cc" -template <class ScalarVector, class Vector> -std::shared_ptr<StateUpdater<ScalarVector, Vector>> initStateUpdater(Config::stateModel model, const std::vector<ScalarVector>& alpha_initial, - const std::vector<Dune::BitSetVector<1>>& frictionalNodes, const std::vector<double>& L, const std::vector<double>& V0) { +template <class ScalarVector, class Vector, class BoundaryPatchNodes> +auto initStateUpdater( + Config::stateModel model, + const std::vector<ScalarVector>& alpha_initial, + const BoundaryPatchNodes& frictionNodes, + const std::vector<double>& L, + const std::vector<double>& V0) +-> std::shared_ptr<StateUpdater<ScalarVector, Vector>> { + switch (model) { case Config::AgeingLaw: return std::make_shared<AgeingLawStateUpdater<ScalarVector, Vector>>( - alpha_initial, frictionalNodes, L, V0); + alpha_initial, frictionNodes, L, V0); case Config::SlipLaw: return std::make_shared<SlipLawStateUpdater<ScalarVector, Vector>>( - alpha_initial, frictionalNodes, L, V0); + alpha_initial, frictionNodes, L, V0); default: assert(false); } diff --git a/src/time-stepping/state.hh b/src/time-stepping/state.hh index 3c70b2db5d0b04263d194e6dc9b29a580962cfa7..ca8352ad6bb73c35aa2425a846f5e373e40edcd3 100644 --- a/src/time-stepping/state.hh +++ b/src/time-stepping/state.hh @@ -10,9 +10,12 @@ #include "state/sliplawstateupdater.hh" #include "state/stateupdater.hh" -template <class ScalarVector, class Vector> -std::shared_ptr<StateUpdater<ScalarVector, Vector>> initStateUpdater( - Config::stateModel model, const std::vector<ScalarVector>& alpha_initial, - const std::vector<Dune::BitSetVector<1>>& frictionalNodes, const std::vector<double>& L, const std::vector<double>& V0); - +template <class ScalarVector, class Vector, class BoundaryPatchNodes> +auto initStateUpdater( + Config::stateModel model, + const std::vector<ScalarVector>& alpha_initial, + const BoundaryPatchNodes& frictionNodes, + const std::vector<double>& L, + const std::vector<double>& V0) +-> std::shared_ptr<StateUpdater<ScalarVector, Vector>>; #endif diff --git a/src/time-stepping/state/ageinglawstateupdater.cc b/src/time-stepping/state/ageinglawstateupdater.cc index 1d7bb0ee570dd34c657684fcaac8f99a71a7b79a..94a7075ceb5f1fcb7d9965168a48e7a45581de51 100644 --- a/src/time-stepping/state/ageinglawstateupdater.cc +++ b/src/time-stepping/state/ageinglawstateupdater.cc @@ -2,14 +2,39 @@ #include "ageinglawstateupdater.hh" #include "../../utils/tobool.hh" +#include "../../utils/debugutils.hh" template <class ScalarVector, class Vector> +template <class BoundaryPatchNodes> AgeingLawStateUpdater<ScalarVector, Vector>::AgeingLawStateUpdater( - const std::vector<ScalarVector>& _alpha_initial, - const std::vector<Dune::BitSetVector<1>>& _nodes, - const std::vector<double>& _L, - const std::vector<double>& _V0) - : alpha(_alpha_initial), nodes(_nodes), L(_L), V0(_V0) {} + const std::vector<ScalarVector>& _alpha_initial, + const BoundaryPatchNodes& _nodes, + const std::vector<double>& _L, + const std::vector<double>& _V0) : + alpha(_alpha_initial), + L(_L), + V0(_V0) { + + size_t nBodies = alpha.size(); + nodes.resize(nBodies); + + for (size_t i=0; i<nBodies; i++) { + auto& bodyNodes = nodes[i]; + const auto& _bcNodes = _nodes[i]; + if (_bcNodes.size() > 0) { + bodyNodes.resize(_bcNodes[0]->size(), false); + } + + for (size_t n=0; n<bodyNodes.size(); n++) { + for (size_t bc=0; bc<_bcNodes.size(); bc++) { + if (toBool((*_bcNodes[bc])[n])) { + bodyNodes[n] = true; + break; + } + } + } + } +} template <class ScalarVector, class Vector> void AgeingLawStateUpdater<ScalarVector, Vector>::nextTimeStep() { @@ -25,7 +50,10 @@ void AgeingLawStateUpdater<ScalarVector, Vector>::setup(double _tau) { Compute [ 1-\exp(c*x) ] / x under the assumption that x is non-negative */ -double liftSingularity(double c, double x) { +auto liftSingularity( + double c, + double x) { + if (x <= 0) return -c; else @@ -33,34 +61,36 @@ double liftSingularity(double c, double x) { } template <class ScalarVector, class Vector> -void AgeingLawStateUpdater<ScalarVector, Vector>::solve( - const std::vector<Vector>& velocity_field) { - for (size_t i = 0; i < alpha.size(); ++i) { - const auto& velocity_fieldi = velocity_field[i]; - const auto& nodesi = nodes[i]; - auto& alphai = alpha[i]; - auto& alpha_oi = alpha_o[i]; - - for (size_t j = 0; j < nodesi.size(); ++j) { - if (not toBool(nodesi[j])) - continue; - - double const V = velocity_fieldi[j].two_norm(); - double const mtoL = -tau / L[i]; - alphai[j] = std::log(std::exp(alpha_oi[j] + V * mtoL) + +void AgeingLawStateUpdater<ScalarVector, Vector>::solve(const std::vector<Vector>& velocity_field) { + + for (size_t i = 0; i < alpha.size(); ++i) { + const auto& velocity_fieldi = velocity_field[i]; + const auto& nodesi = nodes[i]; + auto& alphai = alpha[i]; + auto& alpha_oi = alpha_o[i]; + + for (size_t j = 0; j < nodesi.size(); ++j) { + if (not toBool(nodesi[j])) + continue; + + double const V = velocity_fieldi[j].two_norm(); + double const mtoL = -tau / L[i]; + alphai[j] = std::log(std::exp(alpha_oi[j] + V * mtoL) + V0[i] * liftSingularity(mtoL, V)); + } } - } } template <class ScalarVector, class Vector> void AgeingLawStateUpdater<ScalarVector, Vector>::extractAlpha( - std::vector<ScalarVector>& _alpha) { - _alpha = alpha; + std::vector<ScalarVector>& _alpha) { + + _alpha = alpha; } template <class ScalarVector, class Vector> -std::shared_ptr<StateUpdater<ScalarVector, Vector>> -AgeingLawStateUpdater<ScalarVector, Vector>::clone() const { +auto AgeingLawStateUpdater<ScalarVector, Vector>::clone() const + -> std::shared_ptr<StateUpdater<ScalarVector, Vector>> { + return std::make_shared<AgeingLawStateUpdater<ScalarVector, Vector>>(*this); } diff --git a/src/time-stepping/state/ageinglawstateupdater.hh b/src/time-stepping/state/ageinglawstateupdater.hh index 4b8ec5588167b412a76d65a5477b988d10e3a12b..0c9ab450341bb2288dd41bdddd6d996144e24c90 100644 --- a/src/time-stepping/state/ageinglawstateupdater.hh +++ b/src/time-stepping/state/ageinglawstateupdater.hh @@ -6,21 +6,24 @@ template <class ScalarVector, class Vector> class AgeingLawStateUpdater : public StateUpdater<ScalarVector, Vector> { public: - AgeingLawStateUpdater(const std::vector<ScalarVector>& _alpha_initial, - const std::vector<Dune::BitSetVector<1>>& _nodes, const std::vector<double>& _L, - const std::vector<double>& _V0); + template <class BoundaryPatchNodes> + AgeingLawStateUpdater( + const std::vector<ScalarVector>& _alpha_initial, + const BoundaryPatchNodes& _nodes, + const std::vector<double>& _L, + const std::vector<double>& _V0); void nextTimeStep() override; void setup(double _tau) override; void solve(const std::vector<Vector>& velocity_field) override; void extractAlpha(std::vector<ScalarVector> &) override; - std::shared_ptr<StateUpdater<ScalarVector, Vector>> clone() const override; + auto clone() const -> std::shared_ptr<StateUpdater<ScalarVector, Vector>> override; private: std::vector<ScalarVector> alpha_o; std::vector<ScalarVector> alpha; - const std::vector<Dune::BitSetVector<1>>& nodes; + std::vector<Dune::BitSetVector<1>> nodes; const std::vector<double>& L; const std::vector<double>& V0; double tau; diff --git a/src/time-stepping/state/sliplawstateupdater.cc b/src/time-stepping/state/sliplawstateupdater.cc index 196b02b09be73a622e9983441d09932be1ff8b7c..51ae920bd2ed5d1d51e51dc4f7b5bd9ee39153cc 100644 --- a/src/time-stepping/state/sliplawstateupdater.cc +++ b/src/time-stepping/state/sliplawstateupdater.cc @@ -4,52 +4,78 @@ #include "../../utils/tobool.hh" template <class ScalarVector, class Vector> +template <class BoundaryPatchNodes> SlipLawStateUpdater<ScalarVector, Vector>::SlipLawStateUpdater( - const std::vector<ScalarVector>& _alpha_initial, - const std::vector<Dune::BitSetVector<1>>& _nodes, const std::vector<double>& _L, - const std::vector<double>& _V0) - : alpha(_alpha_initial), nodes(_nodes), L(_L), V0(_V0) {} + const std::vector<ScalarVector>& _alpha_initial, + const BoundaryPatchNodes& _nodes, + const std::vector<double>& _L, + const std::vector<double>& _V0) : + alpha(_alpha_initial), + L(_L), + V0(_V0) { + + size_t nBodies = alpha.size(); + nodes.resize(nBodies); + + for (size_t i=0; i<nBodies; i++) { + auto& bodyNodes = nodes[i]; + auto& _bodyNodes = _nodes[i]; + if (_bodyNodes.size() > 0) { + bodyNodes.resize(_bodyNodes[0]->size(), false); + } + + for (size_t n=0; n<bodyNodes.size(); n++) { + for (size_t bc=0; bc<_bodyNodes.size(); bc++) { + if (toBool((*_bodyNodes[bc])[n])) { + bodyNodes[n] = true; + break; + } + } + } + } +} template <class ScalarVector, class Vector> void SlipLawStateUpdater<ScalarVector, Vector>::nextTimeStep() { - alpha_o = alpha; + alpha_o = alpha; } template <class ScalarVector, class Vector> void SlipLawStateUpdater<ScalarVector, Vector>::setup(double _tau) { - tau = _tau; + tau = _tau; } template <class ScalarVector, class Vector> void SlipLawStateUpdater<ScalarVector, Vector>::solve( - const std::vector<Vector>& velocity_field) { + const std::vector<Vector>& velocity_field) { - for (size_t i = 0; i < alpha.size(); ++i) { - const auto& velocity_fieldi = velocity_field[i]; - const auto& nodesi = nodes[i]; - auto& alphai = alpha[i]; - auto& alpha_oi = alpha_o[i]; + for (size_t i = 0; i < alpha.size(); ++i) { + const auto& velocity_fieldi = velocity_field[i]; + const auto& nodesi = nodes[i]; + auto& alphai = alpha[i]; + auto& alpha_oi = alpha_o[i]; - for (size_t j = 0; j < nodesi.size(); ++j) { - if (not toBool(nodesi[j])) - continue; + for (size_t j = 0; j < nodesi.size(); ++j) { + if (not toBool(nodesi[j])) + continue; - double const V = velocity_fieldi[j].two_norm(); - double const mtoL = -tau * V / L[i]; - alphai[j] = (V <= 0) ? alpha_oi[j] : std::expm1(mtoL) * std::log(V / V0[i]) + + double const V = velocity_fieldi[j].two_norm(); + double const mtoL = -tau * V / L[i]; + alphai[j] = (V <= 0) ? alpha_oi[j] : std::expm1(mtoL) * std::log(V / V0[i]) + alpha_oi[j] * std::exp(mtoL); - } - } + } + } } template <class ScalarVector, class Vector> void SlipLawStateUpdater<ScalarVector, Vector>::extractAlpha( std::vector<ScalarVector>& _alpha) { + _alpha = alpha; } template <class ScalarVector, class Vector> -std::shared_ptr<StateUpdater<ScalarVector, Vector>> -SlipLawStateUpdater<ScalarVector, Vector>::clone() const { +auto SlipLawStateUpdater<ScalarVector, Vector>::clone() const +-> std::shared_ptr<StateUpdater<ScalarVector, Vector>> { return std::make_shared<SlipLawStateUpdater<ScalarVector, Vector>>(*this); } diff --git a/src/time-stepping/state/sliplawstateupdater.hh b/src/time-stepping/state/sliplawstateupdater.hh index 760044e83f12fefe7fce144c3c4378ff647177da..0b3f7ef39170b6db0f572bd7429b94ab9090dc87 100644 --- a/src/time-stepping/state/sliplawstateupdater.hh +++ b/src/time-stepping/state/sliplawstateupdater.hh @@ -6,21 +6,24 @@ template <class ScalarVector, class Vector> class SlipLawStateUpdater : public StateUpdater<ScalarVector, Vector> { public: - SlipLawStateUpdater(const std::vector<ScalarVector>& _alpha_initial, - const std::vector<Dune::BitSetVector<1>>& _nodes, const std::vector<double>& _L, - const std::vector<double>& _V0); + template <class BoundaryPatchNodes> + SlipLawStateUpdater( + const std::vector<ScalarVector>& _alpha_initial, + const BoundaryPatchNodes& _nodes, + const std::vector<double>& _L, + const std::vector<double>& _V0); void nextTimeStep() override; void setup(double _tau) override; void solve(const std::vector<Vector>& velocity_field) override; void extractAlpha(std::vector<ScalarVector> &) override; - std::shared_ptr<StateUpdater<ScalarVector, Vector>> clone() const override; + auto clone() const -> std::shared_ptr<StateUpdater<ScalarVector, Vector>> override; private: std::vector<ScalarVector> alpha_o; std::vector<ScalarVector> alpha; - const std::vector<Dune::BitSetVector<1>>& nodes; + std::vector<Dune::BitSetVector<1>> nodes; const std::vector<double>& L; const std::vector<double>& V0; double tau; diff --git a/src/time-stepping/state_tmpl.cc b/src/time-stepping/state_tmpl.cc index 718150c7af0332286c7fe489863caa35330a7c18..5046cf258356874450b8fb4ad5de5d58ed162795 100644 --- a/src/time-stepping/state_tmpl.cc +++ b/src/time-stepping/state_tmpl.cc @@ -1,6 +1,19 @@ +#ifndef MY_DIM +#error MY_DIM unset +#endif + #include "../explicitvectors.hh" +#include "../explicitgrid.hh" + +#include "../data-structures/levelcontactnetwork.hh" + +using BoundaryPatchNodes = typename LevelContactNetwork<Grid, MY_DIM>::LevelBoundaryPatchNodes; -template std::shared_ptr<StateUpdater<ScalarVector, Vector>> -initStateUpdater<ScalarVector, Vector>( - Config::stateModel model, const std::vector<ScalarVector>& alpha_initial, - const std::vector<Dune::BitSetVector<1>>& frictionalNodes, const std::vector<double>& L, const std::vector<double>& V0); +template +auto initStateUpdater<ScalarVector, Vector, BoundaryPatchNodes>( + Config::stateModel model, + const std::vector<ScalarVector>& alpha_initial, + const BoundaryPatchNodes& frictionalNodes, + const std::vector<double>& L, + const std::vector<double>& V0) +-> std::shared_ptr<StateUpdater<ScalarVector, Vector>>; diff --git a/src/utils/almostequal.hh b/src/utils/almostequal.hh new file mode 100644 index 0000000000000000000000000000000000000000..448c95fef53598bcad3eb0612299f2a7d31b8678 --- /dev/null +++ b/src/utils/almostequal.hh @@ -0,0 +1,11 @@ +#ifndef SRC_ALMOSTEQUAL_HH +#define SRC_ALMOSTEQUAL_HH + +#include <math.h> + +template <typename ctype> +typename std::enable_if<!std::numeric_limits<ctype>::is_integer, bool>::type almost_equal(ctype x, ctype y, int ulp) { + return std::abs(x-y) < std::numeric_limits<ctype>::epsilon() * std::abs(x+y) * ulp || std::abs(x-y) < std::numeric_limits<ctype>::min(); +} + +#endif diff --git a/src/utils/debugutils.hh b/src/utils/debugutils.hh index 75b5c8e8f60484be1d2a3abd826ae646e07e7228..4671ff68de50d8c51cf674d89f968e9097548f56 100644 --- a/src/utils/debugutils.hh +++ b/src/utils/debugutils.hh @@ -73,7 +73,6 @@ using namespace std; std::cout << std::endl; } - /* template <class T=Dune::FieldMatrix<double,1,1>> void print(const Dune::Matrix<T>& mat, std::string message){ std::cout << message << std::endl; @@ -95,7 +94,7 @@ using namespace std; std::cout << std::endl << std::endl; } - void print(const std::vector<Dune::FieldVector<double,1>>& x, std::string message){ + /* void print(const std::vector<Dune::FieldVector<double,1>>& x, std::string message){ std::cout << message << std::endl; for (size_t i=0; i<x.size(); i++) { std::cout << x[i] << " "; @@ -156,7 +155,7 @@ using namespace std; std::cout.rdbuf( lBufferOld ); } -/* + template <class BasisType, typename ctype=double> void printBasisDofLocation(const BasisType& basis) { typedef typename BasisType::GridView GridView; @@ -218,5 +217,5 @@ using namespace std; } std::cout << std::endl; } - } */ + } #endif