3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
test/porousmediumflow/2pncmin/implicit/isothermal/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 *****************************************************************************/
24#ifndef DUMUX_DISSOLUTION_PROBLEM_HH
25#define DUMUX_DISSOLUTION_PROBLEM_HH
26
27#include <dune/grid/yaspgrid.hh>
28
36
40
41#include "spatialparams.hh"
42
43namespace Dumux {
48template <class TypeTag>
49class DissolutionProblem;
50
51namespace Properties {
52// Create new type tags
53namespace TTag {
54struct Dissolution { using InheritsFrom = std::tuple<TwoPNCMin>; };
55struct DissolutionBox { using InheritsFrom = std::tuple<Dissolution, BoxModel>; };
56struct DissolutionCCTpfa { using InheritsFrom = std::tuple<Dissolution, CCTpfaModel>; };
57} // end namespace TTag
58
59// Set the grid type
60template<class TypeTag>
61struct Grid<TypeTag, TTag::Dissolution> { using type = Dune::YaspGrid<2>; };
62
63// Set the problem property
64template<class TypeTag>
65struct Problem<TypeTag, TTag::Dissolution> { using type = DissolutionProblem<TypeTag>; };
66
67// Set fluid configuration
68template<class TypeTag>
69struct FluidSystem<TypeTag, TTag::Dissolution>
70{
73};
74
75template<class TypeTag>
76struct SolidSystem<TypeTag, TTag::Dissolution>
77{
81 static constexpr int numInertComponents = 1;
83};
84
85// Set the spatial parameters
86template<class TypeTag>
87struct SpatialParams<TypeTag, TTag::Dissolution>
88{
92};
93
94// Set properties here to override the default property settings
95template<class TypeTag>
96struct ReplaceCompEqIdx<TypeTag, TTag::Dissolution> { static constexpr int value = 1; };
97template<class TypeTag>
98struct Formulation<TypeTag, TTag::Dissolution>
99{ static constexpr auto value = TwoPFormulation::p1s0; };
100
101} // end namespace Properties
102
129template <class TypeTag>
131{
139
140 enum
141 {
142 // primary variable indices
143 pressureIdx = Indices::pressureIdx,
144 switchIdx = Indices::switchIdx,
145
146 // component indices
147 // TODO: using xwNaClIdx as privaridx works here, but
148 // looks like magic. Can this be done differently??
149 xwNaClIdx = FluidSystem::NaClIdx,
150 precipNaClIdx = FluidSystem::numComponents,
151
152 // Indices of the components
153 H2OIdx = FluidSystem::H2OIdx,
154 NaClIdx = FluidSystem::NaClIdx,
155
156 // Indices of the phases
157 liquidPhaseIdx = FluidSystem::liquidPhaseIdx,
158 gasPhaseIdx = FluidSystem::gasPhaseIdx,
159
160 // index of the solid phase
161 sPhaseIdx = SolidSystem::comp0Idx,
162
163
164 // Index of the primary component of G and L phase
165 conti0EqIdx = Indices::conti0EqIdx,
166 precipNaClEqIdx = Indices::conti0EqIdx + FluidSystem::numComponents,
167
168 // Phase State
169 bothPhases = Indices::bothPhases,
170
171 // Grid and world dimension
172 dim = GridView::dimension,
173 dimWorld = GridView::dimensionworld,
174 };
175
179 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
180 using Element = typename GridView::template Codim<0>::Entity;
183 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
184 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
185 using GlobalPosition = typename SubControlVolume::GlobalPosition;
186
187public:
188 DissolutionProblem(std::shared_ptr<const GridGeometry> gridGeometry)
190 {
191 outerSalinity_ = getParam<Scalar>("Problem.OuterSalinity");
192 temperature_ = getParam<Scalar>("Problem.Temperature");
193 reservoirPressure_ = getParam<Scalar>("Problem.ReservoirPressure");
194 initLiqSaturation_ = getParam<Scalar>("Problem.LiquidSaturation");
195 initPrecipitatedSaltBlock_ = getParam<Scalar>("Problem.InitPrecipitatedSaltBlock");
196
197 outerLiqSaturation_ = getParam<Scalar>("Problem.OuterLiqSaturation");
198 innerLiqSaturation_ = getParam<Scalar>("Problem.InnerLiqSaturation");
199 innerSalinity_ = getParam<Scalar>("Problem.InnerSalinity");
200 innerPressure_ = getParam<Scalar>("Problem.InnerPressure");
201 outerPressure_ = getParam<Scalar>("Problem.OuterPressure");
202 reservoirSaturation_ = getParam<Scalar>("Problem.reservoirSaturation");
203
204 nTemperature_ = getParam<int>("FluidSystem.NTemperature");
205 nPressure_ = getParam<int>("FluidSystem.NPressure");
206 pressureLow_ = getParam<Scalar>("FluidSystem.PressureLow");
207 pressureHigh_ = getParam<Scalar>("FluidSystem.PressureHigh");
208 temperatureLow_ = getParam<Scalar>("FluidSystem.TemperatureLow");
209 temperatureHigh_ = getParam<Scalar>("FluidSystem.TemperatureHigh");
210 name_ = getParam<std::string>("Problem.Name");
211
213 permeability_.resize(gridGeometry->gridView().size(codim));
214
215 FluidSystem::init(/*Tmin=*/temperatureLow_,
216 /*Tmax=*/temperatureHigh_,
217 /*nT=*/nTemperature_,
218 /*pmin=*/pressureLow_,
219 /*pmax=*/pressureHigh_,
220 /*np=*/nPressure_);
221 }
222
223 void setTime( Scalar time )
224 {
225 time_ = time;
226 }
227
228 void setTimeStepSize( Scalar timeStepSize )
229 {
230 timeStepSize_ = timeStepSize;
231 }
232
243 const std::string& name() const
244 { return name_; }
245
251 Scalar temperature() const
252 { return temperature_; }
253
257 // \{
258
263 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
264 {
265 BoundaryTypes bcTypes;
266
267 const Scalar rmax = this->gridGeometry().bBoxMax()[0];
268 const Scalar rmin = this->gridGeometry().bBoxMin()[0];
269
270 // default to Neumann
271 bcTypes.setAllNeumann();
272
273 // Constant pressure at reservoir boundary (Dirichlet condition)
274 if(globalPos[0] > rmax - eps_)
275 bcTypes.setAllDirichlet();
276
277 // Constant pressure at well (Dirichlet condition)
278 if(globalPos[0] < rmin + eps_)
279 bcTypes.setAllDirichlet();
280
281 return bcTypes;
282 }
283
287 PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
288 {
289 PrimaryVariables priVars(0.0);
290 priVars.setState(bothPhases);
291
292 const Scalar rmax = this->gridGeometry().bBoxMax()[0];
293 const Scalar rmin = this->gridGeometry().bBoxMin()[0];
294
295 if(globalPos[0] > rmax - eps_)
296 {
297 priVars[pressureIdx] = outerPressure_ ; // Outer boundary pressure bar
298 priVars[switchIdx] = outerLiqSaturation_; // Saturation outer boundary
299 priVars[xwNaClIdx] = massToMoleFrac_(outerSalinity_);// mole fraction salt
300 priVars[precipNaClIdx] = 0.0;// precipitated salt
301 }
302
303 if(globalPos[0] < rmin + eps_)
304 {
305 priVars[pressureIdx] = innerPressure_ ; // Inner boundary pressure bar
306 priVars[switchIdx] = innerLiqSaturation_; // Saturation inner boundary
307 priVars[xwNaClIdx] = massToMoleFrac_(innerSalinity_);// mole fraction salt
308 priVars[precipNaClIdx] = 0.0;// precipitated salt
309 }
310
311 return priVars;
312 }
313
322 PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const
323 {
324 PrimaryVariables priVars(0.0);
325 priVars.setState(bothPhases);
326
327 priVars[pressureIdx] = reservoirPressure_;
328 priVars[switchIdx] = initLiqSaturation_; // Sw primary variable
329 priVars[xwNaClIdx] = massToMoleFrac_(outerSalinity_); // mole fraction
330 if(globalPos[0] > 5.0 - eps_ && globalPos[0] < 19.0 + eps_)
331 priVars[precipNaClIdx] = initPrecipitatedSaltBlock_; // [kg/m^3]
332 else
333 priVars[precipNaClIdx] = 0.0; // [kg/m^3]
334
335 return priVars;
336 }
337
341 // \{
342
361 NumEqVector source(const Element &element,
362 const FVElementGeometry& fvGeometry,
363 const ElementVolumeVariables& elemVolVars,
364 const SubControlVolume &scv) const
365 {
366 NumEqVector source(0.0);
367
368 const auto& volVars = elemVolVars[scv];
369
370 Scalar moleFracNaCl_wPhase = volVars.moleFraction(liquidPhaseIdx, NaClIdx);
371 Scalar massFracNaCl_Max_wPhase = this->spatialParams().solubilityLimit();
372 Scalar moleFracNaCl_Max_wPhase = massToMoleFrac_(massFracNaCl_Max_wPhase);
373 Scalar saltPorosity = this->spatialParams().minimalPorosity(element, scv);
374
375 // liquid phase
376 using std::abs;
377 Scalar precipSalt = volVars.porosity() * volVars.molarDensity(liquidPhaseIdx)
378 * volVars.saturation(liquidPhaseIdx)
379 * abs(moleFracNaCl_wPhase - moleFracNaCl_Max_wPhase);
380 if (moleFracNaCl_wPhase < moleFracNaCl_Max_wPhase)
381 precipSalt *= -1;
382
383 // make sure we don't dissolve more salt than previously precipitated
384 if (precipSalt*timeStepSize_ + volVars.solidVolumeFraction(sPhaseIdx)* volVars.solidComponentMolarDensity(sPhaseIdx)< 0)
385 precipSalt = -volVars.solidVolumeFraction(sPhaseIdx)* volVars.solidComponentMolarDensity(sPhaseIdx)/timeStepSize_;
386
387 if (volVars.solidVolumeFraction(sPhaseIdx) >= this->spatialParams().referencePorosity(element, scv) - saltPorosity && precipSalt > 0)
388 precipSalt = 0;
389
390 source[conti0EqIdx + NaClIdx] += -precipSalt;
391 source[precipNaClEqIdx] += precipSalt;
392 return source;
393
394 }
395
402 const std::vector<Scalar>& getPermeability()
403 {
404 return permeability_;
405 }
406
407 void updateVtkOutput(const SolutionVector& curSol)
408 {
409 for (const auto& element : elements(this->gridGeometry().gridView()))
410 {
411 const auto elemSol = elementSolution(element, curSol, this->gridGeometry());
412
413 auto fvGeometry = localView(this->gridGeometry());
414 fvGeometry.bindElement(element);
415
416 for (auto&& scv : scvs(fvGeometry))
417 {
418 VolumeVariables volVars;
419 volVars.update(elemSol, *this, element, scv);
420 const auto dofIdxGlobal = scv.dofIndex();
421 permeability_[dofIdxGlobal] = volVars.permeability();
422 }
423 }
424 }
425
426private:
427
433 static Scalar massToMoleFrac_(Scalar XwNaCl)
434 {
435 const Scalar Mw = 18.015e-3; //FluidSystem::molarMass(H2OIdx); /* molecular weight of water [kg/mol] */ //TODO use correct link to FluidSyswem later
436 const Scalar Ms = 58.44e-3; //FluidSystem::molarMass(NaClIdx); /* molecular weight of NaCl [kg/mol] */
437
438 const Scalar X_NaCl = XwNaCl;
439 /* XwNaCl: conversion from mass fraction to mol fraction */
440 auto xwNaCl = -Mw * X_NaCl / ((Ms - Mw) * X_NaCl - Ms);
441 return xwNaCl;
442 }
443
444 int nTemperature_;
445 int nPressure_;
446 std::string name_;
447
448 Scalar pressureLow_, pressureHigh_;
449 Scalar temperatureLow_, temperatureHigh_;
450 Scalar outerSalinity_;
451 Scalar reservoirPressure_;
452 Scalar innerPressure_;
453 Scalar outerPressure_;
454 Scalar temperature_;
455 Scalar initLiqSaturation_;
456 Scalar outerLiqSaturation_;
457 Scalar innerLiqSaturation_;
458 Scalar initPrecipitatedSaltBlock_;
459 Scalar innerSalinity_;
460 Scalar time_ = 0.0;
461 Scalar timeStepSize_ = 0.0;
462 static constexpr Scalar eps_ = 1e-6;
463 Scalar reservoirSaturation_;
464 std::vector<double> permeability_;
465};
466
467} // end namespace Dumux
468
469#endif
Element solution classes and factory functions.
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.
The available discretization methods in Dumux.
Properties of pure molecular oxygen .
Material properties of pure salt .
A compositional two-phase fluid system with a liquid and a gaseous phase and , and (dissolved miner...
A solid phase consisting of multiple inert solid components.
@ p1s0
first phase saturation and second phase pressure as primary variables
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethod::box, BoxElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for box schemes.
Definition: box/elementsolution.hh:115
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
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
Property to specify the type of a problem which has to be solved.
Definition: common/properties.hh:69
The component balance index that should be replaced by the total mass/mole balance.
Definition: common/properties.hh:104
The type of the spatial parameters object.
Definition: common/properties.hh:221
The type of the fluid system to use.
Definition: common/properties.hh:223
The type of the solid system to use.
Definition: common/properties.hh:227
The formulation of the model.
Definition: common/properties.hh:237
Properties of granite.
Definition: granite.hh:45
A class for the NaCl properties.
Definition: nacl.hh:47
A compositional two-phase fluid system with a liquid and a gaseous phase and , and (dissolved miner...
Definition: brineair.hh:75
A solid phase consisting of multiple inert solid components.
Definition: compositionalsolidphase.hh:42
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
Problem where water is injected in a for flushing precipitated salt clogging a gas reservoir.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:131
void updateVtkOutput(const SolutionVector &curSol)
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:407
DissolutionProblem(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:188
PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
Evaluates the boundary conditions for a Dirichlet boundary segment.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:287
NumEqVector source(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Evaluates the source term for all phases within a given sub-controlvolume.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:361
const std::vector< Scalar > & getPermeability()
Adds additional VTK output data to the VTKWriter.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:402
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
Evaluates the initial value for a control volume.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:322
BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
Specifies which kind of boundary condition should be used for which equation on a given boundary segm...
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:263
void setTimeStepSize(Scalar timeStepSize)
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:228
void setTime(Scalar time)
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:223
Scalar temperature() const
Returns the temperature within the domain.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:251
const std::string & name() const
The problem name.
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:243
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:54
std::tuple< TwoPNCMin > InheritsFrom
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:54
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:55
std::tuple< Dissolution, BoxModel > InheritsFrom
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:55
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:56
std::tuple< Dissolution, CCTpfaModel > InheritsFrom
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:56
Dune::YaspGrid< 2 > type
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:61
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:71
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:78
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:90
GetPropType< TypeTag, Properties::GridGeometry > GridGeometry
Definition: test/porousmediumflow/2pncmin/implicit/isothermal/problem.hh:89
Spatial parameters for the dissolution problem where water is injected in a for flushing precipitated...
Definition: porousmediumflow/2pncmin/implicit/isothermal/spatialparams.hh:47
Adaption of the fully implicit scheme to the two-phase n-component fully implicit model with addition...
Base class for all porous media problems.
Definition of the spatial parameters for the MaxwellStefan problem.