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

#include <memory>

#include <dune/common/promotiontraits.hh>

#include "../../spatial-solving/contact/nbodyassembler.hh"
#include "../../assemblers.hh"
#include "../enums.hh"
#include "../matrices.hh"

#include "../body/body.hh"
#include "../body/bodydata.hh"
#include "../friction/frictioncouplingpair.hh"
#include "../friction/globalfriction.hh"
#include "../friction/globalfrictiondata.hh"

#include "levelcontactnetwork.hh"

template <class HostGridType, class VectorType>
class ContactNetwork {
    //using Vector = Dune::BlockVector<Dune::FieldVector<double, dim>>;
public:
    enum {dim = HostGridType::dimensionworld};

    using field_type = typename Dune::PromotionTraits<typename VectorType::field_type,
                                                typename HostGridType::ctype>::PromotedType;

    using LeafBody = LeafBody<HostGridType, VectorType>;
    using GridType = typename LeafBody::GridType;
    using GridView = typename LeafBody::GridView;
    using BoundaryPatch = BoundaryPatch<GridView>;

    using Assembler = typename LeafBody::Assembler;
    using Matrix = typename Assembler::Matrix;

    using ScalarMatrix = typename Assembler::ScalarMatrix;
    using ScalarVector = typename Assembler::ScalarVector;

    using LocalVector = typename VectorType::block_type;
    using FrictionCouplingPair = FrictionCouplingPair<GridType, LocalVector, field_type>;

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

    using BoundaryFunctions = std::vector<typename LeafBody::BoundaryFunctions>;
    using BoundaryNodes = std::vector<typename LeafBody::BoundaryNodes>;
    using BoundaryPatchNodes = std::vector<typename LeafBody::BoundaryPatchNodes>;
    using BoundaryPatches = std::vector<typename LeafBody::BoundaryPatches>;

    using GlobalFriction = GlobalFriction<Matrix, VectorType>;

    using StateEnergyNorms = std::vector<std::unique_ptr<typename LeafBody::StateEnergyNorm> >;
    using ExternalForces = std::vector<std::unique_ptr<const typename LeafBody::ExternalForce> >;

    using NBodyAssembler = NBodyAssembler<GridType, VectorType>;

    using LevelContactNetwork = LevelContactNetwork<GridType, FrictionCouplingPair, field_type>;
    using Body = typename LevelContactNetwork::Body;

private:
    std::vector<std::shared_ptr<LevelContactNetwork>> levelContactNetworks_;

    std::vector<std::shared_ptr<LeafBody>> bodies_;
    std::vector<std::shared_ptr<FrictionCouplingPair>> couplings_;

    std::vector<std::unique_ptr<BoundaryPatch>> frictionBoundaries_; // union of all boundary patches per body
    std::vector<std::unique_ptr<ScalarMatrix>> frictionBoundaryMass_;
    StateEnergyNorms stateEnergyNorms_;
    NBodyAssembler nBodyAssembler_;

    Matrices<Matrix,2> matrices_;

    std::shared_ptr<GlobalFriction> globalFriction_;

public:
    ContactNetwork(size_t nBodies, size_t nCouplings, size_t nLevels = 0);

    void addLevel(std::shared_ptr<LevelContactNetwork> levelContactNetwork);
    void addLevel(const std::vector<size_t>& bodyLevels, const size_t level);

    void assemble();
    void assembleFriction(
            const Config::FrictionModel& frictionModel,
            const std::vector<ScalarVector>& weightedNormalStress);

    void setBodies(const std::vector<std::shared_ptr<LeafBody>> bodies);
    void setCouplings(const std::vector<std::shared_ptr<FrictionCouplingPair>> couplings);

    void setDeformation(const std::vector<VectorType>& totalDeformation);

    void constructBody(
            const std::shared_ptr<BodyData<dim>>& bodyData,
            const std::shared_ptr<HostGridType>& grid,
            std::shared_ptr<LeafBody>& body) const;

    template <class LevelBoundaryPatch>
    void constructCoupling(
            int nonMortarBodyIdx,
            int mortarBodyIdx,
            const std::shared_ptr<LevelBoundaryPatch>& nonmortarPatch,
            const std::shared_ptr<LevelBoundaryPatch>& mortarPatch,
            const std::shared_ptr<ConvexPolyhedron<LocalVector>>& weakeningPatch,
            const std::shared_ptr<GlobalFrictionData<dim>>& frictionData,
            std::shared_ptr<FrictionCouplingPair>& coupling) const;

    // getter
    auto level(size_t level) const -> const std::shared_ptr<LevelContactNetwork>&;

    auto nLevels() const -> size_t;
    auto nBodies() const -> size_t;
    auto nCouplings() const -> size_t;

    auto body(int i) const -> const std::shared_ptr<LeafBody>&;

    auto coupling(int i) const -> const std::shared_ptr<FrictionCouplingPair>&;
    auto couplings() const -> const std::vector<std::shared_ptr<FrictionCouplingPair>>&;

    auto nBodyAssembler() -> NBodyAssembler&;
    auto nBodyAssembler() const -> const NBodyAssembler&;

    auto matrices() const -> const Matrices<Matrix,2>&;

    auto stateEnergyNorms() const -> const StateEnergyNorms&;
    auto globalFriction() const -> GlobalFriction&;
    void externalForces(ExternalForces& externalForces) const;

    void totalNodes(
            const std::string& tag,
            Dune::BitSetVector<dim>& 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 frictionNodes(std::vector<const Dune::BitSetVector<1>*>& nodes) const;
    void frictionPatches(std::vector<const BoundaryPatch*>& patches) const;
};
#endif