3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
test/porousmediumflow/co2/implicit/problem.hh
Go to the documentation of this file.
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * 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 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef DUMUX_HETEROGENEOUS_PROBLEM_HH
26#define DUMUX_HETEROGENEOUS_PROBLEM_HH
27
28#if HAVE_DUNE_ALUGRID
29#include <dune/alugrid/grid.hh>
30#endif
31
34
37
42
43#include "spatialparams.hh"
44#include "co2tables.hh"
45
46// per default use isothermal model
47#ifndef ISOTHERMAL
48#define ISOTHERMAL 1
49#endif
50
51namespace Dumux {
52
53template <class TypeTag>
54class HeterogeneousProblem;
55
56namespace Properties {
57// Create new type tags
58namespace TTag {
59struct Heterogeneous { using InheritsFrom = std::tuple<TwoPTwoCCO2>; };
60struct HeterogeneousBox { using InheritsFrom = std::tuple<Heterogeneous, BoxModel>; };
61struct HeterogeneousCCTpfa { using InheritsFrom = std::tuple<Heterogeneous, CCTpfaModel>; };
62} // end namespace TTag
63
64//Set the grid type
65template<class TypeTag>
66struct Grid<TypeTag, TTag::Heterogeneous> { using type = Dune::ALUGrid<2, 2, Dune::cube, Dune::nonconforming>; };
67
68// Set the problem property
69template<class TypeTag>
70struct Problem<TypeTag, TTag::Heterogeneous> { using type = HeterogeneousProblem<TypeTag>; };
71
72// Set the spatial parameters
73template<class TypeTag>
74struct SpatialParams<TypeTag, TTag::Heterogeneous>
75{
78};
79
80// Set fluid configuration
81template<class TypeTag>
82struct FluidSystem<TypeTag, TTag::Heterogeneous>
83{
85 HeterogeneousCO2Tables::CO2Tables,
87 FluidSystems::BrineCO2DefaultPolicy</*constantSalinity=*/true, /*simpleButFast=*/true>>;
88};
89
90// Use Moles
91template<class TypeTag>
92struct UseMoles<TypeTag, TTag::Heterogeneous> { static constexpr bool value = false; };
93
94#if !ISOTHERMAL
95// Create new type tags
96namespace TTag {
97struct HeterogeneousNI { using InheritsFrom = std::tuple<TwoPTwoCCO2NI>; };
98struct HeterogeneousNIBox { using InheritsFrom = std::tuple<HeterogeneousNI, BoxModel>; };
99struct HeterogeneousNICCTpfa { using InheritsFrom = std::tuple<HeterogeneousNI, CCTpfaModel>; };
100} // end namespace TTag
101
102// Set the grid type
103template<class TypeTag>
104struct Grid<TypeTag, TTag::HeterogeneousNI> { using type = Dune::ALUGrid<2, 2, Dune::cube, Dune::nonconforming>; };
105
106// Set the problem property
107template<class TypeTag>
108struct Problem<TypeTag, TTag::HeterogeneousNI> { using type = HeterogeneousProblem<TypeTag>; };
109
110// Set the spatial parameters
111template<class TypeTag>
112struct SpatialParams<TypeTag, TTag::HeterogeneousNI>
113{
114 using type = HeterogeneousSpatialParams<GetPropType<TypeTag, Properties::GridGeometry>,
115 GetPropType<TypeTag, Properties::Scalar>>;
116};
117
118// Set fluid configuration
119template<class TypeTag>
120struct FluidSystem<TypeTag, TTag::HeterogeneousNI>
121{
122 using type = FluidSystems::BrineCO2<GetPropType<TypeTag, Properties::Scalar>,
123 HeterogeneousCO2Tables::CO2Tables,
124 Components::TabulatedComponent<Components::H2O<GetPropType<TypeTag, Properties::Scalar>>>,
125 FluidSystems::BrineCO2DefaultPolicy</*constantSalinity=*/true, /*simpleButFast=*/true>>;
126};
127
128// Use Moles
129template<class TypeTag>
130struct UseMoles<TypeTag, TTag::HeterogeneousNI> { static constexpr bool value = false; };
131#endif
132} // end namespace Properties
133
162template <class TypeTag >
164{
170 using ElementVolumeVariables = typename GridVariables::GridVolumeVariables::LocalView;
171 using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
172 using VolumeVariables = typename GridVariables::GridVolumeVariables::VolumeVariables;
173
175 using Indices = typename ModelTraits::Indices;
176
177 // copy some indices for convenience
178 enum
179 {
180 // primary variable indices
181 pressureIdx = Indices::pressureIdx,
182 switchIdx = Indices::switchIdx,
183
184 // phase presence index
185 firstPhaseOnly = Indices::firstPhaseOnly,
186
187 // component indices
188 BrineIdx = FluidSystem::BrineIdx,
189 CO2Idx = FluidSystem::CO2Idx,
190
191 // equation indices
192 conti0EqIdx = Indices::conti0EqIdx,
193 contiCO2EqIdx = conti0EqIdx + CO2Idx
194 };
195
196#if !ISOTHERMAL
197 enum {
198 temperatureIdx = Indices::temperatureIdx,
199 energyEqIdx = Indices::energyEqIdx,
200 };
201#endif
202
206 using Element = typename GridView::template Codim<0>::Entity;
207 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
209 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
210 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
211 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
212
214
216 static constexpr bool useMoles = ModelTraits::useMoles();
217
218 // the discretization method we are using
219 static constexpr auto discMethod = GetPropType<TypeTag, Properties::GridGeometry>::discMethod;
220
221 // world dimension to access gravity vector
222 static constexpr int dimWorld = GridView::dimensionworld;
223
224public:
225 template<class SpatialParams>
226 HeterogeneousProblem(std::shared_ptr<const GridGeometry> gridGeometry, std::shared_ptr<SpatialParams> spatialParams)
228 , injectionTop_(1)
229 , injectionBottom_(2)
230 , dirichletBoundary_(3)
231 , noFlowBoundary_(4)
232 {
233 nTemperature_ = getParam<int>("FluidSystem.NTemperature");
234 nPressure_ = getParam<int>("FluidSystem.NPressure");
235 pressureLow_ = getParam<Scalar>("FluidSystem.PressureLow");
236 pressureHigh_ = getParam<Scalar>("FluidSystem.PressureHigh");
237 temperatureLow_ = getParam<Scalar>("FluidSystem.TemperatureLow");
238 temperatureHigh_ = getParam<Scalar>("FluidSystem.TemperatureHigh");
239 depthBOR_ = getParam<Scalar>("Problem.DepthBOR");
240 name_ = getParam<std::string>("Problem.Name");
241 injectionRate_ = getParam<Scalar>("Problem.InjectionRate");
242
243#if !ISOTHERMAL
244 injectionPressure_ = getParam<Scalar>("Problem.InjectionPressure");
245 injectionTemperature_ = getParam<Scalar>("Problem.InjectionTemperature");
246#endif
247
248 // set the spatial parameters by reading the DGF grid file
249 this->spatialParams().getParamsFromGrid();
250
251 // initialize the tables of the fluid system
252 FluidSystem::init(/*Tmin=*/temperatureLow_,
253 /*Tmax=*/temperatureHigh_,
254 /*nT=*/nTemperature_,
255 /*pmin=*/pressureLow_,
256 /*pmax=*/pressureHigh_,
257 /*np=*/nPressure_);
258
259 // stating in the console whether mole or mass fractions are used
260 if(useMoles)
261 std::cout<<"problem uses mole fractions"<<std::endl;
262 else
263 std::cout<<"problem uses mass fractions"<<std::endl;
264
265 // precompute the boundary types for the box method from the cell-centered boundary types
266 scvfToScvBoundaryTypes_.computeBoundaryTypes(*this);
267 }
268
274 template<class VTKWriter>
275 void addFieldsToWriter(VTKWriter& vtk)
276 {
277 const auto numElements = this->gridGeometry().gridView().size(0);
278 const auto numDofs = this->gridGeometry().numDofs();
279
280 vtkKxx_.resize(numElements);
281 vtkPorosity_.resize(numElements);
282 vtkBoxVolume_.resize(numDofs, 0.0);
283
284 vtk.addField(vtkKxx_, "Kxx");
285 vtk.addField(vtkPorosity_, "cellwisePorosity");
286 vtk.addField(vtkBoxVolume_, "boxVolume");
287
288#if !ISOTHERMAL
289 vtk.addVolumeVariable([](const VolumeVariables& v){ return v.enthalpy(BrineIdx); }, "enthalpyW");
290 vtk.addVolumeVariable([](const VolumeVariables& v){ return v.enthalpy(CO2Idx); }, "enthalpyN");
291#else
292 vtkTemperature_.resize(numDofs, 0.0);
293 vtk.addField(vtkTemperature_, "T");
294#endif
295
296 const auto& gridView = this->gridGeometry().gridView();
297 for (const auto& element : elements(gridView))
298 {
299 const auto eIdx = this->gridGeometry().elementMapper().index(element);
300 auto fvGeometry = localView(this->gridGeometry());
301 fvGeometry.bindElement(element);
302
303 for (const auto& scv : scvs(fvGeometry))
304 {
305 const auto dofIdxGlobal = scv.dofIndex();
306 vtkBoxVolume_[dofIdxGlobal] += scv.volume();
307#if ISOTHERMAL
308 vtkTemperature_[dofIdxGlobal] = initialTemperatureField_(scv.dofPosition());
309#endif
310 }
311
312 vtkKxx_[eIdx] = this->spatialParams().permeability(eIdx);
313 vtkPorosity_[eIdx] = 1- this->spatialParams().inertVolumeFraction(eIdx);
314 }
315 }
316
320 // \{
321
327 const std::string& name() const
328 { return name_; }
329
338 Scalar temperatureAtPos(const GlobalPosition &globalPos) const
339 { return initialTemperatureField_(globalPos); }
340
341 // \}
342
346 // \{
347
355 BoundaryTypes boundaryTypes(const Element &element,
356 const SubControlVolume &scv) const
357 { return scvfToScvBoundaryTypes_.boundaryTypes(scv); }
358
366 BoundaryTypes boundaryTypes(const Element &element,
367 const SubControlVolumeFace &scvf) const
368 {
369 BoundaryTypes bcTypes;
370 const auto boundaryId = scvf.boundaryFlag();
371
372 if (boundaryId < 1 || boundaryId > 4)
373 DUNE_THROW(Dune::InvalidStateException, "Invalid boundary ID: " << boundaryId);
374
375 if (boundaryId == dirichletBoundary_)
376 bcTypes.setAllDirichlet();
377 else
378 bcTypes.setAllNeumann();
379
380 return bcTypes;
381 }
382
390 PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
391 { return initial_(globalPos); }
392
410 NumEqVector neumann(const Element& element,
411 const FVElementGeometry& fvGeometry,
412 const ElementVolumeVariables& elemVolVars,
413 const ElementFluxVariablesCache& elemFluxVarsCache,
414 const SubControlVolumeFace& scvf) const
415 {
416 const auto boundaryId = scvf.boundaryFlag();
417
418 NumEqVector fluxes(0.0);
419 // kg/(m^2*s) or mole/(m^2*s) depending on useMoles
420 if (boundaryId == injectionBottom_)
421 {
422 fluxes[contiCO2EqIdx] = useMoles ? -injectionRate_/FluidSystem::molarMass(CO2Idx) : -injectionRate_;
423#if !ISOTHERMAL
424 // energy fluxes are always mass specific
425 fluxes[energyEqIdx] = -injectionRate_/*kg/(m^2 s)*/*CO2::gasEnthalpy(
426 injectionTemperature_, injectionPressure_)/*J/kg*/; // W/(m^2)
427#endif
428 }
429
430 return fluxes;
431 }
432
433 // \}
434
438 // \{
439
447 PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
448 {
449 return initial_(globalPos);
450 }
451
452 // \}
453
454private:
462 PrimaryVariables initial_(const GlobalPosition &globalPos) const
463 {
464 PrimaryVariables values(0.0);
465 values.setState(firstPhaseOnly);
466
467 const Scalar temp = initialTemperatureField_(globalPos);
468 const Scalar densityW = FluidSystem::Brine::liquidDensity(temp, 1e7);
469
470 const Scalar moleFracLiquidCO2 = 0.00;
471 const Scalar moleFracLiquidBrine = 1.0 - moleFracLiquidCO2;
472
473 const Scalar meanM = FluidSystem::molarMass(BrineIdx)*moleFracLiquidBrine
474 + FluidSystem::molarMass(CO2Idx)*moleFracLiquidCO2;
475
476 if(useMoles) // mole-fraction formulation
477 values[switchIdx] = moleFracLiquidCO2;
478 else // mass-fraction formulation
479 values[switchIdx] = moleFracLiquidCO2*FluidSystem::molarMass(CO2Idx)/meanM;
480
481 values[pressureIdx] = 1.0e5 - densityW*this->spatialParams().gravity(globalPos)[dimWorld-1]*(depthBOR_ - globalPos[dimWorld-1]);
482
483#if !ISOTHERMAL
484 values[temperatureIdx] = temp;
485#endif
486 return values;
487 }
488
489 Scalar initialTemperatureField_(const GlobalPosition globalPos) const
490 {
491 return 283.0 + (depthBOR_ - globalPos[dimWorld-1])*0.03;
492 }
493
494 Scalar depthBOR_;
495 Scalar injectionRate_;
496
497#if !ISOTHERMAL
498 Scalar injectionPressure_, injectionTemperature_;
499#endif
500
501 int nTemperature_;
502 int nPressure_;
503
504 std::string name_ ;
505
506 Scalar pressureLow_, pressureHigh_;
507 Scalar temperatureLow_, temperatureHigh_;
508
509 int injectionTop_;
510 int injectionBottom_;
511 int dirichletBoundary_;
512 int noFlowBoundary_;
513
514 // vtk output
515 std::vector<Scalar> vtkKxx_, vtkPorosity_, vtkBoxVolume_, vtkTemperature_;
516 ScvfToScvBoundaryTypes<BoundaryTypes, discMethod> scvfToScvBoundaryTypes_;
517};
518
519} // end namespace Dumux
520
521#endif
Convert intersection boundary types to vertex boundary types.
Defines a type tag and some properties for models using the box scheme.
Properties for all models using cell-centered finite volume scheme with TPFA.
Material properties of pure water .
Tabulates all thermodynamic properties of a given untabulated chemical species.
A compositional fluid with brine (H2O & NaCl) and carbon dioxide as components in both the liquid and...
Provides the class with the tabulated values of CO2 density and enthalpy.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
Property tag Indices
Definition: porousmediumflow/sequential/properties.hh:59
Base class for all finite-volume problems.
Definition: common/fvproblem.hh:50
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition: common/fvproblem.hh:588
The DUNE grid type.
Definition: common/properties.hh:57
UndefinedProperty type
Definition: common/properties.hh:57
Property to specify the type of a problem which has to be solved.
Definition: common/properties.hh:69
UndefinedProperty type
Definition: common/properties.hh:69
Property whether to use moles or kg as amount unit for balance equations.
Definition: common/properties.hh:102
The type of the spatial parameters object.
Definition: common/properties.hh:221
UndefinedProperty type
Definition: common/properties.hh:221
The type of the fluid system to use.
Definition: common/properties.hh:223
UndefinedProperty type
Definition: common/properties.hh:223
A class for the CO2 fluid properties.
Definition: co2.hh:56
static Scalar gasEnthalpy(Scalar temperature, Scalar pressure)
Specific enthalpy of gaseous CO2 .
Definition: co2.hh:161
Tabulates all thermodynamic properties of a given untabulated chemical species.
Definition: tabulatedcomponent.hh:82
Default policy for the Brine-CO2 fluid system.
Definition: brineco2.hh:97
A compositional fluid with brine (H2O & NaCl) and carbon dioxide as components in both the liquid and...
Definition: brineco2.hh:119
Base class for all fully implicit porous media problems.
Definition: dumux/porousmediumflow/problem.hh:39
SpatialParams & spatialParams()
Returns the spatial parameters object.
Definition: dumux/porousmediumflow/problem.hh:146
Definition of a problem, where CO2 is injected in a reservoir.
Definition: test/porousmediumflow/co2/implicit/problem.hh:164
PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
Evaluates the boundary conditions for a Dirichlet boundary segment.
Definition: test/porousmediumflow/co2/implicit/problem.hh:390
Scalar temperatureAtPos(const GlobalPosition &globalPos) const
Returns the temperature within the domain.
Definition: test/porousmediumflow/co2/implicit/problem.hh:338
HeterogeneousProblem(std::shared_ptr< const GridGeometry > gridGeometry, std::shared_ptr< SpatialParams > spatialParams)
Definition: test/porousmediumflow/co2/implicit/problem.hh:226
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolumeFace &scvf) const
Specifies which kind of boundary condition should be used for which equation on a given boundary segm...
Definition: test/porousmediumflow/co2/implicit/problem.hh:366
NumEqVector neumann(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Evaluates the boundary conditions for a Neumann boundary segment.
Definition: test/porousmediumflow/co2/implicit/problem.hh:410
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
Evaluates the initial values at a position.
Definition: test/porousmediumflow/co2/implicit/problem.hh:447
const std::string & name() const
The problem name.
Definition: test/porousmediumflow/co2/implicit/problem.hh:327
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolume &scv) const
Specifies which kind of boundary condition should be used for which equation on a given boundary segm...
Definition: test/porousmediumflow/co2/implicit/problem.hh:355
void addFieldsToWriter(VTKWriter &vtk)
Appends all quantities of interest which can be derived from the solution of the current time step to...
Definition: test/porousmediumflow/co2/implicit/problem.hh:275
Definition: test/porousmediumflow/co2/implicit/problem.hh:59
std::tuple< TwoPTwoCCO2 > InheritsFrom
Definition: test/porousmediumflow/co2/implicit/problem.hh:59
Definition: test/porousmediumflow/co2/implicit/problem.hh:60
std::tuple< Heterogeneous, BoxModel > InheritsFrom
Definition: test/porousmediumflow/co2/implicit/problem.hh:60
Definition: test/porousmediumflow/co2/implicit/problem.hh:61
std::tuple< Heterogeneous, CCTpfaModel > InheritsFrom
Definition: test/porousmediumflow/co2/implicit/problem.hh:61
Dune::ALUGrid< 2, 2, Dune::cube, Dune::nonconforming > type
Definition: test/porousmediumflow/co2/implicit/problem.hh:66
Definition of the spatial parameters for the heterogeneous problem which uses the non-isothermal or i...
Definition: porousmediumflow/co2/implicit/spatialparams.hh:50
Adaption of the fully implicit scheme to the CO2Model model.
Base class for all porous media problems.
Definition of the spatial parameters for the MaxwellStefan problem.