Commit a782cbee authored by Lukas Riedel's avatar Lukas Riedel

Merge branch 'master' into 127-add-data-assimilation-interface-to-richardssimulation

parents 510d5dc2 c79cd5f5
......@@ -148,6 +148,7 @@
* Structure and setup of Sphinx user docs !126
* Switch to stable `dune-randomfield` release branch !151, !153
* System tests for executing `dorie pfg` module !153
* Finite volume solver for the Richards equation !132
### Fixed
* Solver in `RichardsSimulation` was using the wrong time variable.
......
......@@ -52,9 +52,8 @@ adding an empty line, make text **bold** or ``monospaced``.
<parameter name="vertexData">
<definition> Plot vertex based (``true``) or cell-centered (``false``)
data into VTK files. Vertex based data might render sharp
parameterization boundaries inappropriately.
System tests and plotting functions (``dorie plot``) require
data into VTK files. Prefer vertex over cell data for full-precision
output. System tests and plotting functions (``dorie plot``) require
cell-centered data.
</definition>
<values> true, false </values>
......@@ -240,10 +239,12 @@ adding an empty line, make text **bold** or ``monospaced``.
</parameter>
<parameter name="FEorder">
<definition> Order of the finite element method used. Values &gt; 1 are not
thoroughly tested. </definition>
<definition> Polynomial order of the DG method used. Setting this value
to 0 (zero) selects the finite volume (FV) solver (only compatible to
structured rectangular grids).
</definition>
<suggestion> 1 </suggestion>
<values> 1, 2, 3 </values>
<values> 0, 1, 2, 3 </values>
</parameter>
</category>
......
......@@ -39,6 +39,17 @@ singularities.
Use the value ``richards`` in the ``simulation.mode`` keyword to run the
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
=======================
......
......@@ -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.
.. 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
-------------------
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).
+---------------------------+---+---+---+
| Richards FEorder | 1 | 2 | 3 |
+============+====+=========+===+===+===+
| | 2D | Simplex | ✓ | ✓ | ✓ |
| | +---------+---+---+---+
| | | Cube | ✓ | ✓ | ✓ |
| Non-adapt. +----+---------+---+---+---+
| | 3D | Simplex | ✓ | ✓ | ✓ |
| | +---------+---+---+---+
| | | Cube | ✓ | ✓ | |
+------------+----+---------+---+---+---+
| | 2D | Simplex | ✓ | ✓ | ✓ |
| | +---------+---+---+---+
| | | Cube | | | |
| Adapt. +----+---------+---+---+---+
| | 3D | Simplex | ✓ | ✓ | ✓ |
| | +---------+---+---+---+
| | | Cube | | | |
+------------+----+---------+---+---+---+
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 | 0 | 1 | 2 | 3 |
+============+====+=========+===+===+===+===+
| | 2D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+---+
| | | Cube | ✓ | ✓ | ✓ | ✓ |
| Non-adapt. +----+---------+---+---+---+---+
| | 3D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+---+
| | | Cube | ✓ | ✓ | ✓ | |
+------------+----+---------+---+---+---+---+
| | 2D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+---+
| | | Cube | ✗ | | | |
| Adapt. +----+---------+---+---+---+---+
| | 3D | Simplex | ✗ | ✓ | ✓ | ✓ |
| | +---------+---+---+---+---+
| | | 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
-----
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>`.
......@@ -60,9 +60,13 @@ They are controlled by the ``initial.type`` key and available for every model.
.. tip::
The expression for a gaussian pulse of solute concentration centered at
:math:`\mathbf{p} = [0.5, 0.5]^T \, \text{m}` is::
:math:`\vec{p} = [0.5, 0.5]^T \, \mathrm{m}` and variance of
:math:`\sigma^2 = \left( 0.1 \, \mathrm{m} \right)^2` is::
initial.equation = exp(-sqrt((x-0.5)^2+(y-0.5)^2)/(4.*0.002))/(4*pi*0.002)^(2/dim).
initial.equation = <m> * exp(-((x-0.5)^2+(y-0.5)^2)/(2.*0.1^2)) / (2*pi*0.1^2)
where ``<m>`` is the total solute mass of the pulse
:math:`m_s \, [\text{kg}]`.
.. object:: Dataset
......@@ -124,7 +128,12 @@ Initial condition tranformations for the Transport solver.
* ``quantity = soluteConcentration``
The input data is directly interpreted as solute concentration,
<<<<<<< HEAD
:math:`f = c_w [\text{kg}/\text{m}^3]`.
=======
:math:`f = c_w [\mathrm{kg}/\mathrm{m}^d]`, where :math:`d` indicates the
spatial dimensions of the grid.
>>>>>>> master
.. _H5: https://www.h5py.org/
.. _muparser: http://beltoforion.de/article.php?a=muparser&p=features
......@@ -15,7 +15,7 @@
#include <dune/pdelab/localoperator/defaultimp.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 Dorie {
......
add_library(dorie-richards STATIC
sim_yasp_2_0.cc
sim_yasp_2_1.cc
sim_yasp_2_2.cc
sim_ug_2_1.cc
sim_yasp_2_2.cc
sim_yasp_2_3.cc
sim_yasp_3_1.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_3.cc
sim_ug_2_3.cc
sim_ug_3_1.cc
sim_ug_3_2.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
......@@ -133,7 +133,8 @@ inline auto read_experimental_operator_settings(
* enough to support p-adaptivity. (Another likely candidate would be
* 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>
class RichardsDGSpatialOperator
......@@ -937,6 +938,7 @@ public:
* @brief DG local operator for the temporal derivative of the Richards equation
*
* @ingroup LocalOperators
* @ingroup RichardsModel
*/
template<typename Traits, typename Parameter, typename FEM, bool adjoint>
class RichardsDGTemporalOperator
......
This diff is collapsed.
......@@ -56,21 +56,32 @@ RichardsSimulation<Traits>::RichardsSimulation (
finitial = FlowInitialFactory::create(inifile, gv, fparam, this->_log);
// --- Local Operators ---
if constexpr (order>0)
{
this->_log->debug("Setting up local grid operators: DG method");
#ifdef EXPERIMENTAL_DG_FEATURES
// read experimental settings from inifile
namespace OP = Dune::Dorie::Operator;
const auto settings = OP::read_experimental_operator_settings(inifile);
const auto method = std::get<OP::RichardsDGMethod::Type>(settings);
const auto upwinding = std::get<OP::RichardsDGUpwinding::Type>(settings);
const auto weights = std::get<OP::RichardsDGWeights::Type>(settings);
slop = std::make_unique<SLOP>(inifile, fparam, fboundary, fsource,
method, upwinding, weights);
// read experimental settings from inifile
namespace OP = Dune::Dorie::Operator;
const auto settings = OP::read_experimental_operator_settings(inifile);
const auto method = std::get<OP::RichardsDGMethod::Type>(settings);
const auto upwinding = std::get<OP::RichardsDGUpwinding::Type>(settings);
const auto weights = std::get<OP::RichardsDGWeights::Type>(settings);
slop = std::make_unique<SLOP>(inifile, fparam, fboundary, fsource,
method, upwinding, weights);
#else
slop = std::make_unique<SLOP>(inifile, fparam, fboundary, fsource);
slop = std::make_unique<SLOP>(inifile, fparam, fboundary, fsource);
#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>(
inifile, *fboundary, this->_log);
......@@ -277,22 +288,30 @@ void RichardsSimulation<Traits>::write_data () const
if (inifile.get<bool>("output.vertexData")) {
vtkwriter->addVertexData(head,"head");
vtkwriter->addVertexData(wflux,"flux");
vtkwriter->addVertexData(cond,"K_0");
vtkwriter->addVertexData(wc,"theta_w");
vtkwriter->addVertexData(sat,"Theta");
if constexpr (order > 0) {
vtkwriter->addVertexData(wflux, "flux");
}
if constexpr (enable_rt_engine)
if (enable_fluxrc) {
auto wfluxr = get_water_flux_reconstructed();
auto RT_name = "flux_RT" + std::to_string(flux_order);
vtkwriter->addVertexData(wfluxr,RT_name);
}
} else {
}
// cell data
else {
vtkwriter->addCellData(head,"head");
vtkwriter->addCellData(wflux,"flux");
vtkwriter->addCellData(cond,"K_0");
vtkwriter->addCellData(wc,"theta_w");
vtkwriter->addCellData(sat,"Theta");
if constexpr (order > 0) {
vtkwriter->addCellData(wflux, "flux");
}
if constexpr (enable_rt_engine)
if (enable_fluxrc) {
auto wfluxr = get_water_flux_reconstructed();
......
......@@ -31,7 +31,8 @@
#include <dune/dorie/model/richards/flow_parameters.hh>
#include <dune/dorie/model/richards/flow_boundary.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 Dorie{
......@@ -59,8 +60,12 @@ struct RichardsSimulationTraits : public BaseTraits
using Grid = typename BaseTraits::Grid;
using GV = typename BaseTraits::GV;
/// GFS Helper
using GFSHelper = Dune::Dorie::GridFunctionSpaceHelper<GV,RF,order,BaseTraits::GridGeometryType>;
/// GFS Helper
using GFSHelper =
std::conditional_t<order==0,
Dune::Dorie::LinearSolverGridFunctionSpaceHelper<GV,RF,BaseTraits::GridGeometryType>,
Dune::Dorie::GridFunctionSpaceHelper<GV,RF,order,BaseTraits::GridGeometryType>>;
/// Problem GFS
using GFS = typename GFSHelper::Type;
/// GFS Constraints Container
......@@ -90,9 +95,17 @@ struct RichardsSimulationTraits : public BaseTraits
= Dune::Dorie::RichardsInitialConditionFactory<
BaseTraits, FlowParameters>;
/// 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
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
using CalculationController = Dune::Dorie::CalculationController<RF,FlowBoundary>;
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,0>>;
template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,0>>;
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,1>>; +
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,2>>; +
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<2>,Geo::cube>,3,3>>; +
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,0>>;
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,0>>; *
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,1>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,1>>; *
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,2>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,2>>; *
......
......@@ -9,6 +9,7 @@
namespace Dune{
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>,2,3>>; +
// template class RichardsTransportCouplingSimulation<RichardsTransportCouplingSimulationTraits<BaseTraits<YaspGrid<3>,Geo::cube>,3,3>>; *
......
......@@ -142,6 +142,11 @@ int main(int argc, char** argv)
else{ // no adaptivity
Dune::Dorie::GridCreator<Dune::YaspGrid<2>> grid_creator(inifile, helper);
switch(FEorder){
case 0:{
Sim<Cube<2,0>> sim(richards_config, grid_creator, helper);
sim.run();
break;
}
case 1:{
Sim<Cube<2,1>> sim(richards_config, grid_creator, helper);
sim.run();
......@@ -222,6 +227,11 @@ int main(int argc, char** argv)
else{ // no adaptivity
Dune::Dorie::GridCreator<Dune::YaspGrid<3>> grid_creator(inifile, helper);
switch(FEorder){
case 0:{
Sim<Cube<3,0>> sim(richards_config, grid_creator, helper);
sim.run();
break;
}
case 1:{
Sim<Cube<3,1>> sim(richards_config, grid_creator, helper);
sim.run();
......
......@@ -177,6 +177,12 @@ using Cube = Dune::Dorie::RichardsTransportCouplingSimulationTraits<Dune::Dorie:
switch(FEorder_transport){
case 0:{
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:{
Sim<Cube<2,1,0>> sim(richards_config,transport_config,grid_creator,helper);
sim.set_policy(adapt_policy);
......@@ -292,6 +298,12 @@ using Cube = Dune::Dorie::RichardsTransportCouplingSimulationTraits<Dune::Dorie:
switch(FEorder_transport){
case 0:{
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:{
Sim<Cube<3,1,0>> sim(richards_config,transport_config,grid_creator,helper);
sim.set_policy(adapt_policy);
......
......@@ -22,10 +22,12 @@ def evaluate(iniinfo,runtime):
initial_head = float(iniinfo["_ode.headLower"])
extensions = list(map(float,iniinfo["grid.extensions"].split()))
do_flux_rt = iniinfo["richards.fluxReconstruction.enable"]
fe_order = int(iniinfo["richards.numerics.FEorder"])
do_flux_rt = iniinfo["richards.fluxReconstruction.enable"]
do_flux_grad = fe_order > 0
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
param_data = read_yml(iniinfo["richards.parameters.file"])
......@@ -119,19 +121,26 @@ def evaluate(iniinfo,runtime):
plt.savefig("{}/head_residual.png".format(iniinfo["richards.output.outputPath"]))
plt.close()
flux = data["flux"][iy,:]
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]
print("flux L2 errors: {:.2e}, {:.2e}, {:.2e}".format(*l2_flux))
# 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)
plt.figure()
plt.plot(y,res_flux)
plt.savefig("{}/flux_residual.png".format(iniinfo["richards.output.outputPath"]))
plt.close()
# Check flux from gradient
if do_flux_grad:
flux = data["flux"][iy,:]
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]
print("flux L2 errors: {:.2e}, {:.2e}, {:.2e}".format(*l2_flux))
plt.figure()
plt.plot(y,res_flux)
plt.savefig("{}/flux_residual.png".format(iniinfo["richards.output.outputPath"]))
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:
flux_rt = data[flux_rt_key][iy,:]
res_flux_rt = flux_rt - np.array([0.,influx,0.])[np.newaxis,:]
......@@ -145,9 +154,6 @@ def evaluate(iniinfo,runtime):
flux_rt_tol = 1e-13 if not "_ode.flux_rt_abstol" in iniinfo else float(iniinfo["_ode.flux_rt_abstol"])
return bool(l2_head < head_tol) \
and all([l < flux_tol for l in l2_flux]) \
and all([l < flux_rt_tol for l in l2_flux_rt])
passed = passed and all([l < flux_rt_tol for l in l2_flux_rt])
# no flux reconstruction
return bool(l2_head < head_tol) and all([l < flux_tol for l in l2_flux])
return passed
......@@ -23,6 +23,9 @@ def create_and_write_datasets(args):
grid_test_3d_bc_back = np.full((10, 10), 2, dtype=np.int_)
grid_test_3d_bc_back[5:, ...] = 3
ode_layered_320 = np.zeros((320, 1), dtype=np.int_)
ode_layered_320[160:, ...] = 1
ode_layered_160 = np.zeros((160, 1), dtype=np.int_)
ode_layered_160[80:, ...] = 1
......@@ -52,6 +55,7 @@ def create_and_write_datasets(args):
f.create_dataset("grid_test_3d/boundary_front", data=grid_test_3d_bc_front)
f.create_dataset("grid_test_3d/boundary_back", data=grid_test_3d_bc_back)
f.create_dataset("ode_layered_320", data=ode_layered_320)
f.create_dataset("ode_layered_160", data=ode_layered_160)
f.create_dataset("ode_layered_40", data=ode_layered_40)
f.create_dataset("ode_layered_20", data=ode_layered_20)
......
include ${CMAKE_BINARY_DIR}/doc/default_files/config.ini
__name = ode_homogeneous_sand
_test_command = run
_asset_path = "${CMAKE_CURRENT_LIST_DIR}"
_evaluation = ode
_order = 0, 1, 2, 3 | expand prec
__name = ode_homogeneous_sand_k{_order}
[grid]
gridType = rectangular
initialLevel = 0
cells = 1 160, 1 40, 1 20 | expand prec
cells = 1 320, 1 160, 1 40, 1 20 | expand prec
[richards]
output.fileName = ode_homogeneous_sand | unique
output.outputPath = ode_homogeneous_sand | unique
output.fileName = {__name}
output.outputPath = {__name}
output.vertexData = false
initial.type = analytic
......@@ -31,11 +33,12 @@ NewtonParameters.AbsoluteLimit = 1E-10
NewtonParameters.Reduction = 1E-10
numerics.penaltyFactor = 10
numerics.FEorder = 1, 2, 3 | expand prec
numerics.FEorder = 0, 1, 2, 3 | expand prec
[_ode]
flux = -5.55e-6
headLower = 0.
head_abstol = 3E-6, 2E-8, 6E-8 | expand prec
flux_abstol = 5E-11, 1E-9, 3E-12 | expand prec
flux = -5.55e-6
head_abstol = 3E-4, 3E-6, 2E-8, 6E-8 | expand prec
flux_abstol = 1E100, 5E-11, 1E-9, 3E-12 | expand prec
flux_rt_abstol = 4E-14
\ No newline at end of file
include ${CMAKE_BINARY_DIR}/doc/default_files/config.ini
__name = ode_homogeneous_silt
_test_command = run
_asset_path = "${CMAKE_CURRENT_LIST_DIR}"
_evaluation = ode
_order = 0, 1, 2, 3 | expand prec
__name = ode_homogeneous_silt_k{_order}
[grid]
gridType = rectangular
initialLevel = 0
cells = 1 160, 1 40, 1 20 | expand prec
cells = 1 320, 1 160, 1 40, 1 20 | expand prec
[grid.mapping]
file = none
......@@ -16,8 +18,8 @@ volume = 1
[richards]
output.fileName = ode_homogeneous_silt | unique
output.outputPath = ode_homogeneous_silt | unique
output.fileName = {__name}
output.outputPath = {__name}
output.vertexData = false
initial.type = analytic
......@@ -35,11 +37,12 @@ NewtonParameters.AbsoluteLimit = 1E-10
NewtonParameters.Reduction = 1E-10
numerics.penaltyFactor = 10
numerics.FEorder = 1, 2, 3 | expand prec
numerics.FEorder = 0, 1, 2, 3 | expand prec
[_ode]
flux = -5.55e-6
headLower = 0.
head_abstol = 6E-6, 4E-6, 9E-6 | expand prec
flux_abstol = 2E-9, 2E-8, 3E-9 | expand prec
flux = -5.55e-6
head_abstol = 7E-5, 6E-6, 4E-6, 9E-6 | expand prec
flux_abstol = 1E100, 2E-9, 2E-8, 3E-9 | expand prec
flux_rt_abstol = 4E-14
include ${CMAKE_BINARY_DIR}/doc/default_files/config.ini
__name = ode_layered
_test_command = run
_asset_path = "${CMAKE_CURRENT_LIST_DIR}"
_evaluation = ode
_order = 0, 1, 2, 3 | expand prec
__name = ode_layered_k{_order}
[grid]
gridType = rectangular
initialLevel = 0
cells = 1 160, 1 40, 1 20 | expand prec
cells = 1 320, 1 160, 1 40, 1 20 | expand prec
[grid.mapping]
file = "{_asset_path}/maps/cell_ids.h5"
volume = ode_layered_160, ode_layered_40, ode_layered_20 | expand prec
volume = ode_layered_320, ode_layered_160, ode_layered_40, ode_layered_20 | expand prec
[richards]
output.fileName = ode_layered | unique
output.outputPath = ode_layered | unique
output.fileName = {__name}
output.outputPath = {__name}
output.vertexData = false
initial.type = analytic
......@@ -35,11 +37,12 @@ NewtonParameters.AbsoluteLimit = 1E-10
NewtonParameters.Reduction = 1E-10
numerics.penaltyFactor = 10
numerics.FEorder = 1, 2, 3 | expand prec
numerics.FEorder = {_order}
[_ode]
flux = -5.55e-6
headLower = 0.
head_abstol = 3E-5, 4E-8, 4E-6 | expand prec
flux_abstol = 5E-10, 4E-9, 5E-11 | expand prec
flux = -5.55e-6
head_abstol = 1E-3, 3E-5, 4E-8, 4E-6 | expand prec
flux_abstol = 1E100, 5E-10, 4E-9, 5E-11 | expand prec
flux_rt_abstol = 4E-14
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment