Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dumux-repositories
dumux-lecture
Commits
93b6db81
Commit
93b6db81
authored
Mar 03, 2016
by
Timo Koch
Browse files
[bugfix][napl] Use mass fractions for 3p test version
parent
edeea605
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
lecture/mm/naplinfiltration/3p/naplinfiltration3p.input
View file @
93b6db81
...
...
@@ -2,7 +2,7 @@
DtInitial = 60 # [s]
TEnd = 31536000 # [s]
#TEnd = 315360000000 # [s]
EpisodeLength =
31536
00 # [s]
EpisodeLength =
864
00 # [s]
[Grid]
UpperRight = 500 10 # coordinates of upper right grid corner [m]
...
...
lecture/mm/naplinfiltration/3p/problem.hh
View file @
93b6db81
...
...
@@ -251,8 +251,8 @@ public:
&&
globalPos
[
1
]
>
this
->
bBoxMax
()[
1
]
-
eps_
)
// upper boundary
{
values
[
contiWEqIdx
]
=
0.0
;
//
/*
mole flux
,
conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m)
values
[
contiNEqIdx
]
=
-
0.001
;
// mole flux conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m)
values
[
contiNEqIdx
]
=
-
0.001
*
0.12
;
// 3p needs a mass fraction
values
[
contiGEqIdx
]
=
0.0
;
}
}
...
...
lecture/mm/naplinfiltration/3p3c/naplinfiltration3p3c.input
View file @
93b6db81
...
...
@@ -2,7 +2,7 @@
DtInitial = 60 # [s]
TEnd = 31536000 # [s]
#TEnd = 315360000000 # [s]
EpisodeLength =
31536
00 # [s]
EpisodeLength =
864
00 # [s]
[Grid]
UpperRight = 500 10 # coordinates of upper right grid corner [m]
...
...
lecture/mm/naplinfiltration/3p3c/naplinfiltrationproblem.hh
deleted
100644 → 0
View file @
edeea605
// -*- 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 Isothermal NAPL infiltration problem: LNAPL contaminates
* the unsaturated and the saturated groundwater zone.
*/
#ifndef DUMUX_NAPLINFILTRATIONPROBLEM_HH
#define DUMUX_NAPLINFILTRATIONPROBLEM_HH
#include <dumux/porousmediumflow/3p/implicit/propertydefaults.hh>
#include <dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh>
#include <dumux/porousmediumflow/implicit/problem.hh>
#include "h2oairnaplfluidsystem.hh"
#include "naplinfiltrationspatialparams.hh"
namespace
Dumux
{
template
<
class
TypeTag
>
class
InfiltrationProblem
;
namespace
Properties
{
NEW_TYPE_TAG
(
InfiltrationProblem
,
INHERITS_FROM
(
InfiltrationSpatialParams
));
NEW_TYPE_TAG
(
InfiltrationProblemThreeP
,
INHERITS_FROM
(
BoxThreeP
,
InfiltrationProblem
));
NEW_TYPE_TAG
(
InfiltrationProblemThreePThreeC
,
INHERITS_FROM
(
BoxThreePThreeC
,
InfiltrationProblem
));
// Set the grid type
SET_TYPE_PROP
(
InfiltrationProblem
,
Grid
,
Dune
::
YaspGrid
<
2
>
);
// Set the problem property
SET_TYPE_PROP
(
InfiltrationProblem
,
Problem
,
Dumux
::
InfiltrationProblem
<
TypeTag
>
);
// Set the fluid system
SET_TYPE_PROP
(
InfiltrationProblem
,
FluidSystem
,
Dumux
::
FluidSystems
::
H2OAirNAPL
<
TypeTag
,
typename
GET_PROP_TYPE
(
TypeTag
,
Scalar
)
>
);
// Enable gravity?
SET_BOOL_PROP
(
InfiltrationProblem
,
ProblemEnableGravity
,
true
);
// Write newton convergence?
SET_BOOL_PROP
(
InfiltrationProblem
,
NewtonWriteConvergence
,
false
);
// Maximum tolerated relative error in the Newton method
SET_SCALAR_PROP
(
InfiltrationProblem
,
NewtonMaxRelativeShift
,
1e-4
);
// -1 backward differences, 0: central differences, +1: forward differences
SET_INT_PROP
(
InfiltrationProblem
,
ImplicitNumericDifferenceMethod
,
1
);
}
/*!
* \ingroup ThreePThreeCBoxModel
* \ingroup BoxTestProblems
* \brief Isothermal NAPL infiltration problem: LNAPL contaminates
* the unsaturated and the saturated groundwater zone.
*
* The 2D domain of this test problem is 500 m long and 10 m deep, where
* the lower part represents a slightly inclined groundwater table, and the
* upper part is the vadose zone.
* A LNAPL (Non-Aqueous Phase Liquid which is lighter than water) infiltrates
* (modelled with a Neumann boundary condition) into the vadose zone. Upon
* reaching the water table, it spreads (since lighter than water) and migrates
* on top of the water table in the direction of the slope.
* On its way through the vadose zone, it leaves a trace of residually trapped
* immobile NAPL, which can in the following dissolve and evaporate slowly,
* and eventually be transported by advection and diffusion.
*
* Left and right boundaries are constant head boundaries (Dirichlet),
* Top and bottom are Neumann boundaries, all no-flow except for the small
* infiltration zone in the upper left part.
*
* This problem uses the \ref ThreePThreeCModel or the \ref ThreePModel.
*
* This problem should typically be simulated for 30 days.
* A good choice for the initial time step size is 60 s.
* To adjust the simulation time it is necessary to edit the file test_naplfiltrationexercise.input
*
* To run the simulation execute the following line in shell:
* <tt>./test_naplfiltrationexercise -ParameterFile test_naplfiltrationexercise.input</tt>
* */
template
<
class
TypeTag
>
class
InfiltrationProblem
:
public
ImplicitPorousMediaProblem
<
TypeTag
>
{
typedef
ImplicitPorousMediaProblem
<
TypeTag
>
ParentType
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
Scalar
)
Scalar
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
GridView
)
GridView
;
// copy some indices for convenience
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
Indices
)
Indices
;
enum
{
pressureIdx
=
Indices
::
pressureIdx
,
#if USE_THREE_P_MODEL
switch1Idx
=
Indices
::
swIdx
,
switch2Idx
=
Indices
::
snIdx
,
#else
switch1Idx
=
Indices
::
switch1Idx
,
switch2Idx
=
Indices
::
switch2Idx
,
wgPhaseOnly
=
Indices
::
wgPhaseOnly
,
#endif
contiWEqIdx
=
Indices
::
contiWEqIdx
,
contiNEqIdx
=
Indices
::
contiNEqIdx
,
contiGEqIdx
=
Indices
::
contiGEqIdx
,
// Grid and world dimension
dim
=
GridView
::
dimension
,
dimWorld
=
GridView
::
dimensionworld
};
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
PrimaryVariables
)
PrimaryVariables
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
BoundaryTypes
)
BoundaryTypes
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
TimeManager
)
TimeManager
;
typedef
typename
GridView
::
template
Codim
<
0
>
::
Entity
Element
;
typedef
typename
GridView
::
template
Codim
<
dim
>
::
Entity
Vertex
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
FVElementGeometry
)
FVElementGeometry
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
FluidSystem
)
FluidSystem
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
MaterialLaw
)
MaterialLaw
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
MaterialLawParams
)
MaterialLawParams
;
typedef
Dune
::
FieldVector
<
Scalar
,
dimWorld
>
GlobalPosition
;
public:
/*!
* \brief The constructor
*
* \param timeManager The time manager
* \param gridView The grid view
*/
InfiltrationProblem
(
TimeManager
&
timeManager
,
const
GridView
&
gridView
)
:
ParentType
(
timeManager
,
gridView
),
eps_
(
1e-5
)
{
temperature_
=
273.15
+
10.0
;
// -> 10 degrees Celsius
episodeLength_
=
GET_RUNTIME_PARAM_FROM_GROUP
(
TypeTag
,
Scalar
,
TimeManager
,
EpisodeLength
);
this
->
timeManager
().
startNextEpisode
(
episodeLength_
);
FluidSystem
::
init
(
/*tempMin=*/
temperature_
-
1
,
/*tempMax=*/
temperature_
+
1
,
/*nTemp=*/
3
,
/*pressMin=*/
0.8
*
1e5
,
/*pressMax=*/
3
*
1e5
,
/*nPress=*/
200
);
}
/*!
* \name Problem parameters
*/
// \{
/*!
* \brief The problem name.
*
* This is used as a prefix for files generated by the simulation.
*/
const
char
*
name
()
const
{
return
"infiltration"
;
}
/*!
* \brief Returns the temperature within the domain.
*
* This problem assumes a temperature of 10 degrees Celsius.
*/
Scalar
temperature
()
const
{
return
temperature_
;
};
void
sourceAtPos
(
PrimaryVariables
&
values
,
const
GlobalPosition
&
globalPos
)
const
{
values
=
0
;
}
// \}
/*!
* \name Boundary conditions
*/
// \{
/*!
* \brief Specifies which kind of boundary condition should be
* used for which equation on a given boundary segment.
*
* \param values The boundary types for the conservation equations
* \param globalPos The position of the finite volume in global coordinates
*/
void
boundaryTypesAtPos
(
BoundaryTypes
&
values
,
const
GlobalPosition
&
globalPos
)
const
{
if
(
globalPos
[
0
]
>
this
->
bBoxMax
()[
0
]
-
eps_
)
values
.
setAllDirichlet
();
else
if
(
globalPos
[
0
]
<
this
->
bBoxMin
()[
0
]
+
eps_
)
values
.
setAllDirichlet
();
else
values
.
setAllNeumann
();
}
/*!
* \brief Evaluate the boundary conditions for a dirichlet
* control volume.
*
* \param values The dirichlet values for the primary variables
* \param globalPos The position of the center of the finite volume
* for which the dirichlet condition ought to be
* set in global coordinates
*
* For this method, the \a values parameter stores primary variables.
*/
void
dirichletAtPos
(
PrimaryVariables
&
values
,
const
GlobalPosition
&
globalPos
)
const
{
initial_
(
values
,
globalPos
);
}
/*!
* \brief Evaluate the boundary conditions for a neumann
* boundary segment.
*
* \param values The neumann values for the conservation equations in units of
* \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$
* \param globalPos The position of the boundary face's integration point in global coordinates
*
* For this method, the \a values parameter stores the mass flux
* in normal direction of each phase. Negative values mean influx.
*/
void
neumannAtPos
(
PrimaryVariables
&
values
,
const
GlobalPosition
&
globalPos
)
const
{
values
=
0
;
// negative values for injection
if
(
this
->
timeManager
().
time
()
<
2592000
)
{
if
(
globalPos
[
0
]
<
175.0
+
eps_
&&
globalPos
[
0
]
>
150.0
+
eps_
&&
globalPos
[
1
]
>
this
->
bBoxMax
()[
1
]
-
eps_
)
// upper boundary
{
values
[
contiWEqIdx
]
=
0.0
;
// /* mole flux, conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m)
values
[
contiNEqIdx
]
=
-
0.001
;
values
[
contiGEqIdx
]
=
0.0
;
}
}
}
// \}
/*!
* \name Volume terms
*/
// \{
/*!
* \brief Evaluate the initial value for a control volume.
*
* \param values The dirichlet values for the primary variables
* \param globalPos The position of the center of the finite volume
* for which the initial values ought to be
* set (in global coordinates)
*
* For this method, the \a values parameter stores primary variables.
*/
void
initialAtPos
(
PrimaryVariables
&
values
,
const
GlobalPosition
&
globalPos
)
const
{
initial_
(
values
,
globalPos
);
}
#if !USE_THREE_P_MODEL
/*!
* \brief Return the initial phase state inside a control volume.
*
* \param vert The vertex
* \param globalIdx The index of the global vertex
* \param globalPos The global position
*/
int
initialPhasePresence
(
const
Vertex
&
vertex
,
int
globalIdx
,
const
GlobalPosition
&
globalPos
)
const
{
return
Indices
::
wgPhaseOnly
;
}
#endif
bool
shouldWriteOutput
()
const
{
return
this
->
timeManager
().
timeStepIndex
()
==
0
||
this
->
timeManager
().
episodeWillBeOver
()
||
this
->
timeManager
().
willBeFinished
();
}
void
episodeEnd
()
{
this
->
timeManager
().
startNextEpisode
(
episodeLength_
);
}
private:
// internal method for the initial condition (reused for the
// dirichlet conditions!)
void
initial_
(
PrimaryVariables
&
values
,
const
GlobalPosition
&
globalPos
)
const
{
const
auto
&
materialLawParams
=
this
->
spatialParams
().
materialLawParams
();
const
Scalar
swr
=
materialLawParams
.
swr
();
const
Scalar
sgr
=
materialLawParams
.
sgr
();
if
(
globalPos
[
1
]
>=
-
1e-3
*
globalPos
[
0
]
+
5
)
{
const
Scalar
pc
=
std
::
max
(
0.0
,
9.81
*
1000.0
*
(
globalPos
[
1
]
+
5e-4
*
globalPos
[
0
]
-
5
));
const
Scalar
sw
=
std
::
min
(
1.0
-
sgr
,
std
::
max
(
swr
,
invertPcGW_
(
pc
,
materialLawParams
)));
values
[
pressureIdx
]
=
1.0e5
;
values
[
switch1Idx
]
=
sw
;
values
[
switch2Idx
]
=
0.0
;
}
else
{
values
[
pressureIdx
]
=
1.0e5
+
9.81
*
1000.0
*
(
5
-
5.0e-4
*
globalPos
[
0
]
-
globalPos
[
1
]);
values
[
switch1Idx
]
=
1.0
-
sgr
;
values
[
switch2Idx
]
=
0.0
;
}
}
static
Scalar
invertPcGW_
(
const
Scalar
pcIn
,
const
MaterialLawParams
&
pcParams
)
{
Scalar
lower
(
0.0
);
Scalar
upper
(
1.0
);
const
unsigned
int
maxIterations
=
25
;
const
Scalar
bisLimit
=
1.0
;
Scalar
sw
,
pcGW
;
for
(
unsigned
int
k
=
1
;
k
<=
maxIterations
;
k
++
)
{
sw
=
0.5
*
(
upper
+
lower
);
pcGW
=
MaterialLaw
::
pcgw
(
pcParams
,
sw
);
const
Scalar
delta
=
std
::
abs
(
pcGW
-
pcIn
);
if
(
delta
<
bisLimit
)
return
sw
;
if
(
k
==
maxIterations
)
return
sw
;
if
(
pcGW
>
pcIn
)
lower
=
sw
;
else
upper
=
sw
;
}
return
sw
;
}
Scalar
temperature_
;
const
Scalar
eps_
;
Scalar
episodeLength_
;
};
}
//end namespace
#endif
lecture/mm/naplinfiltration/3p3c/problem.hh
View file @
93b6db81
...
...
@@ -253,8 +253,8 @@ public:
&&
globalPos
[
1
]
>
this
->
bBoxMax
()[
1
]
-
eps_
)
// upper boundary
{
values
[
contiWEqIdx
]
=
0.0
;
//
/*
mole flux
,
conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m)
values
[
contiNEqIdx
]
=
-
0.001
;
// mole flux conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m)
values
[
contiNEqIdx
]
=
-
0.001
;
// 3p3c needs a mole fraction
values
[
contiGEqIdx
]
=
0.0
;
}
}
...
...
lecture/references/infiltration-reference.vtu
deleted
100644 → 0
View file @
edeea605
This diff is collapsed.
Click to expand it.
lecture/references/infiltration3p-reference.vtu
View file @
93b6db81
This source diff could not be displayed because it is too large. You can
view the blob
instead.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment