Skip to content
Snippets Groups Projects
Forked from agnumpde / dune-tectonic
156 commits ahead of the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
body.hh 6.82 KiB
#ifndef SRC_DATA_STRUCTURES_BODY_HH
#define SRC_DATA_STRUCTURES_BODY_HH

#include <functional>
#include <type_traits>

#include <dune/common/bitsetvector.hh>
#include <dune/common/function.hh>
#include <dune/common/shared_ptr.hh>

#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/bvector.hh>

//#include <dune/fufem/assemblers/assembler.hh>
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Wsign-compare"
//#include <dune/fufem/functionspacebases/p0basis.hh>
//#pragma clang diagnostic pop
//#include <dune/fufem/functionspacebases/p1nodalbasis.hh>

#include <dune/grid/geometrygrid/grid.hh>

#include <dune/fufem/functions/deformationfunction.hh>

#include <dune/solvers/norms/energynorm.hh>

#include "../../assemblers.hh"
#include "../enums.hh"
#include "../matrices.hh"

#include "boundarycondition.hh"
#include "bodydata.hh"

template <class HostGridType, class VectorType>
class LeafBody {
public:
    static const int dim = HostGridType::dimensionworld;

    using DeformationFunction = DeformationFunction<typename HostGridType::LeafGridView, VectorType>;
    using GridType = Dune::GeometryGrid<HostGridType, DeformationFunction>;
    using GridView = typename GridType::LeafGridView;

    using Function = Dune::VirtualFunction<double, double>;
    using ExternalForce = std::function<void(double, VectorType &)>;

    using Assembler = MyAssembler<GridView, dim>;
    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 BoundaryCondition = BoundaryCondition<GridView, dim>;

    using BoundaryFunctions = std::vector<const Function* >;
    using BoundaryNodes = std::vector<const Dune::BitSetVector<dim>* >;
    using BoundaryPatchNodes = std::vector<const Dune::BitSetVector<1>* >;
    using BoundaryPatches = std::vector<const typename BoundaryCondition::BoundaryPatch* >;

    using StateEnergyNorm = EnergyNorm<ScalarMatrix, ScalarVector>;

private:
    std::shared_ptr<BodyData<dim>> bodyData_;

    std::shared_ptr<HostGridType> hostGrid_;
    std::shared_ptr<DeformationFunction> deformation_;
    std::shared_ptr<GridType> grid_;
    GridView gridView_;

    std::shared_ptr<Assembler> assembler_;
    Matrices<Matrix,1> matrices_;

    ExternalForce externalForce_;

    VectorType gravityFunctional_;

    // boundary conditions
    std::vector<std::shared_ptr<BoundaryCondition>> boundaryConditions_;

public:
    LeafBody(
            const std::shared_ptr<BodyData<dim>>& bodyData,
            const std::shared_ptr<HostGridType>& hostGrid);

    void assemble();

    // setter and getter
    auto data() const -> const std::shared_ptr<BodyData<dim>>&;

    void setDeformation(const VectorType& def);
    auto deformation() const -> DeformationFunction&;
    auto grid() const -> std::shared_ptr<GridType>;
    auto hostGrid() const -> std::shared_ptr<HostGridType>;

    auto gridView() const -> const GridView&;
    auto nVertices() const -> size_t;

    auto assembler() const -> const std::shared_ptr<Assembler>&;
    auto matrices() const -> const Matrices<Matrix,1>&;

    auto externalForce() const -> const ExternalForce&;

    void addBoundaryCondition(std::shared_ptr<BoundaryCondition> boundaryCondition);
    void boundaryConditions(
            const std::string& tag,
            std::vector<std::shared_ptr<BoundaryCondition>>& selectedConditions) const;
    auto boundaryConditions() const -> const std::vector<std::shared_ptr<BoundaryCondition>>&;

    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;
};

template <class GridView>
class Body {
public:
    enum {dim = GridView::dimensionworld};

    using GridType = typename GridView::Grid;

    using Function = Dune::VirtualFunction<double, double>;

    using BoundaryCondition = BoundaryCondition<GridView, dim>;

    using BoundaryFunctions = std::vector<const Function* >;
    using BoundaryNodes = std::vector<const Dune::BitSetVector<dim>* >;
    using BoundaryPatchNodes = std::vector<const Dune::BitSetVector<1>* >;
    using BoundaryPatches = std::vector<const typename BoundaryCondition::BoundaryPatch* >;

private:
    std::shared_ptr<BodyData<dim>> bodyData_;

    std::shared_ptr<GridType> grid_;
    const size_t level_;
    GridView gridView_;

    // boundary conditions
    std::vector<std::shared_ptr<BoundaryCondition>> boundaryConditions_;

public:
    template <class GridView_ = GridView, std::enable_if_t<std::is_same<GridView_, typename GridType::LeafGridView>::value, int> = 0>
    Body(
            const std::shared_ptr<BodyData<dim>>& bodyData,
            const std::shared_ptr<GridType>& grid) :
        bodyData_(bodyData),
        grid_(grid),
        level_(grid_->maxLevel()),
        gridView_(grid_->leafGridView()) {

        boundaryConditions_.resize(0);
    }

    template <class GridView_ = GridView, std::enable_if_t<std::is_same<GridView_, typename GridType::LevelGridView>::value, int> = 0>
    Body(
            const std::shared_ptr<BodyData<dim>>& bodyData,
            const std::shared_ptr<GridType>& grid,
            const size_t level) :
        bodyData_(bodyData),
        grid_(grid),
        level_(level),
        gridView_(grid_->levelGridView(level_)) {

        boundaryConditions_.resize(0);
    }


    // setter and getter
    auto data() const -> const std::shared_ptr<BodyData<dim>>&;
    auto grid() const -> std::shared_ptr<GridType>;

    //template <class GridView_ = GridView, std::enable_if_t<std::is_same<GridView_, typename GridType::LevelGridView>::value, int> = 0>
    auto level() const
    -> size_t {

        return level_;
    }

    auto gridView() const -> const GridView&;
    auto nVertices() const -> size_t;

    void addBoundaryCondition(std::shared_ptr<BoundaryCondition> boundaryCondition);
    void boundaryConditions(
            const std::string& tag,
            std::vector<std::shared_ptr<BoundaryCondition>>& selectedConditions) const;
    auto boundaryConditions() const -> const std::vector<std::shared_ptr<BoundaryCondition>>&;

    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