volumevariables.hh 10.9 KB
Newer Older
1
2
3
4
5
6
7
// -*- 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    *
8
 *   the Free Software Foundation, either version 3 of the License, or       *
9
10
11
12
13
14
15
16
17
18
19
20
 *   (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 <http://www.gnu.org/licenses/>.   *
 *****************************************************************************/
/*!
 * \file
21
 * \ingroup TracerModel
22
 * \brief Quantities required by the tracer model in a control volume.
23
24
25
26
 */
#ifndef DUMUX_TRACER_VOLUME_VARIABLES_HH
#define DUMUX_TRACER_VOLUME_VARIABLES_HH

27
#include <type_traits>
Bernd Flemisch's avatar
Bernd Flemisch committed
28
#include <array>
29
#include <dune/common/std/type_traits.hh>
Bernd Flemisch's avatar
Bernd Flemisch committed
30

31
#include <dumux/porousmediumflow/volumevariables.hh>
Timo Koch's avatar
Timo Koch committed
32
#include <dumux/material/solidstates/updatesolidvolumefractions.hh>
33

34
namespace Dumux {
35

36
37
38
39
40
41
42
43
44
45
46
47
namespace Detail {
// helper structs and functions detecting if the user-defined spatial params class
// has user-specified functions saturation() for multi-phase tracer.
template <typename T, typename ...Ts>
using SaturationDetector = decltype(std::declval<T>().spatialParams().saturation(std::declval<Ts>()...));

template<class T, typename ...Args>
static constexpr bool hasSaturation()
{ return Dune::Std::is_detected<SaturationDetector, T, Args...>::value; }

} // end namespace Detail

48
49
50
51
52
/*!
 * \ingroup TracerModel
 * \brief Contains the quantities which are constant within a
 *        finite volume for the tracer model.
 */
53
54
template <class Traits>
class TracerVolumeVariables
55
: public PorousMediumFlowVolumeVariables<Traits>
56
{
57
    using ParentType = PorousMediumFlowVolumeVariables<Traits>;
58
59
    using Scalar = typename Traits::PrimaryVariables::value_type;
    static constexpr bool useMoles = Traits::ModelTraits::useMoles();
60
    using EffDiffModel = typename Traits::EffectiveDiffusivityModel;
61
    static constexpr int numFluidComps = ParentType::numFluidComponents();
62
    using DiffusionCoefficients = typename Traits::DiffusionType::template DiffusionCoefficientsContainer<1, numFluidComps>;
63
64

public:
65
    //! Export fluid system type
66
    using FluidSystem = typename Traits::FluidSystem;
67
    using SolidState = typename Traits::SolidState;
68
69

    /*!
70
     * \brief Updates all quantities for a given control volume.
71
72
73
74
75
76
     *
     * \param elemSol A vector containing all primary variables connected to the element
     * \param problem The object specifying the problem which ought to
     *                be simulated
     * \param element An element which contains part of the control volume
     * \param scv The sub-control volume
77
     */
78
79
    template<class ElemSol, class Problem, class Element, class Scv>
    void update(const ElemSol &elemSol,
80
81
                const Problem &problem,
                const Element &element,
82
                const Scv &scv)
83
84
85
86
    {
        // update parent type sets primary variables
        ParentType::update(elemSol, problem, element, scv);

87
        updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, ParentType::numFluidComponents());
88
        // dispersivity_ = problem.spatialParams().dispersivity(element, scv, elemSol);
89
90
91
92

        // the spatial params special to the tracer model
        fluidDensity_ = problem.spatialParams().fluidDensity(element, scv);
        fluidMolarMass_ = problem.spatialParams().fluidMolarMass(element, scv);
93
        fluidSaturation_ = saturation_(problem, element, scv);
94

95
        for (int compIdx = 0; compIdx < ParentType::numFluidComponents(); ++compIdx)
96
        {
97
            moleOrMassFraction_[compIdx] = this->priVars()[compIdx];
98
        }
99

100
        // Update the binary diffusion and effective diffusion coefficients.
101
102
        auto getDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx)
        {
103
104
            return FluidSystem::binaryDiffusionCoefficient( compIIdx,
                                                            compJIdx,
105
106
107
108
109
110
111
                                                            problem,
                                                            element,
                                                            scv);
        };

        auto getEffectiveDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx)
        {
112
            return EffDiffModel::effectiveDiffusionCoefficient(*this, phaseIdx, compIIdx, compJIdx);
113
114
115
116
        };

        diffCoeff_.update(getDiffusionCoefficient);
        effectiveDiffCoeff_.update(getEffectiveDiffusionCoefficient);
117
118
119
    }

    /*!
120
     * \brief Returns the density \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase.
121
122
     *
     * We always forward to the fluid state with the phaseIdx property (see class description).
123
     *
124
     * \param phaseIdx The phase index
125
     */
126
    Scalar density(int phaseIdx = 0) const
127
128
    { return fluidDensity_; }

129
    /*!
Kilian Weishaupt's avatar
Kilian Weishaupt committed
130
     * \brief Returns the average molar mass \f$\mathrm{[kg/mol]}\f$ of the fluid phase.
131
132
133
134
135
136
     *
     * \param phaseIdx The phase index
     */
    Scalar averageMolarMass(int phaseIdx = 0) const
    { return fluidMolarMass_; }

