// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
*****************************************************************************/
/**
* \file
* \brief Definition of a problem, for the linear elasticity problem:
* Problem definition for the deformation of an elastic solid.
*/
#ifndef DUMUX_ELASTICMATRIXPROBLEM_HH
#define DUMUX_ELASTICMATRIXPROBLEM_HH
#include
#include
#include
#include "elasticspatialparams.hh"
namespace Dumux
{
template
class ElasticMatrixProblem;
namespace Properties
{
NEW_TYPE_TAG(ElasticMatrixProblem, INHERITS_FROM(BoxElastic,ElSpatialParams));
// Set the grid type
SET_TYPE_PROP(ElasticMatrixProblem, Grid, Dune::YaspGrid<3>);
// Set the problem property
SET_TYPE_PROP(ElasticMatrixProblem, Problem, Dumux::ElasticMatrixProblem);
}
/*!
* \ingroup ElasticBoxProblems
* \ingroup ImplicitTestProblems
*
* \brief Problem definition for the deformation of an elastic matrix.
*
* The problem defined here leads to the following linear distribution of the
* solid displacement: u(x,y,z) = 1/E * (x,0,-nu*z) which for the given grid
* The numerical results can be verified analytically.
*
* The 3D domain given in linearelastic.dgf spans from (0,0,0) to (10,1,10).
*
* Dirichlet boundary conditions (u=0.0) are applied for the displacement in y-direction
* in the whole domain, for the displacement in x-direction on the left boundary (x < eps)
* and for the displacement in z-direction for the lower left edge (x./test_elastic -parameterFile ./test_elastic.input
*/
template
class ElasticMatrixProblem: public ImplicitPorousMediaProblem
{
typedef ImplicitPorousMediaProblem ParentType;
typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;
// copy some indices for convenience
typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
enum {
// Grid and world dimension
dim = GridView::dimension,
dimWorld = GridView::dimensionworld,
};
enum {
// indices of the primary variables
uxIdx = Indices::uxIdx,
uyIdx = Indices::uyIdx,
uzIdx = Indices::uzIdx,
};
enum {
// indices of the equations
momentumXEqIdx = Indices::momentumXEqIdx,
momentumYEqIdx = Indices::momentumYEqIdx,
momentumZEqIdx = Indices::momentumZEqIdx,
};
typedef typename GridView::template Codim<0>::Entity Element;
typedef typename GridView::template Codim::Entity Vertex;
typedef typename GridView::Intersection Intersection;
typedef Dune::FieldVector GlobalPosition;
public:
ElasticMatrixProblem(TimeManager &timeManager, const GridView &gridView)
: ParentType(timeManager, gridView)
{}
/*!
* \name Problem parameters
*/
// \{
/*!
* \brief The problem name.
*
* This is used as a prefix for files generated by the simulation.
*/
const char *name() const
{ return "elasticmatrix";}
// \}
/*!
* \name Boundary conditions
*/
// \{
/*!
* \brief Specifies which kind of boundary condition should be
* used for which equation on a given boundary segment.
*
* \param values The boundary types for the conservation equations
* \param globalPos The global position
*/
void boundaryTypesAtPos(BoundaryTypes &values,
const GlobalPosition &globalPos) const
{
values.setAllNeumann();
values.setDirichlet(uyIdx);
if(globalPos[0] < eps_)
{
values.setDirichlet(uxIdx);
if(globalPos[2] < eps_)
values.setDirichlet(uzIdx);
}
}
/*!
* \brief Evaluate the boundary conditions for a Dirichlet
* boundary segment.
*
* \param values The Dirichlet values for the primary variables
* \param vertex The vertex for which the boundary type is set
*
* For this method, the \a values parameter stores primary variables.
*/
void dirichlet(PrimaryVariables &values, const Vertex &vertex) const
{
values = 0.0;
}
/*!
* \brief Evaluate the boundary conditions for a Neumann
* boundary segment.
*
* For this method, the \a values parameter stores the mass flux
* in normal direction of each phase. Negative values mean influx.
*/
void neumann(PrimaryVariables &values,
const Element &element,
const FVElementGeometry &fvGeometry,
const Intersection &intersection,
int scvIdx,
int boundaryFaceIdx) const
{
values = 0.0;
// get Lame parameters
Scalar lambda = this->spatialParams().lameParams(element, fvGeometry, scvIdx)[0];
Scalar mu = this->spatialParams().lameParams(element, fvGeometry, scvIdx)[1];
Scalar E = this->spatialParams().E(element, fvGeometry, scvIdx);
Scalar nu = this->spatialParams().nu(element, fvGeometry, scvIdx);
// calculate values of sigma in normal direction
Dune::FieldMatrix sigma(0);
sigma[0][0] = 2.0*mu + lambda*(1 - nu);
sigma[1][1] = lambda*(1 - nu);
sigma[2][2] = -2.0*mu*nu + lambda*(1 - nu);
sigma *= -1.0/E;
// determine normal vector of current face
Dune::FieldVector localDimM1(0);
Dune::FieldVector normal = intersection.unitOuterNormal(localDimM1);
// use stress in normal direction as boundary condition
sigma.mv(normal, values);
}
// \}
/*!
* \name Volume terms
*/
// \{
/*!
* \brief Evaluate the source term for all phases within a given
* sub-control-volume.
*
* For this method, the \a priVars parameter stores the rate momentum
* is generated or annihilate per volume
* unit. Positive values mean that momentum is created, negative ones
* mean that it vanishes.
*/
void sourceAtPos(PrimaryVariables &priVars,
const GlobalPosition &globalPos) const
{
priVars = Scalar(0.0);
}
/*!
* \brief Evaluate the initial value for a control volume.
*
* \param values The initial values for the primary variables
* \param globalPos The position for which the initial condition should be evaluated
*
* For this method, the \a values parameter stores primary
* variables.
*/
void initialAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const
{
initial_(values, globalPos);
}
// \}
private:
// the internal method for the initial condition
void initial_(PrimaryVariables &priVars,
const GlobalPosition &globalPos) const
{
priVars = 0.0; // initial condition for the solid displacement
}
static constexpr Scalar eps_ = 3e-6;
};
} //end namespace
#endif