volumevariables.hh 11 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
63
64

    static constexpr bool onlyTracerComponents = true;
    using DiffusionCoefficients = typename Traits::DiffusionType::template DiffusionCoefficientsContainer<onlyTracerComponents>;
65
66

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

    /*!
72
     * \brief Updates all quantities for a given control volume.
73
74
75
76
77
78
     *
     * \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
79
     */
80
81
    template<class ElemSol, class Problem, class Element, class Scv>
    void update(const ElemSol &elemSol,
82
83
                const Problem &problem,
                const Element &element,
84
                const Scv &scv)
85
86
87
88
    {
        // update parent type sets primary variables
        ParentType::update(elemSol, problem, element, scv);

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

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

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

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

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

        diffCoeff_.update(getDiffusionCoefficient);
        effectiveDiffCoeff_.update(getEffectiveDiffusionCoefficient);
119
120
121
    }

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

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

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

145
    /*!
146
     * \brief Returns the saturation.
147
148
     *
     * This method is here for compatibility reasons with other models. The saturation
149
150
151
152
     * 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.

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

    /*!
159
     * \brief Returns the mobility.
160
161
162
     *
     * 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
163
     *
164
     * \param phaseIdx The phase index
165
     */
166
    Scalar mobility(int phaseIdx = 0) const
167
168
169
    { return 1.0; }

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

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

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

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

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

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

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

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

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

protected:
237
    SolidState solidState_;
238
    Scalar fluidDensity_, fluidMolarMass_;
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
268
269
    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; }

270
    // DispersivityType dispersivity_;
271
272
273
274
275
276
277

    // Binary diffusion coefficient
    DiffusionCoefficients diffCoeff_;

    // Effective diffusion coefficients for the phases
    DiffusionCoefficients effectiveDiffCoeff_;

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

} // end namespace Dumux

#endif