137
138
139
140
141
142
    /*!
     * \brief Returns the phase state for the control volume.
     */
    const SolidState &solidState() const
    { return solidState_; }

143
    /*!
144
     * \brief Returns the saturation.
145
146
     *
     * This method is here for compatibility reasons with other models. The saturation
147
148
149
150
     * is always 1.0 in a one-phasic context, if two-phases or richards are considered,
     * the spatialParams serve as way to pass the saturation from the main-file to the
     * volVars and then to the localresidual for the tracer model.

151
     * \param phaseIdx The phase index
152
     */
153
    Scalar saturation(int phaseIdx = 0) const
154
    { return fluidSaturation_ ; }
155
156

    /*!
157
     * \brief Returns the mobility.
158
159
160
     *
     * This method is here for compatibility reasons with other models. The mobility is always 1
     * for one-phasic models where the velocity field is given
161
     *
162
     * \param phaseIdx The phase index
163
     */
164
    Scalar mobility(int phaseIdx = 0) const
165
166
167
    { return 1.0; }

    /*!
168
     * \brief Returns the molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase.
169
     *
170
     * \param phaseIdx The phase index
171
     */
172
    Scalar molarDensity(int phaseIdx = 0) const
173
174
175
    { return fluidDensity_/fluidMolarMass_; }

    /*!
176
     * \brief Returns the mole fraction \f$\mathrm{[mol/mol]}\f$ of a component in the phase.
177
     *
178
     * \param phaseIdx The phase index
179
180
     * \param compIdx The index of the component
     */
181
    Scalar moleFraction(int phaseIdx, int compIdx) const
182
    { return useMoles ? moleOrMassFraction_[compIdx] : moleOrMassFraction_[compIdx]/FluidSystem::molarMass(compIdx)*fluidMolarMass_; }
183
184

    /*!
185
     * \brief Returns the mass fraction \f$\mathrm{[kg/kg]}\f$ of a component in the phase.
186
     *
187
     * \param phaseIdx The phase index
188
189
     * \param compIdx The index of the component
     */
190
    Scalar massFraction(int phaseIdx, int compIdx) const
191
    { return useMoles ? moleOrMassFraction_[compIdx]*FluidSystem::molarMass(compIdx)/fluidMolarMass_ : moleOrMassFraction_[compIdx]; }
192
193

    /*!
194
     * \brief Returns the concentration \f$\mathrm{[mol/m^3]}\f$  of a component in the phase.
195
     *
196
     * \param phaseIdx The phase index
197
198
     * \param compIdx The index of the component
     */
199
200
    Scalar molarity(int phaseIdx, int compIdx) const
    { return moleFraction(phaseIdx, compIdx)*molarDensity(); }
201

202
    /*!
203
     * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$.
204
     */
205
    [[deprecated("Signature deprecated. Use diffusionCoefficient(phaseIdx, compIIdx, compJIdx)!")]]
206
    Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
207
    { return diffCoeff_(0, 0, compIdx); }
208

209
    /*!
210
     * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$.
211
     */
212
    Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
213
    { return diffCoeff_(phaseIdx, compIIdx, compJIdx); }
214
215
216
217
218

    /*!
     * \brief Returns the effective diffusion coefficients for a phase in \f$[m^2/s]\f$.
     */
    Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
219
    { return effectiveDiffCoeff_(phaseIdx, compIIdx, compJIdx); }
220

221
222
223
224
225
226
    // /*!
    //  * \brief Returns the dispersivity of the fluid's streamlines.
    //  * \todo implement me
    //  */
    // const DispersivityType &dispersivity() const
    // { return dispersivity_; }
227
228
229
230
231

    /*!
     * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume.
     */
    Scalar porosity() const
232
    { return solidState_.porosity(); }
233
234

protected:
235
    SolidState solidState_;
236
    Scalar fluidDensity_, fluidMolarMass_;
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
    Scalar fluidSaturation_ = 1.0;
    /*!
     * \brief Gets the saturation in an scv.
     *
     * \param problem the problem to solve
     * \param element the element (codim-0-entity) the scv belongs to
     * \param scv the sub control volume
     * \note this gets selected if the user uses the multiphase tracer
     */
     template<class Problem, class Element, class Scv,
              std::enable_if_t<Detail::hasSaturation<Problem, Element, Scv>(), int> = 0>
     Scalar saturation_(const Problem& problem,
                        const Element& element,
                        const Scv& scv)
     { return problem.spatialParams().saturation(element, scv); }

    /*!
     * \brief Gets the saturation in an scv.
     *
     * \param problem the problem to solve
     * \param element the element (codim-0-entity) the scv belongs to
     * \param scv the sub control volume
     * \note this gets selected if the user a single phase tracer
     */
    template<class Problem, class Element, class Scv,
             std::enable_if_t<!Detail::hasSaturation<Problem, Element, Scv>(), int> = 0>
    Scalar saturation_(const Problem& problem,
                       const Element &element,
                       const Scv &scv)
    { return 1.0; }

268
    // DispersivityType dispersivity_;
269
270
271
272
273
274
275

    // Binary diffusion coefficient
    DiffusionCoefficients diffCoeff_;

    // Effective diffusion coefficients for the phases
    DiffusionCoefficients effectiveDiffCoeff_;

276
    std::array<Scalar, ParentType::numFluidComponents()> moleOrMassFraction_;
277
278
279
280
281
};

} // end namespace Dumux

#endif