My Project
tutorial1problem.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
28 #ifndef EWOMS_TUTORIAL1_PROBLEM_HH /*@\label{tutorial1:guardian1}@*/
29 #define EWOMS_TUTORIAL1_PROBLEM_HH /*@\label{tutorial1:guardian2}@*/
30 
31 // The numerical model
32 #include <opm/models/immiscible/immisciblemodel.hh>
33 
34 // The spatial discretization (VCFV == Vertex-Centered Finite Volumes)
35 #include <opm/models/discretization/vcfv/vcfvdiscretization.hh> /*@\label{tutorial1:include-discretization}@*/
36 
37 // The chemical species that are used
38 #include <opm/material/components/SimpleH2O.hpp>
39 #include <opm/material/components/Lnapl.hpp>
40 
41 // Headers required for the capillary pressure law
42 #include <opm/material/fluidmatrixinteractions/RegularizedBrooksCorey.hpp> /*@\label{tutorial1:rawLawInclude}@*/
43 #include <opm/material/fluidmatrixinteractions/EffToAbsLaw.hpp>
44 #include <opm/material/fluidmatrixinteractions/MaterialTraits.hpp>
45 
46 // For the DUNE grid
47 #include <dune/grid/yaspgrid.hh> /*@\label{tutorial1:include-grid-manager}@*/
48 #include <opm/models/io/cubegridvanguard.hh> /*@\label{tutorial1:include-grid-manager}@*/
49 
50 // For Dune::FieldMatrix
51 #include <dune/common/fmatrix.hh>
52 #include <dune/common/version.hh>
53 
54 namespace Opm {
55 // forward declaration of the problem class
56 template <class TypeTag>
57 class Tutorial1Problem;
58 }
59 
60 namespace Opm::Properties {
61 
62 // Create a new type tag for the problem
63 // Create new type tags
64 namespace TTag {
65 struct Tutorial1Problem { using InheritsFrom = std::tuple<ImmiscibleTwoPhaseModel>; };
66 } // end namespace TTag
67 
68 // Select the vertex centered finite volume method as spatial discretization
69 template<class TypeTag>
70 struct SpatialDiscretizationSplice<TypeTag, TTag::Tutorial1Problem>
71 { using type = TTag::VcfvDiscretization; }; /*@\label{tutorial1:set-spatial-discretization}@*/
72 
73 // Set the "Problem" property
74 template<class TypeTag>
75 struct Problem<TypeTag, TTag::Tutorial1Problem>
76 { using type = Opm::Tutorial1Problem<TypeTag>; }; /*@\label{tutorial1:set-problem}@*/
77 
78 // Set grid and the grid manager to be used
79 template<class TypeTag>
80 struct Grid<TypeTag, TTag::Tutorial1Problem> { using type = Dune::YaspGrid</*dim=*/2>; }; /*@\label{tutorial1:set-grid}@*/
81 template<class TypeTag>
82 struct Vanguard<TypeTag, TTag::Tutorial1Problem> { using type = Opm::CubeGridVanguard<TypeTag>; }; /*@\label{tutorial1:set-grid-manager}@*/
83 
84 // Set the wetting phase /*@\label{tutorial1:2p-system-start}@*/
85 template<class TypeTag>
86 struct WettingPhase<TypeTag, TTag::Tutorial1Problem> /*@\label{tutorial1:wettingPhase}@*/
87 {
88  using Scalar = GetPropType<TypeTag, Properties::Scalar>;
89  using type = Opm::LiquidPhase<Scalar, Opm::SimpleH2O<Scalar> >;
90 };
91 
92 // Set the non-wetting phase
93 template<class TypeTag>
94 struct NonwettingPhase<TypeTag, TTag::Tutorial1Problem> /*@\label{tutorial1:nonwettingPhase}@*/
95 {
96  using Scalar = GetPropType<TypeTag, Properties::Scalar>;
97  using type = Opm::LiquidPhase<Scalar, Opm::LNAPL<Scalar> >;
98 }; /*@\label{tutorial1:2p-system-end}@*/
99 
100 // Set the material law
101 template<class TypeTag>
102 struct MaterialLaw<TypeTag, TTag::Tutorial1Problem>
103 {
104 private:
105  // create a class holding the necessary information for a
106  // two-phase capillary pressure law
107  using Scalar = GetPropType<TypeTag, Properties::Scalar>;
108  using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
109  enum { wettingPhaseIdx = FluidSystem::wettingPhaseIdx };
110  enum { nonWettingPhaseIdx = FluidSystem::nonWettingPhaseIdx };
111  using Traits = Opm::TwoPhaseMaterialTraits<Scalar, wettingPhaseIdx, nonWettingPhaseIdx>;
112 
113  // define the material law which is parameterized by effective
114  // saturations
115  using RawMaterialLaw = Opm::RegularizedBrooksCorey<Traits>; /*@\label{tutorial1:rawlaw}@*/
116 
117 public:
118  // Convert absolute saturations into effective ones before passing
119  // it to the base capillary pressure law
120  using type = Opm::EffToAbsLaw<RawMaterialLaw>; /*@\label{tutorial1:eff2abs}@*/
121 };
122 
123 // Disable gravity
124 template<class TypeTag>
125 struct EnableGravity<TypeTag, TTag::Tutorial1Problem> { static constexpr bool value = false; }; /*@\label{tutorial1:gravity}@*/
126 
127 // define how long the simulation should run [s]
128 template<class TypeTag>
129 struct EndTime<TypeTag, TTag::Tutorial1Problem>
130 {
131  using type = GetPropType<TypeTag, Scalar>;
132  static constexpr type value = 100e3;
133 }; /*@\label{tutorial1:default-params-begin}@*/
134 
135 // define the size of the initial time step [s]
136 template<class TypeTag>
137 struct InitialTimeStepSize<TypeTag, TTag::Tutorial1Problem>
138 {
139  using type = GetPropType<TypeTag, Scalar>;
140  static constexpr type value = 125.0;
141 };
142 
143 // define the physical size of the problem's domain [m]
144 template<class TypeTag>
145 struct DomainSizeX<TypeTag, TTag::Tutorial1Problem>
146 {
147  using type = GetPropType<TypeTag, Scalar>;
148  static constexpr type value = 300.0;
149 }; /*@\label{tutorial1:grid-default-params-begin}@*/
150 template<class TypeTag>
151 struct DomainSizeY<TypeTag, TTag::Tutorial1Problem>
152 {
153  using type = GetPropType<TypeTag, Scalar>;
154  static constexpr type value = 60.0;
155 };
156 template<class TypeTag>
157 struct DomainSizeZ<TypeTag, TTag::Tutorial1Problem>
158 {
159  using type = GetPropType<TypeTag, Scalar>;
160  static constexpr type value = 0.0;
161 };
162 
163 // // define the number of cells used for discretizing the physical domain
164 template<class TypeTag>
165 struct CellsX<TypeTag, TTag::Tutorial1Problem> { static constexpr int value = 100; };
166 template<class TypeTag>
167 struct CellsY<TypeTag, TTag::Tutorial1Problem> { static constexpr int value = 1; };
168 template<class TypeTag>
169 struct CellsZ<TypeTag, TTag::Tutorial1Problem> { static constexpr int value = 1; }; /*@\label{tutorial1:default-params-end}@*/
170 
171 } // namespace Opm::Properties
172 
173 namespace Opm {
175 template <class TypeTag>
177  : public GetPropType<TypeTag, Properties::BaseProblem> /*@\label{tutorial1:def-problem}@*/
178 {
179  using ParentType = GetPropType<TypeTag, Properties::BaseProblem>;
180  using Scalar = GetPropType<TypeTag, Properties::Scalar>;
181  using GridView = GetPropType<TypeTag, Properties::GridView>;
182 
183  // Grid dimension
184  enum { dimWorld = GridView::dimensionworld };
185 
186  // The type of the intrinsic permeability tensor
187  using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
188 
189  // eWoms specific types are specified via the property system
190  using Simulator = GetPropType<TypeTag, Properties::Simulator>;
191  using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
192  using RateVector = GetPropType<TypeTag, Properties::RateVector>;
193  using BoundaryRateVector = GetPropType<TypeTag, Properties::BoundaryRateVector>;
194  using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
195  using Indices = GetPropType<TypeTag, Properties::Indices>;
196  using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
197  using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>; /*@\label{tutorial1:matLawObjectType}@*/
198 
199  // phase indices
200  enum { numPhases = FluidSystem::numPhases };
201  enum { wettingPhaseIdx = FluidSystem::wettingPhaseIdx };
202  enum { nonWettingPhaseIdx = FluidSystem::nonWettingPhaseIdx };
203 
204  // Indices of the conservation equations
205  enum { contiWettingEqIdx = Indices::conti0EqIdx + wettingPhaseIdx };
206  enum { contiNonWettingEqIdx = Indices::conti0EqIdx + nonWettingPhaseIdx };
207 
208 public:
211  Tutorial1Problem(Simulator& simulator)
212  : ParentType(simulator)
213  , eps_(3e-6)
214  { }
215 
219  void finishInit()
220  {
221  ParentType::finishInit();
222 
223  // Use an isotropic and homogeneous intrinsic permeability
224  K_ = this->toDimMatrix_(1e-7);
225 
226  // Parameters of the Brooks-Corey law
227  materialParams_.setEntryPressure(500.0 /*Pa*/); /*@\label{tutorial1:setLawParams}@*/
228  materialParams_.setLambda(2); // shape parameter
229 
230  // Set the residual saturations
231  materialParams_.setResidualSaturation(wettingPhaseIdx, 0.0);
232  materialParams_.setResidualSaturation(nonWettingPhaseIdx, 0.0);
233 
234  // wrap up the initialization of the material law's parameters
235  materialParams_.finalize();
236  }
237 
239  std::string name() const
240  { return "tutorial1"; }
241 
243  template <class Context>
244  Scalar temperature(const Context& /*context*/,
245  unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
246  { return 283.15; }
247 
249  template <class Context>
250  const DimMatrix& intrinsicPermeability(const Context& /*context*/, /*@\label{tutorial1:permeability}@*/
251  unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
252  { return K_; }
253 
255  template <class Context>
256  Scalar porosity(const Context& /*context*/,
257  unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const /*@\label{tutorial1:porosity}@*/
258  { return 0.2; }
259 
261  template <class Context>
262  const MaterialLawParams& materialLawParams(const Context& /*context*/, /*@\label{tutorial1:matLawParams}@*/
263  unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
264  { return materialParams_; }
265 
267  template <class Context>
268  void boundary(BoundaryRateVector& values, const Context& context,
269  unsigned spaceIdx, unsigned timeIdx) const
270  {
271  const auto& pos = context.pos(spaceIdx, timeIdx);
272  if (pos[0] < eps_) {
273  // Free-flow conditions on left boundary
274  const auto& materialParams = this->materialLawParams(context, spaceIdx, timeIdx);
275 
276  Opm::ImmiscibleFluidState<Scalar, FluidSystem> fs;
277  Scalar Sw = 1.0;
278  fs.setSaturation(wettingPhaseIdx, Sw);
279  fs.setSaturation(nonWettingPhaseIdx, 1.0 - Sw);
280  fs.setTemperature(temperature(context, spaceIdx, timeIdx));
281 
282  Scalar pC[numPhases];
283  MaterialLaw::capillaryPressures(pC, materialParams, fs);
284  fs.setPressure(wettingPhaseIdx, 200e3);
285  fs.setPressure(nonWettingPhaseIdx, 200e3 + pC[nonWettingPhaseIdx] - pC[nonWettingPhaseIdx]);
286 
287  typename FluidSystem::template ParameterCache<Scalar> paramCache;
288  paramCache.updateAll(fs);
289  for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
290  fs.setDensity(phaseIdx, FluidSystem::density(fs, paramCache, phaseIdx));
291  fs.setViscosity(phaseIdx, FluidSystem::viscosity(fs, paramCache, phaseIdx));
292  }
293 
294  values.setFreeFlow(context, spaceIdx, timeIdx, fs);
295  }
296  else if (pos[0] > this->boundingBoxMax()[0] - eps_) {
297  // forced outflow at the right boundary
298  RateVector massRate(0.0);
299 
300  massRate[contiWettingEqIdx] = 0.0; // [kg / (s m^2)]
301  massRate[contiNonWettingEqIdx] = 3e-2; // [kg / (s m^2)]
302 
303  values.setMassRate(massRate);
304  }
305  else // no flow at the remaining boundaries
306  values.setNoFlow();
307  }
308 
312  template <class Context>
313  void source(RateVector& sourceRate, const Context& /*context*/,
314  unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const
315  {
316  sourceRate[contiWettingEqIdx] = 0.0;
317  sourceRate[contiNonWettingEqIdx] = 0.0;
318  }
319 
321  template <class Context>
322  void initial(PrimaryVariables& values, const Context& context,
323  unsigned spaceIdx, unsigned timeIdx) const
324  {
325  Opm::ImmiscibleFluidState<Scalar, FluidSystem> fs;
326 
327  // the domain is initially fully saturated by LNAPL
328  Scalar Sw = 0.0;
329  fs.setSaturation(wettingPhaseIdx, Sw);
330  fs.setSaturation(nonWettingPhaseIdx, 1.0 - Sw);
331 
332  // the temperature is given by the temperature() method
333  fs.setTemperature(temperature(context, spaceIdx, timeIdx));
334 
335  // set pressure of the wetting phase to 200 kPa = 2 bar
336  Scalar pC[numPhases];
337  MaterialLaw::capillaryPressures(pC, materialLawParams(context, spaceIdx, timeIdx),
338  fs);
339  fs.setPressure(wettingPhaseIdx, 200e3);
340  fs.setPressure(nonWettingPhaseIdx, 200e3 + pC[nonWettingPhaseIdx] - pC[nonWettingPhaseIdx]);
341 
342  values.assignNaive(fs);
343  }
344 
345 private:
346  DimMatrix K_;
347  // Object that holds the parameters of required by the capillary pressure law.
348  MaterialLawParams materialParams_; /*@\label{tutorial1:matParamsObject}@*/
349 
350  // small epsilon value
351  Scalar eps_;
352 };
353 } // namespace Opm
354 
355 #endif
356 
Tutorial problem using the "immiscible" model.
Definition: tutorial1problem.hh:178
const DimMatrix & intrinsicPermeability(const Context &, unsigned, unsigned) const
Returns the intrinsic permeability tensor [m^2] at a position.
Definition: tutorial1problem.hh:250
Scalar porosity(const Context &, unsigned, unsigned) const
Defines the porosity [-] of the medium at a given position.
Definition: tutorial1problem.hh:256
void initial(PrimaryVariables &values, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluates the initial value at a given position in the domain.
Definition: tutorial1problem.hh:322
void finishInit()
This method initializes the data structures allocated by the problem constructor.
Definition: tutorial1problem.hh:219
Tutorial1Problem(Simulator &simulator)
The constructor of the problem.
Definition: tutorial1problem.hh:211
void boundary(BoundaryRateVector &values, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluates the boundary conditions.
Definition: tutorial1problem.hh:268
void source(RateVector &sourceRate, const Context &, unsigned, unsigned) const
Evaluates the source term for all conserved quantities at a given position of the domain [kg/(m^3 * s...
Definition: tutorial1problem.hh:313
std::string name() const
Specifies the problem name. This is used for files generated by the simulation.
Definition: tutorial1problem.hh:239
const MaterialLawParams & materialLawParams(const Context &, unsigned, unsigned) const
Returns the parameter object for the material law at a given position.
Definition: tutorial1problem.hh:262
Scalar temperature(const Context &, unsigned, unsigned) const
Returns the temperature at a given position.
Definition: tutorial1problem.hh:244
Definition: tutorial1problem.hh:65