...
 
Commits (9)
...@@ -131,6 +131,7 @@ build:debug: &debug ...@@ -131,6 +131,7 @@ build:debug: &debug
$DUNECONTROL --only=dorie configure $DUNECONTROL --only=dorie configure
- $DUNECONTROL --only=dorie make $MAKE_FLAGS dorie-rfg - $DUNECONTROL --only=dorie make $MAKE_FLAGS dorie-rfg
- $DUNECONTROL --only=dorie make $MAKE_FLAGS build_unit_tests - $DUNECONTROL --only=dorie make $MAKE_FLAGS build_unit_tests
- $DUNECONTROL --only=dorie make $MAKE_FLAGS richards_d2_r1 transport_d2_r0_t0
build:debug-clang: build:debug-clang:
<<: *debug <<: *debug
...@@ -145,6 +146,7 @@ build:debug-clang: ...@@ -145,6 +146,7 @@ build:debug-clang:
$DUNECONTROL --only=dorie configure $DUNECONTROL --only=dorie configure
- $DUNECONTROL --only=dorie make $MAKE_FLAGS dorie-rfg - $DUNECONTROL --only=dorie make $MAKE_FLAGS dorie-rfg
- $DUNECONTROL --only=dorie make $MAKE_FLAGS build_unit_tests - $DUNECONTROL --only=dorie make $MAKE_FLAGS build_unit_tests
- $DUNECONTROL --only=dorie make $MAKE_FLAGS transport_d2_r0_t0 transport_d2_r1_t0
# --- Tests --- # --- Tests ---
...@@ -217,7 +219,7 @@ deploy:dockerhub-devel: &deploy ...@@ -217,7 +219,7 @@ deploy:dockerhub-devel: &deploy
- $DOCKER_LOGIN - $DOCKER_LOGIN
script: script:
- docker build -f docker/dorie.dockerfile - docker build -f docker/dorie.dockerfile
--build-arg DUNE_ENV_IMAGE=$DUNE_ENV_IMAGE --build-arg PROCNUM=$CPUS_DIND --build-arg BASE_IMG_VERSION=$IMAGE_VERSION --build-arg PROCNUM=$CPUS_DIND
-t dorie/dorie:devel . -t dorie/dorie:devel .
- docker push dorie/dorie:devel - docker push dorie/dorie:devel
...@@ -227,7 +229,7 @@ deploy:dockerhub-stable: ...@@ -227,7 +229,7 @@ deploy:dockerhub-stable:
- tags@dorie/dorie - tags@dorie/dorie
script: script:
- docker build -f docker/dorie.dockerfile - docker build -f docker/dorie.dockerfile
--build-arg DUNE_ENV_IMAGE=$DUNE_ENV_IMAGE --build-arg PROCNUM=$CPUS_DIND --build-arg BASE_IMG_VERSION=$IMAGE_VERSION --build-arg PROCNUM=$CPUS_DIND
-t dorie/dorie:$CI_COMMIT_TAG . -t dorie/dorie:$CI_COMMIT_TAG .
- docker push dorie/dorie:$CI_COMMIT_TAG - docker push dorie/dorie:$CI_COMMIT_TAG
......
[submodule "plugins/vendor/spdlog"] [submodule "plugins/vendor/spdlog"]
path = plugins/vendor/spdlog path = plugins/vendor/spdlog
url = https://github.com/gabime/spdlog.git url = https://github.com/gabime/spdlog.git
[submodule "plugins/vendor/googletest"]
path = plugins/vendor/googletest
url = https://github.com/google/googletest.git
...@@ -43,6 +43,10 @@ ...@@ -43,6 +43,10 @@
* Linear interpolator for initial conditions and scaling fields !145, !156 * Linear interpolator for initial conditions and scaling fields !145, !156
* Parameterizations for hydrodynamic dispersion in solute transport !141 * Parameterizations for hydrodynamic dispersion in solute transport !141
* Generic Python VTK file reader !143, !150 * Generic Python VTK file reader !143, !150
* Define compile-time settings via CPP macros !144
* [Google Test](https://github.com/google/googletest) unit test framework
as Git Submodule !159
* Upwinding options for Richards finite volume local operator !161
### Changed ### Changed
* `Simulation` is renamed `RichardsSimulation` and moved to * `Simulation` is renamed `RichardsSimulation` and moved to
...@@ -149,6 +153,8 @@ ...@@ -149,6 +153,8 @@
* Switch to stable `dune-randomfield` release branch !151, !153 * Switch to stable `dune-randomfield` release branch !151, !153
* System tests for executing `dorie pfg` module !153 * System tests for executing `dorie pfg` module !153
* Finite volume solver for the Richards equation !132 * Finite volume solver for the Richards equation !132
* Build independent library and executable for each compile-time setting !144
* `SimulationBase` unit test now uses Google Test !159
### Fixed ### Fixed
* Solver in `RichardsSimulation` was using the wrong time variable. * Solver in `RichardsSimulation` was using the wrong time variable.
......
...@@ -14,12 +14,6 @@ endif() ...@@ -14,12 +14,6 @@ endif()
# add extra flags to debug compiler flags # add extra flags to debug compiler flags
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
# option to change DG scheme via config file
option(EXPERIMENTAL_DG_FEATURES
"Enable experimental DG settings through the config file"
OFF
)
# #
if(NOT (dune-common_DIR OR dune-common_ROOT OR if(NOT (dune-common_DIR OR dune-common_ROOT OR
"${CMAKE_PREFIX_PATH}" MATCHES ".*dune-common.*")) "${CMAKE_PREFIX_PATH}" MATCHES ".*dune-common.*"))
...@@ -40,6 +34,10 @@ dune_project() ...@@ -40,6 +34,10 @@ dune_project()
dune_enable_all_packages() dune_enable_all_packages()
dune_require_cxx_standard(MODULE "dorie" VERSION 14) dune_require_cxx_standard(MODULE "dorie" VERSION 14)
# Cache the executable path
set(DORIE_EXE_PATH ${PROJECT_BINARY_DIR}/dune/dorie/
CACHE STRING "Path to the directory containing the executables")
# add subdirectories # add subdirectories
add_subdirectory("plugins/vendor") add_subdirectory("plugins/vendor")
add_subdirectory("m4") add_subdirectory("m4")
...@@ -48,7 +46,7 @@ add_subdirectory("python") ...@@ -48,7 +46,7 @@ add_subdirectory("python")
add_subdirectory("doc") add_subdirectory("doc")
add_subdirectory("dune") add_subdirectory("dune")
add_subdirectory("lib") add_subdirectory("lib")
if(dune-testtools_FOUND) if(DORIE_TESTING)
add_subdirectory("test") add_subdirectory("test")
endif() endif()
......
...@@ -77,6 +77,7 @@ by CI tests. ...@@ -77,6 +77,7 @@ by CI tests.
| SuperLU | 5.2 | | SuperLU | 5.2 |
| [yaml-cpp](https://github.com/jbeder/yaml-cpp) | >= 5.2.0 | | [yaml-cpp](https://github.com/jbeder/yaml-cpp) | >= 5.2.0 |
| [spdlog](https://github.com/gabime/spdlog) | 1.1.0 | Included as Git Submodule | [spdlog](https://github.com/gabime/spdlog) | 1.1.0 | Included as Git Submodule
| [Google Test](https://github.com/google/googletest) | `HEAD` | Included as Git Submodule
| [muparser](http://beltoforion.de/article.php?a=muparser) | master | | [muparser](http://beltoforion.de/article.php?a=muparser) | master |
| [VTK](https://vtk.org/) | >= 7.1.1 | For the Python module only | [VTK](https://vtk.org/) | >= 7.1.1 | For the Python module only
| [dune-common](https://gitlab.dune-project.org/core/dune-common) | releases/2.6 | [dune-common](https://gitlab.dune-project.org/core/dune-common) | releases/2.6
...@@ -198,16 +199,6 @@ If you installed [Anaconda](https://conda.io/docs/user-guide/install/download.ht ...@@ -198,16 +199,6 @@ If you installed [Anaconda](https://conda.io/docs/user-guide/install/download.ht
path chosen as installation prefix when configuring HDF5. path chosen as installation prefix when configuring HDF5.
### Experimental Features
The local operator implementing Richards equation's discretization supports
multiple scheme settings. Setting these via the config file is disabled by
default. You can enable this feature by reconfiguring DORiE with the CMake flag
`-DEXPERIMENTAL_DG_FEATURES=On`, and rebuilding it.
The configuration settings in the section `[dg.experimental]` will then override
the default settings.
### Recommended Third-Party Software ### Recommended Third-Party Software
The following software packages are cross-platform, so you should be able to find a release that fits your operating system: The following software packages are cross-platform, so you should be able to find a release that fits your operating system:
......
# Default Dorie model targets
add_custom_target("richards")
add_custom_target("transport")
# Maximum polynomial orders of Richards model for available targets
set(DORIE_MAX_RORDER_2 6)
set(DORIE_MAX_RORDER_3 6)
# Maximum polynomial orders of transport model for available targets
set(DORIE_MAX_TORDER_2 0)
set(DORIE_MAX_TORDER_3 0)
# Maximum polynomial orders of Richards model for default targets
set(DORIE_MAX_DEFAULT_RORDER_2 3)
set(DORIE_MAX_DEFAULT_RORDER_3 1)
# Maximum polynomial orders of transport model for default targets
set(DORIE_MAX_DEFAULT_TORDER_2 0)
set(DORIE_MAX_DEFAULT_TORDER_3 0)
#
# .. cmake_function:: dorie_compile_instance
#
# Adds an executable and library for the specified model.
#
# The parameters specify static settings for the model instance. If these
# settings comply to the limits of the default variables, the instance is
# added to the global "richards" or "transport" targets, depending on which
# MODEL type is built.
#
# In case of "transport", the appropriate "richards" library must be available.
# Otherwise, it is also defined by this function.
#
# A sanity check for the input variables is not performed by CMake, but by
# the C++ code during compile-time.
#
# This function takes the following arguments:
#
# - MODEL: Name of the model. Accepts "richards" or "transport".
# - DIMENSION: Spatial dimension.
# - RORDER: Finite element polynomial order of the Richards module.
# - TORDER: Finite element polynomial order of the Transport module.
# - CREATED_LIB: Variable to store the created library target name in.
#
function(dorie_compile_instance)
# parse the function arguments
set(SINGLE_ARGS MODEL DIMENSION RORDER TORDER CREATED_LIB)
cmake_parse_arguments(ARGS "" "${SINGLE_ARGS}" "" ${ARGN})
if (ARGS_UNPARSED_ARGUMENTS)
message(WARNING "Unparsed arguments when calling "
"'dorie_create_executable: "
"${ARGS_UNPARSED_ARGUMENTS}")
endif ()
# set dimension string
set(DIM_STR "d${ARGS_DIMENSION}")
# set option string
set(OPTION_STR "r${ARGS_RORDER}")
# issue warning if transport order is given for 'richards'
if (ARGS_MODEL STREQUAL "richards")
set (lib_src ${PROJECT_SOURCE_DIR}/dune/dorie/model/richards/impl/impl.cc)
if (ARGS_TORDER)
message(WARNING "Ignoring argument TORDER for MODEL "
"'richards'")
endif ()
# append transport order to option string
elseif (ARGS_MODEL STREQUAL "transport")
set (lib_src ${PROJECT_SOURCE_DIR}/dune/dorie/model/coupling/impl/impl.cc)
string(APPEND OPTION_STR "_t${ARGS_TORDER}")
# unknown model
else ()
message(SEND_ERROR "Unsupported model: ${ARGS_MODEL}. "
"Must be either 'richards' or 'transport'")
endif ()
# register the library
set(lib_name "dorie_${ARGS_MODEL}_${DIM_STR}_${OPTION_STR}")
if (NOT TARGET ${lib_name})
add_library(${lib_name} EXCLUDE_FROM_ALL STATIC ${lib_src})
# link to dependencies
target_link_libraries(${lib_name}
PUBLIC
spdlog
muparser::muparser
hdf5
yaml-cpp
${DUNE_LIBS}
)
# register the executable
set(exe_name "${ARGS_MODEL}_${DIM_STR}_${OPTION_STR}")
set(src_file ${CMAKE_SOURCE_DIR}/dune/dorie/${ARGS_MODEL}.cc)
add_executable(${exe_name} EXCLUDE_FROM_ALL ${src_file})
target_link_libraries(${exe_name} PUBLIC ${lib_name})
# Add the executable to the default targets
if ((ARGS_RORDER LESS_EQUAL DORIE_MAX_DEFAULT_RORDER_${ARGS_DIMENSION})
AND ((NOT ARGS_TORDER)
OR ARGS_TORDER LESS_EQUAL DORIE_MAX_DEFAULT_TORDER_${ARGS_DIMENSION})
)
add_dependencies(${ARGS_MODEL} ${exe_name})
endif()
# set compile definitions
target_compile_definitions(${lib_name}
PUBLIC
DORIE_DIM=${ARGS_DIMENSION}
DORIE_RORDER=${ARGS_RORDER})
if (ARGS_MODEL STREQUAL "transport")
target_compile_definitions(${lib_name}
PUBLIC DORIE_TORDER=${ARGS_TORDER})
endif ()
endif()
# If we build a transport model, build the Richards library as well
if (ARGS_MODEL STREQUAL "transport")
dorie_compile_instance(MODEL "richards"
DIMENSION ${ARGS_DIMENSION}
RORDER ${ARGS_RORDER}
CREATED_LIB richards_lib
)
# ... and link to it!
target_link_libraries(${exe_name} PUBLIC ${richards_lib})
endif()
# Report the library target name
if (ARGS_CREATED_LIB)
set(${ARGS_CREATED_LIB} ${lib_name} PARENT_SCOPE)
endif ()
endfunction()
# --- DEPENDENCIES --- #
# These macros check for the following packages, yielding the respective # These macros check for the following packages, yielding the respective
# targets # targets
# #
...@@ -56,5 +57,17 @@ message (STATUS "DUNE Libraries: ${DUNE_LIBS}") ...@@ -56,5 +57,17 @@ message (STATUS "DUNE Libraries: ${DUNE_LIBS}")
# Remove CMake policy stack # Remove CMake policy stack
cmake_policy(POP) cmake_policy(POP)
# Add DORiE testing functions # --- CMAKE MODULES --- #
include(DorieTesting) # Include the CMake modules used in the project
include(DorieCompileInstance)
# Check if testing is enabled
if (dune-testtools_FOUND)
message(STATUS "Testing enabled: dune-testtools found.")
set(DORIE_TESTING TRUE)
# include the DORiE testing macros
include(DorieTesting)
else()
message(STATUS "Testing disabled: dune-testtools not found.")
endif()
...@@ -48,6 +48,12 @@ endfunction() ...@@ -48,6 +48,12 @@ endfunction()
# The target this test applies to. This is only required if no SOURCES # The target this test applies to. This is only required if no SOURCES
# are specified. # are specified.
# #
# .. cmake_param:: CUSTOM_MAIN
# :option:
#
# Write a custom `main()` function for the unit test executables instead
# of generating a default one automatically.
#
# This function serves as wrapper around the function `dune_add_test` which # This function serves as wrapper around the function `dune_add_test` which
# registers test for existing targets or adds new test executables from the # registers test for existing targets or adds new test executables from the
# given source files. This function additionally registers the tests as unit # given source files. This function additionally registers the tests as unit
...@@ -61,7 +67,8 @@ endfunction() ...@@ -61,7 +67,8 @@ endfunction()
# #
function(dorie_add_unit_test) function(dorie_add_unit_test)
set(SINGLE NAME TARGET) set(SINGLE NAME TARGET)
cmake_parse_arguments(UNIT_TEST "" "${SINGLE}" "" ${ARGN}) set(OPTION CUSTOM_MAIN)
cmake_parse_arguments(UNIT_TEST "${OPTION}" "${SINGLE}" "" ${ARGN})
# use name prefix for test # use name prefix for test
if(NOT UNIT_TEST_NAME) if(NOT UNIT_TEST_NAME)
...@@ -81,7 +88,14 @@ function(dorie_add_unit_test) ...@@ -81,7 +88,14 @@ function(dorie_add_unit_test)
# add to build target and employ compile options # add to build target and employ compile options
target_link_libraries(${UNIT_TEST_TARGET} target_link_libraries(${UNIT_TEST_TARGET}
muparser::muparser hdf5 yaml-cpp spdlog) muparser::muparser hdf5 yaml-cpp spdlog)
add_coverage_links(${UNIT_TEST_TARGET}) # add_coverage_links(${UNIT_TEST_TARGET})
if (UNIT_TEST_CUSTOM_MAIN)
target_link_libraries(${UNIT_TEST_TARGET} gtest)
else ()
target_link_libraries(${UNIT_TEST_TARGET} gtest_main)
endif()
add_dependencies(build_unit_tests ${UNIT_TEST_TARGET}) add_dependencies(build_unit_tests ${UNIT_TEST_TARGET})
endfunction() endfunction()
......
...@@ -231,13 +231,6 @@ adding an empty line, make text **bold** or ``monospaced``. ...@@ -231,13 +231,6 @@ adding an empty line, make text **bold** or ``monospaced``.
</category> </category>
<category name="numerics"> <category name="numerics">
<parameter name="penaltyFactor">
<definition> Penalty factor to be used in the Discontinuous Galerkin scheme
</definition>
<values> float </values>
<suggestion> 10 </suggestion>
</parameter>
<parameter name="FEorder"> <parameter name="FEorder">
<definition> Polynomial order of the DG method used. Setting this value <definition> Polynomial order of the DG method used. Setting this value
to 0 (zero) selects the finite volume (FV) solver (only compatible to to 0 (zero) selects the finite volume (FV) solver (only compatible to
...@@ -245,6 +238,52 @@ adding an empty line, make text **bold** or ``monospaced``. ...@@ -245,6 +238,52 @@ adding an empty line, make text **bold** or ``monospaced``.
</definition> </definition>
<suggestion> 1 </suggestion> <suggestion> 1 </suggestion>
<values> 0, 1, 2, 3 </values> <values> 0, 1, 2, 3 </values>
<comment> Select '0' for the finite volume (FV) solver </comment>
</parameter>
<parameter name="upwinding">
<definition> Upwinding method for skeleton terms. Upwinding typically
increases numeric stability while reducing accuracy.
**semiUpwind:** Apply upwinding to conductivity factor (only).
**fullUpwind:** Apply upwinding to conductivity.
**Not recommended for DG**.
</definition>
<values> none, semiUpwind, fullUpwind </values>
<suggestion> none </suggestion>
<comment> Choose upwinding type: 'none', 'semiUpwind', 'fullUpwind'
</comment>
</parameter>
<parameter name="DGMethod">
<definition> DG discretization method for skeleton terms.
**SIPG:** Symmetric Interior Penalty
**NIPG:** Non-Symmetric Interior Penalty
**OBB:** Oden, Babuska, Baumann: no penalty term
**IIP:** Incomplete Interior Penalty: no symmetry term
</definition>
<values> SIPG, NIPG, OBB, IIP </values>
<suggestion> SIPG </suggestion>
</parameter>
<parameter name="DGWeights">
<definition> Apply harmonic weighting to skeleton term contributions
in DG.
</definition>
<values> true, false </values>
<suggestion> true </suggestion>
</parameter>
<parameter name="penaltyFactor">
<definition> Penalty factor to be used in the Discontinuous Galerkin scheme
</definition>
<values> float </values>
<suggestion> 10 </suggestion>
</parameter> </parameter>
</category> </category>
...@@ -328,61 +367,4 @@ adding an empty line, make text **bold** or ``monospaced``. ...@@ -328,61 +367,4 @@ adding an empty line, make text **bold** or ``monospaced``.
</parameter> </parameter>
</category> </category>
<category name="numerics.experimental">
<parameter name="method">
<definition> DG discretization method for skeleton terms.
**SIPG:** Symmetric Interior Penalty
**NIPG:** Non-Symmetric Interior Penalty
**OOB:** Oden, Babuska, Baumann: no penalty term
**IIP:** Incomplete Interior Penalty: no symmetry term
</definition>
<values> SIPG, NIPG, OOB, IIP </values>
<suggestion> SIPG </suggestion>
<comment> Experimental settings are enabled by the appropriate CMake flag.
</comment>
</parameter>
<parameter name="upwinding">
<definition> Upwinding method for skeleton terms.
**semiUpwind:** Apply upwinding to conductivity factor (only).
**fullUpwind:** Apply upwinding on numeric flux and conductivity.
</definition>
<values> none, semiUpwind, fullUpwind </values>
<suggestion> none </suggestion>
</parameter>
<parameter name="weights">
<definition> Apply harmonic weighting to skeleton term contributions.
</definition>
<values> true, false </values>
<suggestion> true </suggestion>
</parameter>
</category>
<category name="KnoFu" hidden="true">
<parameter name="saturationMin">
<definition> Minimum saturation when transforming water content to
matric head.
</definition>
<values> float </values>
<suggestion> 1E-4 </suggestion>
<comment> Settings for the KnoFu data assimilation interface
</comment>
</parameter>
<parameter name="saturationMax">
<definition> Maximum saturation when transforming water content to
matric head.
</definition>
<values> float </values>
<suggestion> 1.0 </suggestion>
</parameter>
</category>
</dorie> </dorie>
...@@ -82,5 +82,31 @@ the Richards solver must be utilized to solve them. Use the value ...@@ -82,5 +82,31 @@ the Richards solver must be utilized to solve them. Use the value
``richards+transport`` in the ``simulation.mode`` keyword to run the solute ``richards+transport`` in the ``simulation.mode`` keyword to run the solute
transport solver. transport solver.
Available Models
================
Several settings like solver coupling, spatial dimension, or polynomial order
must be given at compile time. DORiE includes a discrete set of setting
combinations users may choose from via the
:doc:`configuration file </manual/config-file>`. If DORiE is run from its public
Docker image or with the default targets built locally on your machine, these
are the available combinations of options:
+----------------------+-------------------+-----------------------------+------------------------------+----------------+
|``simulation.mode`` |``grid.dimensions``|``richards.numerics.FEorder``|``transport.numerics.FEorder``| GMSH Grid and |
| | | | | grid refinement|
+======================+===================+=============================+==============================+================+
|``richards`` | 2 | <= 3 | ✗ | ✓* |
| +-------------------+-----------------------------+------------------------------+----------------+
| | 3 | <= 1 | ✗ | ✓* |
+----------------------+-------------------+-----------------------------+------------------------------+----------------+
|``richards+transport``| 2 | <= 3 | 0 | ✗ |
| +-------------------+-----------------------------+------------------------------+----------------+
| | 3 | <= 1 | 0 | ✗ |
+----------------------+-------------------+-----------------------------+------------------------------+----------------+
* *: Only for ``richards.numerics.FEorder`` > 0. Finite volume solvers do not
support unstructured grids.
.. _DUNE: https://www.dune-project.org/ .. _DUNE: https://www.dune-project.org/
.. _DUNE-PDELab: https://www.dune-project.org/modules/dune-pdelab/ .. _DUNE-PDELab: https://www.dune-project.org/modules/dune-pdelab/
...@@ -48,7 +48,7 @@ They are controlled by the ``initial.type`` key and available for every model. ...@@ -48,7 +48,7 @@ They are controlled by the ``initial.type`` key and available for every model.
.. tip:: .. tip::
Assuming the target quantity is the matric head (see Assuming the target quantity is the matric head (see
:ref:`initial-transformation`), typical initial conditions for a :ref:`initial-transformation`), typical initial conditions for a
Richards simulation are Richards model are
* Hydrostatic equilibrium: A vertical gradient of * Hydrostatic equilibrium: A vertical gradient of
:math:`\partial_h h_m = -1` and a fixed value ``<v>`` at height :math:`\partial_h h_m = -1` and a fixed value ``<v>`` at height
......
...@@ -181,10 +181,10 @@ Mualem–van Genuchten ...@@ -181,10 +181,10 @@ Mualem–van Genuchten
Transport Parameterizations Transport Parameterizations
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Regardless of the parameterization, the transport simulation always computes Regardless of the parameterization, the transport model always computes
the microscopic péclet number, for which it requires the characteristic pore the microscopic péclet number, for which it requires the characteristic pore
length, the molecular diffusion, and the fluid velocity. The latter is directly length, the molecular diffusion, and the fluid velocity. The latter is directly
provided by the richards simulation while the other two have to be specified provided by the richards model while the other two have to be specified
for each volume: for each volume:
Permanent parameters: Permanent parameters:
...@@ -217,7 +217,7 @@ Permanent parameters: ...@@ -217,7 +217,7 @@ Permanent parameters:
The hydrodynamic dispersion tensor :math:`\mathsf{D}_\text{hd} \, The hydrodynamic dispersion tensor :math:`\mathsf{D}_\text{hd} \,
[\text{m}^2\text{s}^{-1}]` is the main parameter to provide in the [\text{m}^2\text{s}^{-1}]` is the main parameter to provide in the
transport simulation. Below you will find several parameterization for this. transport model. Below you will find several parameterization for this.
Constant Constant
"""""""" """"""""
...@@ -358,7 +358,7 @@ Milligton-Quirk I Effective Diffusion ...@@ -358,7 +358,7 @@ Milligton-Quirk I Effective Diffusion
D_\text{eff} = D_m \frac{\theta_w^{7/3}}{\phi^{2/3}}. D_\text{eff} = D_m \frac{\theta_w^{7/3}}{\phi^{2/3}}.
where the volumetric water content :math:`\theta_w \, [-]` where the volumetric water content :math:`\theta_w \, [-]`
is automatically obtained from the Richards simulation. is automatically obtained from the Richards model.
* ``Deff_type: Deff_MQ1`` * ``Deff_type: Deff_MQ1``
...@@ -389,7 +389,7 @@ Milligton-Quirk II Effective Diffusion ...@@ -389,7 +389,7 @@ Milligton-Quirk II Effective Diffusion
D_\text{eff} = D_m \frac{\theta_w}{\phi^{2/3}}. D_\text{eff} = D_m \frac{\theta_w}{\phi^{2/3}}.
where the volumetric water content :math:`\theta_w \, [-]` where the volumetric water content :math:`\theta_w \, [-]`
is automatically obtained from the Richards simulation. is automatically obtained from the Richards model.
* ``Deff_type: Deff_MQ2`` * ``Deff_type: Deff_MQ2``
......
...@@ -21,15 +21,43 @@ The main routine (`dorie run <config>`) also requires input files for ...@@ -21,15 +21,43 @@ The main routine (`dorie run <config>`) also requires input files for
Code API Code API
======== ========
DORiE supplies the `Simulation` template. This is the main class for assembling DORiE supplies the `Model` abstract base class. All other models follow this
and running the solver. structure.
.. doxygenclass:: Dune::Dorie::RichardsSimulation ABC Model
---------
.. doxygenclass:: Dune::Dorie::ModelBase
:members: :members:
The simulation template requires compile-time type specifications wrapped in a
Model Traits
------------
The model template requires compile-time type specifications wrapped in a
suitable `Traits` structure. suitable `Traits` structure.
.. doxygenstruct:: Dune::Dorie::BaseTraits .. doxygenstruct:: Dune::Dorie::BaseTraits
:members: :members:
:undoc-members: :undoc-members:
Richards Model
--------------
.. doxygenclass:: Dune::Dorie::ModelRichards
:members:
Transport Model
---------------
.. doxygenclass:: Dune::Dorie::ModelTransport
:members:
Coupling Model
--------------
The coupling between Richards and Transport models is done by yet another
model which is in charge of managing the steps of the two sub-models.
.. doxygenclass:: Dune::Dorie::ModelTransport
:members:
\ No newline at end of file
ARG DUNE_ENV_IMAGE=dorie/dune-env:2.6 ARG BASE_IMG_VERSION=1.2
FROM $DUNE_ENV_IMAGE ARG DUNE_ENV_IMAGE=dorie/dune-env:img-v${BASE_IMG_VERSION}
# start build image
FROM ${DUNE_ENV_IMAGE} as build-env
# maintainer info
LABEL maintainer="lriedel@iup.uni-heidelberg.de" LABEL maintainer="lriedel@iup.uni-heidelberg.de"
# number of cores for parallel builds # number of cores for parallel builds
ARG PROCNUM=1 ARG PROCNUM=1
# Compilers to be used # Compilers to be used
ARG CC=gcc ARG CC=gcc
ARG CXX=g++ ARG CXX=g++
# build DORiE # copy the build context to this image
WORKDIR /opt/dune/dorie
COPY ./ ./
# build the executable
WORKDIR /opt/dune/
RUN MAKE_FLAGS="-j${PROCNUM}" \
CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} -DDUNE_PYTHON_VIRTUALENV_SETUP=True -DDUNE_PYTHON_ALLOW_GET_PIP=True" \
./dune-common/bin/dunecontrol --only=dorie all
# Start a fresh image as production environment
FROM $DUNE_ENV_IMAGE as prod-env
# Copy binaries, Python venv, and Python scripts (editable install)
WORKDIR /opt/dune WORKDIR /opt/dune
ADD . /opt/dune/dorie/ COPY --from=build-env /opt/dune/dune-common/build-cmake/dune-env ./dune-common/build-cmake/dune-env
RUN CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} -DDUNE_PYTHON_VIRTUALENV_SETUP=True -DDUNE_PYTHON_ALLOW_GET_PIP=True" \ WORKDIR /opt/dune/dorie
./dune-common/bin/dunecontrol --only=dorie configure \ COPY --from=build-env /opt/dune/dorie/build-cmake ./build-cmake/
&& ./dune-common/bin/dunecontrol --only=dorie make -j ${PROCNUM} dorie-rfg dorie \ COPY --from=build-env /opt/dune/dorie/python ./python/
&& ./dune-common/bin/dunecontrol --only=dorie exec \
"rm build-cmake/dune/dorie/model/richards/impl/libdorie-richards.a build-cmake/dune/dorie/model/transport/impl/libdorie-transport.a build-cmake/dune/dorie/model/richards/impl/CMakeFiles/dorie-richards.dir/*.cc.o build-cmake/dune/dorie/model/transport/impl/CMakeFiles/dorie-transport.dir/*.cc.o"
# move to working directory # move to working directory
WORKDIR /mnt WORKDIR /mnt
# run bash in the virtualenv (this actually creates two bash instances...) # run bash in the virtualenv (this actually creates two bash instances...)
# TODO: create new user with restricted privileges
ENTRYPOINT ["/opt/dune/dune-common/build-cmake/run-in-dune-env", "/bin/bash"] ENTRYPOINT ["/opt/dune/dune-common/build-cmake/run-in-dune-env", "/bin/bash"]
add_subdirectory("common") add_subdirectory("common")
add_subdirectory("model") add_subdirectory("model")
if(dune-testtools_FOUND) if(DORIE_TESTING)
add_subdirectory("test") add_subdirectory("test")
endif() endif()
# enable setting operator scheme from config file
if(EXPERIMENTAL_DG_FEATURES)
target_compile_definitions(dorie-richards PUBLIC -DEXPERIMENTAL_DG_FEATURES)
endif()
add_executable(richards richards.cc)
dune_target_link_libraries(richards ${DUNE_LIBS})
target_link_libraries(richards
dorie-richards spdlog muparser::muparser hdf5 yaml-cpp)
add_executable(transport transport.cc) # create targets for many possible combinations
dune_target_link_libraries(transport ${DUNE_LIBS}) foreach(dim 2 3)
target_link_libraries(transport foreach(rorder RANGE ${DORIE_MAX_RORDER_${dim}})
dorie-richards dorie-transport spdlog muparser::muparser hdf5 yaml-cpp) dorie_compile_instance(MODEL "richards"
DIMENSION ${dim}
RORDER ${rorder})
foreach(torder RANGE ${DORIE_MAX_TORDER_${dim}})
dorie_compile_instance(MODEL "transport"
DIMENSION ${dim}
RORDER ${rorder}
TORDER ${torder})
endforeach()
endforeach()
endforeach()
# Global target
add_custom_target("dorie" DEPENDS richards transport) add_custom_target("dorie" DEPENDS richards transport)
...@@ -11,7 +11,6 @@ install(FILES ...@@ -11,7 +11,6 @@ install(FILES
h5tools.hh h5tools.hh
interpolator.hh interpolator.hh
setup_inifile.hh setup_inifile.hh
simulation_base.hh
time_controller.hh time_controller.hh
typedefs.hh typedefs.hh
util.hh util.hh
......
...@@ -95,8 +95,8 @@ namespace Dorie{ ...@@ -95,8 +95,8 @@ namespace Dorie{
const DF height = extensions[dim-1]; //!< Domain height. This must be set to the maximum height of the domain! const DF height = extensions[dim-1]; //!< Domain height. This must be set to the maximum height of the domain!
const DF depth = extensions[1]; //!< Domain depth. depth=height for dim=2 const DF depth = extensions[1]; //!< Domain depth. depth=height for dim=2
const std::string bcFilePath; //!< Path to file containing BC data const std::string bcFilePath; //!< Path to file containing BC data
const RF tStart; //!< Starting time of simulation const RF tStart; //!< Starting time of model
const RF tEnd; //!< Finish time of simulation const RF tEnd; //!< Finish time of model
//! Boolean whether consecutive BC values of the same type will be interpolated. //! Boolean whether consecutive BC values of the same type will be interpolated.
const bool interpolate; const bool interpolate;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <dune/common/power.hh> #include <dune/common/power.hh>
#include <dune/common/typetraits.hh> #include <dune/common/typetraits.hh>
#include <dune/pdelab/finiteelementmap/qkdg.hh>
#include <vector> #include <vector>
namespace Dune{ namespace Dune{
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include <dune/common/power.hh> #include <dune/common/power.hh>
#include <dune/pdelab/finiteelement/l2orthonormal.hh>
#include <dune/pdelab/finiteelementmap/finiteelementmap.hh>
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
......
#ifndef DUNE_DORIE_RAVIART_THOMAS_PROJECTION_HH #ifndef DUNE_DORIE_RAVIART_THOMAS_PROJECTION_HH
#define DUNE_DORIE_RAVIART_THOMAS_PROJECTION_HH #define DUNE_DORIE_RAVIART_THOMAS_PROJECTION_HH
// hard-coded bool helpers
#define DORIE_SUPPORT_RT_SIMPLEX(dim, order) (order <= 2)
#define DORIE_SUPPORT_RT_CUBE(dim, order) (dim==2) ? (order <= 2) : (order <= 1)
#include <vector> #include <vector>
#include <string> #include <string>
#include <dune/common/exceptions.hh> #include <dune/common/exceptions.hh>
#include <dune/common/parametertree.hh>
#include <dune/pdelab/backend/istl.hh>
#include <dune/pdelab/gridoperator/gridoperator.hh>
#include <dune/dorie/common/logging.hh> #include <dune/dorie/common/logging.hh>
#include <dune/dorie/common/utility.hh>
#include <dune/dorie/common/flux_reconstruction/raviart_thomas/assembler.hh> #include <dune/dorie/common/flux_reconstruction/raviart_thomas/assembler.hh>
#include <dune/dorie/common/flux_reconstruction/raviart_thomas/local_engine.hh> #include <dune/dorie/common/flux_reconstruction/raviart_thomas/local_engine.hh>
...@@ -26,28 +35,30 @@ namespace Dorie{ ...@@ -26,28 +35,30 @@ namespace Dorie{
* reconstruction method is available for the combination of the * reconstruction method is available for the combination of the
* used template parameters. * used template parameters.
* *
* @tparam GV Grid view * @tparam dim Grid dimension
* @tparam order Order of the flux reconstruction. * @tparam order Order of the flux reconstruction.
* @tparam gt Geometry type. * @tparam gt Geometry type.
*/ */
template<class GV, unsigned int order, Dune::GeometryType::BasicType gt> template<int dim, unsigned int order, Dune::GeometryType::BasicType gt>
struct RaviartThomasFluxReconstructionHelper struct RaviartThomasFluxReconstructionHelper
{ {
private: private:
static constexpr int dim = GV::dimension;
static_assert(dim==2||dim==3); static_assert(dim==2||dim==3);
static_assert(gt==GeometryType::simplex||gt==GeometryType::cube); static_assert(gt==GeometryType::simplex||gt==GeometryType::cube);
// hard-coded bool helpers // hard-coded bool helpers
static constexpr bool val_2d_simplex = true; static constexpr bool val_simplex = DORIE_SUPPORT_RT_SIMPLEX(dim, order);
static constexpr bool val_3d_simplex = true; static constexpr bool val_cube = DORIE_SUPPORT_RT_CUBE(dim, order);
static constexpr bool val_2d_cube = (order <= 2);
static constexpr bool val_3d_cube = (order <= 1);
static constexpr bool val_simplex = (dim==2) ? val_2d_simplex : val_3d_simplex;
static constexpr bool val_cube = (dim==2) ? val_2d_cube : val_3d_cube;
public: public:
static constexpr bool enable = (gt==GeometryType::simplex) ? val_simplex : val_cube; static constexpr bool enable = (gt==GeometryType::simplex) ? val_simplex : val_cube;
}; };
/// Shortcut helper for querying if flux reconstruction is available
/** \see RaviartThomasFluxReconstructionHelper
*/
template<int dim, unsigned int rt_order, Dune::GeometryType::BasicType gt>
constexpr bool supports_flux_reconstr_v
= RaviartThomasFluxReconstructionHelper<dim, rt_order, gt>::enable;
/*-------------------------------------------------------------------------*//** /*-------------------------------------------------------------------------*//**
* @brief Raviart Thomas flux reconstruction for discontinuous Galerkin * @brief Raviart Thomas flux reconstruction for discontinuous Galerkin
* grid operators. * grid operators.
......
...@@ -77,8 +77,8 @@ public: ...@@ -77,8 +77,8 @@ public:
} }
private: private:
const Entity* _entity;
std::shared_ptr<const GF> _gf; std::shared_ptr<const GF> _gf;
const Entity* _entity;
}; };
......
...@@ -238,8 +238,6 @@ ...@@ -238,8 +238,6 @@
@} @}
@defgroup Models Models
@defgroup LocalOperators Local Operators @defgroup LocalOperators Local Operators
@{ @{
Local operators are in many senses the heart of dorie; in them, we transform Local operators are in many senses the heart of dorie; in them, we transform
...@@ -270,4 +268,109 @@ ...@@ -270,4 +268,109 @@
local operator convention. local operator convention.
@} @}
@defgroup UnitTests Unit Tests
@{
@ingroup Common
@brief Information on the unit testing framework used in DORiE
## Overview
DORiE uses and vendors [Google Test](https://github.com/google/googletest)
for managing unit tests. Not all unit tests are currently using it, but all
unit tests to be created in the future will have to.
Unit tests are an essential part of programming for ensuring the software
works as intended on the microscopic level. They help with verifying the
initial implementation, facilitate understanding of the code they test, and
simplify bug fixing. The programming technique of Test-Driven Development
(TDD) even _begins_ with writing a test for the desired functionality before
the actual implementation. This is not required for DORiE, but testing should
always be kept in mind when writing code.
## Build System
Google Test is included into the build system and automatically linked to
executables when using the `dorie_add_unit_test()` CMake function. For most
use cases, it suffices to only write the test functions into the unit test
source file. Google Test then assembles the `main` function of the final
program itself. If a custom `main` is required, pass the `CUSTOM_MAIN` option
to the aforementioned CMake function (this will link to `gtest` instead of
`gtest_main`). Finally, you need to include the Google Test header into your
source file and you're good to go!
## Writing Unit Tests
Google Test offers several macros for writing unit tests.
[_Test cases_](https://github.com/google/googletest/blob/master/googletest/docs/primer.md#simple-tests)
look like regular C++ functions. They are grouped into _test suites_. One
test typically consists of several
[_assertions_](https://github.com/google/googletest/blob/master/googletest/docs/primer.md#assertions)
which can each result in a _success_, a _non-fatal failure_, or a _failure_.
Refer to the Google Test
[nomenclature and basic concepts](https://github.com/google/googletest/blob/master/googletest/docs/primer.md#beware-of-the-nomenclature)
for more information. Source files are structured like this:
@code{.cc}
#include <gtest/gtest.h>
TEST(TestSuite, FirstTestCase)
{
EXPECT_EQ(1, 1); // Success
} // Success!
TEST(TestSuite, SecondTestCase)
{
EXPECT_EQ(1, 2); // Non-fatal failure
ASSERT_TRUE(False); // Fatal failure
EXPECT_TRUE(False); // (never executed)
} // Failure
@endcode
Contrary to a regular program, we want any test case to continue executing as
long as possible after it encountered an error. Doing so it can report any,
not just a single, failing assertion. Any test case in Google Test either has
the form `EXPECT_XXX` or `ASSERT_XXX`. Only the latter aborts the execution
of the current test. It should only be used when further execution does not
make sense, e.g., because it would lead to a severe error.
@code{.cc}
TEST(TestSuite, ThirdTestCase)
{
std::vector vec(10);
std::iota(begin(vec), end(vec), 0);
const auto idx = get_random_index();
ASSERT_LT(idx, vec.size()); // stop here if check fails
EXPECT_EQ(vec[idx], idx); // danger of segfault!
}
@endcode
### Resources
The entire documentation of the Google Test suite is condensed into three
documents:
- <a href="https://github.com/google/googletest/blob/master/googletest/docs/primer.md">Primer</a>
- <a href="https://github.com/google/googletest/blob/master/googletest/docs/advanced.md">Advanced Topics</a>
- <a href="https://github.com/google/googletest/blob/master/googletest/docs/faq.md">FAQ</a>
Here is a non-exhaustive list of shortcuts tocommonly used concepts in unit
testing:
- Organizing [simple tests](https://github.com/google/googletest/blob/master/googletest/docs/primer.md#simple-tests)
- [Assertions](https://github.com/google/googletest/blob/master/googletest/docs/primer.md#assertions)
- [Fixtures](https://github.com/google/googletest/blob/master/googletest/docs/primer.md#test-fixtures-using-the-same-data-configuration-for-multiple-tests):
Class-like structures that are freshly instantiated for every test case
they are used in. Useful for testing classes or running starting tests with
a more complex program state.
- [Parameterized tests](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#value-parameterized-tests):
Execute the same test multiple times with different parameters.
- [Typed tests](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#typed-tests):
Execute the same test multiple times with different object types. Useful
for testing templates.
- [Exception assertions](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#exception-assertions):
Check if a statement throws an exception and optionally check for its type.
@}
**/ **/
...@@ -118,7 +118,7 @@ namespace Setup ...@@ -118,7 +118,7 @@ namespace Setup
} }
/*------------------------------------------------------------------------*//** /*------------------------------------------------------------------------*//**
* @brief Set up the configuration keys for Richards simulations * @brief Set up the configuration keys for Richards models
* *
* @param ini The inifile * @param ini The inifile
*/ */
...@@ -143,7 +143,7 @@ namespace Setup ...@@ -143,7 +143,7 @@ namespace Setup
} }
/*------------------------------------------------------------------------*//** /*------------------------------------------------------------------------*//**
* @brief Set up the configuration keys for Transport simulations * @brief Set up the configuration keys for Transport models
* *
* @param ini The inifile * @param ini The inifile
*/ */
......
...@@ -21,7 +21,7 @@ namespace Dorie{ ...@@ -21,7 +21,7 @@ namespace Dorie{
/** /**
* @brief Enum class for output policy. * @brief Enum class for output policy.
* @details It defines when a simulation class should produce an output. * @details It defines when a model class should produce an output.
*/ */
enum class OutputPolicy {None,EndOfRichardsStep,EndOfTransportStep}; enum class OutputPolicy {None,EndOfRichardsStep,EndOfTransportStep};
......
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdio>
#include <cerrno>
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
#include <dune/common/exceptions.hh> #include <dune/common/exceptions.hh>
...@@ -116,6 +121,30 @@ inline bool is_none (const std::string& in) ...@@ -116,6 +121,30 @@ inline bool is_none (const std::string& in)
return false; return false;
} }
/// Recursively create directories to match the given path
/** This function follows the implementation suggestion in
* http://pubs.opengroup.org/onlinepubs/009695399/functions/mkdir.html.
*
* \param path String representation of the path to be created.
* \param exist_ok Set to `true` to make this function ignore errors related
* to the fact that the target directory already exists.
* \throw std::runtime_error If directories cannot be created.
*/
inline void create_directories (const std::string& path,
const bool exist_ok=true)
{
int status = mkdir(path.c_str(),
S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (status != 0) {
// existing directory may be accepted
if (exist_ok and errno == EEXIST) {
return;
}
throw std::runtime_error("Error creating directory '"
+ path + "': " + std::strerror(errno));
}
}
/*-------------------------------------------------------------------------*//** /*-------------------------------------------------------------------------*//**
* @brief Transform a Yaml node with sequences to map * @brief Transform a Yaml node with sequences to map
* @details This function check all the nodes within 'in' and transform every * @details This function check all the nodes within 'in' and transform every
......
add_subdirectory("richards") add_subdirectory("richards")
add_subdirectory("transport") add_subdirectory("transport")
add_subdirectory("coupling")
#ifndef DUNE_DORIE_SIMULATION_BASE_HH #ifndef DUNE_DORIE_MODEL_BASE_HH
#define DUNE_DORIE_SIMULATION_BASE_HH #define DUNE_DORIE_MODEL_BASE_HH
#include "util.hh"
#include <dune/dorie/common/logging.hh> #include <dune/dorie/common/logging.hh>
#include <dune/common/exceptions.hh> #include <dune/common/exceptions.hh>
#include <dune/common/float_cmp.hh> #include <dune/common/float_cmp.hh>
#include <dune/dorie/common/util.hh>
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
/*-------------------------------------------------------------------------*//** /*-------------------------------------------------------------------------*//**
* @brief Base class for simulations. * @brief Base class for models.
* @details This class is used to handle simulations with a common interface. * @details This class is used to handle models with a common interface.
* @author Santiago Ospina De Los Ríos * @author Santiago Ospina De Los Ríos
* @date 2018 * @date 2018
* @todo Dune::Dorie::OutputPolicy can handle specific intermediate times * @todo Dune::Dorie::OutputPolicy can handle specific intermediate times
* of the stepping. * of the stepping.
* @ingroup Models * @ingroup Models
*/ */
class SimulationBase class ModelBase
{ {
public: public:
/** /**
* @brief Constructs the SimulationBase. * @brief Constructs the ModelBase.
* *
* @param[in] log_name Name of this model. Appears in the log. * @param[in] log_name Name of this model. Appears in the log.
* @param[in] log_level The log level of the logger. * @param[in] log_level The log level of the logger.
...@@ -35,7 +35,7 @@ public: ...@@ -35,7 +35,7 @@ public:
* @param[in] adapt_policy The adapt policy. * @param[in] adapt_policy The adapt policy.
* Defaults to AdaptiviyPolicy::None. * Defaults to AdaptiviyPolicy::None.
*/ */
SimulationBase( ModelBase(
const std::string log_name, const std::string log_name,
const std::string log_level, const std::string log_level,
const Dune::MPIHelper& helper, const Dune::MPIHelper& helper,
...@@ -47,8 +47,7 @@ public: ...@@ -47,8 +47,7 @@ public:
, _log(create_logger(log_name, helper, spdlog::level::from_str(log_level))) , _log(create_logger(log_name, helper, spdlog::level::from_str(log_level)))
{ } { }
virtual ~SimulationBase () = default; virtual ~ModelBase () = default;
/*-----------------------------------------------------------------------*//** /*-----------------------------------------------------------------------*//**
* @brief Sets the output policy. * @brief Sets the output policy.
* *
...@@ -81,7 +80,7 @@ public: ...@@ -81,7 +80,7 @@ public:
*/ */
AdaptivityPolicy adaptivity_policy() const {return _adapt_policy;} AdaptivityPolicy adaptivity_policy() const {return _adapt_policy;}
/// Set the logger for this simulation /// Set the logger for this model
/** @param logger The new logger /** @param logger The new logger
*/ */
void set_logger (const std::shared_ptr<spdlog::logger> logger) void set_logger (const std::shared_ptr<spdlog::logger> logger)
...@@ -89,7 +88,7 @@ public: ...@@ -89,7 +88,7 @@ public:
_log = logger; _log = logger;
} }
/// Return the logger of this simulation /// Return the logger of this model
std::shared_ptr<spdlog::logger> logger() const { return _log; } std::shared_ptr<spdlog::logger> logger() const { return _log; }
/*-----------------------------------------------------------------------*//** /*-----------------------------------------------------------------------*//**
...@@ -98,7 +97,7 @@ public: ...@@ -98,7 +97,7 @@ public:
void virtual write_data() const void virtual write_data() const
{ {
if (_output_policy != OutputPolicy::None) { if (_output_policy != OutputPolicy::None) {
_log->error("This simulation does not implement writing data. " _log->error("This model does not implement writing data. "
"Override this function if you set a different output policy " "Override this function if you set a different output policy "
"than None"); "than None");
DUNE_THROW(Dune::IOError, "'write_data' not implemented!"); DUNE_THROW(Dune::IOError, "'write_data' not implemented!");
...@@ -110,7 +109,7 @@ public: ...@@ -110,7 +109,7 @@ public:
*/ */
virtual void mark_grid() virtual void mark_grid()
{ {
_log->error("This simulation does not implement an algorithm for marking " _log->error("This model does not implement an algorithm for marking "
"the grid"); "the grid");
DUNE_THROW(Dune::NotImplemented, "'mark_grid' not implemented!"); DUNE_THROW(Dune::NotImplemented, "'mark_grid' not implemented!");
} }
...@@ -127,12 +126,12 @@ public: ...@@ -127,12 +126,12 @@ public:
virtual void adapt_grid() virtual void adapt_grid()
{ {
if (_adapt_policy != AdaptivityPolicy::None) { if (_adapt_policy != AdaptivityPolicy::None) {
_log->error("This simulation does not implement a grid adaptation " _log->error("This model does not implement a grid adaptation "
"algorithm."); "algorithm.");
DUNE_THROW(Dune::NotImplemented, "'adapt_grid' not implemented"); DUNE_THROW(Dune::NotImplemented, "'adapt_grid' not implemented");
} }
else { else {
_log->error("Calling 'adapt_grid' on a simulation with " _log->error("Calling 'adapt_grid' on a model with "
"AdaptivityPolicy::None. Grid adaptation refused"); "AdaptivityPolicy::None. Grid adaptation refused");
DUNE_THROW(Dune::InvalidStateException, "Invalid adaptation policy"); DUNE_THROW(Dune::InvalidStateException, "Invalid adaptation policy");
} }
...@@ -208,21 +207,21 @@ private: ...@@ -208,21 +207,21 @@ private:
AdaptivityPolicy _adapt_policy; AdaptivityPolicy _adapt_policy;
protected: protected:
//! The logger of this simulation //! The logger of this model
std::shared_ptr<spdlog::logger> _log; std::shared_ptr<spdlog::logger> _log;
}; };
/** /**
@{ @{
@class SimulationBase @class ModelBase
## Base class for simulations ## Base class for models
### Stepping: ### Stepping:
The method `step()` must be an abstract method that always has to be The method `step()` must be an abstract method that always has to be
implemented by the derived class. The step must succeed always, otherwise, implemented by the derived class. The step must succeed always, otherwise,
it should throw a `SimulationStepException`. It means that time adaptivity it should throw a `ModelStepException`. It means that time adaptivity
must be done internally so that the time step succeeds. must be done internally so that the time step succeeds.
### Writing data: ### Writing data:
...@@ -231,7 +230,7 @@ protected: ...@@ -231,7 +230,7 @@ protected:
(Say that in one case one wants that transport writes that every step and in (Say that in one case one wants that transport writes that every step and in
another case one wants that it writes at the end of the Richards step. The another case one wants that it writes at the end of the Richards step. The
first case can't be covered writing data in the `run()` method of the first case can't be covered writing data in the `run()` method of the
coupled simulation.) Then, enum class called `OutputPolicy` must decide coupled model.) Then, enum class called `OutputPolicy` must decide
whether to call the method `write_data()`. This policy can be set and be whether to call the method `write_data()`. This policy can be set and be
extracted by the methods `set_policy(OutputPolicy)` and `output_policy()` extracted by the methods `set_policy(OutputPolicy)` and `output_policy()`
respectively. respectively.
...@@ -239,9 +238,9 @@ protected: ...@@ -239,9 +238,9 @@ protected:
The method `write_data()` should be in charge of writing the data. The method `write_data()` should be in charge of writing the data.
In principle, this method should be only used following the `OutputPolicy`. In principle, this method should be only used following the `OutputPolicy`.
Usually called at the end of each step and at the beginning of the Usually called at the end of each step and at the beginning of the
simulation. Since the `step()` method is in charge of it, it is assumed that model. Since the `step()` method is in charge of it, it is assumed that
this method writes the *current* state of the model (e.g. intermediate this method writes the *current* state of the model (e.g. intermediate
results of the coupled simulation for the transport state). results of the coupled model for the transport state).
### Adaptivity: ### Adaptivity:
...@@ -274,11 +273,11 @@ protected: ...@@ -274,11 +273,11 @@ protected:
within the model, and the model must ensure that the timestep is done in within the model, and the model must ensure that the timestep is done in
`step()` is never bigger than the suggested one so that coupled models can `step()` is never bigger than the suggested one so that coupled models can
achieve synchronization. Naturally, models have to ensure that achieve synchronization. Naturally, models have to ensure that
`begin_time()` \f$=\f$ `current_time()` at when they are constructed. `begin_time()` \f$=\f$ `current_time()` when they are constructed.
### Local Operator Setup: ### Local Operator Setup:
Since adaptivity can modify the complete setup of the simulation, and since Since adaptivity can modify the complete setup of the model, and since
the method `adapt_grid()` is not necessarily called by the model. the method `adapt_grid()` is not necessarily called by the model.
There is a need for the method `post_adapt_grid()` which is in charge of There is a need for the method `post_adapt_grid()` which is in charge of
setup everything again to the new grid. Same argument holds for setup everything again to the new grid. Same argument holds for
...@@ -317,4 +316,4 @@ protected: ...@@ -317,4 +316,4 @@ protected:
} // namespace Dorie } // namespace Dorie
} // namespace Dune } // namespace Dune
#endif // DUNE_DORIE_SIMULATION_BASE_HH #endif // DUNE_DORIE_MODEL_BASE_HH
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef DORIE_DIM
#error DORIE_DIM must be defined
#endif
#ifndef DORIE_RORDER
#error DORIE_RORDER must be defined
#endif
#ifndef DORIE_TORDER
#error DORIE_TORDER must be defined
#endif
#ifdef DORIE_RT_ORDER
#error DORIE_RT_ORDER must be undefined
#endif
#if DORIE_RORDER == 0
#define DORIE_RT_ORDER 0
#else
#define DORIE_RT_ORDER DORIE_RORDER-1
#endif
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/uggrid.hh>
#include <dune/geometry/type.hh>
#include <dune/dorie/common/flux_reconstruction/raviart_thomas.hh>
#include <dune/dorie/model/transport/transport.cc>
#include <dune/dorie/model/coupling/richards_coupling.cc>
namespace Dune{
namespace Dorie{
using Geo = Dune::GeometryType::BasicType;
#if DORIE_SUPPORT_RT_CUBE(DORIE_DIM, DORIE_RT_ORDER)
template class ModelRichardsTransportCoupling<ModelRichardsTransportCouplingTraits<BaseTraits<YaspGrid<DORIE_DIM>, Geo::cube>,
DORIE_RORDER,
DORIE_TORDER>>;
#else
#warning Coupling for cubes is not available for this order and dimension. Case (YaspGrid) will be ignored
#endif
#if DORIE_TORDER > 0
#if DORIE_SUPPORT_RT_CUBE(DORIE_DIM, DORIE_RT_ORDER)
template class ModelRichardsTransportCoupling<ModelRichardsTransportCouplingTraits<BaseTraits<UGGrid<DORIE_DIM>, Geo::cube>,
DORIE_RORDER,
DORIE_TORDER>>;
#else
#warning Coupling for cubes is not available for this order and dimension. Case (UGGrid, cubes) will be ignored
#endif
#if DORIE_SUPPORT_RT_SIMPLEX(DORIE_DIM, DORIE_RT_ORDER)
template class ModelRichardsTransportCoupling<ModelRichardsTransportCouplingTraits<BaseTraits<UGGrid<DORIE_DIM>, Geo::simplex>,
DORIE_RORDER,
DORIE_TORDER>>;
#else
#warning Coupling for simplices is not available for this order. Case (UGGrid, simplices) will be ignored
#endif
#endif
} // namespace Dorie
} // namespace Dune
#include <dune/dorie/model/transport/richards_coupling.hh> #include <dune/dorie/model/coupling/richards_coupling.hh>
#include <dune/pdelab/adaptivity/adaptivity.hh> #include <dune/pdelab/adaptivity/adaptivity.hh>
...@@ -6,12 +6,12 @@ namespace Dune{ ...@@ -6,12 +6,12 @@ namespace Dune{
namespace Dorie{ namespace Dorie{
template<typename Traits> template<typename Traits>
RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation( ModelRichardsTransportCoupling<Traits>::ModelRichardsTransportCoupling(
Dune::ParameterTree& inifile_richards, Dune::ParameterTree& inifile_richards,
Dune::ParameterTree& inifile_transport, Dune::ParameterTree& inifile_transport,
const GridCreator& grid_creator, const GridCreator& grid_creator,
Dune::MPIHelper& helper Dune::MPIHelper& helper
) : SimulationBase(log_coupling, ) : ModelBase(log_coupling,
inifile_transport.get<std::string>("output.logLevel"), inifile_transport.get<std::string>("output.logLevel"),
helper) helper)
, _grid(grid_creator.grid()) , _grid(grid_creator.grid())
...@@ -30,13 +30,13 @@ RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation ...@@ -30,13 +30,13 @@ RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation
} }
this->_log->trace("Setting up Richards model"); this->_log->trace("Setting up Richards model");
// create richards simulations // create richards model
_richards = std::make_unique<RichardsSimulation>(_inifile_richards,grid_creator,helper); _richards = std::make_unique<ModelRichards>(_inifile_richards,grid_creator,helper);
auto time_begin = _richards->begin_time(); auto time_begin = _richards->begin_time();
this->_log->trace("Setting up Transport model"); this->_log->trace("Setting up Transport model");
// set initial water state into the transport simulation // set initial water state into the transport model
auto igf_water_content = std::make_shared<GFWaterContentContainer>(); auto igf_water_content = std::make_shared<GFWaterContentContainer>();
auto igf_water_flux = std::make_shared<GFWaterFluxContainer>(); auto igf_water_flux = std::make_shared<GFWaterFluxContainer>();
...@@ -46,8 +46,8 @@ RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation ...@@ -46,8 +46,8 @@ RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation
auto gf_water_flux = _richards->get_water_flux_reconstructed(); auto gf_water_flux = _richards->get_water_flux_reconstructed();
igf_water_flux->push(gf_water_flux,time_begin); igf_water_flux->push(gf_water_flux,time_begin);
// create transport simulations // create transport model
_transport = std::make_unique<TransportSimulation>(_inifile_transport, _transport = std::make_unique<ModelTransport>(_inifile_transport,
grid_creator, grid_creator,
helper); helper);
_transport->set_water_flux(igf_water_flux); _transport->set_water_flux(igf_water_flux);
...@@ -59,7 +59,7 @@ RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation ...@@ -59,7 +59,7 @@ RichardsTransportCouplingSimulation<Traits>::RichardsTransportCouplingSimulation
} }
template<typename Traits> template<typename Traits>
void RichardsTransportCouplingSimulation<Traits>::step() void ModelRichardsTransportCoupling<Traits>::step()
{ {
TimeField time_begin = _richards->current_time(); TimeField time_begin = _richards->current_time();
...@@ -133,7 +133,7 @@ void RichardsTransportCouplingSimulation<Traits>::step() ...@@ -133,7 +133,7 @@ void RichardsTransportCouplingSimulation<Traits>::step()
} }
template<typename Traits> template<typename Traits>
void RichardsTransportCouplingSimulation<Traits>::adapt_grid() void ModelRichardsTransportCoupling<Traits>::adapt_grid()
{ {
this->_log->debug("Adapting grid"); this->_log->debug("Adapting grid");
...@@ -151,8 +151,8 @@ void RichardsTransportCouplingSimulation<Traits>::adapt_grid() ...@@ -151,8 +151,8 @@ void RichardsTransportCouplingSimulation<Traits>::adapt_grid()
const int add_int_order = 2; const int add_int_order = 2;
const int quadrature_factor = 2; const int quadrature_factor = 2;
const int richards_order = RichardsSimulationTraits::order; const int richards_order = ModelRichardsTraits::order;
const int transport_order = TransportSimulationTraits::order; const int transport_order = ModelTransportTraits::order;
auto richards_int_order = quadrature_factor*richards_order + add_int_order; auto richards_int_order = quadrature_factor*richards_order + add_int_order;
auto transport_int_order = quadrature_factor*transport_order + add_int_order; auto transport_int_order = quadrature_factor*transport_order + add_int_order;
...@@ -172,14 +172,14 @@ void RichardsTransportCouplingSimulation<Traits>::adapt_grid() ...@@ -172,14 +172,14 @@ void RichardsTransportCouplingSimulation<Traits>::adapt_grid()
auto transport_pack = Dune::PDELab::transferSolutions(transport_gfs,transport_int_order,transport_coeff); auto transport_pack = Dune::PDELab::transferSolutions(transport_gfs,transport_int_order,transport_coeff);
if (adaptivity_policy() == AdaptivityPolicy::WaterFlux) if (adaptivity_policy() == AdaptivityPolicy::WaterFlux)
{ // adaptivity on water flux assumes that simulations are synchronized { // adaptivity on water flux assumes that model are synchronized
// pack richards state // pack richards state
auto richards_pack = Dune::PDELab::transferSolutions(richards_gfs,richards_int_order,richards_coeff); auto richards_pack = Dune::PDELab::transferSolutions(richards_gfs,richards_int_order,richards_coeff);
// adapt grid and packs // adapt grid and packs
Dune::PDELab::adaptGrid(*_grid,richards_pack,transport_pack); Dune::PDELab::adaptGrid(*_grid,richards_pack,transport_pack);
} }
else if (adaptivity_policy() == AdaptivityPolicy::SoluteFlux) else if (adaptivity_policy() == AdaptivityPolicy::SoluteFlux)
{ // adaptivity on solute flux assumes that simulations are not synchronized { // adaptivity on solute flux assumes that model are not synchronized
// get DOF vector richards at begging of step // get DOF vector richards at begging of step
auto& richards_coeff_before = *(richards_state_before_step.coefficients); auto& richards_coeff_before = *(richards_state_before_step.coefficients);
// pack richards current and before state // pack richards current and before state
...@@ -193,7 +193,7 @@ void RichardsTransportCouplingSimulation<Traits>::adapt_grid() ...@@ -193,7 +193,7 @@ void RichardsTransportCouplingSimulation<Traits>::adapt_grid()
} }
template<typename Traits> template<typename Traits>
void RichardsTransportCouplingSimulation<Traits>::post_adapt_grid() void ModelRichardsTransportCoupling<Traits>::post_adapt_grid()
{ {
this->_log->debug("Post-adapt grid"); this->_log->debug("Post-adapt grid");
// if water state was adapted, containers have to be reset // if water state was adapted, containers have to be reset
......
#ifndef DUNE_DORIE_COUPLED_SIMULATION_HH #ifndef DUNE_DORIE_MODEL_COUPLING_HH
#define DUNE_DORIE_COUPLED_SIMULATION_HH #define DUNE_DORIE_MODEL_COUPLING_HH
#include <dune/dorie/common/grid_function_container.hh> #include <dune/dorie/common/grid_function_container.hh>
#include <dune/dorie/model/richards/richards.hh> #include <dune/dorie/model/richards/richards.hh>
#include <dune/dorie/model/transport/transport.hh> #include <dune/dorie/model/transport/transport.hh>
#include <dune/dorie/model/transport/richards_coupling.hh>
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
/*-------------------------------------------------------------------------*//** /*-------------------------------------------------------------------------*//**
* @brief Traits for the class RichardsTransportCouplingSimulation. * @brief Traits for the class ModelRichardsTransportCoupling.
* @details This class extends BaseTraits to be used for the implementation * @details This class extends BaseTraits to be used for the implementation
* of the Richards and Transport simulations. * of the Richards and Transport models.
* @author Santiago Ospina De Los Ríos * @author Santiago Ospina De Los Ríos
* @date 2018-2019 * @date 2018-2019
* @ingroup TransportModel * @ingroup ModelTransport
* @ingroup RichardsModel * @ingroup ModelRichards
* *
* @tparam BaseTraits Traits defining domain and range field properties * @tparam BaseTraits Traits defining domain and range field properties
* of the simulation. * of the model.
* @tparam RichardsOrder Order of the polynomial degree used for the basis * @tparam RichardsOrder Order of the polynomial degree used for the basis
* functions in the Richards DG method. * functions in the Richards DG method.
* @tparam TransportOrder Order of the polynomial degree used for the basis * @tparam TransportOrder Order of the polynomial degree used for the basis
* functions in the Transport DG/FV method. * functions in the Transport DG/FV method.
*/ */