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 Hooke's law for the box scheme. This computes | ||
11 | * the stress tensor and surface forces resulting from mechanical deformation. | ||
12 | */ | ||
13 | #ifndef DUMUX_DISCRETIZATION_BOX_HOOKES_LAW_HH | ||
14 | #define DUMUX_DISCRETIZATION_BOX_HOOKES_LAW_HH | ||
15 | |||
16 | #include <dune/common/fmatrix.hh> | ||
17 | |||
18 | #include <dumux/flux/hookeslaw.hh> | ||
19 | #include <dumux/discretization/method.hh> | ||
20 | #include <dumux/discretization/extrusion.hh> | ||
21 | |||
22 | namespace Dumux { | ||
23 | |||
24 | /*! | ||
25 | * \ingroup BoxFlux | ||
26 | * \brief Hooke's law for box scheme | ||
27 | * \tparam ScalarType the scalar type for scalar physical quantities | ||
28 | * \tparam GridGeometry the grid geometry | ||
29 | */ | ||
30 | template<class ScalarType, class GridGeometry> | ||
31 | class HookesLaw<ScalarType, GridGeometry, typename GridGeometry::DiscretizationMethod> | ||
32 | { | ||
33 | using FVElementGeometry = typename GridGeometry::LocalView; | ||
34 | using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; | ||
35 | using Extrusion = Extrusion_t<GridGeometry>; | ||
36 | |||
37 | using GridView = typename GridGeometry::GridView; | ||
38 | using Element = typename GridView::template Codim<0>::Entity; | ||
39 | |||
40 | static constexpr int dim = GridView::dimension; | ||
41 | static constexpr int dimWorld = GridView::dimensionworld; | ||
42 | static_assert(dim == dimWorld, "Hookes Law not implemented for network/surface grids"); | ||
43 | |||
44 | public: | ||
45 | //! export the type used for scalar values | ||
46 | using Scalar = ScalarType; | ||
47 | //! export the type used for the stress tensor | ||
48 | using StressTensor = Dune::FieldMatrix<Scalar, dim, dimWorld>; | ||
49 | //! export the type used for force vectors | ||
50 | using ForceVector = typename StressTensor::row_type; | ||
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 Returns the force (in Newton) acting on a sub-control volume face. | ||
59 | */ | ||
60 | template<class Problem, class ElementVolumeVariables, class ElementFluxVarsCache> | ||
61 | 7200 | 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 | 14400 | const auto sigma = stressTensor(problem, element, fvGeometry, elemVolVars, elemFluxVarCache[scvf]); | |
69 | |||
70 | 7200 | ForceVector scvfForce(0.0); | |
71 | 7200 | sigma.mv(scvf.unitOuterNormal(), scvfForce); | |
72 | 14400 | scvfForce *= Extrusion::area(fvGeometry, scvf); | |
73 | |||
74 | 7200 | return scvfForce; | |
75 | } | ||
76 | |||
77 | //! assembles the stress tensor at a given integration point | ||
78 | template<class Problem, class ElementVolumeVariables, class FluxVarsCache> | ||
79 | 1204576 | static StressTensor stressTensor(const Problem& problem, | |
80 | const Element& element, | ||
81 | const FVElementGeometry& fvGeometry, | ||
82 | const ElementVolumeVariables& elemVolVars, | ||
83 | const FluxVarsCache& fluxVarCache) | ||
84 | { | ||
85 | 2409152 | const auto& lameParams = problem.spatialParams().lameParams(element, fvGeometry, elemVolVars, fluxVarCache); | |
86 | |||
87 | // evaluate displacement gradient | ||
88 | 1204576 | StressTensor gradU(0.0); | |
89 |
2/2✓ Branch 0 taken 3585728 times.
✓ Branch 1 taken 1204576 times.
|
4790304 | for (int dir = 0; dir < dim; ++dir) |
90 |
4/4✓ Branch 0 taken 28461824 times.
✓ Branch 1 taken 3585728 times.
✓ Branch 2 taken 28461824 times.
✓ Branch 3 taken 3585728 times.
|
64095104 | for (const auto& scv : scvs(fvGeometry)) |
91 | 170770944 | gradU[dir].axpy(elemVolVars[scv.indexInElement()].displacement(dir), fluxVarCache.gradN(scv.indexInElement())); | |
92 | |||
93 | // evaluate strain tensor | ||
94 | 1204576 | StressTensor epsilon; | |
95 |
2/2✓ Branch 0 taken 3585728 times.
✓ Branch 1 taken 1204576 times.
|
4790304 | for (int i = 0; i < dim; ++i) |
96 |
2/2✓ Branch 0 taken 10701184 times.
✓ Branch 1 taken 3585728 times.
|
14286912 | for (int j = 0; j < dimWorld; ++j) |
97 | 74908288 | epsilon[i][j] = 0.5*(gradU[i][j] + gradU[j][i]); | |
98 | |||
99 | // calculate sigma | ||
100 | 1204576 | StressTensor sigma(0.0); | |
101 | const auto traceEpsilon = trace(epsilon); | ||
102 |
2/2✓ Branch 0 taken 3585728 times.
✓ Branch 1 taken 1204576 times.
|
4790304 | for (int i = 0; i < dim; ++i) |
103 | { | ||
104 | 7171456 | sigma[i][i] = lameParams.lambda()*traceEpsilon; | |
105 |
2/2✓ Branch 0 taken 10701184 times.
✓ Branch 1 taken 3585728 times.
|
14286912 | for (int j = 0; j < dimWorld; ++j) |
106 | 53505920 | sigma[i][j] += 2.0*lameParams.mu()*epsilon[i][j]; | |
107 | } | ||
108 | |||
109 | 1204576 | return sigma; | |
110 | } | ||
111 | }; | ||
112 | |||
113 | } // end namespace Dumux | ||
114 | |||
115 | #endif | ||
116 |