Skip to content
Snippets Groups Projects
globalratestatefriction.hh 4.47 KiB
Newer Older
#ifndef DUNE_TECTONIC_GLOBALRATESTATEFRICTION_HH
#define DUNE_TECTONIC_GLOBALRATESTATEFRICTION_HH
Elias Pipping's avatar
Elias Pipping committed

Elias Pipping's avatar
Elias Pipping committed
#include <vector>

Elias Pipping's avatar
Elias Pipping committed
#include <dune/common/bitsetvector.hh>
Elias Pipping's avatar
Elias Pipping committed
#include <dune/common/fmatrix.hh>
Elias Pipping's avatar
Elias Pipping committed
#include <dune/common/fvector.hh>
#include <dune/grid/common/mcmgmapper.hh>
Elias Pipping's avatar
Elias Pipping committed
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/bvector.hh>
Elias Pipping's avatar
Elias Pipping committed

podlesny's avatar
podlesny committed
#include "../../spatial-solving/contact/dualmortarcoupling.hh"
podlesny's avatar
.  
podlesny committed

podlesny's avatar
podlesny committed
#include "globalfrictiondata.hh"
#include "globalfriction.hh"
#include "frictioncouplingpair.hh"
podlesny's avatar
podlesny committed
#include "../../utils/geocoordinate.hh"
#include "../../utils/index-in-sorted-range.hh"
podlesny's avatar
.  
podlesny committed

template <class Matrix, class Vector, class ScalarFriction, class GridType>
class GlobalRateStateFriction : public GlobalFriction<Matrix, Vector> {
  using GlobalFriction<Matrix, Vector>::block_size;
  using typename GlobalFriction<Matrix, Vector>::LocalNonlinearity;
Elias Pipping's avatar
Elias Pipping committed
private:
podlesny's avatar
.  
podlesny committed
  using Base = GlobalFriction<Matrix, Vector>;

  using field_type = typename Vector::field_type;
  using typename Base::ScalarVector;
  using typename Base::LocalVectorType;

podlesny's avatar
podlesny committed
  using FrictionCoupling = FrictionCouplingPair<GridType, LocalVectorType, field_type>;
podlesny's avatar
podlesny committed
  using ContactCoupling =  DualMortarCoupling<field_type, GridType>;
podlesny's avatar
.  
podlesny committed

  size_t bodyIndex(const size_t globalIdx) {
     size_t i = offSet_.size()-1;
podlesny's avatar
.  
podlesny committed

     for (; i>0; ) {
         if (globalIdx >= offSet_[i])
podlesny's avatar
.  
podlesny committed
             break;
podlesny's avatar
.  
podlesny committed
     }
     return i;
  }
Elias Pipping's avatar
Elias Pipping committed

Elias Pipping's avatar
Elias Pipping committed
public:
podlesny's avatar
.  
podlesny committed
  GlobalRateStateFriction(const std::vector<std::shared_ptr<ContactCoupling>>& contactCouplings, // contains nonmortarBoundary
podlesny's avatar
podlesny committed
                          const std::vector<std::shared_ptr<FrictionCoupling>>& couplings, // contains frictionInfo
podlesny's avatar
.  
podlesny committed
                          const std::vector<ScalarVector>& weights,
                          const std::vector<ScalarVector>& weightedNormalStress)
      : restrictions_(), localToGlobal_(), zeroFriction_() {

    assert(contactCouplings.size() == couplings.size());
    assert(weights.size() == weightedNormalStress.size());

    const auto nBodies = weights.size();
podlesny's avatar
podlesny committed
    offSet_.resize(nBodies, 0);
    for (size_t i=1; i<nBodies; i++) {
        offSet_[i] = offSet_[i-1] + weights[i-1].size();
podlesny's avatar
podlesny committed
    }
podlesny's avatar
.  
podlesny committed

    std::vector<std::vector<int>> nonmortarBodies(nBodies); // first index body, second index coupling
    for (size_t i=0; i<contactCouplings.size(); i++) {
        const auto nonmortarIdx = couplings[i]->gridIdx_[0];
        nonmortarBodies[nonmortarIdx].emplace_back(i);
    }

    for (size_t bodyIdx=0; bodyIdx<nBodies; bodyIdx++) {
        const auto& couplingIndices = nonmortarBodies[bodyIdx];

        if (couplingIndices.size()==0)
            continue;

        const auto gridView = contactCouplings[couplingIndices[0]]->nonmortarBoundary().gridView();

        Dune::MultipleCodimMultipleGeomTypeMapper<
            decltype(gridView), Dune::MCMGVertexLayout> const vertexMapper(gridView, Dune::mcmgVertexLayout());

        for (auto it = gridView.template begin<block_size>(); it != gridView.template end<block_size>(); ++it) {
            const auto i = vertexMapper.index(*it);

            for (size_t j=0; j<couplingIndices.size(); j++) {
                const auto couplingIdx = couplingIndices[j];

                if (not contactCouplings[couplingIdx]->nonmortarBoundary().containsVertex(i))
                  continue;

podlesny's avatar
podlesny committed
                localToGlobal_.emplace_back(offSet_[bodyIdx] + i);
podlesny's avatar
.  
podlesny committed
                restrictions_.emplace_back(weights[bodyIdx][i], weightedNormalStress[bodyIdx][i],
podlesny's avatar
.  
podlesny committed
                                          couplings[j]->frictionData()(geoToPoint(it->geometry())));
podlesny's avatar
.  
podlesny committed
                break;
            }
        }
Elias Pipping's avatar
Elias Pipping committed
  }
Elias Pipping's avatar
Elias Pipping committed

podlesny's avatar
.  
podlesny committed
  void updateAlpha(const std::vector<ScalarVector>& alpha) override {
    //print(alpha, "alpha");
podlesny's avatar
.  
podlesny committed
    for (size_t j = 0; j < restrictions_.size(); ++j) {
      const auto globalDof = localToGlobal_[j];
podlesny's avatar
podlesny committed
      const auto bodyIdx = bodyIndex(globalDof);
      size_t bodyDof = globalDof - offSet_[bodyIdx];
podlesny's avatar
.  
podlesny committed

      restrictions_[j].updateAlpha(alpha[bodyIdx][bodyDof]);
    }
Elias Pipping's avatar
Elias Pipping committed
  /*
    Return a restriction of the outer function to the i'th node.
  */
  LocalNonlinearity const &restriction(size_t i) const override {
podlesny's avatar
.  
podlesny committed
    auto const index = indexInSortedRange(localToGlobal_, i);
    if (index == localToGlobal_.size())
      return zeroFriction_;
    return restrictions_[index];
Elias Pipping's avatar
Elias Pipping committed
  }

private:
podlesny's avatar
.  
podlesny committed
  std::vector<WrappedScalarFriction<block_size, ScalarFriction>> restrictions_;
podlesny's avatar
podlesny committed
  std::vector<size_t> offSet_; // index off-set by body id
podlesny's avatar
.  
podlesny committed
  std::vector<size_t> localToGlobal_;
  WrappedScalarFriction<block_size, ZeroFunction> const zeroFriction_;
Elias Pipping's avatar
Elias Pipping committed
};
#endif