Line | Branch | Exec | Source |
---|---|---|---|
1 | // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||
2 | // vi: set et ts=4 sw=4 sts=4: | ||
3 | // | ||
4 | // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup BoxFlux | ||
10 | * \brief Specialization of the effective stress law for the box scheme. This computes the stress | ||
11 | * tensor and surface forces resulting from mechanical deformation and the pore pressure. | ||
12 | */ | ||
13 | #ifndef DUMUX_DISCRETIZATION_BOX_EFFECTIVE_STRESS_LAW_HH | ||
14 | #define DUMUX_DISCRETIZATION_BOX_EFFECTIVE_STRESS_LAW_HH | ||
15 | |||
16 | #include <dumux/flux/effectivestresslaw.hh> | ||
17 | #include <dumux/discretization/method.hh> | ||
18 | #include <dumux/discretization/extrusion.hh> | ||
19 | |||
20 | namespace Dumux { | ||
21 | |||
22 | /*! | ||
23 | * \ingroup BoxFlux | ||
24 | * \brief Effective stress law for box scheme | ||
25 | * \tparam StressType type used for the computation of | ||
26 | * purely mechanical stresses (i.e. material law) | ||
27 | * \tparam GridGeometry the finite volume grid geometry | ||
28 | */ | ||
29 | template<class StressType, class GridGeometry> | ||
30 | class EffectiveStressLaw<StressType, GridGeometry, typename GridGeometry::DiscretizationMethod> | ||
31 | { | ||
32 | using FVElementGeometry = typename GridGeometry::LocalView; | ||
33 | using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; | ||
34 | using Extrusion = Extrusion_t<GridGeometry>; | ||
35 | |||
36 | using GridView = typename GridGeometry::GridView; | ||
37 | using Element = typename GridView::template Codim<0>::Entity; | ||
38 | |||
39 | static constexpr int dim = GridView::dimension; | ||
40 | static constexpr int dimWorld = GridView::dimensionworld; | ||
41 | static_assert(dim == dimWorld, "EffectiveStressLaw not implemented for network/surface grids"); | ||
42 | static_assert(StressType::discMethod == DiscretizationMethods::box, "The provided stress type must be specialized for the box scheme"); | ||
43 | |||
44 | public: | ||
45 | //! export the type used for scalar values | ||
46 | using Scalar = typename StressType::Scalar; | ||
47 | //! export the type used for the stress tensor | ||
48 | using StressTensor = typename StressType::StressTensor; | ||
49 | //! export the type used for force vectors | ||
50 | using ForceVector = typename StressType::ForceVector; | ||
51 | //! state the discretization method this implementation belongs to | ||
52 | |||
53 | using DiscretizationMethod = DiscretizationMethods::Box; | ||
54 | // state the discretization method this implementation belongs to | ||
55 | static constexpr DiscretizationMethod discMethod{}; | ||
56 | |||
57 | /*! | ||
58 | * \brief Computes the force (in Newton) acting on a sub-control volume face. | ||
59 | */ | ||
60 | template<class Problem, class ElementVolumeVariables, class ElementFluxVarsCache> | ||
61 | 1196976 | static ForceVector force(const Problem& problem, | |
62 | const Element& element, | ||
63 | const FVElementGeometry& fvGeometry, | ||
64 | const ElementVolumeVariables& elemVolVars, | ||
65 | const SubControlVolumeFace& scvf, | ||
66 | const ElementFluxVarsCache& elemFluxVarCache) | ||
67 | { | ||
68 | 2393952 | const auto sigma = stressTensor(problem, element, fvGeometry, elemVolVars, elemFluxVarCache[scvf]); | |
69 | |||
70 | 1196976 | ForceVector scvfForce(0.0); | |
71 | 1196976 | sigma.mv(scvf.unitOuterNormal(), scvfForce); | |
72 | 2393952 | scvfForce *= Extrusion::area(fvGeometry, scvf); | |
73 | |||
74 | 1196976 | return scvfForce; | |
75 | } | ||
76 | |||
77 | //! assembles the (total) stress tensor of the porous medium at a given integration point | ||
78 | template<class Problem, class ElementVolumeVariables, class FluxVarsCache> | ||
79 | 1197176 | static StressTensor stressTensor(const Problem& problem, | |
80 | const Element& element, | ||
81 | const FVElementGeometry& fvGeometry, | ||
82 | const ElementVolumeVariables& elemVolVars, | ||
83 | const FluxVarsCache& fluxVarsCache) | ||
84 | { | ||
85 | // compute the purely mechanical stress | ||
86 | 1197176 | auto sigma = StressType::stressTensor(problem, element, fvGeometry, elemVolVars, fluxVarsCache); | |
87 | |||
88 | // obtain biot coefficient and effective pore pressure | ||
89 | 2394352 | const auto biotCoeff = problem.spatialParams().biotCoefficient(element, fvGeometry, elemVolVars, fluxVarsCache); | |
90 | 1210376 | const auto effPress = problem.spatialParams().effectivePorePressure(element, fvGeometry, elemVolVars, fluxVarsCache); | |
91 | |||
92 | // subtract pore pressure from the diagonal entries | ||
93 | 1197176 | const auto bcp = biotCoeff*effPress; | |
94 |
3/3✓ Branch 0 taken 26400 times.
✓ Branch 1 taken 3557728 times.
✓ Branch 2 taken 1183976 times.
|
4768104 | for (int i = 0; i < dim; ++i) |
95 | 10712784 | sigma[i][i] -= bcp; | |
96 | |||
97 | 1197176 | return sigma; | |
98 | } | ||
99 | |||
100 | //! assembles the (effective) stress tensor of the solid skeleton at a given integration point | ||
101 | template<class Problem, class ElementVolumeVariables, class FluxVarsCache> | ||
102 | static StressTensor effectiveStressTensor(const Problem& problem, | ||
103 | const Element& element, | ||
104 | const FVElementGeometry& fvGeometry, | ||
105 | const ElementVolumeVariables& elemVolVars, | ||
106 | const FluxVarsCache& fluxVarsCache) | ||
107 | 200 | { return StressType::stressTensor(problem, element, fvGeometry, elemVolVars, fluxVarsCache); } | |
108 | }; | ||
109 | |||
110 | } // end namespace Dumux | ||
111 | |||
112 | #endif | ||
113 |