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 Experimental | ||
10 | * \ingroup Assembly | ||
11 | * \brief A local operator wrapper for multi-stage time stepping schemes | ||
12 | */ | ||
13 | #ifndef DUMUX_EXPERIMENTAL_MULTISTAGE_FV_LOCAL_OPERATOR_HH | ||
14 | #define DUMUX_EXPERIMENTAL_MULTISTAGE_FV_LOCAL_OPERATOR_HH | ||
15 | |||
16 | #include <cmath> | ||
17 | #include <dumux/discretization/extrusion.hh> | ||
18 | |||
19 | namespace Dumux::Experimental { | ||
20 | |||
21 | template<class LocalOperator> | ||
22 | class MultiStageFVLocalOperator | ||
23 | { | ||
24 | using ElementOperatorResultVector = typename LocalOperator::ElementResidualVector; | ||
25 | public: | ||
26 | // compatibility | ||
27 | using ElementResidualVector = ElementOperatorResultVector; | ||
28 | |||
29 | 5062100 | MultiStageFVLocalOperator(const LocalOperator& op) | |
30 | : op_(op) | ||
31 | , spatialWeight_(1.0) | ||
32 |
3/6✓ Branch 1 taken 5057344 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4736 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
|
5062100 | , temporalWeight_(1.0) |
33 | {} | ||
34 | |||
35 | // discretization-agnostic interface (apart from FV) | ||
36 | template<class FVGeometry, class ElemVolVars> | ||
37 | 21244928 | ElementOperatorResultVector evalStorage( | |
38 | const FVGeometry& fvGeometry, | ||
39 | const ElemVolVars& elemVolVars | ||
40 | ) const { | ||
41 |
2/4✓ Branch 0 taken 20784896 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20784896 times.
✗ Branch 3 not taken.
|
42489856 | ElementOperatorResultVector result(fvGeometry.numScv()); |
42 | |||
43 |
2/4✓ Branch 0 taken 20784896 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20784896 times.
✗ Branch 3 not taken.
|
42489856 | if (std::abs(temporalWeight_) > 1e-6) |
44 | { | ||
45 |
4/4✓ Branch 0 taken 21976960 times.
✓ Branch 1 taken 20784896 times.
✓ Branch 2 taken 21538560 times.
✓ Branch 3 taken 20346496 times.
|
87780608 | for (const auto& scv : scvs(fvGeometry)) |
46 | 23050752 | result[scv.localDofIndex()] += | |
47 | 26035456 | op_.computeStorage(op_.problem(), scv, elemVolVars[scv]) | |
48 | 27372288 | * elemVolVars[scv].extrusionFactor() | |
49 | 47504384 | * Extrusion_t<typename FVGeometry::GridGeometry>::volume(fvGeometry, scv) | |
50 | 90800128 | * temporalWeight_; | |
51 | } | ||
52 | |||
53 | 21244928 | return result; | |
54 | } | ||
55 | |||
56 | // discretization-agnostic interface (apart from FV) | ||
57 | template<class FVGeometry, class ElemVolVars, class ElemFluxVars, class ElemBCTypes> | ||
58 | 11263104 | ElementOperatorResultVector evalFluxAndSource( | |
59 | const typename FVGeometry::Element&, // not needed, here for compatibility | ||
60 | const FVGeometry& fvGeometry, | ||
61 | const ElemVolVars& elemVolVars, | ||
62 | const ElemFluxVars& elemFluxVarsCache, | ||
63 | const ElemBCTypes& bcTypes | ||
64 | ) const { | ||
65 |
2/4✓ Branch 0 taken 10793984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10793984 times.
✗ Branch 3 not taken.
|
22526208 | ElementOperatorResultVector result(fvGeometry.numScv()); |
66 |
2/4✓ Branch 0 taken 10793984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10793984 times.
✗ Branch 3 not taken.
|
22526208 | if (std::abs(spatialWeight_) > 1e-6) |
67 | { | ||
68 | 22526208 | result = op_.evalFluxAndSource(fvGeometry.element(), fvGeometry, elemVolVars, elemFluxVarsCache, bcTypes); | |
69 |
2/2✓ Branch 0 taken 12058624 times.
✓ Branch 1 taken 10793984 times.
|
47003392 | for (auto& r : result) |
70 | 13214080 | r *= spatialWeight_; | |
71 | } | ||
72 | |||
73 | 11263104 | return result; | |
74 | } | ||
75 | |||
76 | // interface allowing for optimization when computing the cell-centered finite volume Jacobian | ||
77 | template<class Problem, class FVGeometry, class ElemVolVars, class ElemFluxVars> | ||
78 | 1612896 | auto evalFlux( | |
79 | const Problem&, // not needed | ||
80 | const typename FVGeometry::Element& element, // can be neighbor | ||
81 | const FVGeometry& fvGeometry, | ||
82 | const ElemVolVars& elemVolVars, | ||
83 | const ElemFluxVars& elemFluxVarsCache, | ||
84 | const typename FVGeometry::SubControlVolumeFace& scvf | ||
85 | ) const { | ||
86 | using NumEqVector = std::decay_t<decltype(op_.evalFlux(op_.problem(), element, fvGeometry, elemVolVars, elemFluxVarsCache, scvf))>; | ||
87 | 1612896 | NumEqVector result(0.0); | |
88 |
2/4✓ Branch 0 taken 1612896 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1612896 times.
✗ Branch 3 not taken.
|
3225792 | if (std::abs(spatialWeight_) > 1e-6) |
89 | { | ||
90 | 1612896 | result = op_.evalFlux(op_.problem(), element, fvGeometry, elemVolVars, elemFluxVarsCache, scvf); | |
91 | result *= spatialWeight_; | ||
92 | } | ||
93 | 1612896 | return result; | |
94 | } | ||
95 | |||
96 |
5/10✓ Branch 1 taken 2515744 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2500000 times.
✓ Branch 4 taken 3072 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4352 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1280 times.
✗ Branch 10 not taken.
|
5034816 | void spatialWeight(double w) { spatialWeight_ = w; } |
97 | ✗ | double spatialWeight() const { return spatialWeight_; } | |
98 | |||
99 |
5/10✓ Branch 1 taken 2515744 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2500000 times.
✓ Branch 4 taken 3072 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4352 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1280 times.
✗ Branch 10 not taken.
|
5034816 | void temporalWeight(double w) { temporalWeight_ = w; } |
100 | double temporalWeight() const { return temporalWeight_; } | ||
101 | |||
102 | const auto& problem() const | ||
103 | { return op_.problem(); } | ||
104 | |||
105 | // some old interface (TODO: get rid of this) | ||
106 | // (stationary is also the wrong word by the way, systems with zero | ||
107 | // time derivative are in a steady-state but not necessarily stationary/not-moving at all) | ||
108 | // can we decide this somehow from the temporal weight? | ||
109 | ✗ | bool isStationary() const | |
110 | ✗ | { return false; } | |
111 | |||
112 | private: | ||
113 | LocalOperator op_; | ||
114 | double spatialWeight_, temporalWeight_; // TODO: get correct type | ||
115 | }; | ||
116 | |||
117 | } // end namespace Dumux::Experimental | ||
118 | |||
119 | #endif | ||
120 |