interactionvolumedatahandle.hh 18.7 KB
Newer Older
Dennis Gläser's avatar
Dennis Gläser committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// -*- 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    *
 *   the Free Software Foundation, either version 2 of the License, or       *
 *   (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
 * \brief Data handle class for interaction volumes of mpfa methods.
 *        This class is passed to interaction volumes to store the necessary data in it.
 */
#ifndef DUMUX_DISCRETIZATION_CC_MPFA_INTERACTIONVOLUMEDATAHANDLE_HH
#define DUMUX_DISCRETIZATION_CC_MPFA_INTERACTIONVOLUMEDATAHANDLE_HH

27
#include <dune/common/exceptions.hh>
Timo Koch's avatar
Timo Koch committed
28
29
#include <dumux/common/properties.hh>

Dennis Gläser's avatar
Dennis Gläser committed
30
31
namespace Dumux
{
32
    //! Empty data handle class
Dennis Gläser's avatar
Dennis Gläser committed
33
    template<class TypeTag>
34
35
36
37
38
39
40
41
    class EmptyDataHandle
    {
        //! we use the dynamic types here to be compatible on the boundary
        using InteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
        using DirichletDataContainer = typename InteractionVolume::DirichletDataContainer;
        using GlobalIndexContainer = typename InteractionVolume::Traits::DynamicGlobalIndexContainer;
        using Matrix = typename InteractionVolume::Traits::DynamicMatrix;
        using Vector = typename InteractionVolume::Traits::DynamicVector;
Dennis Gläser's avatar
Dennis Gläser committed
42

43
44
45
46
47
48
49
50
51
    public:
        //! diffusion caches need to set phase and component index
        void setDiffusionContext(unsigned int phaseIdx, unsigned int compIdx) {}

        //! functions to set the size of the matrices
        void resizeT(unsigned int n, unsigned int m) {}
        void resizeAB(unsigned int n, unsigned int m) {}
        void resizeOutsideTij(unsigned int n, unsigned int m) {}

52
        //! functions to set the pointers to the stencil
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
        void setVolVarsStencilPointer(const GlobalIndexContainer& stencil) {}

        //! return functions for the stored data
        const GlobalIndexContainer& volVarsStencil() const { return throw_<const GlobalIndexContainer&>(); }
        const DirichletDataContainer& dirichletData() const { return throw_<DirichletDataContainer&>(); }

        const Matrix& T() const { return throw_<const Matrix&>(); }
        Matrix& T() { return throw_<Matrix&>(); }

        const Matrix& AB() const { return throw_<const Matrix&>(); }
        Matrix& AB() { return throw_<Matrix&>(); }

        const Matrix& outsideTij() const { return throw_<const Matrix&>(); }
        Matrix& outsideTij() { return throw_<Matrix&>(); }

    private:
        template<class ReturnType>
        ReturnType throw_() const { DUNE_THROW(Dune::InvalidStateException, "Trying to access data for a deactivated physical process"); }
    };

    //! Data handle for quantities related to advection
    template<class TypeTag, bool EnableAdvection>
    class AdvectionDataHandle
Dennis Gläser's avatar
Dennis Gläser committed
76
    {
77
78
79
80
81
82
83
84
        //! we use the dynamic types here to be compatible on the boundary
        using InteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
        using DirichletDataContainer = typename InteractionVolume::DirichletDataContainer;
        using GlobalIndexContainer = typename InteractionVolume::Traits::DynamicGlobalIndexContainer;
        using Matrix = typename InteractionVolume::Traits::DynamicMatrix;
        using Vector = typename InteractionVolume::Traits::DynamicVector;

    public:
85
        //! set the sizes of the matrices
86
87
88
89
        void resizeT(unsigned int n, unsigned int m) { advectionT_.resize(n, m); }
        void resizeAB(unsigned int n, unsigned int m) { advectionAB_.resize(n, m); }
        void resizeOutsideTij(unsigned int n, unsigned int m) { advectionTout_.resize(n, m); }

90
        //! sets the pointer to the stencil
91
92
93
94
95
96
97
98
99
100
101
102
103
104
        void setVolVarsStencilPointer(const GlobalIndexContainer& stencil) { advectionVolVarsStencil_ = &stencil; }

        //! return functions for the stored data
        const GlobalIndexContainer& volVarsStencil() const { return *advectionVolVarsStencil_; }

        const Matrix& T() const { return advectionT_; }
        Matrix& T() { return advectionT_; }

        const Matrix& AB() const { return advectionAB_; }
        Matrix& AB() { return advectionAB_; }

        const Matrix& outsideTij() const { return advectionTout_; }
        Matrix& outsideTij() { return advectionTout_; }

Dennis Gläser's avatar
Dennis Gläser committed
105
    private:
106
        // advection-related variables
107
108
109
110
        const GlobalIndexContainer* advectionVolVarsStencil_;  //!< Pointer to the global volvar indices (stored in the interaction volume)
        Matrix advectionT_;                                    //!< The transmissibilities
        Matrix advectionAB_;                                   //!< Coefficients for gradient reconstruction
        Matrix advectionTout_;                                 //!< The transmissibilities associated with "outside" faces (only necessary on surface grids)
111
    };
Dennis Gläser's avatar
Dennis Gläser committed
112

113
114
115
116
    //! Data handle for quantities related to diffusion
    template<class TypeTag, bool EnableDiffusion>
    class DiffusionDataHandle
    {
Dennis Gläser's avatar
Dennis Gläser committed
117
118
119
120
121
122
123
        //! we use the dynamic types here to be compatible on the boundary
        using InteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
        using DirichletDataContainer = typename InteractionVolume::DirichletDataContainer;
        using GlobalIndexContainer = typename InteractionVolume::Traits::DynamicGlobalIndexContainer;
        using Matrix = typename InteractionVolume::Traits::DynamicMatrix;
        using Vector = typename InteractionVolume::Traits::DynamicVector;

124
125
126
        static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases);
        static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents);

Dennis Gläser's avatar
Dennis Gläser committed
127
    public:
128
129
        //! diffusion caches need to set phase and component index
        void setDiffusionContext(unsigned int phaseIdx, unsigned int compIdx)
Dennis Gläser's avatar
Dennis Gläser committed
130
        {
131
132
133
            contextPhaseIdx_ = phaseIdx;
            contextCompIdx_ = compIdx;
        }
Dennis Gläser's avatar
Dennis Gläser committed
134

135
        //! set the sizes of the matrices
136
137
138
139
140
141
        void resizeT(unsigned int n, unsigned int m)
        {
            for (auto& array : diffusionT_)
                for (auto& matrix : array)
                    matrix.resize(n, m);
        }
Dennis Gläser's avatar
Dennis Gläser committed
142

143
144
145
146
147
148
        void resizeAB(unsigned int n, unsigned int m)
        {
            for (auto& array : diffusionAB_)
                for (auto& matrix : array)
                    matrix.resize(n, m);
        }
Dennis Gläser's avatar
Dennis Gläser committed
149

150
151
152
153
154
155
156
        void resizeOutsideTij(unsigned int n, unsigned int m)
        {
            for (auto& array : diffusionTout_)
                for (auto& matrix : array)
                    matrix.resize(n, m);
        }

157
        //! sets the pointer to stencil
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
        void setVolVarsStencilPointer(const GlobalIndexContainer& stencil)
        {
            diffusionVolVarsStencil_[contextPhaseIdx_][contextCompIdx_] = &stencil;
        }

        //! return functions for the stored data
        const GlobalIndexContainer& volVarsStencil() const
        { return *diffusionVolVarsStencil_[contextPhaseIdx_][contextCompIdx_]; }

        const Matrix& T() const { return diffusionT_[contextPhaseIdx_][contextCompIdx_]; }
        Matrix& T() { return diffusionT_[contextPhaseIdx_][contextCompIdx_]; }

        const Matrix& AB() const { return diffusionAB_[contextPhaseIdx_][contextCompIdx_]; }
        Matrix& AB() { return diffusionAB_[contextPhaseIdx_][contextCompIdx_]; }

        const Matrix& outsideTij() const { return diffusionTout_[contextPhaseIdx_][contextCompIdx_]; }
        Matrix& outsideTij() { return diffusionTout_[contextPhaseIdx_][contextCompIdx_]; }

    private:
        // diffusion-related variables (see comments in AdvectionDataHandle)
178
179
        unsigned int contextPhaseIdx_;                         //!< The phase index set for the context
        unsigned int contextCompIdx_;                          //!< The component index set for the context
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
        std::array<std::array<const GlobalIndexContainer*, numComponents>, numPhases> diffusionVolVarsStencil_;
        std::array<std::array<Matrix, numComponents>, numPhases> diffusionT_;
        std::array<std::array<Matrix, numComponents>, numPhases> diffusionAB_;
        std::array<std::array<Matrix, numComponents>, numPhases> diffusionTout_;
    };

    //! Data handle for quantities related to advection
    template<class TypeTag, bool EnableHeatConduction>
    class HeatConductionDataHandle
    {
        //! we use the dynamic types here to be compatible on the boundary
        using InteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
        using DirichletDataContainer = typename InteractionVolume::DirichletDataContainer;
        using GlobalIndexContainer = typename InteractionVolume::Traits::DynamicGlobalIndexContainer;
        using Matrix = typename InteractionVolume::Traits::DynamicMatrix;
        using Vector = typename InteractionVolume::Traits::DynamicVector;
Dennis Gläser's avatar
Dennis Gläser committed
196

197
    public:
198
        //! set the sizes of the matrices
199
200
201
        void resizeT(unsigned int n, unsigned int m) { heatConductionT_.resize(n, m); }
        void resizeAB(unsigned int n, unsigned int m) { heatConductionAB_.resize(n, m); }
        void resizeOutsideTij(unsigned int n, unsigned int m) { heatConductionTout_.resize(n, m); }
Dennis Gläser's avatar
Dennis Gläser committed
202

203
        //! sets the pointer to the stencil
204
        void setVolVarsStencilPointer(const GlobalIndexContainer& stencil) { heatConductionVolVarsStencil_ = &stencil; }
Dennis Gläser's avatar
Dennis Gläser committed
205
206

        //! return functions for the stored data
207
        const GlobalIndexContainer& volVarsStencil() const { return *heatConductionVolVarsStencil_; }
Dennis Gläser's avatar
Dennis Gläser committed
208

209
210
        const Matrix& T() const { return heatConductionT_; }
        Matrix& T() { return heatConductionT_; }
Dennis Gläser's avatar
Dennis Gläser committed
211

212
213
        const Matrix& AB() const { return heatConductionAB_; }
        Matrix& AB() { return heatConductionAB_; }
Dennis Gläser's avatar
Dennis Gläser committed
214

215
216
        const Matrix& outsideTij() const { return heatConductionTout_; }
        Matrix& outsideTij() { return heatConductionTout_; }
Dennis Gläser's avatar
Dennis Gläser committed
217
218

    private:
219
        // heat conduction-related variables
220
221
222
223
        const GlobalIndexContainer* heatConductionVolVarsStencil_;  //!< Pointer to the global volvar indices (stored in the interaction volume)
        Matrix heatConductionT_;                                    //!< The transmissibilities
        Matrix heatConductionAB_;                                   //!< Coefficients for gradient reconstruction
        Matrix heatConductionTout_;                                 //!< The transmissibilities associated with "outside" faces (only necessary on surface grids)
Dennis Gläser's avatar
Dennis Gläser committed
224
225
    };

