3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
test/porousmediumflow/2pncmin/implicit/nonisothermal/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_SALINIZATION_PROBLEM_HH
25#define DUMUX_SALINIZATION_PROBLEM_HH
26
27#include <dune/grid/yaspgrid.hh>
28
37
41
42#include "spatialparams.hh"
43
44namespace Dumux {
49template <class TypeTag>
50class SalinizationProblem;
51
52namespace Properties {
53// Create new type tags
54namespace TTag {
55struct Salinization { using InheritsFrom = std::tuple<TwoPNCMinNI>; };
56struct SalinizationBox { using InheritsFrom = std::tuple<Salinization, BoxModel>; };
57struct SalinizationCCTpfa { using InheritsFrom = std::tuple<Salinization, CCTpfaModel>; };
58} // end namespace TTag
59
60// Set the grid type
61template<class TypeTag>
62struct Grid<TypeTag, TTag::Salinization>
63{
65 using type = Dune::YaspGrid<2, Dune::TensorProductCoordinates<Scalar, 2>>;
66};
67
68// Set the problem property
69template<class TypeTag>
70struct Problem<TypeTag, TTag::Salinization> { using type = SalinizationProblem<TypeTag>; };
71
72// Set fluid configuration
73template<class TypeTag>
74struct FluidSystem<TypeTag, TTag::Salinization>
75{
78};
79
80template<class TypeTag>
81struct SolidSystem<TypeTag, TTag::Salinization>
82{
86 static constexpr int numInertComponents = 1;
88};
89
90// Set the spatial parameters
91template<class TypeTag>
92struct SpatialParams<TypeTag, TTag::Salinization>
93{
97};
98
99// Set properties here to override the default property settings
100template<class TypeTag>
101struct ReplaceCompEqIdx<TypeTag, TTag::Salinization> { static constexpr int value = 1; };
102template<class TypeTag>
103struct Formulation<TypeTag, TTag::Salinization>
104{ static constexpr auto value = TwoPFormulation::p0s1; };
105
106} // end namespace Properties
107
134template <class TypeTag>
136{
144
145 enum
146 {
147 // primary variable indices
148 pressureIdx = Indices::pressureIdx,
149 switchIdx = Indices::switchIdx,
150
151 // component indices
152 // TODO: using xwNaClIdx as privaridx works here, but
153 // looks like magic. Can this be done differently??
154 xwNaClIdx = FluidSystem::NaClIdx,
155 precipNaClIdx = FluidSystem::numComponents,
156
157 // Indices of the components
158 H2OIdx = FluidSystem::H2OIdx,
159 NaClIdx = FluidSystem::NaClIdx,
160 AirIdx = FluidSystem::AirIdx,
161
162 // Indices of the phases
163 liquidPhaseIdx = FluidSystem::liquidPhaseIdx,
164 gasPhaseIdx = FluidSystem::gasPhaseIdx,
165
166 // index of the solid phase
167 sPhaseIdx = SolidSystem::comp0Idx,
168
169
170 // Index of the primary component of G and L phase
171 conti0EqIdx = Indices::conti0EqIdx, //water component
172 conti1EqIdx = Indices::conti0EqIdx + 1, //air component
173 precipNaClEqIdx = Indices::conti0EqIdx + FluidSystem::numComponents,
174 energyEqIdx = Indices::energyEqIdx,
175
176 // Phase State
177 bothPhases = Indices::bothPhases,
178
179 // Grid and world dimension
180 dim = GridView::dimension,
181 dimWorld = GridView::dimensionworld,
182 };
183
188 using ElementFluxVariablesCache = typename GridVariables::GridFluxVariablesCache::LocalView;
189 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
190 using Element = typename GridView::template Codim<0>::Entity;
193 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
194 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
195 using GlobalPosition = typename SubControlVolume::GlobalPosition;
196 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
198
199public:
200 SalinizationProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
202 {
203 //Fluidsystem
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
212 //problem
213 name_ = getParam<std::string>("Problem.Name");
214 temperature_ = getParam<Scalar>("Problem.Temperature");
215
216 //inital conditions
217 initPressure_ = getParam<Scalar>("Problem.InitialPressure");
218 initGasSaturation_ = getParam<Scalar>("Problem.InitialGasSaturation");
219 initSalinity_ = getParam<Scalar>("Problem.InitialSalinity");
220
222
223 permeability_.resize(fvGridGeometry->gridView().size(codim));
224 FluidSystem::init(/*Tmin=*/temperatureLow_,
225 /*Tmax=*/temperatureHigh_,
226 /*nT=*/nTemperature_,
227 /*pmin=*/pressureLow_,
228 /*pmax=*/pressureHigh_,
229 /*np=*/nPressure_);
230 }
231
235 void setTime( Scalar time )
236 {
237 time_ = time;
238 }
239
245 void setTimeStepSize( Scalar timeStepSize )
246 {
247 timeStepSize_ = timeStepSize;
248 }
249
259 const std::string& name() const
260 { return name_; }
261
267 Scalar temperature() const
268 { return temperature_; }
269
270
274 // \{
275
280 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
281 {
282 BoundaryTypes bcTypes;
283
284 // default to Neumann
285 bcTypes.setAllNeumann();
286
287 return bcTypes;
288 }
289
293 PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
294 {
295 PrimaryVariables priVars(0.0);
296 priVars.setState(bothPhases);
297
298 return priVars;
299 }
300
301
318 NumEqVector neumann(const Element& element,
319 const FVElementGeometry& fvGeometry,
320 const ElementVolumeVariables& elemVolVars,
321 const ElementFluxVariablesCache& elemFluxVarsCache,
322 const SubControlVolumeFace& scvf) const
323 {
324 PrimaryVariables values(0.0);
325
326 const auto& globalPos = scvf.ipGlobal();
327 const auto& volVars = elemVolVars[scvf.insideScvIdx()];
328 const Scalar hmax = this->gridGeometry().bBoxMax()[1];
329
330 static const Scalar temperatureRef = getParam<Scalar>("FreeFlow.RefTemperature");
331
332 if (globalPos[1] > hmax - eps_)
333 {
334 // get free-flow properties:
335 static const Scalar moleFracRefH2O = getParam<Scalar>("FreeFlow.RefMoleFracH2O");
336 static const Scalar boundaryLayerThickness = getParam<Scalar>("FreeFlow.BoundaryLayerThickness");
337 static const Scalar massTransferCoefficient = getParam<Scalar>("FreeFlow.MassTransferCoefficient");
338
339 // get porous medium values:
340 const Scalar moleFracH2OInside = volVars.moleFraction(gasPhaseIdx, H2OIdx);
341 static const Scalar referencePermeability = getParam<Scalar>("SpatialParams.referencePermeability", 2.23e-14);
342
343 // calculate fluxes
344 // liquid phase
345 Scalar evaporationRateMole = 0;
346 if (moleFracH2OInside - moleFracRefH2O > 0)
347 {
348 evaporationRateMole = massTransferCoefficient
349 * volVars.diffusionCoefficient(gasPhaseIdx, H2OIdx)
350 * (moleFracH2OInside - moleFracRefH2O)
351 / boundaryLayerThickness
352 * volVars.molarDensity(gasPhaseIdx);
353 }
354 else
355 {
356 evaporationRateMole = massTransferCoefficient
357 * volVars.diffusionCoefficient(gasPhaseIdx, H2OIdx)
358 * (moleFracH2OInside - moleFracRefH2O)
359 / boundaryLayerThickness
360 * 1.2;
361
362 }
363
364 values[conti0EqIdx] = evaporationRateMole;
365
366 // gas phase
367 // gas flows in
368 if (volVars.pressure(gasPhaseIdx) - 1e5 > 0) {
369 values[conti1EqIdx] = (volVars.pressure(gasPhaseIdx) - 1e5)
370 /(globalPos - fvGeometry.scv(scvf.insideScvIdx()).center()).two_norm()
371 *volVars.mobility(gasPhaseIdx)
372 *referencePermeability
373 *volVars.molarDensity(gasPhaseIdx)
374 *volVars.moleFraction(gasPhaseIdx, AirIdx);
375 }
376 //gas flows out
377 else {
378 values[conti1EqIdx] = (volVars.pressure(gasPhaseIdx) - 1e5)
379 /(globalPos - fvGeometry.scv(scvf.insideScvIdx()).center()).two_norm()
380 *volVars.mobility(gasPhaseIdx)
381 *referencePermeability
382 *volVars.molarDensity(gasPhaseIdx) * (1-moleFracRefH2O);
383 }
384
385 // energy fluxes
386 values[energyEqIdx] = FluidSystem::componentEnthalpy(volVars.fluidState(), gasPhaseIdx, H2OIdx) * values[conti0EqIdx] * FluidSystem::molarMass(H2OIdx);
387
388 values[energyEqIdx] += FluidSystem::componentEnthalpy(volVars.fluidState(), gasPhaseIdx, AirIdx)* values[conti1EqIdx] * FluidSystem::molarMass(AirIdx);
389
390 values[energyEqIdx] += FluidSystem::thermalConductivity(elemVolVars[scvf.insideScvIdx()].fluidState(), gasPhaseIdx) * (volVars.temperature() - temperatureRef)/boundaryLayerThickness;
391 }
392 return values;
393 }
394
403 PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const
404 {
405 PrimaryVariables priVars(0.0);
406 priVars.setState(bothPhases);
407 Scalar density = 1000.00; //FluidSystem::density(, liquidPhaseIdx);
408
409 priVars[pressureIdx] = initPressure_ - density*9.81*globalPos[dimWorld-1];
410 priVars[switchIdx] = initGasSaturation_; // Sg primary variable
411 priVars[xwNaClIdx] = massToMoleFrac_(initSalinity_); // mole fraction
412 priVars[precipNaClIdx] = 0.0; // [kg/m^3]
413 priVars[energyEqIdx] = temperature_; // [K]
414
415 return priVars;
416 }
417
421 // \{
422
439 NumEqVector source(const Element &element,
440 const FVElementGeometry& fvGeometry,
441 const ElementVolumeVariables& elemVolVars,
442 const SubControlVolume &scv) const
443 {
444 NumEqVector source(0.0);
445
446 const auto& volVars = elemVolVars[scv];
447
448 Scalar moleFracNaCl_wPhase = volVars.moleFraction(liquidPhaseIdx, NaClIdx);
449 Scalar massFracNaCl_Max_wPhase = this->spatialParams().solubilityLimit();
450 Scalar moleFracNaCl_Max_wPhase = massToMoleFrac_(massFracNaCl_Max_wPhase);
451 Scalar saltPorosity = this->spatialParams().minimalPorosity(element, scv);
452
453 // precipitation of amount of salt whic hexeeds the solubility limit
454 using std::abs;
455 Scalar precipSalt = volVars.porosity() * volVars.molarDensity(liquidPhaseIdx)
456 * volVars.saturation(liquidPhaseIdx)
457 * abs(moleFracNaCl_wPhase - moleFracNaCl_Max_wPhase);
458 if (moleFracNaCl_wPhase < moleFracNaCl_Max_wPhase)
459 precipSalt *= -1;
460
461 // make sure we don't dissolve more salt than previously precipitated
462 if (precipSalt*timeStepSize_ + volVars.solidVolumeFraction(sPhaseIdx)* volVars.solidComponentMolarDensity(sPhaseIdx)< 0)
463 precipSalt = -volVars.solidVolumeFraction(sPhaseIdx)* volVars.solidComponentMolarDensity(sPhaseIdx)/timeStepSize_;
464
465 // make sure there is still pore space available for precipitation
466 if (volVars.solidVolumeFraction(sPhaseIdx) >= this->spatialParams().referencePorosity(element, scv) - saltPorosity && precipSalt > 0)
467 precipSalt = 0;
468
469 source[conti0EqIdx + NaClIdx] += -precipSalt;
470 source[precipNaClEqIdx] += precipSalt;
471 return source;
472 }
473
480 const std::vector<Scalar>& getPermeability()
481 {
482 return permeability_;
483 }
484
485 void updateVtkOutput(const SolutionVector& curSol)
486 {
487 for (const auto& element : elements(this->gridGeometry().gridView()))
488 {
489 const auto elemSol = elementSolution(element, curSol, this->gridGeometry());
490
491 auto fvGeometry = localView(this->gridGeometry());
492 fvGeometry.bindElement(element);
493
494 for (auto&& scv : scvs(fvGeometry))
495 {
496 VolumeVariables volVars;
497 volVars.update(elemSol, *this, element, scv);
498 const auto dofIdxGlobal = scv.dofIndex();
499 permeability_[dofIdxGlobal] = volVars.permeability();
500 }
501 }
502 }
503
504 Scalar extrusionFactorAtPos(const GlobalPosition& globalPos) const
505 {
506 return 0.054977871437821;
507 }
508
509private:
510
516 static Scalar massToMoleFrac_(Scalar XwNaCl)
517 {
518 const Scalar Mw = 18.015e-3; //FluidSystem::molarMass(H2OIdx); /* molecular weight of water [kg/mol] */
519 const Scalar Ms = 58.44e-3; //FluidSystem::molarMass(NaClIdx); /* molecular weight of NaCl [kg/mol] */
520
521 const Scalar X_NaCl = XwNaCl;
522 /* XwNaCl: conversion from mass fraction to mol fraction */
523 auto xwNaCl = -Mw * X_NaCl / ((Ms - Mw) * X_NaCl - Ms);
524 return xwNaCl;
525 }
526
527
528 std::string name_;
529
530 Scalar initPressure_;
531 Scalar initGasSaturation_;
532 Scalar initSalinity_;
533
534 Scalar temperature_;
535
536 Scalar pressureLow_, pressureHigh_;
537 Scalar temperatureLow_, temperatureHigh_;
538 int nTemperature_;
539 int nPressure_;
540
541 Scalar time_ = 0.0;
542 Scalar timeStepSize_ = 0.0;
543 static constexpr Scalar eps_ = 1e-6;
544
545 std::vector<Scalar> permeability_;
546
549 std::vector<Scalar> x_;
550 std::vector<Scalar> y_;
551 std::vector<Scalar> y2_;
552};
553
554} // end namespace Dumux
555
556#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.
@ p0s1
first phase pressure and second phase saturation 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
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
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
const GridGeometry & fvGridGeometry() const
The finite volume grid geometry.
Definition: common/fvproblem.hh:584
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
Interface for passing data sets to a file and plotting them, if gnuplot is installed.
Definition: gnuplotinterface.hh:57
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 brine is evaporating at the top boundary. The system is closed at the remaining boundar...
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:136
void setTimeStepSize(Scalar timeStepSize)
The time step size.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:245
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/nonisothermal/problem.hh:280
Scalar extrusionFactorAtPos(const GlobalPosition &globalPos) const
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:504
void setTime(Scalar time)
The current time.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:235
void updateVtkOutput(const SolutionVector &curSol)
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:485
NumEqVector neumann(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Evaluate the boundary conditions for a neumann boundary segment.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:318
SalinizationProblem(std::shared_ptr< const FVGridGeometry > fvGridGeometry)
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:200
PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
Evaluates the boundary conditions for a Dirichlet boundary segment.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:293
const std::vector< Scalar > & getPermeability()
Adds additional VTK output data to the VTKWriter.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:480
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/nonisothermal/problem.hh:439
const std::string & name() const
The problem name.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:259
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
Evaluates the initial value for a control volume.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:403
Scalar temperature() const
Returns the temperature within the domain.
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:267
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:55
std::tuple< TwoPNCMinNI > InheritsFrom
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:55
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:56
std::tuple< Salinization, BoxModel > InheritsFrom
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:56
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:57
std::tuple< Salinization, CCTpfaModel > InheritsFrom
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:57
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:64
Dune::YaspGrid< 2, Dune::TensorProductCoordinates< Scalar, 2 > > type
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:65
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:76
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:83
GetPropType< TypeTag, Properties::GridGeometry > FVGridGeometry
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:94
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/porousmediumflow/2pncmin/implicit/nonisothermal/problem.hh:95
Spatial parameters for the salinization problem, where evaporation from a porous medium saturated wit...
Definition: porousmediumflow/2pncmin/implicit/nonisothermal/spatialparams.hh:49
Declares all properties used in Dumux.
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.