Commit c79cd5f5 authored by Lukas Riedel's avatar Lukas Riedel

Merge branch '137-add-a-finite-volume-local-operator-for-the-richards-equation' into 'master'

Resolve "Add a Finite Volume local operator for the Richards equation"

Closes #137

See merge request !132
parents a73adde6 e7823bce
...@@ -148,6 +148,7 @@ ...@@ -148,6 +148,7 @@
* Structure and setup of Sphinx user docs !126 * Structure and setup of Sphinx user docs !126
* 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
### Fixed ### Fixed
* Solver in `RichardsSimulation` was using the wrong time variable. * Solver in `RichardsSimulation` was using the wrong time variable.
......
...@@ -52,9 +52,8 @@ adding an empty line, make text **bold** or ``monospaced``. ...@@ -52,9 +52,8 @@ adding an empty line, make text **bold** or ``monospaced``.
<parameter name="vertexData"> <parameter name="vertexData">
<definition> Plot vertex based (``true``) or cell-centered (``false``) <definition> Plot vertex based (``true``) or cell-centered (``false``)
data into VTK files. Vertex based data might render sharp data into VTK files. Prefer vertex over cell data for full-precision
parameterization boundaries inappropriately. output. System tests and plotting functions (``dorie plot``) require
System tests and plotting functions (``dorie plot``) require
cell-centered data. cell-centered data.
</definition> </definition>
<values> true, false </values> <values> true, false </values>
...@@ -240,10 +239,12 @@ adding an empty line, make text **bold** or ``monospaced``. ...@@ -240,10 +239,12 @@ adding an empty line, make text **bold** or ``monospaced``.
</parameter> </parameter>
<parameter name="FEorder"> <parameter name="FEorder">
<definition> Order of the finite element method used. Values &gt; 1 are not <definition> Polynomial order of the DG method used. Setting this value
thoroughly tested. </definition> to 0 (zero) selects the finite volume (FV) solver (only compatible to
structured rectangular grids).
</definition>
<suggestion> 1 </suggestion> <suggestion> 1 </suggestion>
<values> 1, 2, 3 </values> <values> 0, 1, 2, 3 </values>
</parameter> </parameter>
</category> </category>
......
...@@ -39,6 +39,17 @@ singularities. ...@@ -39,6 +39,17 @@ singularities.
Use the value ``richards`` in the ``simulation.mode`` keyword to run the Use the value ``richards`` in the ``simulation.mode`` keyword to run the
standalone Richards solver. standalone Richards solver.
.. _richards_solver_options:
Solver Options
--------------
DORiE includes a finite volume (FV) and a discontinuous Galerkin (DG) solver
for the Richards equation. The FV solver can be selected for structured
rectangular grids by setting ``richards.numerics.FEorder = 0`` when adaptivity
is disabled. The DG solver is used for orders :math:`k \geq 1` and is available
for all grid options.
Solute Transport Solver Solute Transport Solver
======================= =======================
......
...@@ -10,34 +10,44 @@ Firstly, we have to recall that DORiE solves a Discontinuous Galerking finite el ...@@ -10,34 +10,44 @@ Firstly, we have to recall that DORiE solves a Discontinuous Galerking finite el
From the description above one can infer that one has to distinguish between * fluxes* at the interior of each element and at the intersections of all elements (we call these intersections skeleton of the grid). Unfortunately, there is no a standard form to write the skeleton fluxes on formats like VTK and that's the main reason why DORiE only provides the interior fluxes. However, assuming one can write both fluxes into some output format, they are still discontinuous (notice that direct use of discontinuous fluxes are useless for conservative computations since the transported quantities are very likely to get stagnated or over-transported in the nearby of intersections between elements). It means that it is needed some sort of post-processing that ensures that the *mass* is still locally and globally conserved. From the description above one can infer that one has to distinguish between * fluxes* at the interior of each element and at the intersections of all elements (we call these intersections skeleton of the grid). Unfortunately, there is no a standard form to write the skeleton fluxes on formats like VTK and that's the main reason why DORiE only provides the interior fluxes. However, assuming one can write both fluxes into some output format, they are still discontinuous (notice that direct use of discontinuous fluxes are useless for conservative computations since the transported quantities are very likely to get stagnated or over-transported in the nearby of intersections between elements). It means that it is needed some sort of post-processing that ensures that the *mass* is still locally and globally conserved.
.. DORiE allow finite volume computations under certain specific conditions. In such case, if generated, the raw flux output generated by DORiE has no meaning. The reason is that finite volumes are computed with finite elements of order 0 where gradients are 0. When employing a finite volume solver, the regular flux output is omitted
because the basis function gradients are always zero. In this case, the only
option for evaluating flux data is flux reconstruction which has to be enabled
in the :doc:`config file <config-file>`.
Flux reconstruction Flux reconstruction
------------------- -------------------
The flux reconstruction is a projection of the fluxes used in the Discontinuous Galerkin method into a vector field function. Using correct elements, this procedure can ensure that fluxes in normal direction to the element are *equivalent* to those computed by the Discontinuous Galerkin method, and most importantly, it can also ensure the continuity of them. Hence, the resulting vector field is useful to compute other problems that rely on the fluxes of the water (i.e. solute transport). The flux reconstruction is a projection of the fluxes used in the Discontinuous Galerkin method into a vector field function. Using correct elements, this procedure can ensure that fluxes in normal direction to the element are *equivalent* to those computed by the Discontinuous Galerkin method, and most importantly, it can also ensure the continuity of them. Hence, the resulting vector field is useful to compute other problems that rely on the fluxes of the water (i.e. solute transport).
The flux reconstruction technique always use Raviar Thomas finite elements of one degree less than the one set for the Richards model. It can be identified in the vtk file by the name ``flux_RT{k-1}``, where ``k`` is the finite element order set for the Richards model. Flux reconstruction is not available for non-conforming grids (i.e. Cube-adaptive grids). The flux reconstruction technique always use Raviar Thomas finite elements of one degree less than the one set for the Richards model. It can be identified in the vtk file by the name ``flux_RT{min(k-1,0)}``, where ``k`` is the finite element order set for the Richards model. Flux reconstruction is not available for non-conforming grids (i.e. Cube-adaptive grids).
+---------------------------+---+---+---+ +---------------------------+---+---+---+---+
| Richards FEorder | 1 | 2 | 3 | | Richards FEorder | 0 | 1 | 2 | 3 |
+============+====+=========+===+===+===+ +============+====+=========+===+===+===+===+
| | 2D | Simplex | ✓ | ✓ | ✓ | | | 2D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+ | | +---------+---+---+---+---+
| | | Cube | ✓ | ✓ | ✓ | | | | Cube | ✓ | ✓ | ✓ | ✓ |
| Non-adapt. +----+---------+---+---+---+ | Non-adapt. +----+---------+---+---+---+---+
| | 3D | Simplex | ✓ | ✓ | ✓ | | | 3D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+ | | +---------+---+---+---+---+
| | | Cube | ✓ | ✓ | | | | | Cube | ✓ | ✓ | ✓ | |
+------------+----+---------+---+---+---+ +------------+----+---------+---+---+---+---+
| | 2D | Simplex | ✓ | ✓ | ✓ | | | 2D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+ | | +---------+---+---+---+---+
| | | Cube | | | | | | | Cube | ✗ | | | |
| Adapt. +----+---------+---+---+---+ | Adapt. +----+---------+---+---+---+---+
| | 3D | Simplex | ✓ | ✓ | ✓ | | | 3D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+ | | +---------+---+---+---+---+
| | | Cube | | | | | | | Cube | ✗ | | | |
+------------+----+---------+---+---+---+ +------------+----+---------+---+---+---+---+
Legend:
* ✓: Flux reconstruction available.
* ( ): Flux reconstruction unavailable.
* ✗: Invalid setting. Finite volume solvers only works on regular grids,
see :ref:`Richards Solver Options <richards_solver_options>`.
Usage Usage
----- -----
To activate/deactivate flux reconstruction use the keyword ``richards.numeric.fluxReconstruction = true/false`` in the :doc:`config file<man-config-file>`. To activate/deactivate flux reconstruction use the keyword ``richards.numeric.fluxReconstruction = true/false`` in the :doc:`config file <config-file>`.
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <dune/pdelab/localoperator/defaultimp.hh> #include <dune/pdelab/localoperator/defaultimp.hh>
#include <dune/pdelab/finiteelement/localbasiscache.hh> #include <dune/pdelab/finiteelement/localbasiscache.hh>
#include <dune/dorie/model/richards/local_operator.hh> #include <dune/dorie/model/richards/local_operator_DG.hh>
namespace Dune { namespace Dune {
namespace Dorie { namespace Dorie {
......
add_library(dorie-richards STATIC add_library(dorie-richards STATIC
sim_yasp_2_0.cc
sim_yasp_2_1.cc sim_yasp_2_1.cc
sim_yasp_2_2.cc
sim_ug_2_1.cc sim_ug_2_1.cc
sim_yasp_2_2.cc
sim_yasp_2_3.cc sim_yasp_2_3.cc
sim_yasp_3_1.cc
sim_ug_2_2.cc sim_ug_2_2.cc
sim_yasp_3_0.cc
sim_yasp_3_1.cc
sim_ug_2_3.cc
sim_yasp_3_2.cc sim_yasp_3_2.cc
sim_yasp_3_3.cc sim_yasp_3_3.cc
sim_ug_2_3.cc
sim_ug_3_1.cc sim_ug_3_1.cc
sim_ug_3_2.cc sim_ug_3_2.cc
sim_ug_3_3.cc) sim_ug_3_3.cc)
......
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <dune/dorie/model/richards/impl/impl.hh>
#include <dune/dorie/model/richards/richards.cc>
namespace Dune{
namespace Dorie{
template class RichardsSimulation<RichardsSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,0>>;
} // namespace Dorie
} // namespace Dune
\ No newline at end of file
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <dune/dorie/model/richards/impl/impl.hh>
#include <dune/dorie/model/richards/richards.cc>
namespace Dune{
namespace Dorie{
template class RichardsSimulation<RichardsSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,0>>;
} // namespace Dorie
} // namespace Dune
\ No newline at end of file
...@@ -134,6 +134,7 @@ inline auto read_experimental_operator_settings( ...@@ -134,6 +134,7 @@ inline auto read_experimental_operator_settings(
* differing geometry types, i.e. hybrid meshes.) * differing geometry types, i.e. hybrid meshes.)
* *
* @ingroup LocalOperators * @ingroup LocalOperators
* @ingroup RichardsModel
*/ */
template<typename Traits, typename Parameter, typename Boundary, typename SourceTerm, typename FEM, bool adjoint> template<typename Traits, typename Parameter, typename Boundary, typename SourceTerm, typename FEM, bool adjoint>
class RichardsDGSpatialOperator class RichardsDGSpatialOperator
...@@ -937,6 +938,7 @@ public: ...@@ -937,6 +938,7 @@ public:
* @brief DG local operator for the temporal derivative of the Richards equation * @brief DG local operator for the temporal derivative of the Richards equation
* *
* @ingroup LocalOperators * @ingroup LocalOperators
* @ingroup RichardsModel
*/ */
template<typename Traits, typename Parameter, typename FEM, bool adjoint> template<typename Traits, typename Parameter, typename FEM, bool adjoint>
class RichardsDGTemporalOperator class RichardsDGTemporalOperator
......
This diff is collapsed.
...@@ -56,6 +56,10 @@ RichardsSimulation<Traits>::RichardsSimulation ( ...@@ -56,6 +56,10 @@ RichardsSimulation<Traits>::RichardsSimulation (
finitial = FlowInitialFactory::create(inifile, gv, this->_log); finitial = FlowInitialFactory::create(inifile, gv, this->_log);
// --- Local Operators --- // --- Local Operators ---
if constexpr (order>0)
{
this->_log->debug("Setting up local grid operators: DG method");
#ifdef EXPERIMENTAL_DG_FEATURES #ifdef EXPERIMENTAL_DG_FEATURES
// read experimental settings from inifile // read experimental settings from inifile
namespace OP = Dune::Dorie::Operator; namespace OP = Dune::Dorie::Operator;
...@@ -71,6 +75,13 @@ RichardsSimulation<Traits>::RichardsSimulation ( ...@@ -71,6 +75,13 @@ RichardsSimulation<Traits>::RichardsSimulation (
#endif // EXPERIMENTAL_DG_FEATURES #endif // EXPERIMENTAL_DG_FEATURES
tlop = std::make_unique<TLOP>(inifile, fparam); tlop = std::make_unique<TLOP>(inifile, fparam);
}
else {
this->_log->debug("Setting up local grid operators: FV method");
slop = std::make_unique<SLOP>(fparam, fboundary);
tlop = std::make_unique<TLOP>(fparam);
}
controller = std::make_unique<CalculationController>( controller = std::make_unique<CalculationController>(
inifile, *fboundary, this->_log); inifile, *fboundary, this->_log);
...@@ -277,22 +288,30 @@ void RichardsSimulation<Traits>::write_data () const ...@@ -277,22 +288,30 @@ void RichardsSimulation<Traits>::write_data () const
if (inifile.get<bool>("output.vertexData")) { if (inifile.get<bool>("output.vertexData")) {
vtkwriter->addVertexData(head,"head"); vtkwriter->addVertexData(head,"head");
vtkwriter->addVertexData(wflux,"flux");
vtkwriter->addVertexData(cond,"K_0"); vtkwriter->addVertexData(cond,"K_0");
vtkwriter->addVertexData(wc,"theta_w"); vtkwriter->addVertexData(wc,"theta_w");
vtkwriter->addVertexData(sat,"Theta"); vtkwriter->addVertexData(sat,"Theta");
if constexpr (order > 0) {
vtkwriter->addVertexData(wflux, "flux");
}
if constexpr (enable_rt_engine) if constexpr (enable_rt_engine)
if (enable_fluxrc) { if (enable_fluxrc) {
auto wfluxr = get_water_flux_reconstructed(); auto wfluxr = get_water_flux_reconstructed();
auto RT_name = "flux_RT" + std::to_string(flux_order); auto RT_name = "flux_RT" + std::to_string(flux_order);
vtkwriter->addVertexData(wfluxr,RT_name); vtkwriter->addVertexData(wfluxr,RT_name);
} }
} else { }
// cell data
else {
vtkwriter->addCellData(head,"head"); vtkwriter->addCellData(head,"head");
vtkwriter->addCellData(wflux,"flux");
vtkwriter->addCellData(cond,"K_0"); vtkwriter->addCellData(cond,"K_0");
vtkwriter->addCellData(wc,"theta_w"); vtkwriter->addCellData(wc,"theta_w");
vtkwriter->addCellData(sat,"Theta"); vtkwriter->addCellData(sat,"Theta");
if constexpr (order > 0) {
vtkwriter->addCellData(wflux, "flux");
}
if constexpr (enable_rt_engine) if constexpr (enable_rt_engine)
if (enable_fluxrc) { if (enable_fluxrc) {
auto wfluxr = get_water_flux_reconstructed(); auto wfluxr = get_water_flux_reconstructed();
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <dune/dorie/model/richards/flow_parameters.hh> #include <dune/dorie/model/richards/flow_parameters.hh>
#include <dune/dorie/model/richards/flow_boundary.hh> #include <dune/dorie/model/richards/flow_boundary.hh>
#include <dune/dorie/model/richards/flow_source.hh> #include <dune/dorie/model/richards/flow_source.hh>
#include <dune/dorie/model/richards/local_operator.hh> #include <dune/dorie/model/richards/local_operator_DG.hh>
#include <dune/dorie/model/richards/local_operator_FV.hh>
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
...@@ -60,7 +61,11 @@ struct RichardsSimulationTraits : public BaseTraits ...@@ -60,7 +61,11 @@ struct RichardsSimulationTraits : public BaseTraits
using GV = typename BaseTraits::GV; using GV = typename BaseTraits::GV;
/// GFS Helper /// GFS Helper
using GFSHelper = Dune::Dorie::GridFunctionSpaceHelper<GV,RF,order,BaseTraits::GridGeometryType>; using GFSHelper =
std::conditional_t<order==0,
Dune::Dorie::LinearSolverGridFunctionSpaceHelper<GV,RF,BaseTraits::GridGeometryType>,
Dune::Dorie::GridFunctionSpaceHelper<GV,RF,order,BaseTraits::GridGeometryType>>;
/// Problem GFS /// Problem GFS
using GFS = typename GFSHelper::Type; using GFS = typename GFSHelper::Type;
/// GFS Constraints Container /// GFS Constraints Container
...@@ -88,9 +93,17 @@ struct RichardsSimulationTraits : public BaseTraits ...@@ -88,9 +93,17 @@ struct RichardsSimulationTraits : public BaseTraits
/// Class defining the initial condition factory /// Class defining the initial condition factory
using FlowInitialFactory = Dune::Dorie::RichardsInitialConditionFactory<BaseTraits>; using FlowInitialFactory = Dune::Dorie::RichardsInitialConditionFactory<BaseTraits>;
/// Local spatial operator /// Local spatial operator
using SLOP = Dune::Dorie::Operator::RichardsDGSpatialOperator<BaseTraits,FlowParameters,FlowBoundary,FlowSource,typename GFSHelper::FEM,false>; using SLOP =
std::conditional_t<order==0,
Dune::Dorie::Operator::RichardsFVSpatialOperator<FlowParameters,FlowBoundary>,
Dune::Dorie::Operator::RichardsDGSpatialOperator<BaseTraits,FlowParameters,FlowBoundary,FlowSource,typename GFSHelper::FEM,false>>;
/// Local temporal operator /// Local temporal operator
using TLOP = Dune::Dorie::Operator::RichardsDGTemporalOperator<BaseTraits,FlowParameters,typename GFSHelper::FEM,false>; using TLOP =
std::conditional_t<order==0,
Dune::Dorie::Operator::RichardsFVTemporalOperator<FlowParameters>,
Dune::Dorie::Operator::RichardsDGTemporalOperator<BaseTraits,FlowParameters,typename GFSHelper::FEM,false>>;
/// Time controller /// Time controller
using CalculationController = Dune::Dorie::CalculationController<RF,FlowBoundary>; using CalculationController = Dune::Dorie::CalculationController<RF,FlowBoundary>;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,0,0>>;
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,0>>; template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,0>>;
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,0>>; template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,0>>;
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,0>>; template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,0>>;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,0,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,1>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,1>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,1>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,1>>; +
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,0,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,2>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,2>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,2>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,2>>; +
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,0,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,3>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,1,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,3>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,2,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,3>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,3>>; +
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,0,0>>;
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,0>>; template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,0>>;
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,0>>; template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,0>>;
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,0>>; * // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,0>>; *
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,0,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,1>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,1>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,1>>; * // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,1>>; *
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,0,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,2>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,2>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,2>>; * // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,2>>; *
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace Dune{ namespace Dune{
namespace Dorie{ namespace Dorie{
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,0,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,3>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,1,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,3>>; + // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,2,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,3>>; * // template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,3>>; *
......
...@@ -142,6 +142,11 @@ int main(int argc, char** argv) ...@@ -142,6 +142,11 @@ int main(int argc, char** argv)
else{ // no adaptivity else{ // no adaptivity
Dune::Dorie::GridCreator<Dune::YaspGrid<2>> grid_creator(inifile, helper); Dune::Dorie::GridCreator<Dune::YaspGrid<2>> grid_creator(inifile, helper);
switch(FEorder){ switch(FEorder){
case 0:{
Sim<Cube<2,0>> sim(richards_config, grid_creator, helper);
sim.run();
break;
}
case 1:{ case 1:{
Sim<Cube<2,1>> sim(richards_config, grid_creator, helper); Sim<Cube<2,1>> sim(richards_config, grid_creator, helper);
sim.run(); sim.run();
...@@ -222,6 +227,11 @@ int main(int argc, char** argv) ...@@ -222,6 +227,11 @@ int main(int argc, char** argv)
else{ // no adaptivity else{ // no adaptivity
Dune::Dorie::GridCreator<Dune::YaspGrid<3>> grid_creator(inifile, helper); Dune::Dorie::GridCreator<Dune::YaspGrid<3>> grid_creator(inifile, helper);
switch(FEorder){ switch(FEorder){
case 0:{
Sim<Cube<3,0>> sim(richards_config, grid_creator, helper);
sim.run();
break;
}
case 1:{ case 1:{
Sim<Cube<3,1>> sim(richards_config, grid_creator, helper); Sim<Cube<3,1>> sim(richards_config, grid_creator, helper);
sim.run(); sim.run();
......
...@@ -177,6 +177,12 @@ using Cube = Dune::Dorie::RichardsTransportCouplingSimulationTraits<Dune::Dorie: ...@@ -177,6 +177,12 @@ using Cube = Dune::Dorie::RichardsTransportCouplingSimulationTraits<Dune::Dorie:
switch(FEorder_transport){ switch(FEorder_transport){
case 0:{ case 0:{
switch (FEorder_richards){ switch (FEorder_richards){
case 0:{
Sim<Cube<2,0,0>> sim(richards_config,transport_config,grid_creator,helper);
sim.set_policy(adapt_policy);
sim.run();
break;
}
case 1:{ case 1:{
Sim<Cube<2,1,0>> sim(richards_config,transport_config,grid_creator,helper); Sim<Cube<2,1,0>> sim(richards_config,transport_config,grid_creator,helper);
sim.set_policy(adapt_policy); sim.set_policy(adapt_policy);
...@@ -292,6 +298,12 @@ using Cube = Dune::Dorie::RichardsTransportCouplingSimulationTraits<Dune::Dorie: ...@@ -292,6 +298,12 @@ using Cube = Dune::Dorie::RichardsTransportCouplingSimulationTraits<Dune::Dorie:
switch(FEorder_transport){ switch(FEorder_transport){
case 0:{ case 0:{
switch (FEorder_richards){ switch (FEorder_richards){
case 0:{
Sim<Cube<3,0,0>> sim(richards_config,transport_config,grid_creator,helper);
sim.set_policy(adapt_policy);
sim.run();
break;
}
case 1:{ case 1:{
Sim<Cube<3,1,0>> sim(richards_config,transport_config,grid_creator,helper); Sim<Cube<3,1,0>> sim(richards_config,transport_config,grid_creator,helper);
sim.set_policy(adapt_policy); sim.set_policy(adapt_policy);
......
...@@ -22,10 +22,12 @@ def evaluate(iniinfo,runtime): ...@@ -22,10 +22,12 @@ def evaluate(iniinfo,runtime):
initial_head = float(iniinfo["_ode.headLower"]) initial_head = float(iniinfo["_ode.headLower"])
extensions = list(map(float,iniinfo["grid.extensions"].split())) extensions = list(map(float,iniinfo["grid.extensions"].split()))
do_flux_rt = iniinfo["richards.fluxReconstruction.enable"]
fe_order = int(iniinfo["richards.numerics.FEorder"]) fe_order = int(iniinfo["richards.numerics.FEorder"])
do_flux_rt = iniinfo["richards.fluxReconstruction.enable"]
do_flux_grad = fe_order > 0
if do_flux_rt: if do_flux_rt:
flux_rt_key = "flux_RT" + str(fe_order-1) flux_rt_key = "flux_RT" + str(max(0,fe_order-1))
# get parameter data # get parameter data
param_data = read_yml(iniinfo["richards.parameters.file"]) param_data = read_yml(iniinfo["richards.parameters.file"])
...@@ -119,6 +121,12 @@ def evaluate(iniinfo,runtime): ...@@ -119,6 +121,12 @@ def evaluate(iniinfo,runtime):
plt.savefig("{}/head_residual.png".format(iniinfo["richards.output.outputPath"])) plt.savefig("{}/head_residual.png".format(iniinfo["richards.output.outputPath"]))
plt.close() plt.close()
# Check matric head
head_tol = 1E-5 if not "_ode.head_abstol" in iniinfo else float(iniinfo["_ode.head_abstol"])
passed = bool(l2_head < head_tol)
# Check flux from gradient
if do_flux_grad:
flux = data["flux"][iy,:] flux = data["flux"][iy,:]
res_flux = flux - np.array([0.,influx,0.])[np.newaxis,:] res_flux = flux - np.array([0.,influx,0.])[np.newaxis,:]
l2_flux = [np.sqrt(average(np.square(r[iy_inv]))) for r in res_flux.T] l2_flux = [np.sqrt(average(np.square(r[iy_inv]))) for r in res_flux.T]
...@@ -129,9 +137,10 @@ def evaluate(iniinfo,runtime): ...@@ -129,9 +137,10 @@ def evaluate(iniinfo,runtime):
plt.savefig("{}/flux_residual.png".format(iniinfo["richards.output.outputPath"])) plt.savefig("{}/flux_residual.png".format(iniinfo["richards.output.outputPath"]))
plt.close() plt.close()
head_tol = 1E-5 if not "_ode.head_abstol" in iniinfo else float(iniinfo["_ode.head_abstol"])
flux_tol = abs(influx) * 1e-5 if not "_ode.flux_abstol" in iniinfo else float(iniinfo["_ode.flux_abstol"]) flux_tol = abs(influx) * 1e-5 if not "_ode.flux_abstol" in iniinfo else float(iniinfo["_ode.flux_abstol"])
passed = passed and all([l < flux_tol for l in l2_flux])
# Check reconstructed flux
if do_flux_rt: if do_flux_rt:
flux_rt = data[flux_rt_key][iy,:] flux_rt = data[flux_rt_key][iy,:]
res_flux_rt = flux_rt - np.ar