226
227
228
229
230
231
    //! Process-dependet data handle when related process is disabled
    template<class TypeTag> class AdvectionDataHandle<TypeTag, false> : public EmptyDataHandle<TypeTag> {};
    template<class TypeTag> class DiffusionDataHandle<TypeTag, false> : public EmptyDataHandle<TypeTag> {};
    template<class TypeTag> class HeatConductionDataHandle<TypeTag, false> : public EmptyDataHandle<TypeTag> {};

    //! Interaction volume data handle class
Dennis Gläser's avatar
Dennis Gläser committed
232
    template<class TypeTag>
233
234
235
    class InteractionVolumeDataHandle : public AdvectionDataHandle<TypeTag, GET_PROP_VALUE(TypeTag, EnableAdvection)>,
                                        public DiffusionDataHandle<TypeTag, GET_PROP_VALUE(TypeTag, EnableMolecularDiffusion)>,
                                        public HeatConductionDataHandle<TypeTag, GET_PROP_VALUE(TypeTag, EnableEnergyBalance)>
Dennis Gläser's avatar
Dennis Gläser committed
236
    {
237
238
239
        using AdvectionHandle = AdvectionDataHandle<TypeTag, GET_PROP_VALUE(TypeTag, EnableAdvection)>;
        using DiffusionHandle = DiffusionDataHandle<TypeTag, GET_PROP_VALUE(TypeTag, EnableMolecularDiffusion)>;
        using HeatConductionHandle = HeatConductionDataHandle<TypeTag, GET_PROP_VALUE(TypeTag, EnableEnergyBalance)>;
Dennis Gläser's avatar
Dennis Gläser committed
240
241
242
243
244
245
246
247
248
249
250
251
252

        //! we use the dynamic types here to be compatible on the boundary
        using InteractionVolume = typename GET_PROP_TYPE(TypeTag, PrimaryInteractionVolume);
        using DirichletDataContainer = typename InteractionVolume::DirichletDataContainer;
        using GlobalIndexContainer = typename InteractionVolume::Traits::DynamicGlobalIndexContainer;
        using Matrix = typename InteractionVolume::Traits::DynamicMatrix;
        using Vector = typename InteractionVolume::Traits::DynamicVector;

    public:
        enum class Contexts : unsigned int
        {
            undefined,
            advection,
253
254
            diffusion,
            heatConduction
Dennis Gläser's avatar
Dennis Gläser committed
255
256
257
        };

        //! The constructor
258
        InteractionVolumeDataHandle() : context_(Contexts::undefined) {}
Dennis Gläser's avatar
Dennis Gläser committed
259

260
261
262
        //! set the context of the cache
        void setAdvectionContext() { context_ = Contexts::advection; }
        void setHeatConductionContext() { context_ = Contexts::heatConduction; }
Dennis Gläser's avatar
Dennis Gläser committed
263
264
265
        void setDiffusionContext(unsigned int phaseIdx, unsigned int compIdx)
        {
            context_ = Contexts::diffusion;
266
            DiffusionHandle::setDiffusionContext(phaseIdx, compIdx);
Dennis Gläser's avatar
Dennis Gläser committed
267
268
269
        }

        //! returns the current context
270
        Contexts getContext() const { return context_; }
Dennis Gläser's avatar
Dennis Gläser committed
271

272
        //! set the sizes of the matrices
Dennis Gläser's avatar
Dennis Gläser committed
273
274
        void resizeT(unsigned int n, unsigned int m)
        {
275
276
277
            AdvectionHandle::resizeT(n, m);
            DiffusionHandle::resizeT(n, m);
            HeatConductionHandle::resizeT(n, m);
Dennis Gläser's avatar
Dennis Gläser committed
278
279
280
281
        }

        void resizeAB(unsigned int n, unsigned int m)
        {
282
283
284
            AdvectionHandle::resizeAB(n, m);
            DiffusionHandle::resizeAB(n, m);
            HeatConductionHandle::resizeAB(n, m);
Dennis Gläser's avatar
Dennis Gläser committed
285
286
287
288
        }

        void resizeOutsideTij(unsigned int n, unsigned int m)
        {
289
290
291
            AdvectionHandle::resizeOutsideTij(n, m);
            DiffusionHandle::resizeOutsideTij(n, m);
            HeatConductionHandle::resizeOutsideTij(n, m);
Dennis Gläser's avatar
Dennis Gläser committed
292
293
        }

294
        //! sets the pointer to the stencil
Dennis Gläser's avatar
Dennis Gläser committed
295
296
        void setVolVarsStencilPointer(const GlobalIndexContainer& stencil)
        {
297
298
299
300
301
302
303
304
            if (context_ == Contexts::advection)
                AdvectionHandle::setVolVarsStencilPointer(stencil);
            else if (context_ == Contexts::diffusion)
                DiffusionHandle::setVolVarsStencilPointer(stencil);
            else if (context_ == Contexts::heatConduction)
                HeatConductionHandle::setVolVarsStencilPointer(stencil);
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
305
306
        }

307
308
        //! sets the dirichlet data container
        void setDirichletData(DirichletDataContainer&& data)
Dennis Gläser's avatar
Dennis Gläser committed
309
        {
310
            dirichletData_ = std::move(data);
Dennis Gläser's avatar
Dennis Gläser committed
311
312
313
        }

        //! return functions for the stored data
314
315
        const DirichletDataContainer& dirichletData() const { return dirichletData_; }

Dennis Gläser's avatar
Dennis Gläser committed
316
317
        const GlobalIndexContainer& volVarsStencil() const
        {
318
319
320
321
322
323
324
325
            if (context_ == Contexts::advection)
                return AdvectionHandle::volVarsStencil();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::volVarsStencil();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::volVarsStencil();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
326
327
328
329
        }

        const Matrix& T() const
        {
330
331
332
333
334
335
336
337
            if (context_ == Contexts::advection)
                return AdvectionHandle::T();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::T();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::T();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
338
339
340
341
        }

        Matrix& T()
        {
342
343
344
345
346
347
348
349
            if (context_ == Contexts::advection)
                return AdvectionHandle::T();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::T();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::T();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
350
351
352
353
        }

        const Matrix& AB() const
        {
354
355
356
357
358
359
360
361
            if (context_ == Contexts::advection)
                return AdvectionHandle::AB();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::AB();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::AB();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
362
363
364
365
        }

        Matrix& AB()
        {
366
367
368
369
370
371
372
373
            if (context_ == Contexts::advection)
                return AdvectionHandle::AB();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::AB();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::AB();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
374
375
376
377
        }

        const Matrix& outsideTij() const
        {
378
379
380
381
382
383
384
385
            if (context_ == Contexts::advection)
                return AdvectionHandle::outsideTij();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::outsideTij();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::outsideTij();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
386
387
388
389
        }

        Matrix& outsideTij()
        {
390
391
392
393
394
395
396
397
            if (context_ == Contexts::advection)
                return AdvectionHandle::outsideTij();
            else if (context_ == Contexts::diffusion)
                return DiffusionHandle::outsideTij();
            else if (context_ == Contexts::heatConduction)
                return HeatConductionHandle::outsideTij();
            else
                DUNE_THROW(Dune::InvalidStateException, "No valid context set!");
Dennis Gläser's avatar
Dennis Gläser committed
398
399
400
        }

    private:
401
402
        Contexts context_;                     //!< The context variable
        DirichletDataContainer dirichletData_; //!< The dirichlet data container of this iv
Dennis Gläser's avatar
Dennis Gläser committed
403
404
    };

405
} // end namespace Dumux
Dennis Gläser's avatar
Dennis Gläser committed
406
407

#endif