Commit b391efed authored by Kilian Weishaupt's avatar Kilian Weishaupt Committed by Timo Koch
Browse files

[test][md][stokesdarcy] Clean-up 1p2c_1p2c

* use only one executable
parent a1e232e1
add_subdirectory("verticalflow")
add_subdirectory("horizontalflow")
add_subdirectory("diffusionlawcomparison")
add_input_file_links()
add_executable(test_md_boundary_darcy1p2c_stokes1p2c EXCLUDE_FROM_ALL main.cc)
dune_add_test(NAME test_md_boundary_darcy1p2c_stokes1p2c_horizontal
LABELS multidomain freeflow 1pnc
TARGET test_md_boundary_darcy1p2c_stokes1p2c
CMAKE_GUARD HAVE_UMFPACK
COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py
CMD_ARGS --script fuzzy
--files ${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_stokes-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_stokes-00020.vtu
${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_darcy-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_darcy-00020.vtu
--command "${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c params_horizontalflow.input
-Vtk.OutputName test_md_boundary_darcy1p2c_stokes1p2c_horizontal")
dune_add_test(NAME test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion
LABELS multidomain freeflow 1pnc
TARGET test_md_boundary_darcy1p2c_stokes1p2c
CMAKE_GUARD HAVE_UMFPACK
COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py
CMD_ARGS --script fuzzy
--zeroThreshold {"velocity_liq \(m/s\)":1e-20}
--files ${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_stokes-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_stokes-00003.vtu
${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_darcy-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_darcy-00003.vtu
--command "${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c params_verticalflow_diffusion.input
-Vtk.OutputName test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion")
dune_add_test(NAME test_md_boundary_darcy1p2c_stokes1p2c_vertical_advection
LABELS multidomain freeflow 1pnc
TARGET test_md_boundary_darcy1p2c_stokes1p2c
CMAKE_GUARD HAVE_UMFPACK
COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py
CMD_ARGS --script fuzzy
--zeroThreshold {"velocity_liq \(m/s\)":1e-15}
--files ${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_vertical_advection_stokes-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_vertical_stokes-00030.vtu
${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_vertical_advection_darcy-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_vertical_darcy-00030.vtu
--command "${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c params_verticalflow.input
-Vtk.OutputName test_md_boundary_darcy1p2c_stokes1p2c_vertical")
add_input_file_links()
dune_add_test(NAME test_md_boundary_darcy1p2c_stokes1p2c_horizontal
LABELS multidomain freeflow 1pnc
SOURCES main.cc
CMAKE_GUARD HAVE_UMFPACK
COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py
CMD_ARGS --script fuzzy
--files ${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_stokes-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_stokes-00020.vtu
${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_darcy-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_horizontal_darcy-00020.vtu
--command "${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_horizontal params.input
-Vtk.OutputName test_md_boundary_darcy1p2c_stokes1p2c_horizontal")
......@@ -25,6 +25,7 @@
#include <ctime>
#include <iostream>
#include <fstream>
#include <dune/common/parallel/mpihelper.hh>
#include <dune/common/timer.hh>
......@@ -32,7 +33,9 @@
#include <dumux/common/properties.hh>
#include <dumux/common/parameters.hh>
#include <dumux/common/partial.hh>
#include <dumux/common/dumuxmessage.hh>
#include <dumux/common/geometry/diameter.hh>
#include <dumux/linear/seqsolverbackend.hh>
#include <dumux/assembly/fvassembler.hh>
#include <dumux/assembly/diffmethod.hh>
......@@ -137,17 +140,11 @@ int main(int argc, char** argv) try
auto dt = getParam<Scalar>("TimeLoop.DtInitial");
// instantiate time loop
auto timeLoop = std::make_shared<CheckPointTimeLoop<Scalar>>(0, dt, tEnd);
auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0, dt, tEnd);
timeLoop->setMaxTimeStepSize(maxDt);
// control the injection period
const Scalar injectionBegin = getParam<Scalar>("Stokes.Problem.InjectionBegin");
const Scalar injectionEnd = getParam<Scalar>("Stokes.Problem.InjectionEnd");
if(injectionBegin > 0.0)
timeLoop->setCheckPoint({injectionBegin, injectionEnd});
else
timeLoop->setCheckPoint({injectionEnd});
stokesProblem->setTimeLoop(timeLoop);
darcyProblem->setTimeLoop(timeLoop);
// the solution vector
Traits::SolutionVector sol;
......@@ -155,20 +152,12 @@ int main(int argc, char** argv) try
sol[stokesFaceIdx].resize(stokesFvGridGeometry->numFaceDofs());
sol[darcyIdx].resize(darcyFvGridGeometry->numDofs());
const auto& cellCenterSol = sol[stokesCellCenterIdx];
const auto& faceSol = sol[stokesFaceIdx];
// get a solution vector storing references to the two Stokes solution vectors
auto stokesSol = partial(sol, stokesCellCenterIdx, stokesFaceIdx);
// apply initial solution for instationary problems
GetPropType<StokesTypeTag, Properties::SolutionVector> stokesSol;
std::get<0>(stokesSol) = cellCenterSol;
std::get<1>(stokesSol) = faceSol;
stokesProblem->applyInitialSolution(stokesSol);
auto solStokesOld = stokesSol;
sol[stokesCellCenterIdx] = stokesSol[stokesCellCenterIdx];
sol[stokesFaceIdx] = stokesSol[stokesFaceIdx];
darcyProblem->applyInitialSolution(sol[darcyIdx]);
auto solDarcyOld = sol[darcyIdx];
auto solOld = sol;
......@@ -183,7 +172,7 @@ int main(int argc, char** argv) try
darcyGridVariables->init(sol[darcyIdx]);
// intialize the vtk output module
StaggeredVtkOutputModule<StokesGridVariables, GetPropType<StokesTypeTag, Properties::SolutionVector>> stokesVtkWriter(*stokesGridVariables, stokesSol, stokesProblem->name());
StaggeredVtkOutputModule<StokesGridVariables, decltype(stokesSol)> stokesVtkWriter(*stokesGridVariables, stokesSol, stokesProblem->name());
GetPropType<StokesTypeTag, Properties::IOFields>::initOutputModule(stokesVtkWriter);
stokesVtkWriter.write(0.0);
......@@ -213,20 +202,12 @@ int main(int argc, char** argv) try
using NewtonSolver = MultiDomainNewtonSolver<Assembler, LinearSolver, CouplingManager>;
NewtonSolver nonLinearSolver(assembler, linearSolver, couplingManager);
constexpr auto eps = 1e-6;
// time loop
timeLoop->start(); do
{
// set previous solution for storage evaluations
assembler->setPreviousSolution(solOld);
if(timeLoop->time() > injectionBegin - eps && timeLoop->time() < injectionEnd + eps)
stokesProblem->setInjectionState(true);
else
stokesProblem->setInjectionState(false);
// solve the non-linear system with time step control
nonLinearSolver.solve(sol, *timeLoop);
......
......@@ -14,15 +14,12 @@ Cells = 20 20
[Stokes.Problem]
Name = stokes
Velocity = 1e-6
Pressure = 1.0e5
InletMoleFraction = 1e-3
InjectionBegin = 0
InjectionEnd = 3e6
[Darcy.Problem]
Name = darcy
Pressure = 1.0e5
InitialMoleFraction = 0.0
[SpatialParams]
AlphaBeaversJoseph = 1.0
......
......@@ -31,7 +31,7 @@
#include <dumux/porousmediumflow/1pnc/model.hh>
#include <dumux/porousmediumflow/problem.hh>
#include "./../spatialparams.hh"
#include "spatialparams.hh"
#include <dumux/material/fluidsystems/1padapter.hh>
#include <dumux/material/fluidsystems/h2oair.hh>
......@@ -93,42 +93,32 @@ template <class TypeTag>
class DarcySubProblem : public PorousMediumFlowProblem<TypeTag>
{
using ParentType = PorousMediumFlowProblem<TypeTag>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
using GridView = typename FVGridGeometry::GridView;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>;
using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
using FVElementGeometry = typename GetPropType<TypeTag, Properties::FVGridGeometry>::LocalView;
using SubControlVolume = typename FVElementGeometry::SubControlVolume;
using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
// copy some indices for convenience
using Element = typename GridView::template Codim<0>::Entity;
using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
enum {
// grid and world dimension
dim = GridView::dimension,
dimworld = GridView::dimensionworld,
// primary variable indices
conti0EqIdx = Indices::conti0EqIdx,
pressureIdx = Indices::pressureIdx,
};
using Element = typename GridView::template Codim<0>::Entity;
using GlobalPosition = Dune::FieldVector<Scalar, dimworld>;
using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
using TimeLoopPtr = std::shared_ptr<TimeLoop<Scalar>>;
public:
DarcySubProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry,
std::shared_ptr<CouplingManager> couplingManager)
: ParentType(fvGridGeometry, "Darcy"), eps_(1e-7), couplingManager_(couplingManager)
{
pressure_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.Pressure");
initialMoleFraction_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.InitialMoleFraction");
problemName_ = getParam<std::string>("Vtk.OutputName") + "_" + getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name");
// determine whether to simulate a vertical or horizontal flow configuration
verticalFlow_ = problemName_.find("vertical") != std::string::npos;
}
/*!
......@@ -139,26 +129,6 @@ public:
return problemName_;
}
/*!
* \name Simulation steering
*/
// \{
/*!
* \brief Returns true if a restart file should be written to
* disk.
*/
bool shouldWriteRestartFile() const
{ return false; }
/*!
* \name Problem parameters
*/
// \{
bool shouldWriteOutput() const // define output
{ return true; }
/*!
* \brief Return the temperature within the domain in [K].
*
......@@ -187,6 +157,46 @@ public:
if (couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf))
values.setAllCouplingNeumann();
if (verticalFlow_)
{
if (onLowerBoundary_(scvf.center()))
values.setAllDirichlet();
}
return values;
}
/*!
* \brief Evaluate the boundary conditions for a Dirichlet control volume.
*
* \param element The element for which the Dirichlet boundary condition is set
* \param scvf The boundary subcontrolvolumeface
*
*/
PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const
{
PrimaryVariables values(0.0);
values = initial(element);
if (verticalFlow_)
{
// Check if this a pure diffusion problem.
static const bool isDiffusionProblem = problemName_.find("diffusion") != std::string::npos;
Scalar bottomMoleFraction = 0.0;
if (isDiffusionProblem)
{
// For the diffusion problem, change the top mole fraction after some time
// in order to revert the concentration gradient.
if (time() >= 1e10)
bottomMoleFraction = 1e-3;
}
if(onLowerBoundary_(scvf.center()))
values[Indices::conti0EqIdx + 1] = bottomMoleFraction;
}
return values;
}
......@@ -249,8 +259,7 @@ public:
PrimaryVariables initial(const Element &element) const
{
PrimaryVariables values(0.0);
values[pressureIdx] = pressure_;
values[conti0EqIdx + 1] = initialMoleFraction_;
values[Indices::pressureIdx] = 1e5;
return values;
}
......@@ -261,6 +270,18 @@ public:
const CouplingManager& couplingManager() const
{ return *couplingManager_; }
/*!
* \brief Sets the time loop pointer
*/
void setTimeLoop(TimeLoopPtr timeLoop)
{ timeLoop_ = timeLoop; }
/*!
* \brief Returns the time
*/
Scalar time() const
{ return timeLoop_->time(); }
private:
bool onLeftBoundary_(const GlobalPosition &globalPos) const
{ return globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_; }
......@@ -275,10 +296,10 @@ private:
{ return globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_; }
Scalar eps_;
Scalar pressure_;
Scalar initialMoleFraction_;
std::string problemName_;
bool verticalFlow_;
std::shared_ptr<CouplingManager> couplingManager_;
TimeLoopPtr timeLoop_;
};
} //end namespace
......
......@@ -91,7 +91,6 @@ class StokesSubProblem : public NavierStokesProblem<TypeTag>
using GridView = GetPropType<TypeTag, Properties::GridView>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
using FVGridGeometry = GetPropType<TypeTag, Properties::FVGridGeometry>;
using FVElementGeometry = typename FVGridGeometry::LocalView;
......@@ -103,15 +102,16 @@ class StokesSubProblem : public NavierStokesProblem<TypeTag>
using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
using TimeLoopPtr = std::shared_ptr<TimeLoop<Scalar>>;
public:
StokesSubProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry, std::shared_ptr<CouplingManager> couplingManager)
: ParentType(fvGridGeometry, "Stokes"), eps_(1e-6), injectionState_(false), couplingManager_(couplingManager)
: ParentType(fvGridGeometry, "Stokes"), eps_(1e-6), couplingManager_(couplingManager)
{
inletVelocity_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.Velocity");
pressure_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.Pressure");
inletMoleFraction_ = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.InletMoleFraction");
problemName_ = getParam<std::string>("Vtk.OutputName") + "_" + getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name");
// determine whether to simulate a vertical or horizontal flow configuration
verticalFlow_ = problemName_.find("vertical") != std::string::npos;
}
/*!
......@@ -127,9 +127,6 @@ public:
*/
// \{
bool shouldWriteRestartFile() const
{ return false; }
/*!
* \brief Return the temperature within the domain in [K].
*
......@@ -166,23 +163,46 @@ public:
const auto& globalPos = scvf.dofPosition();
if(onLeftBoundary_(globalPos))
{
values.setDirichlet(Indices::conti0EqIdx + 1);
values.setDirichlet(Indices::velocityXIdx);
values.setDirichlet(Indices::velocityYIdx);
}
else if(onRightBoundary_(globalPos))
if (verticalFlow_)
{
values.setDirichlet(Indices::pressureIdx);
values.setOutflow(Indices::conti0EqIdx + 1);
// inflow
if(onUpperBoundary_(globalPos))
{
values.setDirichlet(Indices::velocityXIdx);
values.setDirichlet(Indices::velocityYIdx);
values.setDirichlet(Indices::conti0EqIdx + 1);
}
// left/right wall
if (onRightBoundary_(globalPos) || (onLeftBoundary_(globalPos)))
{
values.setDirichlet(Indices::velocityXIdx);
values.setDirichlet(Indices::velocityYIdx);
values.setNeumann(Indices::conti0EqIdx);
values.setNeumann(Indices::conti0EqIdx + 1);
}
}
else
else // horizontal flow
{
values.setDirichlet(Indices::velocityXIdx);
values.setDirichlet(Indices::velocityYIdx);
values.setNeumann(Indices::conti0EqIdx);
values.setNeumann(Indices::conti0EqIdx + 1);
if (onLeftBoundary_(globalPos))
{
values.setDirichlet(Indices::conti0EqIdx + 1);
values.setDirichlet(Indices::velocityXIdx);
values.setDirichlet(Indices::velocityYIdx);
}
else if (onRightBoundary_(globalPos))
{
values.setDirichlet(Indices::pressureIdx);
values.setOutflow(Indices::conti0EqIdx + 1);
}
else
{
values.setDirichlet(Indices::velocityXIdx);
values.setDirichlet(Indices::velocityYIdx);
values.setNeumann(Indices::conti0EqIdx);
values.setNeumann(Indices::conti0EqIdx + 1);
}
}
if(couplingManager().isCoupledEntity(CouplingManager::stokesIdx, scvf))
......@@ -207,9 +227,37 @@ public:
PrimaryVariables values(0.0);
values = initialAtPos(globalPos);
// start injecting after the velocity field had enough time to initialize
if(globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_ && isInjectionPeriod())
values[Indices::conti0EqIdx + 1] = inletMoleFraction_;
if (verticalFlow_)
{
// Check if this a pure diffusion problem.
static const bool isDiffusionProblem = problemName_.find("diffusion") != std::string::npos;
Scalar topMoleFraction = 1e-3;
if (isDiffusionProblem)
{
// For the diffusion problem, change the top mole fraction after some time
// in order to revert the concentration gradient.
if (time() >= 1e10)
topMoleFraction = 0.0;
}
else // advection problem
{
// reverse the flow direction after some time for the advection problem
if (time() >= 3e5)
values[Indices::velocityYIdx] *= -1.0;
}
if(globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_)
values[Indices::conti0EqIdx + 1] = topMoleFraction;
}
else // horizontal flow
{
static const Scalar inletMoleFraction = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.InletMoleFraction");
if(globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_)
values[Indices::conti0EqIdx + 1] = inletMoleFraction;
}
return values;
}
......@@ -259,14 +307,25 @@ public:
*
* \param globalPos The global position
*/
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const
{
PrimaryVariables values(0.0);
values[Indices::pressureIdx] = pressure_;
values[Indices::velocityXIdx] = inletVelocity_ * (globalPos[1] - this->fvGridGeometry().bBoxMin()[1])
* (this->fvGridGeometry().bBoxMax()[1] - globalPos[1])
/ (0.25 * (this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1])
* (this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1]));
values[Indices::pressureIdx] = 1e5;
static const Scalar vMax = getParamFromGroup<Scalar>(this->paramGroup(), "Problem.Velocity", 0.0);
auto parabolicProfile = [&](const GlobalPosition& globalPos, int coord)
{
return vMax * (globalPos[coord] - this->fvGridGeometry().bBoxMin()[coord])
* (this->fvGridGeometry().bBoxMax()[coord] - globalPos[coord])
/ (0.25 * (this->fvGridGeometry().bBoxMax()[coord] - this->fvGridGeometry().bBoxMin()[coord])
* (this->fvGridGeometry().bBoxMax()[coord] - this->fvGridGeometry().bBoxMin()[coord]));
};
if (verticalFlow_)
values[Indices::velocityYIdx] = parabolicProfile(globalPos, 0);
else // horizontal flow
values[Indices::velocityXIdx] = parabolicProfile(globalPos, 1);
return values;
}
......@@ -287,15 +346,17 @@ public:
return 1.0;
}
void setInjectionState(const bool yesNo)
{
injectionState_ = yesNo;
}
/*!
* \brief Sets the time loop pointer
*/
void setTimeLoop(TimeLoopPtr timeLoop)
{ timeLoop_ = timeLoop; }
bool isInjectionPeriod() const
{
return injectionState_;
}
/*!
* \brief Returns the time
*/
Scalar time() const
{ return timeLoop_->time(); }
// \}
......@@ -313,12 +374,10 @@ private:
{ return globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_; }
Scalar eps_;
Scalar inletVelocity_;
Scalar pressure_;
Scalar inletMoleFraction_;
bool injectionState_;
bool verticalFlow_;
std::string problemName_;
std::shared_ptr<CouplingManager> couplingManager_;
TimeLoopPtr timeLoop_;
};
} //end namespace
......
add_input_file_links()
add_executable(test_md_boundary_darcy1p2c_stokes1p2c_vertical EXCLUDE_FROM_ALL main.cc)
dune_add_test(NAME test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion
LABELS multidomain freeflow 1pnc
TARGET test_md_boundary_darcy1p2c_stokes1p2c_vertical
CMAKE_GUARD HAVE_UMFPACK
COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py
CMD_ARGS --script fuzzy
--zeroThreshold {"velocity_liq \(m/s\)":1e-20}
--files ${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_stokes-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_stokes-00003.vtu
${CMAKE_SOURCE_DIR}/test/references/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_darcy-reference.vtu
${CMAKE_CURRENT_BINARY_DIR}/test_md_boundary_darcy1p2c_stokes1p2c_vertical_diffusion_darcy-00003.vtu