28#ifndef EWOMS_FINGER_PROBLEM_HH
29#define EWOMS_FINGER_PROBLEM_HH
32#include <dune/alugrid/grid.hh>
35#include <dune/common/fmatrix.hh>
36#include <dune/common/fvector.hh>
37#include <dune/common/version.hh>
39#include <dune/grid/utility/persistentcontainer.hh>
41#include <opm/material/components/Air.hpp>
42#include <opm/material/components/SimpleH2O.hpp>
44#include <opm/material/fluidmatrixinteractions/EffToAbsLaw.hpp>
45#include <opm/material/fluidmatrixinteractions/LinearMaterial.hpp>
46#include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
47#include <opm/material/fluidmatrixinteractions/ParkerLenhard.hpp>
48#include <opm/material/fluidmatrixinteractions/RegularizedVanGenuchten.hpp>
50#include <opm/material/fluidstates/ImmiscibleFluidState.hpp>
52#include <opm/material/fluidsystems/TwoPhaseImmiscibleFluidSystem.hpp>
66template <
class TypeTag>
80template<
class TypeTag>
81struct Grid<TypeTag, TTag::FingerBaseProblem>
82{
using type = Dune::ALUGrid<2,
85 Dune::nonconforming>; };
89template<
class TypeTag>
93template<
class TypeTag>
100 using type = Opm::LiquidPhase<Scalar, Opm::SimpleH2O<Scalar> >;
104template<
class TypeTag>
111 using type = Opm::GasPhase<Scalar, Opm::Air<Scalar> >;
115template<
class TypeTag>
121 FluidSystem::wettingPhaseIdx,
122 FluidSystem::nonWettingPhaseIdx>;
130template<
class TypeTag>
131struct EnableConstraints<TypeTag, TTag::FingerBaseProblem> {
static constexpr int value =
true; };
137template<
class Scalar>
159template <
class TypeTag>
178 numPhases = FluidSystem::numPhases,
181 wettingPhaseIdx = FluidSystem::wettingPhaseIdx,
182 nonWettingPhaseIdx = FluidSystem::nonWettingPhaseIdx,
185 contiWettingEqIdx = Indices::conti0EqIdx + wettingPhaseIdx,
188 dim = GridView::dimension,
189 dimWorld = GridView::dimensionworld
194 enum { codim = Stencil::Entity::codimension };
203 using CoordScalar =
typename GridView::ctype;
204 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
205 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
207 using Grid =
typename GridView :: Grid;
209 using MaterialLawParamsContainer = Dune::PersistentContainer< Grid, std::shared_ptr< MaterialLawParams > > ;
219 : ParentType(simulator),
220 materialParams_( simulator.vanguard().grid(), codim )
242 std::string(
"finger") +
243 "_" + Model::name() +
244 "_" + Model::discretizationName() +
245 (this->model().enableGridAdaptation()?
"_adaptive":
"");
253 ParentType::registerParameters();
255 Parameters::Register<Parameters::InitialWaterSaturation<Scalar>>
256 (
"The initial saturation in the domain [] of the wetting phase");
258 Parameters::SetDefault<Parameters::CellsX>(20);
259 Parameters::SetDefault<Parameters::DomainSizeX<Scalar>>(0.1);
261 if constexpr (
dim > 1) {
262 Parameters::SetDefault<Parameters::CellsY>(70);
263 Parameters::SetDefault<Parameters::DomainSizeY<Scalar>>(0.3);
265 if constexpr (
dim == 3) {
266 Parameters::SetDefault<Parameters::CellsZ>(1);
267 Parameters::SetDefault<Parameters::DomainSizeZ<Scalar>>(0.1);
271 Parameters::SetDefault<Parameters::NumericDifferenceMethod>(+1);
273 Parameters::SetDefault<Parameters::EndTime<Scalar>>(215);
274 Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(10);
275 Parameters::SetDefault<Parameters::EnableGravity>(
true);
283 ParentType::finishInit();
287 temperature_ = 273.15 + 20;
293 micParams_.setVgAlpha(0.0037);
294 micParams_.setVgN(4.7);
295 micParams_.finalize();
297 mdcParams_.setVgAlpha(0.0037);
298 mdcParams_.setVgN(4.7);
299 mdcParams_.finalize();
303 materialParams_.resize();
305 for (
auto it = materialParams_.begin(),
306 end = materialParams_.end(); it != end; ++it ) {
307 std::shared_ptr< MaterialLawParams >& materialParams = *it ;
308 if( ! materialParams )
310 materialParams.reset(
new MaterialLawParams() );
311 materialParams->setMicParams(&micParams_);
312 materialParams->setMdcParams(&mdcParams_);
313 materialParams->setSwr(0.0);
314 materialParams->setSnr(0.1);
315 materialParams->finalize();
320 K_ = this->toDimMatrix_(4.6e-10);
322 setupInitialFluidState_();
337 this->model().globalStorage(storage);
340 if (this->gridView().comm().rank() == 0) {
341 std::cout <<
"Storage: " << storage << std::endl << std::flush;
346 ElementContext elemCtx(this->simulator());
348 for (
const auto& elem : elements(this->gridView())) {
349 elemCtx.updateAll(elem);
350 size_t numDofs = elemCtx.numDof(0);
351 for (
unsigned scvIdx = 0; scvIdx < numDofs; ++scvIdx)
354 const auto& fs = elemCtx.intensiveQuantities(scvIdx, 0).fluidState();
355 ParkerLenhard::update(materialParam, fs);
370 template <
class Context>
372 {
return temperature_; }
377 template <
class Context>
384 template <
class Context>
385 Scalar
porosity(
const Context& ,
unsigned ,
unsigned )
const
391 template <
class Context>
393 unsigned spaceIdx,
unsigned timeIdx)
395 const auto& entity = context.stencil(timeIdx).entity(spaceIdx);
396 assert(materialParams_[entity]);
397 return *materialParams_[entity];
403 template <
class Context>
405 unsigned spaceIdx,
unsigned timeIdx)
const
407 const auto& entity = context.stencil(timeIdx).entity( spaceIdx );
408 assert(materialParams_[entity]);
409 return *materialParams_[entity];
422 template <
class Context>
423 void boundary(BoundaryRateVector& values,
const Context& context,
424 unsigned spaceIdx,
unsigned timeIdx)
const
426 const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
428 if (onLeftBoundary_(pos) || onRightBoundary_(pos) || onLowerBoundary_(pos))
431 assert(onUpperBoundary_(pos));
433 values.setFreeFlow(context, spaceIdx, timeIdx, initialFluidState_);
439 values[contiWettingEqIdx] = -0.001;
453 template <
class Context>
454 void initial(PrimaryVariables& values,
const Context& ,
unsigned ,
unsigned )
const
457 values.assignNaive(initialFluidState_);
463 template <
class Context>
465 unsigned spaceIdx,
unsigned timeIdx)
const
467 const GlobalPosition& pos = context.pos(spaceIdx, timeIdx);
469 if (onUpperBoundary_(pos) && !onInlet_(pos)) {
473 else if (onLowerBoundary_(pos)) {
485 template <
class Context>
486 void source(RateVector& rate,
const Context& ,
487 unsigned ,
unsigned )
const
488 { rate = Scalar(0.0); }
492 bool onLeftBoundary_(
const GlobalPosition& pos)
const
493 {
return pos[0] < this->boundingBoxMin()[0] + eps_; }
495 bool onRightBoundary_(
const GlobalPosition& pos)
const
496 {
return pos[0] > this->boundingBoxMax()[0] - eps_; }
498 bool onLowerBoundary_(
const GlobalPosition& pos)
const
499 {
return pos[1] < this->boundingBoxMin()[1] + eps_; }
501 bool onUpperBoundary_(
const GlobalPosition& pos)
const
502 {
return pos[1] > this->boundingBoxMax()[1] - eps_; }
504 bool onInlet_(
const GlobalPosition& pos)
const
506 Scalar width = this->boundingBoxMax()[0] - this->boundingBoxMin()[0];
507 Scalar lambda = (this->boundingBoxMax()[0] - pos[0]) / width;
509 if (!onUpperBoundary_(pos))
512 Scalar xInject[] = { 0.25, 0.75 };
513 Scalar injectLen[] = { 0.1, 0.1 };
514 for (
unsigned i = 0; i <
sizeof(xInject) /
sizeof(Scalar); ++i) {
515 if (xInject[i] - injectLen[i] / 2 < lambda
516 && lambda < xInject[i] + injectLen[i] / 2)
522 void setupInitialFluidState_()
524 auto& fs = initialFluidState_;
525 fs.setPressure(wettingPhaseIdx, 1e5);
527 Scalar Sw = Parameters::Get<Parameters::InitialWaterSaturation<Scalar>>();
528 fs.setSaturation(wettingPhaseIdx, Sw);
529 fs.setSaturation(nonWettingPhaseIdx, 1 - Sw);
531 fs.setTemperature(temperature_);
535 fs.setPressure(nonWettingPhaseIdx, pn);
536 fs.setPressure(wettingPhaseIdx, pn);
538 typename FluidSystem::template ParameterCache<Scalar> paramCache;
539 paramCache.updateAll(fs);
540 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
541 fs.setDensity(phaseIdx, FluidSystem::density(fs, paramCache, phaseIdx));
542 fs.setViscosity(phaseIdx, FluidSystem::viscosity(fs, paramCache, phaseIdx));
549 typename MaterialLawParams::VanGenuchtenParams micParams_;
550 typename MaterialLawParams::VanGenuchtenParams mdcParams_;
552 MaterialLawParamsContainer materialParams_;
554 Opm::ImmiscibleFluidState<Scalar, FluidSystem> initialFluidState_;
Definition: restrictprolong.hh:47
Two-phase problem featuring some gravity-driven saturation fingers.
Definition: fingerproblem.hh:161
MaterialLawParams & materialLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx)
Definition: fingerproblem.hh:392
void boundary(BoundaryRateVector &values, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluate the boundary conditions for a boundary segment.
Definition: fingerproblem.hh:423
const MaterialLawParams & materialLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: fingerproblem.hh:404
const DimMatrix & intrinsicPermeability(const Context &, unsigned, unsigned) const
Definition: fingerproblem.hh:378
Scalar porosity(const Context &, unsigned, unsigned) const
Definition: fingerproblem.hh:385
void source(RateVector &rate, const Context &, unsigned, unsigned) const
Evaluate the source term for all phases within a given sub-control-volume.
Definition: fingerproblem.hh:486
void constraints(Constraints &constraints, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluate the constraints for a control volume.
Definition: fingerproblem.hh:464
void finishInit()
Called by the Opm::Simulator in order to initialize the problem.
Definition: fingerproblem.hh:281
Scalar temperature(const Context &, unsigned, unsigned) const
Definition: fingerproblem.hh:371
void initial(PrimaryVariables &values, const Context &, unsigned, unsigned) const
Evaluate the initial value for a control volume.
Definition: fingerproblem.hh:454
void endTimeStep()
Called by the simulator after each time integration.
Definition: fingerproblem.hh:328
RestrictProlongOperator restrictProlongOperator()
return restriction and prolongation operator
Definition: fingerproblem.hh:232
static void registerParameters()
Definition: fingerproblem.hh:251
CopyRestrictProlong< Grid, MaterialLawParamsContainer > RestrictProlongOperator
Definition: fingerproblem.hh:213
std::string name() const
The problem name.
Definition: fingerproblem.hh:240
FingerProblem(Simulator &simulator)
Definition: fingerproblem.hh:218
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:92
Defines the properties required for the immiscible multi-phase model.
Defines the common parameters for the porous medium multi-phase models.
Definition: blackoilnewtonmethodparams.hpp:31
void reset()
Reset parameter system.
Definition: blackoilmodel.hh:72
static const int dim
Definition: structuredgridvanguard.hh:67
Definition: blackoilboundaryratevector.hh:37
@ cube
Definition: vcfvstencil.hh:55
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:235
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:226
Definition: fingerproblem.hh:138
static constexpr Scalar value
Definition: fingerproblem.hh:138
Specify whether the some degrees of fredom can be constraint.
Definition: fvbaseproperties.hh:199
The type of the DUNE grid.
Definition: basicproperties.hh:100
UndefinedProperty type
Definition: basicproperties.hh:100
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: fingerproblem.hh:118
Opm::ParkerLenhard< Traits > ParkerLenhard
Definition: fingerproblem.hh:125
ParkerLenhard type
Definition: fingerproblem.hh:126
GetPropType< TypeTag, Properties::FluidSystem > FluidSystem
Definition: fingerproblem.hh:119
Opm::TwoPhaseMaterialTraits< Scalar, FluidSystem::wettingPhaseIdx, FluidSystem::nonWettingPhaseIdx > Traits
Definition: fingerproblem.hh:122
The material law which ought to be used (extracted from the spatial parameters)
Definition: multiphasebaseproperties.hh:51
Opm::GasPhase< Scalar, Opm::Air< Scalar > > type
Definition: fingerproblem.hh:111
The non-wetting phase for two-phase models.
Definition: immiscibleproperties.hh:44
The type of the problem.
Definition: fvbaseproperties.hh:81
Definition: fingerproblem.hh:75
std::tuple< StructuredGridVanguard > InheritsFrom
Definition: fingerproblem.hh:75
Opm::LiquidPhase< Scalar, Opm::SimpleH2O< Scalar > > type
Definition: fingerproblem.hh:100
The wetting phase for two-phase models.
Definition: immiscibleproperties.hh:41