Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • podlesny/dune-tectonic
  • agnumpde/dune-tectonic
2 results
Show changes
Showing
with 1052 additions and 80 deletions
......@@ -4,7 +4,8 @@
#include <dune/istl/scaledidmatrix.hh>
#include <dune/fufem/assemblers/localassemblers/boundarymassassembler.hh>
#include <dune/fufem/assemblers/localassemblers/massassembler.hh>
#include <dune/fufem/assemblers/boundaryoperatorassembler.hh>
#include <dune/fufem/assemblers/localassemblers/l2functionalassembler.hh>
#include <dune/fufem/assemblers/localassemblers/neumannboundaryassembler.hh>
#include <dune/fufem/assemblers/localassemblers/normalstressboundaryassembler.hh>
......@@ -12,41 +13,49 @@
#include <dune/fufem/assemblers/localassemblers/variablecoefficientviscosityassembler.hh>
#include <dune/fufem/assemblers/localassemblers/vonmisesstressassembler.hh>
#include <dune/fufem/assemblers/localassemblers/weightedmassassembler.hh>
#include <dune/fufem/boundarypatch.hh>
#include <dune/fufem/functions/basisgridfunction.hh>
#include <dune/fufem/functions/constantfunction.hh>
#include <dune/fufem/functiontools/p0p1interpolation.hh>
#include <dune/fufem/quadraturerules/quadraturerulecache.hh>
#include <dune/tectonic/frictionpotential.hh>
#include <dune/tectonic/globalratestatefriction.hh>
#include "data-structures/friction/frictionpotential.hh"
#include "data-structures/friction/globalratestatefriction.hh"
#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),
vertexAssembler(vertexBasis, vertexBasis) {}
template <class GridView, int dimension>
template <class LocalBoundaryFunctionalAssemblerType, class GlobalVectorType>
void MyAssembler<GridView, dimension>::assembleBoundaryFunctional(LocalBoundaryFunctionalAssemblerType& localAssembler,
GlobalVectorType& b,
const BoundaryPatch<GridView>& boundaryPatch,
bool initializeVector) const {
vertexAssembler.assembleBoundaryFunctional(localAssembler, b, boundaryPatch, initializeVector);
}
template <class GridView, int dimension>
void MyAssembler<GridView, dimension>::assembleFrictionalBoundaryMass(
BoundaryPatch<GridView> const &frictionalBoundary,
ScalarMatrix &frictionalBoundaryMass) const {
BoundaryMassAssembler<Grid, BoundaryPatch<GridView>, LocalVertexBasis,
LocalVertexBasis, Dune::FieldMatrix<double, 1, 1>> const
frictionalBoundaryMassAssembler(frictionalBoundary);
vertexAssembler.assembleOperator(frictionalBoundaryMassAssembler,
frictionalBoundaryMass);
BoundaryPatch<GridView> const &frictionalBoundary,
ScalarMatrix &frictionalBoundaryMass) const {
MassAssembler<Grid, LocalVertexBasis, LocalVertexBasis> localMassAssembler;
const BoundaryOperatorAssembler<VertexBasis, VertexBasis> boundaryAssembler(vertexBasis, vertexBasis, frictionalBoundary);
boundaryAssembler.assemble(localMassAssembler, frictionalBoundaryMass);
}
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 +67,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 +79,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 +96,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,11 +106,33 @@ 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 {
const BoundaryPatch<GridView>& neumannBoundary,
const Dune::BitSetVector<dimension>& neumannNodes,
Vector& f,
const Dune::VirtualFunction<double, double>& neumann,
double relativeTime) const {
typename LocalVector::field_type val = 0;
neumann.evaluate(relativeTime, val);
size_t idx = 0;
bool neumannIdx = false;
for (; idx<neumannNodes.size() && !neumannIdx; idx++) {
for (size_t d=0; d<dimension; d++) {
if (neumannNodes[idx][d]) {
neumannIdx = true;
break;
}
}
}
idx--;
LocalVector localNeumann(0);
neumann.evaluate(relativeTime, localNeumann[0]);
for (size_t i=0; i<localNeumann.size(); i++) {
if (neumannNodes[idx][i])
localNeumann[i] = val;
}
NeumannBoundaryAssembler<Grid, LocalVector> neumannBoundaryAssembler(
std::make_shared<ConstantFunction<LocalVector, LocalVector>>(
localNeumann));
......@@ -106,9 +142,12 @@ 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,
ScalarVector &weights,
double youngModulus,
double poissonRatio,
Vector const &displacement) const {
BasisGridFunction<VertexBasis, Vector> displacementFunction(vertexBasis,
displacement);
......@@ -121,7 +160,6 @@ void MyAssembler<GridView, dimension>::assembleWeightedNormalStress(
auto const nodalTractionAverage =
interpolateP0ToP1(frictionalBoundary, traction);
ScalarVector weights;
{
NeumannBoundaryAssembler<Grid, typename ScalarVector::block_type>
frictionalBoundaryAssembler(
......@@ -130,47 +168,20 @@ void MyAssembler<GridView, dimension>::assembleWeightedNormalStress(
vertexAssembler.assembleBoundaryFunctional(frictionalBoundaryAssembler,
weights, frictionalBoundary);
}
auto const normals = frictionalBoundary.getNormals();
for (size_t i = 0; i < vertexBasis.size(); ++i)
weightedNormalStress[i] =
std::fmin(normals[i] * nodalTractionAverage[i], 0) * weights[i];
}
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>> {
// Lumping of the nonlinearity
ScalarVector weights;
{
NeumannBoundaryAssembler<Grid, typename ScalarVector::block_type>
frictionalBoundaryAssembler(std::make_shared<
ConstantFunction<LocalVector, typename ScalarVector::block_type>>(
1));
vertexAssembler.assembleBoundaryFunctional(frictionalBoundaryAssembler,
weights, frictionalBoundary);
}
switch (frictionModel) {
case Config::Truncated:
return std::make_shared<GlobalRateStateFriction<
Matrix, Vector, TruncatedRateState, GridView>>(
frictionalBoundary, frictionInfo, weights, weightedNormalStress);
case Config::Regularised:
return std::make_shared<GlobalRateStateFriction<
Matrix, Vector, RegularisedRateState, GridView>>(
frictionalBoundary, frictionInfo, weights, weightedNormalStress);
default:
assert(false);
}
}
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);
......
#ifndef SRC_ASSEMBLERS_HH
#define SRC_ASSEMBLERS_HH
#include <dune/common/bitsetvector.hh>
#include <dune/common/function.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/fufem/boundarypatch.hh>
#include "data-structures/friction/globalfriction.hh"
#include "data-structures/friction/globalfrictiondata.hh"
#include "data-structures/enums.hh"
template <class GridView, int dimension>
class MyAssembler {
public:
using GV = GridView;
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 CellBasis = P0Basis<GridView, double>;
using VertexBasis = P1NodalBasis<GridView, double>;
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 LocalCellBasis = typename CellBasis::LocalFiniteElement;
using LocalVertexBasis = typename VertexBasis::LocalFiniteElement;
Assembler<CellBasis, CellBasis> cellAssembler;
Assembler<VertexBasis, VertexBasis> vertexAssembler;
public:
MyAssembler(GridView const &gridView);
template <class LocalBoundaryFunctionalAssemblerType, class GlobalVectorType>
void assembleBoundaryFunctional(LocalBoundaryFunctionalAssemblerType& localAssembler,
GlobalVectorType& b,
const BoundaryPatch<GridView>& boundaryPatch,
bool initializeVector=true) const;
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(
const BoundaryPatch<GridView>& neumannBoundary,
const Dune::BitSetVector<dimension>& neumannNodes,
Vector& f,
const Dune::VirtualFunction<double, double>& neumann,
double relativeTime) const;
void assembleWeightedNormalStress(
BoundaryPatch<GridView> const &frictionalBoundary,
ScalarVector &weightedNormalStress,
ScalarVector &weights,
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
#ifndef MY_DIM
#error MY_DIM unset
#endif
#include "explicitgrid.hh"
#include "explicitvectors.hh"
#include <dune/fufem/assemblers/localassemblers/neumannboundaryassembler.hh>
#include <dune/fufem/boundarypatch.hh>
#include "assemblers.hh"
template class MyAssembler<DefLeafGridView, MY_DIM>;
using MyNeumannBoundaryAssembler = NeumannBoundaryAssembler<DeformedGrid, typename ScalarVector::block_type>;
template void MyAssembler<DefLeafGridView, MY_DIM>::assembleBoundaryFunctional<MyNeumannBoundaryAssembler, ScalarVector>(
MyNeumannBoundaryAssembler& localAssembler,
ScalarVector& b,
const BoundaryPatch<DefLeafGridView>& boundaryPatch,
bool initializeVector) const;
#ifndef MY_DIM
#error MY_DIM unset
#endif
#include "../explicitgrid.hh"
template class ContactNetwork<Grid, MY_DIM>;
add_subdirectory("body")
add_subdirectory("friction")
add_subdirectory("network")
add_custom_target(tectonic_dune_data-structures SOURCES
enumparser.hh
enumparser.cc
enums.hh
matrices.hh
program_state.hh
)
#install headers
install(FILES
enumparser.hh
enums.hh
matrices.hh
program_state.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/tectonic)
add_custom_target(tectonic_dune_data-structures_body SOURCES
body.hh
body.cc
bodydata.hh
boundarycondition.hh
)
#install headers
install(FILES
body.hh
bodydata.hh
boundarycondition.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/tectonic)
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <dune/common/hybridutilities.hh>
#include "body.hh"
#include <dune/tectonic/utils/debugutils.hh>
// -------------------------------
// --- LeafBody Implementation ---
// -------------------------------
template <class GridTEMPLATE, class VectorType>
LeafBody<GridTEMPLATE, VectorType>::LeafBody(
const std::shared_ptr<BodyData<dim>>& bodyData,
const std::shared_ptr<GridTEMPLATE>& hostGrid) :
bodyData_(bodyData),
hostGrid_(hostGrid),
deformation_(std::make_shared<DeformationFunction>(hostGrid_->leafGridView())),
grid_(std::make_shared<GridType>(*hostGrid_, *deformation_)),
gridView_(grid_->leafGridView()),
assembler_(std::make_shared<Assembler>(gridView_)),
matrices_()
{
boundaryConditions_.resize(0);
externalForce_ = [&](double relativeTime, VectorType &ell) {
// Problem formulation: right-hand side
std::vector<std::shared_ptr<BoundaryCondition>> leafNeumannConditions;
boundaryConditions("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(),
*leafNeumannCondition->boundaryNodes(),
b,
*leafNeumannCondition->boundaryFunction(),
relativeTime);
ell += b;
}
};
}
template <class GridTEMPLATE, class VectorType>
void LeafBody<GridTEMPLATE, VectorType>::assemble() {
// assemble matrices
assembler_->assembleElasticity(bodyData_->getYoungModulus(), bodyData_->getPoissonRatio(), *matrices_.elasticity);
//print(*matrices_.elasticity, "elasticity");
assembler_->assembleViscosity(bodyData_->getShearViscosityField(), bodyData_->getBulkViscosityField(), *matrices_.damping);
//print(*matrices_.damping, "viscosity");
assembler_->assembleMass(bodyData_->getDensityField(), *matrices_.mass);
//print(*matrices_.mass, "mass");
// assemble forces
assembler_->assembleBodyForce(bodyData_->getGravityField(), gravityFunctional_);
//print(gravityFunctional_, "gravity");
}
// setter and getter
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::data() const
-> const std::shared_ptr<BodyData<dim>>& {
return bodyData_;
}
template <class GridTEMPLATE, class VectorType>
void LeafBody<GridTEMPLATE, VectorType>::setDeformation(const VectorType& def) {
deformation_->setDeformation(def);
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::deformation() const
-> DeformationFunction& {
return *deformation_;
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::grid() const
-> std::shared_ptr<GridType> {
return grid_;
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::hostGrid() const
-> std::shared_ptr<GridTEMPLATE> {
return hostGrid_;
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::gridView() const
-> const GridView& {
return gridView_;
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::nVertices() const
-> size_t {
return gridView_.size(dim);
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::assembler() const
-> const std::shared_ptr<Assembler>& {
return assembler_;
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::matrices() const
-> const Matrices<Matrix,1>& {
return matrices_;
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::externalForce() const
-> const ExternalForce& {
return externalForce_;
}
template <class GridTEMPLATE, class VectorType>
void LeafBody<GridTEMPLATE, VectorType>::addBoundaryCondition(std::shared_ptr<BoundaryCondition> boundaryCondition) {
boundaryConditions_.emplace_back(boundaryCondition);
}
template <class GridTEMPLATE, class VectorType>
void LeafBody<GridTEMPLATE, VectorType>::boundaryConditions(
const std::string& tag,
std::vector<std::shared_ptr<BoundaryCondition>>& selectedConditions) const {
selectedConditions.resize(0);
for (size_t i=0; i<boundaryConditions_.size(); i++) {
if (boundaryConditions_[i]->tag() == tag)
selectedConditions.emplace_back(boundaryConditions_[i]);
}
}
template <class GridTEMPLATE, class VectorType>
auto LeafBody<GridTEMPLATE, VectorType>::boundaryConditions() const
-> const std::vector<std::shared_ptr<BoundaryCondition>>& {
return boundaryConditions_;
}
template <class GridTEMPLATE, class VectorType>
void LeafBody<GridTEMPLATE, VectorType>::boundaryPatchNodes(
const std::string& tag,
BoundaryPatchNodes& nodes) const {
std::vector<std::shared_ptr<typename LeafBody::BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(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 VectorType>
void LeafBody<GridTEMPLATE, VectorType>::boundaryNodes(
const std::string& tag,
BoundaryNodes& nodes) const {
std::vector<std::shared_ptr<typename LeafBody::BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(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 VectorType>
void LeafBody<GridTEMPLATE, VectorType>::boundaryFunctions(
const std::string& tag,
BoundaryFunctions& functions) const {
std::vector<std::shared_ptr<typename LeafBody::BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(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 VectorType>
void LeafBody<GridTEMPLATE, VectorType>::boundaryPatches(
const std::string& tag,
BoundaryPatches& patches) const {
std::vector<std::shared_ptr<typename LeafBody::BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(tag, _boundaryConditions);
patches.resize(_boundaryConditions.size());
for (size_t i=0; i<patches.size(); i++) {
patches[i] = _boundaryConditions[i]->boundaryPatch().get();
}
}
// ---------------------------
// --- Body Implementation ---
// ---------------------------
// setter and getter
template <class GridView>
auto Body<GridView>::data() const
-> const std::shared_ptr<BodyData<dim>>& {
return bodyData_;
}
template <class GridView>
auto Body<GridView>::grid() const
-> std::shared_ptr<GridType> {
return grid_;
}
template <class GridView>
auto Body<GridView>::gridView() const
-> const GridView& {
return gridView_;
}
template <class GridView>
auto Body<GridView>::nVertices() const
-> size_t {
return gridView_.size(dim);
}
template <class GridView>
void Body<GridView>::addBoundaryCondition(std::shared_ptr<BoundaryCondition> boundaryCondition) {
boundaryConditions_.push_back(boundaryCondition);
}
template <class GridView>
void Body<GridView>::boundaryConditions(
const std::string& tag,
std::vector<std::shared_ptr<BoundaryCondition>>& selectedConditions) const {
selectedConditions.resize(0);
for (size_t i=0; i<boundaryConditions_.size(); i++) {
if (boundaryConditions_[i]->tag() == tag)
selectedConditions.push_back(boundaryConditions_[i]);
}
}
template <class GridView>
auto Body<GridView>::boundaryConditions() const
-> const std::vector<std::shared_ptr<BoundaryCondition>>& {
return boundaryConditions_;
}
template <class GridView>
void Body<GridView>::boundaryPatchNodes(
const std::string& tag,
BoundaryPatchNodes& nodes) const {
std::vector<std::shared_ptr<BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(tag, _boundaryConditions);
nodes.resize(_boundaryConditions.size());
for (size_t i=0; i<nodes.size(); i++) {
nodes[i] = _boundaryConditions[i]->boundaryPatch()->getVertices();
}
}
template <class GridView>
void Body<GridView>::boundaryNodes(
const std::string& tag,
BoundaryNodes& nodes) const {
std::vector<std::shared_ptr<BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(tag, _boundaryConditions);
nodes.resize(_boundaryConditions.size());
for (size_t i=0; i<nodes.size(); i++) {
nodes[i] = _boundaryConditions[i]->boundaryNodes().get();
}
}
template <class GridView>
void Body<GridView>::boundaryFunctions(
const std::string& tag,
BoundaryFunctions& functions) const {
std::vector<std::shared_ptr<BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(tag, _boundaryConditions);
functions.resize(_boundaryConditions.size());
for (size_t i=0; i<functions.size(); i++) {
functions[i] = _boundaryConditions[i]->boundaryFunction().get();
}
}
template <class GridView>
void Body<GridView>::boundaryPatches(
const std::string& tag,
BoundaryPatches& patches) const {
std::vector<std::shared_ptr<BoundaryCondition>> _boundaryConditions;
this->boundaryConditions(tag, _boundaryConditions);
patches.resize(_boundaryConditions.size());
for (size_t i=0; i<patches.size(); i++) {
patches[i] = _boundaryConditions[i]->boundaryPatch().get();
}
}
#include "body_tmpl.cc"
#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
#ifndef MY_DIM
#error MY_DIM unset
#endif
#include "../../explicitgrid.hh"
#include "../../explicitvectors.hh"
template class LeafBody<Grid, Vector>;
template class Body<DefLeafGridView>;
template class Body<DefLevelGridView>;
#ifndef DUNE_TECTONIC_BODY_HH
#define DUNE_TECTONIC_BODY_HH
#ifndef DUNE_TECTONIC_BODY_DATA_HH
#define DUNE_TECTONIC_BODY_DATA_HH
template <int dimension> struct Body {
template <int dimension> struct BodyData {
using ScalarFunction =
Dune::VirtualFunction<Dune::FieldVector<double, dimension>,
Dune::FieldVector<double, 1>>;
......
#ifndef SRC_BOUNDARYCONDITION_HH
#define SRC_BOUNDARYCONDITION_HH
#include <dune/common/bitsetvector.hh>
#include <dune/common/function.hh>
#include <dune/fufem/boundarypatch.hh>
#include <dune/tectonic/utils/tobool.hh>
template <class GridView, int dims>
class BoundaryCondition {
public:
using BoundaryPatch = BoundaryPatch<GridView>;
private:
using Function = Dune::VirtualFunction<double, double>;
const std::string tag_; // store type of boundary condition, e.g. dirichlet, neumann, friction, etc
std::shared_ptr<BoundaryPatch> boundaryPatch_;
std::shared_ptr<Dune::BitSetVector<dims>> boundaryNodes_;
std::shared_ptr<Function> boundaryFunction_;
public:
BoundaryCondition(const std::string& tag = "") :
tag_(tag)
{}
BoundaryCondition(std::shared_ptr<BoundaryPatch> patch, std::shared_ptr<Function> function, const std::string& tag = "") :
tag_(tag),
boundaryFunction_(function)
{
setBoundaryPatch(patch);
}
void setBoundaryPatch(const GridView& gridView, std::shared_ptr<Dune::BitSetVector<dims>> nodes) {
boundaryNodes_ = nodes;
boundaryPatch_ = std::make_shared<BoundaryPatch>(gridView, *nodes);
}
void setBoundaryPatch(std::shared_ptr<BoundaryPatch> patch) {
boundaryPatch_ = patch;
auto nodes = patch->getVertices();
boundaryNodes_ = std::make_shared<Dune::BitSetVector<dims>>(nodes->size(), false);
for (size_t i=0; i<nodes->size(); i++) {
if (toBool((*nodes)[i])) {
for (size_t d=0; d<dims; d++) {
(*boundaryNodes_)[i][d] = true;
}
}
}
}
void setBoundaryPatch(const BoundaryPatch& patch) {
auto patch_ptr = std::make_shared<BoundaryPatch>(patch);
setBoundaryPatch(patch_ptr);
}
void setBoundaryFunction(std::shared_ptr<Function> function) {
boundaryFunction_ = function;
}
void set(std::shared_ptr<BoundaryPatch> patch, std::shared_ptr<Function> function) {
setBoundaryPatch(patch);
boundaryFunction_ = function;
}
const std::string& tag() const {
return tag_;
}
const std::shared_ptr<BoundaryPatch>& boundaryPatch() const {
return boundaryPatch_;
}
const std::shared_ptr<Dune::BitSetVector<dims>>& boundaryNodes() const {
return boundaryNodes_;
}
const std::shared_ptr<Function>& boundaryFunction() const {
return boundaryFunction_;
}
};
#endif
......@@ -32,6 +32,12 @@ Config::FrictionModel StringToEnum<Config::FrictionModel>::convert(
if (s == "Regularised")
return Config::Regularised;
if (s == "Tresca")
return Config::Tresca;
if (s == "None")
return Config::None;
DUNE_THROW(Dune::Exception, "failed to parse enum");
}
......
#ifndef SRC_ENUMPARSER_HH
#define SRC_ENUMPARSER_HH
#ifndef SRC_DATA_STRUCTURES_ENUMPARSER_HH
#define SRC_DATA_STRUCTURES_ENUMPARSER_HH
// Copyright Carsten Graeser 2012
......
......@@ -2,7 +2,7 @@
#define SRC_ENUMS_HH
struct Config {
enum FrictionModel { Truncated, Regularised };
enum FrictionModel { Truncated, Regularised, Tresca, None };
enum stateModel { AgeingLaw, SlipLaw };
enum scheme { Newmark, BackwardEuler };
enum PatchType { Rectangular, Trapezoidal };
......
add_custom_target(tectonic_dune_data-structures_friction SOURCES
frictioncouplingpair.hh
frictiondata.hh
frictionpotential.hh
globalfriction.hh
globalfrictiondata.hh
globalratestatefriction.hh
localfriction.hh
)
#install headers
install(FILES
frictioncouplingpair.hh
frictiondata.hh
frictionpotential.hh
globalfriction.hh
globalfrictiondata.hh
globalratestatefriction.hh
localfriction.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/tectonic)
#ifndef SRC_FRICTIONCOUPLINGPAIR_HH
#define SRC_FRICTIONCOUPLINGPAIR_HH
#include <dune/fufem/geometry/convexpolyhedron.hh>
#include <dune/contact/common/couplingpair.hh>
#include "globalfrictiondata.hh"
template <class GridType, class LocalVectorType, class field_type = double>
class FrictionCouplingPair : public Dune::Contact::CouplingPair<GridType, GridType, field_type>{
private:
static const int dim = GridType::dimensionworld;
using Base = Dune::Contact::CouplingPair<GridType,GridType,field_type>;
using LocalVector = LocalVectorType;
// friction data
std::shared_ptr<ConvexPolyhedron<LocalVector>> weakeningPatch_;
std::shared_ptr<GlobalFrictionData<dim>> frictionData_;
public:
void setWeakeningPatch(std::shared_ptr<ConvexPolyhedron<LocalVector>> weakeningPatch) {
weakeningPatch_ = weakeningPatch;
}
void setFrictionData(std::shared_ptr<GlobalFrictionData<dim>> frictionData) {
frictionData_ = frictionData;
}
const auto& weakeningPatch() const {
return *weakeningPatch_;
}
const auto& frictionData() const {
return *frictionData_;
}
};
#endif
......@@ -9,7 +9,7 @@
#include <dune/common/exceptions.hh>
#include <dune/common/function.hh>
#include <dune/tectonic/frictiondata.hh>
#include "frictiondata.hh"
class FrictionPotential {
public:
......@@ -37,30 +37,53 @@ class TruncatedRateState : public FrictionPotential {
if (V <= Vmin)
return 0.0;
return fd.a * std::log(V / Vmin);
//std::cout << "V: " << V << " Vmin: " << Vmin << std::endl;
auto res = fd.a * std::log(V / Vmin);
if (std::isinf(res)) {
//std::cout << "V: " << V << " Vmin: " << Vmin << std::endl;
}
return res;
}
double differential(double V) const override {
//std::cout << "differential: " << weight * fd.C - weightedNormalStress * coefficientOfFriction(V) << std::endl;
if (V <= Vmin)
return 0.0;
return weight * fd.C - weightedNormalStress * coefficientOfFriction(V);
}
double second_deriv(double V) const override {
//std::cout << "second deriv: " << ((V<=Vmin) ? 0.0 : -weightedNormalStress * (fd.a / V)) << std::endl;
if (V <= Vmin)
return 0;
return 0.0;
return -weightedNormalStress * (fd.a / V);
return - weightedNormalStress * (fd.a / V);
}
double regularity(double V) const override {
//std::cout << "regularity: " << ((std::abs(V - Vmin) < 1e-14) ? std::numeric_limits<double>::infinity() : std::abs(second_deriv(V))) << std::endl;
if (std::abs(V - Vmin) < 1e-14) // TODO
return std::numeric_limits<double>::infinity();
return std::abs(second_deriv(V));
}
double evaluate(double V) const override {
if (V <= Vmin)
return 0.0;
return weight * fd.C * V - weightedNormalStress * fd.a * V * (std::log(V / Vmin) - 1);
}
void updateAlpha(double alpha) override {
double const logrest = (fd.mu0 + fd.b * alpha) / fd.a;
Vmin = fd.V0 / std::exp(logrest);
//Vmin = 0.0;
}
private:
......@@ -92,6 +115,10 @@ class RegularisedRateState : public FrictionPotential {
return std::abs(second_deriv(V));
}
double evaluate(double V) const override {
return weight * fd.C * V - weightedNormalStress * 4 * fd.a * Vmin * std::pow(std::asinh(0.25 * V / Vmin), 2.0);
}
void updateAlpha(double alpha) override {
double const logrest = (fd.mu0 + fd.b * alpha) / fd.a;
Vmin = fd.V0 / std::exp(logrest);
......@@ -104,8 +131,48 @@ class RegularisedRateState : public FrictionPotential {
double Vmin;
};
class Tresca : public FrictionPotential {
public:
Tresca(double _weight, double _weightedNormalStress, FrictionData _fd)
: fd(_fd), weightedNormalStress(_weightedNormalStress) {}
double coefficientOfFriction(double V) const override {
return fd.mu0;
}
double differential(double V) const override {
//if (std::isinf(regularity(V)))
// return 0.0;
return - weightedNormalStress * coefficientOfFriction(V);
}
double second_deriv(double V) const override {
return 0;
}
double regularity(double V) const override {
if (std::abs(V) < 1e-7) // TODO
return std::numeric_limits<double>::infinity();
return std::abs(second_deriv(V));
}
double evaluate(double V) const override {
return - weightedNormalStress * fd.mu0 * V;
}
void updateAlpha(double alpha) override {}
private:
FrictionData const fd;
double const weightedNormalStress;
};
class ZeroFunction : public FrictionPotential {
public:
template <typename... Args>
ZeroFunction(Args... args) {}
double evaluate(double) const override { return 0; }
double coefficientOfFriction(double s) const override { return 0; }
......
......@@ -9,9 +9,10 @@
#include <dune/solvers/common/interval.hh>
#include <dune/tectonic/localfriction.hh>
#include "localfriction.hh"
template <class Matrix, class Vector> class GlobalFriction {
template <class Matrix, class Vector>
class GlobalFriction {
protected:
using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>;
......@@ -38,8 +39,9 @@ template <class Matrix, class Vector> class GlobalFriction {
LocalNonlinearity const virtual &restriction(size_t i) const = 0;
void addHessian(Vector const &v, Matrix &hessian) const {
for (size_t i = 0; i < v.size(); ++i)
for (size_t i = 0; i < v.size(); ++i) {
restriction(i).addHessian(v[i], hessian[i][i]);
}
}
void directionalDomain(Vector const &, Vector const &,
......@@ -76,11 +78,13 @@ template <class Matrix, class Vector> class GlobalFriction {
ScalarVector coefficientOfFriction(Vector const &x) const {
ScalarVector ret(x.size());
for (size_t i = 0; i < x.size(); ++i)
for (size_t i = 0; i < x.size(); ++i) {
ret[i] = restriction(i).coefficientOfFriction(x[i]);
}
return ret;
}
void virtual updateAlpha(ScalarVector const &alpha) = 0;
void virtual updateAlpha(const std::vector<ScalarVector>& alpha) = 0;
};
#endif
......@@ -4,7 +4,7 @@
#include <dune/common/function.hh>
#include <dune/common/fvector.hh>
#include <dune/tectonic/frictiondata.hh>
#include "frictiondata.hh"
template <class DomainType>
double evaluateScalarFunction(
......@@ -27,6 +27,7 @@ template <int dimension> class GlobalFrictionData {
Dune::VirtualFunction<Dune::FieldVector<double, dimension>,
Dune::FieldVector<double, 1>>;
public:
double virtual const &C() const = 0;
double virtual const &L() const = 0;
double virtual const &V0() const = 0;
......