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
Commits
921757a2
Commit
921757a2
authored
May 26, 2020
by
Martin Schneider
Browse files
Merge branch 'feature/navier-stokes-darcy-convtest' into 'master'
Feature/navier stokes darcy convtest See merge request
!2128
parents
141fe13d
d8932fc1
Changes
10
Hide whitespace changes
Inline
Side-by-side
dumux/freeflow/navierstokes/problem.hh
View file @
921757a2
...
...
@@ -25,6 +25,7 @@
#define DUMUX_NAVIERSTOKES_PROBLEM_HH
#include
<dune/common/exceptions.hh>
#include
<dune/common/typetraits.hh>
#include
<dumux/common/properties.hh>
#include
<dumux/common/staggeredfvproblem.hh>
#include
<dumux/discretization/method.hh>
...
...
@@ -204,8 +205,19 @@ public:
}
/*!
* \brief Returns the beta value
, or
the alpha value divided by the square root of the
intrinsic
permeability.
* \brief Returns the beta value
which is
the alpha value divided by the square root of the
(scalar-valued) interface
permeability.
*/
Scalar
betaBJ
(
const
Element
&
element
,
const
SubControlVolumeFace
&
scvf
,
const
GlobalPosition
&
tangentialVector
)
const
{
const
Scalar
interfacePermeability
=
interfacePermeability_
(
element
,
scvf
,
tangentialVector
);
using
std
::
sqrt
;
return
asImp_
().
alphaBJ
(
scvf
)
/
sqrt
(
interfacePermeability
);
}
/*!
* \brief Returns the beta value which is the alpha value divided by the square root of the (scalar-valued) interface permeability.
*/
[[
deprecated
(
"Use betaBJ with tangential vector instead. Will be removed after 3.3"
)]]
Scalar
betaBJ
(
const
Element
&
element
,
const
SubControlVolumeFace
&
scvf
)
const
{
using
std
::
sqrt
;
...
...
@@ -220,7 +232,10 @@ public:
return
VelocityVector
(
0.0
);
}
//! helper function to evaluate the slip velocity on the boundary when the Beavers-Joseph condition is used
/*!
* \brief Returns the slip velocity at a porous boundary based on the Beavers-Joseph(-Saffman) condition.
*/
const
Scalar
beaversJosephVelocity
(
const
Element
&
element
,
const
SubControlVolume
&
scv
,
const
SubControlVolumeFace
&
ownScvf
,
...
...
@@ -228,21 +243,33 @@ public:
const
Scalar
velocitySelf
,
const
Scalar
tangentialVelocityGradient
)
const
{
// du/dy + dv/dx = alpha/sqrt(K) * (u_boundary-uPM)
// beta = alpha/sqrt(K)
const
Scalar
betaBJ
=
asImp_
().
betaBJ
(
element
,
faceOnPorousBoundary
);
const
Scalar
distanceNormalToBoundary
=
(
faceOnPorousBoundary
.
center
()
-
scv
.
center
()).
two_norm
();
// create a unit normal vector oriented in positive coordinate direction
GlobalPosition
orientation
=
ownScvf
.
unitOuterNormal
();
orientation
[
ownScvf
.
directionIndex
()]
=
1.0
;
// du/dy + dv/dx = alpha/sqrt(K) * (u_boundary-uPM)
// beta = alpha/sqrt(K)
const
Scalar
betaBJ
=
asImp_
().
betaBJ
(
element
,
faceOnPorousBoundary
,
orientation
);
const
Scalar
distanceNormalToBoundary
=
(
faceOnPorousBoundary
.
center
()
-
scv
.
center
()).
two_norm
();
return
(
tangentialVelocityGradient
*
distanceNormalToBoundary
+
asImp_
().
porousMediumVelocity
(
element
,
faceOnPorousBoundary
)
*
orientation
*
betaBJ
*
distanceNormalToBoundary
+
velocitySelf
)
/
(
betaBJ
*
distanceNormalToBoundary
+
1.0
);
}
private:
//! Returns a scalar permeability value at the coupling interface
Scalar
interfacePermeability_
(
const
Element
&
element
,
const
SubControlVolumeFace
&
scvf
,
const
GlobalPosition
&
tangentialVector
)
const
{
const
auto
&
K
=
asImp_
().
permeability
(
element
,
scvf
);
// use t*K*t for permeability tensors
if
constexpr
(
Dune
::
IsNumber
<
std
::
decay_t
<
decltype
(
K
)
>>::
value
)
return
K
;
else
return
vtmv
(
tangentialVector
,
K
,
tangentialVector
);
}
//! Returns the implementation of the problem (i.e. static polymorphism)
Implementation
&
asImp_
()
{
return
*
static_cast
<
Implementation
*>
(
this
);
}
...
...
dumux/multidomain/boundary/stokesdarcy/couplingdata.hh
View file @
921757a2
...
...
@@ -283,7 +283,7 @@ public:
/*!
* \brief Returns the intrinsic permeability of the coupled Darcy element.
*/
Scalar
darcyPermeability
(
const
Element
<
stokesIdx
>&
element
,
const
SubControlVolumeFace
<
stokesIdx
>&
scvf
)
const
auto
darcyPermeability
(
const
Element
<
stokesIdx
>&
element
,
const
SubControlVolumeFace
<
stokesIdx
>&
scvf
)
const
{
const
auto
&
stokesContext
=
couplingManager
().
stokesCouplingContext
(
element
,
scvf
);
return
stokesContext
.
volVars
.
permeability
();
...
...
test/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt
View file @
921757a2
add_input_file_links
()
dune_symlink_to_source_files
(
FILES
"convergencetest.py"
)
add_executable
(
test_md_boundary_darcy1p_freeflow1p_convtest EXCLUDE_FROM_ALL main.cc
)
dune_add_test
(
NAME test_md_boundary_darcy1p_stokes1p_convtest
SOURCES main.cc
TARGET test_md_boundary_darcy1p_freeflow1p_convtest
LABELS multidomain multidomain_boundary stokesdarcy
TIMEOUT 1000
CMAKE_GUARD HAVE_UMFPACK
COMMAND ./convergencetest.py
CMD_ARGS test_md_boundary_darcy1p_freeflow1p_convtest params.input
-Darcy.SpatialParams.Permeability 1.0
)
dune_add_test
(
NAME test_md_boundary_darcy1p_navierstokes1p_convtest
TARGET test_md_boundary_darcy1p_freeflow1p_convtest
LABELS multidomain multidomain_boundary stokesdarcy
TIMEOUT 1000
CMAKE_GUARD HAVE_UMFPACK
COMMAND ./convergencetest.py
CMD_ARGS test_md_boundary_darcy1p_stokes1p_convtest params.input
)
CMD_ARGS test_md_boundary_darcy1p_freeflow1p_convtest params.input
-Problem.TestCase Schneider
-FreeFlow.Problem.EnableInertiaTerms true
-FreeFlow.EnableUnsymmetrizedVelocityGradientForBeaversJoseph true
)
test/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/convergencetest.py
View file @
921757a2
...
...
@@ -12,8 +12,8 @@ testname = str(sys.argv[1])
testargs
=
[
str
(
i
)
for
i
in
sys
.
argv
][
2
:]
# remove the old log files
subprocess
.
call
([
'rm'
,
testname
+
'_
stokes
.log'
])
print
(
"Removed old log file ({})!"
.
format
(
testname
+
'_
stokes
.log'
))
subprocess
.
call
([
'rm'
,
testname
+
'_
freeFlow
.log'
])
print
(
"Removed old log file ({})!"
.
format
(
testname
+
'_
freeFlow
.log'
))
subprocess
.
call
([
'rm'
,
testname
+
'_darcy.log'
])
print
(
"Removed old log file ({})!"
.
format
(
testname
+
'_darcy.log'
))
...
...
@@ -22,9 +22,9 @@ for i in [0, 1, 2]:
subprocess
.
call
([
'./'
+
testname
]
+
testargs
+
[
'-Grid.Refinement'
,
str
(
i
),
'-Vtk.OutputName'
,
testname
])
def
checkRates
Stokes
():
def
checkRates
FreeFlow
():
# check the rates and append them to the log file
logfile
=
open
(
testname
+
'_
stokes
.log'
,
"r+"
)
logfile
=
open
(
testname
+
'_
freeFlow
.log'
,
"r+"
)
errorP
=
[]
errorVx
=
[]
...
...
@@ -64,7 +64,7 @@ def checkRatesStokes():
logfile
.
close
()
print
(
"
\n
Computed the following convergence rates for {}:
\n
"
.
format
(
testname
))
subprocess
.
call
([
'cat'
,
testname
+
'_
stokes
.log'
])
subprocess
.
call
([
'cat'
,
testname
+
'_
freeFlow
.log'
])
return
{
"p"
:
resultsP
,
"v_x"
:
resultsVx
,
"v_y"
:
resultsVy
}
...
...
@@ -104,23 +104,23 @@ def checkRatesDarcy():
return
{
"p"
:
resultsP
}
def
checkRates
Stokes
AndDarcy
():
results
Stokes
=
checkRates
Stokes
()
def
checkRates
FreeFlow
AndDarcy
():
results
FreeFlow
=
checkRates
FreeFlow
()
resultsDarcy
=
checkRatesDarcy
()
def
mean
(
numbers
):
return
float
(
sum
(
numbers
))
/
len
(
numbers
)
# check the rates, we expect rates around 2
if
mean
(
results
Stokes
[
"p"
])
<
2.05
and
mean
(
results
Stokes
[
"p"
])
<
1.84
:
if
mean
(
results
FreeFlow
[
"p"
])
<
2.05
and
mean
(
results
FreeFlow
[
"p"
])
<
1.84
:
sys
.
stderr
.
write
(
"*"
*
70
+
"
\n
"
+
"The convergence rates for pressure were not close enough to 2! Test failed.
\n
"
+
"*"
*
70
+
"
\n
"
)
sys
.
exit
(
1
)
if
mean
(
results
Stokes
[
"v_x"
])
<
2.05
and
mean
(
results
Stokes
[
"v_x"
])
<
1.95
:
if
mean
(
results
FreeFlow
[
"v_x"
])
<
2.05
and
mean
(
results
FreeFlow
[
"v_x"
])
<
1.95
:
sys
.
stderr
.
write
(
"*"
*
70
+
"
\n
"
+
"The convergence rates for x-velocity were not close enough to 2! Test failed.
\n
"
+
"*"
*
70
+
"
\n
"
)
sys
.
exit
(
1
)
if
mean
(
results
Stokes
[
"v_y"
])
<
2.05
and
mean
(
results
Stokes
[
"v_y"
])
<
1.95
:
if
mean
(
results
FreeFlow
[
"v_y"
])
<
2.05
and
mean
(
results
FreeFlow
[
"v_y"
])
<
1.95
:
sys
.
stderr
.
write
(
"*"
*
70
+
"
\n
"
+
"The convergence rates for y-velocity were not close enough to 2! Test failed.
\n
"
+
"*"
*
70
+
"
\n
"
)
sys
.
exit
(
1
)
...
...
@@ -129,4 +129,4 @@ def checkRatesStokesAndDarcy():
sys
.
exit
(
1
)
checkRates
Stokes
AndDarcy
()
checkRates
FreeFlow
AndDarcy
()
test/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc
View file @
921757a2
...
...
@@ -19,9 +19,7 @@
/*!
* \file
* \ingroup BoundaryTests
* \brief A test problem for the coupled Stokes/Darcy problem (1p).
* The analytical solution is given in Shiue et al., 2018:
* "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem"
* \brief A test problem for the coupled FreeFlow/Darcy problem (1p).
*/
#include
<config.h>
...
...
@@ -51,6 +49,7 @@
#include
<dumux/multidomain/boundary/stokesdarcy/couplingmanager.hh>
#include
"testcase.hh"
#include
"problem_darcy.hh"
#include
"problem_stokes.hh"
...
...
@@ -58,7 +57,7 @@ namespace Dumux {
namespace
Properties
{
template
<
class
TypeTag
>
struct
CouplingManager
<
TypeTag
,
TTag
::
Stokes
OneP
>
struct
CouplingManager
<
TypeTag
,
TTag
::
FreeFlow
OneP
>
{
using
Traits
=
StaggeredMultiDomainTraits
<
TypeTag
,
TypeTag
,
Properties
::
TTag
::
DarcyOneP
>
;
using
type
=
Dumux
::
StokesDarcyCouplingManager
<
Traits
>
;
...
...
@@ -67,7 +66,7 @@ struct CouplingManager<TypeTag, TTag::StokesOneP>
template
<
class
TypeTag
>
struct
CouplingManager
<
TypeTag
,
TTag
::
DarcyOneP
>
{
using
Traits
=
StaggeredMultiDomainTraits
<
Properties
::
TTag
::
Stokes
OneP
,
Properties
::
TTag
::
Stokes
OneP
,
TypeTag
>
;
using
Traits
=
StaggeredMultiDomainTraits
<
Properties
::
TTag
::
FreeFlow
OneP
,
Properties
::
TTag
::
FreeFlow
OneP
,
TypeTag
>
;
using
type
=
Dumux
::
StokesDarcyCouplingManager
<
Traits
>
;
};
...
...
@@ -80,7 +79,7 @@ struct CouplingManager<TypeTag, TTag::DarcyOneP>
* \param problem the problem for which to evaluate the analytical solution
*/
template
<
class
Scalar
,
class
Problem
>
auto
create
Stokes
AnalyticalSolution
(
const
Problem
&
problem
)
auto
create
FreeFlow
AnalyticalSolution
(
const
Problem
&
problem
)
{
const
auto
&
gridGeometry
=
problem
.
gridGeometry
();
using
GridView
=
typename
std
::
decay_t
<
decltype
(
gridGeometry
)
>::
GridView
;
...
...
@@ -171,11 +170,11 @@ auto createDarcyAnalyticalSolution(const Problem& problem)
}
template
<
class
Problem
,
class
SolutionVector
>
void
print
Stokes
L2Error
(
const
Problem
&
problem
,
const
SolutionVector
&
x
)
void
print
FreeFlow
L2Error
(
const
Problem
&
problem
,
const
SolutionVector
&
x
)
{
using
namespace
Dumux
;
using
Scalar
=
double
;
using
TypeTag
=
Properties
::
TTag
::
Stokes
OneP
;
using
TypeTag
=
Properties
::
TTag
::
FreeFlow
OneP
;
using
Indices
=
typename
GetPropType
<
TypeTag
,
Properties
::
ModelTraits
>::
Indices
;
using
ModelTraits
=
GetPropType
<
TypeTag
,
Properties
::
ModelTraits
>
;
using
PrimaryVariables
=
GetPropType
<
TypeTag
,
Properties
::
PrimaryVariables
>
;
...
...
@@ -253,7 +252,7 @@ int main(int argc, char** argv) try
Parameters
::
init
(
argc
,
argv
);
// Define the sub problem type tags
using
Stokes
TypeTag
=
Properties
::
TTag
::
Stokes
OneP
;
using
FreeFlow
TypeTag
=
Properties
::
TTag
::
FreeFlow
OneP
;
using
DarcyTypeTag
=
Properties
::
TTag
::
DarcyOneP
;
// try to create a grid (from the given grid file or the input file)
...
...
@@ -262,67 +261,83 @@ int main(int argc, char** argv) try
DarcyGridManager
darcyGridManager
;
darcyGridManager
.
init
(
"Darcy"
);
// pass parameter group
using
Stokes
GridManager
=
Dumux
::
GridManager
<
GetPropType
<
Stokes
TypeTag
,
Properties
::
Grid
>>
;
Stokes
GridManager
stokes
GridManager
;
stokes
GridManager
.
init
(
"
Stokes
"
);
// pass parameter group
using
FreeFlow
GridManager
=
Dumux
::
GridManager
<
GetPropType
<
FreeFlow
TypeTag
,
Properties
::
Grid
>>
;
FreeFlow
GridManager
freeFlow
GridManager
;
freeFlow
GridManager
.
init
(
"
FreeFlow
"
);
// pass parameter group
// we compute on the leaf grid view
const
auto
&
darcyGridView
=
darcyGridManager
.
grid
().
leafGridView
();
const
auto
&
stokes
GridView
=
stokes
GridManager
.
grid
().
leafGridView
();
const
auto
&
freeFlow
GridView
=
freeFlow
GridManager
.
grid
().
leafGridView
();
// create the finite volume grid geometry
using
Stokes
GridGeometry
=
GetPropType
<
Stokes
TypeTag
,
Properties
::
GridGeometry
>
;
auto
stokes
GridGeometry
=
std
::
make_shared
<
Stokes
GridGeometry
>
(
stokes
GridView
);
stokes
GridGeometry
->
update
();
using
FreeFlow
GridGeometry
=
GetPropType
<
FreeFlow
TypeTag
,
Properties
::
GridGeometry
>
;
auto
freeFlow
GridGeometry
=
std
::
make_shared
<
FreeFlow
GridGeometry
>
(
freeFlow
GridView
);
freeFlow
GridGeometry
->
update
();
using
DarcyGridGeometry
=
GetPropType
<
DarcyTypeTag
,
Properties
::
GridGeometry
>
;
auto
darcyGridGeometry
=
std
::
make_shared
<
DarcyGridGeometry
>
(
darcyGridView
);
darcyGridGeometry
->
update
();
using
Traits
=
StaggeredMultiDomainTraits
<
Stokes
TypeTag
,
Stokes
TypeTag
,
DarcyTypeTag
>
;
using
Traits
=
StaggeredMultiDomainTraits
<
FreeFlow
TypeTag
,
FreeFlow
TypeTag
,
DarcyTypeTag
>
;
// the coupling manager
using
CouplingManager
=
StokesDarcyCouplingManager
<
Traits
>
;
auto
couplingManager
=
std
::
make_shared
<
CouplingManager
>
(
stokes
GridGeometry
,
darcyGridGeometry
);
auto
couplingManager
=
std
::
make_shared
<
CouplingManager
>
(
freeFlow
GridGeometry
,
darcyGridGeometry
);
// the indices
constexpr
auto
stokes
CellCenterIdx
=
CouplingManager
::
stokesCellCenterIdx
;
constexpr
auto
stokes
FaceIdx
=
CouplingManager
::
stokesFaceIdx
;
constexpr
auto
freeFlow
CellCenterIdx
=
CouplingManager
::
stokesCellCenterIdx
;
constexpr
auto
freeFlow
FaceIdx
=
CouplingManager
::
stokesFaceIdx
;
constexpr
auto
darcyIdx
=
CouplingManager
::
darcyIdx
;
// the problem (initial and boundary conditions)
using
StokesProblem
=
GetPropType
<
StokesTypeTag
,
Properties
::
Problem
>
;
auto
stokesProblem
=
std
::
make_shared
<
StokesProblem
>
(
stokesGridGeometry
,
couplingManager
);
const
auto
testCase
=
[]()
{
const
auto
testCaseInput
=
getParam
<
std
::
string
>
(
"Problem.TestCase"
,
"ShiueExampleTwo"
);
if
(
testCaseInput
==
"ShiueExampleOne"
)
return
TestCase
::
ShiueExampleOne
;
else
if
(
testCaseInput
==
"ShiueExampleTwo"
)
return
TestCase
::
ShiueExampleTwo
;
else
if
(
testCaseInput
==
"Rybak"
)
return
TestCase
::
Rybak
;
else
if
(
testCaseInput
==
"Schneider"
)
return
TestCase
::
Schneider
;
else
DUNE_THROW
(
Dune
::
InvalidStateException
,
testCaseInput
+
" is not a valid test case"
);
}();
using
FreeFlowProblem
=
GetPropType
<
FreeFlowTypeTag
,
Properties
::
Problem
>
;
auto
freeFlowProblem
=
std
::
make_shared
<
FreeFlowProblem
>
(
freeFlowGridGeometry
,
couplingManager
,
testCase
);
using
DarcyProblem
=
GetPropType
<
DarcyTypeTag
,
Properties
::
Problem
>
;
auto
darcyProblem
=
std
::
make_shared
<
DarcyProblem
>
(
darcyGridGeometry
,
couplingManager
);
auto
spatialParams
=
std
::
make_shared
<
typename
DarcyProblem
::
SpatialParams
>
(
darcyGridGeometry
,
testCase
);
auto
darcyProblem
=
std
::
make_shared
<
DarcyProblem
>
(
darcyGridGeometry
,
couplingManager
,
spatialParams
,
testCase
);
// the solution vector
Traits
::
SolutionVector
sol
;
sol
[
stokes
CellCenterIdx
].
resize
(
stokes
GridGeometry
->
numCellCenterDofs
());
sol
[
stokes
FaceIdx
].
resize
(
stokes
GridGeometry
->
numFaceDofs
());
sol
[
freeFlow
CellCenterIdx
].
resize
(
freeFlow
GridGeometry
->
numCellCenterDofs
());
sol
[
freeFlow
FaceIdx
].
resize
(
freeFlow
GridGeometry
->
numFaceDofs
());
sol
[
darcyIdx
].
resize
(
darcyGridGeometry
->
numDofs
());
// get a solution vector storing references to the two
Stokes
solution vectors
auto
stokes
Sol
=
partial
(
sol
,
stokes
FaceIdx
,
stokes
CellCenterIdx
);
// get a solution vector storing references to the two
FreeFlow
solution vectors
auto
freeFlow
Sol
=
partial
(
sol
,
freeFlow
FaceIdx
,
freeFlow
CellCenterIdx
);
couplingManager
->
init
(
stokes
Problem
,
darcyProblem
,
sol
);
couplingManager
->
init
(
freeFlow
Problem
,
darcyProblem
,
sol
);
// the grid variables
using
Stokes
GridVariables
=
GetPropType
<
Stokes
TypeTag
,
Properties
::
GridVariables
>
;
auto
stokes
GridVariables
=
std
::
make_shared
<
Stokes
GridVariables
>
(
stokes
Problem
,
stokes
GridGeometry
);
stokes
GridVariables
->
init
(
stokes
Sol
);
using
FreeFlow
GridVariables
=
GetPropType
<
FreeFlow
TypeTag
,
Properties
::
GridVariables
>
;
auto
freeFlow
GridVariables
=
std
::
make_shared
<
FreeFlow
GridVariables
>
(
freeFlow
Problem
,
freeFlow
GridGeometry
);
freeFlow
GridVariables
->
init
(
freeFlow
Sol
);
using
DarcyGridVariables
=
GetPropType
<
DarcyTypeTag
,
Properties
::
GridVariables
>
;
auto
darcyGridVariables
=
std
::
make_shared
<
DarcyGridVariables
>
(
darcyProblem
,
darcyGridGeometry
);
darcyGridVariables
->
init
(
sol
[
darcyIdx
]);
// intialize the vtk output module
using
Scalar
=
typename
Traits
::
Scalar
;
StaggeredVtkOutputModule
<
Stokes
GridVariables
,
decltype
(
stokesSol
)
>
stokes
VtkWriter
(
*
stokes
GridVariables
,
stokesSol
,
stokes
Problem
->
name
());
GetPropType
<
Stokes
TypeTag
,
Properties
::
IOFields
>::
initOutputModule
(
stokes
VtkWriter
);
const
auto
stokes
AnalyticalSolution
=
create
Stokes
AnalyticalSolution
<
Scalar
>
(
*
stokes
Problem
);
stokes
VtkWriter
.
addField
(
std
::
get
<
0
>
(
stokes
AnalyticalSolution
),
"pressureExact"
);
stokes
VtkWriter
.
addField
(
std
::
get
<
1
>
(
stokes
AnalyticalSolution
),
"velocityExact"
);
stokes
VtkWriter
.
addFaceField
(
std
::
get
<
2
>
(
stokes
AnalyticalSolution
),
"faceVelocityExact"
);
stokes
VtkWriter
.
write
(
0.0
);
StaggeredVtkOutputModule
<
FreeFlow
GridVariables
,
decltype
(
freeFlowSol
)
>
freeFlow
VtkWriter
(
*
freeFlow
GridVariables
,
freeFlowSol
,
freeFlow
Problem
->
name
());
GetPropType
<
FreeFlow
TypeTag
,
Properties
::
IOFields
>::
initOutputModule
(
freeFlow
VtkWriter
);
const
auto
freeFlow
AnalyticalSolution
=
create
FreeFlow
AnalyticalSolution
<
Scalar
>
(
*
freeFlow
Problem
);
freeFlow
VtkWriter
.
addField
(
std
::
get
<
0
>
(
freeFlow
AnalyticalSolution
),
"pressureExact"
);
freeFlow
VtkWriter
.
addField
(
std
::
get
<
1
>
(
freeFlow
AnalyticalSolution
),
"velocityExact"
);
freeFlow
VtkWriter
.
addFaceField
(
std
::
get
<
2
>
(
freeFlow
AnalyticalSolution
),
"faceVelocityExact"
);
freeFlow
VtkWriter
.
write
(
0.0
);
VtkOutputModule
<
DarcyGridVariables
,
GetPropType
<
DarcyTypeTag
,
Properties
::
SolutionVector
>>
darcyVtkWriter
(
*
darcyGridVariables
,
sol
[
darcyIdx
],
darcyProblem
->
name
());
using
DarcyVelocityOutput
=
GetPropType
<
DarcyTypeTag
,
Properties
::
VelocityOutput
>
;
...
...
@@ -335,12 +350,12 @@ int main(int argc, char** argv) try
// the assembler for a stationary problem
using
Assembler
=
MultiDomainFVAssembler
<
Traits
,
CouplingManager
,
DiffMethod
::
numeric
>
;
auto
assembler
=
std
::
make_shared
<
Assembler
>
(
std
::
make_tuple
(
stokes
Problem
,
stokes
Problem
,
darcyProblem
),
std
::
make_tuple
(
stokes
GridGeometry
->
faceFVGridGeometryPtr
(),
stokes
GridGeometry
->
cellCenterFVGridGeometryPtr
(),
auto
assembler
=
std
::
make_shared
<
Assembler
>
(
std
::
make_tuple
(
freeFlow
Problem
,
freeFlow
Problem
,
darcyProblem
),
std
::
make_tuple
(
freeFlow
GridGeometry
->
faceFVGridGeometryPtr
(),
freeFlow
GridGeometry
->
cellCenterFVGridGeometryPtr
(),
darcyGridGeometry
),
std
::
make_tuple
(
stokes
GridVariables
->
faceGridVariablesPtr
(),
stokes
GridVariables
->
cellCenterGridVariablesPtr
(),
std
::
make_tuple
(
freeFlow
GridVariables
->
faceGridVariablesPtr
(),
freeFlow
GridVariables
->
cellCenterGridVariablesPtr
(),
darcyGridVariables
),
couplingManager
);
...
...
@@ -356,10 +371,10 @@ int main(int argc, char** argv) try
nonLinearSolver
.
solve
(
sol
);
// write vtk output
stokes
VtkWriter
.
write
(
1.0
);
freeFlow
VtkWriter
.
write
(
1.0
);
darcyVtkWriter
.
write
(
1.0
);
print
Stokes
L2Error
(
*
stokes
Problem
,
stokes
Sol
);
print
FreeFlow
L2Error
(
*
freeFlow
Problem
,
freeFlow
Sol
);
printDarcyL2Error
(
*
darcyProblem
,
sol
[
darcyIdx
]);
////////////////////////////////////////////////////////////
...
...
test/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input
View file @
921757a2
...
...
@@ -2,24 +2,23 @@
UpperRight = 1 1
Cells = 40 40
[
Stokes
.Grid]
[
FreeFlow
.Grid]
LowerLeft = 0 1
UpperRight = 1 2
Cells = 40 40
[
Stokes
.Problem]
Name =
stokes
[
FreeFlow
.Problem]
Name =
freeFlow
EnableInertiaTerms = false
[Darcy.Problem]
Name = darcy
[Darcy.SpatialParams]
Permeability = 1.0
AlphaBeaversJoseph = 1.0
[Vtk]
OutputName = test_md_boundary_
stokes
1p_darcy1p_convergencetest
OutputName = test_md_boundary_
freeflow
1p_darcy1p_convergencetest
[Problem]
EnableGravity = false
...
...
@@ -33,3 +32,6 @@ LiquidKinematicViscosity = 1.0
[Assembly]
NumericDifference.BaseEpsilon = 1e-4
[FreeFlow.Flux]
UpwindWeight = 0.5
test/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_darcy.hh
View file @
921757a2
...
...
@@ -33,7 +33,8 @@
#include
<dumux/porousmediumflow/1p/model.hh>
#include
<dumux/porousmediumflow/problem.hh>
#include
"../spatialparams.hh"
#include
"spatialparams.hh"
#include
"testcase.hh"
#include
<dumux/material/components/constant.hh>
#include
<dumux/material/fluidsystems/1pliquid.hh>
...
...
@@ -69,7 +70,7 @@ struct SpatialParams<TypeTag, TTag::DarcyOneP>
{
using
GridGeometry
=
GetPropType
<
TypeTag
,
Properties
::
GridGeometry
>
;
using
Scalar
=
GetPropType
<
TypeTag
,
Properties
::
Scalar
>
;
using
type
=
OneP
SpatialParams
<
GridGeometry
,
Scalar
>
;
using
type
=
ConvergenceTest
SpatialParams
<
GridGeometry
,
Scalar
>
;
};
}
// end namespace Properties
...
...
@@ -100,30 +101,19 @@ class DarcySubProblem : public PorousMediumFlowProblem<TypeTag>
static
constexpr
auto
velocityYIdx
=
1
;
static
constexpr
auto
pressureIdx
=
2
;
enum
class
TestCase
{
ShiueExampleOne
,
ShiueExampleTwo
,
Rybak
};
public:
//! export the Indices
using
Indices
=
typename
GetPropType
<
TypeTag
,
Properties
::
ModelTraits
>::
Indices
;
DarcySubProblem
(
std
::
shared_ptr
<
const
GridGeometry
>
gridGeometry
,
std
::
shared_ptr
<
CouplingManager
>
couplingManager
)
:
ParentType
(
gridGeometry
,
"Darcy"
),
couplingManager_
(
couplingManager
)
std
::
shared_ptr
<
CouplingManager
>
couplingManager
,
std
::
shared_ptr
<
typename
ParentType
::
SpatialParams
>
spatialParams
,
const
TestCase
testCase
)
:
ParentType
(
gridGeometry
,
spatialParams
,
"Darcy"
)
,
couplingManager_
(
couplingManager
)
,
testCase_
(
testCase
)
{
problemName_
=
getParam
<
std
::
string
>
(
"Vtk.OutputName"
)
+
"_"
+
getParamFromGroup
<
std
::
string
>
(
this
->
paramGroup
(),
"Problem.Name"
);
const
auto
testCaseInput
=
getParamFromGroup
<
std
::
string
>
(
this
->
paramGroup
(),
"Problem.TestCase"
,
"ShiueExampleTwo"
);
if
(
testCaseInput
==
"ShiueExampleOne"
)
testCase_
=
TestCase
::
ShiueExampleOne
;
else
if
(
testCaseInput
==
"ShiueExampleTwo"
)
testCase_
=
TestCase
::
ShiueExampleTwo
;
else
if
(
testCaseInput
==
"Rybak"
)
testCase_
=
TestCase
::
Rybak
;
else
DUNE_THROW
(
Dune
::
InvalidStateException
,
testCaseInput
+
" is not a valid test case"
);
}
/*!
...
...
@@ -233,6 +223,8 @@ public:
return
rhsShiueEtAlExampleTwo_
(
globalPos
);
case
TestCase
::
Rybak
:
return
rhsRybak_
(
globalPos
);
case
TestCase
::
Schneider
:
return
rhsSchneiderEtAl_
(
globalPos
);
default:
DUNE_THROW
(
Dune
::
InvalidStateException
,
"Invalid test case"
);
}
...
...
@@ -268,6 +260,8 @@ public:
return
analyticalSolutionShiueEtAlExampleTwo_
(
globalPos
);
case
TestCase
::
Rybak
:
return
analyticalSolutionRybak_
(
globalPos
);
case
TestCase
::
Schneider
:
return
analyticalSolutionSchneiderEtAl_
(
globalPos
);
default:
DUNE_THROW
(
Dune
::
InvalidStateException
,
"Invalid test case"
);
}
...
...
@@ -346,6 +340,50 @@ private:
NumEqVector
rhsShiueEtAlExampleTwo_
(
const
GlobalPosition
&
globalPos
)
const
{
return
NumEqVector
(
0.0
);
}
// see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for
// free flow/porous-medium flow problems"
Dune
::
FieldVector
<
Scalar
,
3
>
analyticalSolutionSchneiderEtAl_
(
const
GlobalPosition
&
globalPos
)
const
{
Dune
::
FieldVector
<
Scalar
,
3
>
sol
(
0.0
);
const
Scalar
x
=
globalPos
[
0
];
const
Scalar
y
=
globalPos
[
1
];
static
constexpr
Scalar
omega
=
M_PI
;
static
constexpr
Scalar
c
=
0.0
;
using
std
::
exp
;
using
std
::
sin
;
using
std
::
cos
;
const
Scalar
sinOmegaX
=
sin
(
omega
*
x
);
const
Scalar
cosOmegaX
=
cos
(
omega
*
x
);
static
const
Scalar
expTwo
=
exp
(
2
);
const
Scalar
expYPlusOne
=
exp
(
y
+
1
);
sol
[
pressureIdx
]
=
(
expYPlusOne
+
2
-
expTwo
)
*
sinOmegaX
;
sol
[
velocityXIdx
]
=
c
/
(
2
*
omega
)
*
expYPlusOne
*
sinOmegaX
*
sinOmegaX
-
omega
*
(
expYPlusOne
+
2
-
expTwo
)
*
cosOmegaX
;
sol
[
velocityYIdx
]
=
(
0.5
*
c
*
(
expYPlusOne
+
2
-
expTwo
)
*
cosOmegaX
-
(
c
*
cosOmegaX
+
1
)
*
exp
(
y
-
1
))
*
sinOmegaX
;
return
sol
;
}
// see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for
// free flow/porous-medium flow problems (with c = 0)"
NumEqVector
rhsSchneiderEtAl_
(
const
GlobalPosition
&
globalPos
)
const
{
const
Scalar
x
=
globalPos
[
0
];
const
Scalar
y
=
globalPos
[
1
];
using
std
::
exp
;
using
std
::
sin
;
using
std
::
cos
;
static
constexpr
Scalar
omega
=
M_PI
;
static
constexpr
Scalar
c
=
0.0
;
const
Scalar
cosOmegaX
=
cos
(
omega
*
x
);
static
const
Scalar
expTwo
=
exp
(
2
);
const
Scalar
expYPlusOne
=
exp
(
y
+
1
);
const
Scalar
result
=
(
-
(
c
*
cosOmegaX
+
1
)
*
exp
(
y
-
1
)
+
1.5
*
c
*
expYPlusOne
*
cosOmegaX
+
omega
*
omega
*
(
expYPlusOne
-
expTwo
+
2
))
*
sin
(
omega
*
x
);
return
NumEqVector
(
result
);
}
static
constexpr
Scalar
eps_
=
1e-7
;
std
::
shared_ptr
<
CouplingManager
>
couplingManager_
;
std
::
string
problemName_
;
...
...
test/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh
View file @
921757a2
...
...
@@ -19,11 +19,11 @@
/*!
* \file
* \ingroup BoundaryTests
* \brief The
Stokes
sub-problem of coupled
Stokes-
Darcy convergence test
* \brief The
free-flow
sub-problem of coupled
FreeFlow/
Darcy convergence test
*/
#ifndef DUMUX_
STOKES
_SUBPROBLEM_HH
#define DUMUX_
STOKES
_SUBPROBLEM_HH
#ifndef DUMUX_
FREEFLOW
_SUBPROBLEM_HH
#define DUMUX_
FREEFLOW
_SUBPROBLEM_HH
#include
<dune/common/fvector.hh>
#include
<dune/grid/yaspgrid.hh>
...
...
@@ -34,20 +34,21 @@
#include
<dumux/freeflow/navierstokes/problem.hh>
#include
<dumux/discretization/staggered/freeflow/properties.hh>
#include
<dumux/freeflow/navierstokes/model.hh>
#include
"testcase.hh"