Newer
Older
#ifndef DUNE_TECTONIC_GLOBALRATESTATEFRICTION_HH
#define DUNE_TECTONIC_GLOBALRATESTATEFRICTION_HH
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/bvector.hh>
#include "../../spatial-solving/contact/dualmortarcoupling.hh"
#include "globalfrictiondata.hh"
#include "globalfriction.hh"
#include "frictioncouplingpair.hh"
#include "../../utils/geocoordinate.hh"
#include "../../utils/index-in-sorted-range.hh"
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;
using Base = GlobalFriction<Matrix, Vector>;
using field_type = typename Vector::field_type;
using typename Base::ScalarVector;
using typename Base::LocalVectorType;
using FrictionCoupling = FrictionCouplingPair<GridType, LocalVectorType, field_type>;
using ContactCoupling = DualMortarCoupling<field_type, GridType>;
size_t i = offSet_.size()-1;
for (; i>0; ) {
if (globalIdx >= offSet_[i])
GlobalRateStateFriction(const std::vector<std::shared_ptr<ContactCoupling>>& contactCouplings, // contains nonmortarBoundary
const std::vector<std::shared_ptr<FrictionCoupling>>& couplings, // contains frictionInfo
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();
offSet_.resize(nBodies, 0);
for (size_t i=1; i<nBodies; i++) {
offSet_[i] = offSet_[i-1] + weights[i-1].size();
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;
restrictions_.emplace_back(weights[bodyIdx][i], weightedNormalStress[bodyIdx][i],
for (size_t j = 0; j < restrictions_.size(); ++j) {
const auto globalDof = localToGlobal_[j];
size_t bodyDof = globalDof - offSet_[bodyIdx];
/*
Return a restriction of the outer function to the i'th node.
*/
LocalNonlinearity const &restriction(size_t i) const override {
auto const index = indexInSortedRange(localToGlobal_, i);
if (index == localToGlobal_.size())
return zeroFriction_;
return restrictions_[index];
std::vector<WrappedScalarFriction<block_size, ScalarFriction>> restrictions_;
std::vector<size_t> localToGlobal_;
WrappedScalarFriction<block_size, ZeroFunction> const zeroFriction_;