co2ptflashproblem.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 OPM_CO2PTFLASH_PROBLEM_HH
29#define OPM_CO2PTFLASH_PROBLEM_HH
30
31#include <opm/common/Exceptions.hpp>
32
33#include <opm/input/eclipse/EclipseState/Compositional/CompositionalConfig.hpp>
34
35#include <opm/material/components/SimpleCO2.hpp>
36#include <opm/material/components/C10.hpp>
37#include <opm/material/components/C1.hpp>
38#include <opm/material/fluidmatrixinteractions/RegularizedBrooksCorey.hpp>
39#include <opm/material/fluidmatrixinteractions/BrooksCorey.hpp>
40#include <opm/material/constraintsolvers/PTFlash.hpp>
41#include <opm/material/fluidsystems/GenericOilGasWaterFluidSystem.hpp>
42#include <opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityWaterPvt.hpp>
43#include <opm/material/common/Valgrind.hpp>
52#include <dune/grid/yaspgrid.hh>
53#include <dune/grid/io/file/dgfparser/dgfyasp.hh>
54#include <dune/common/version.hh>
55#include <dune/common/fvector.hh>
56#include <dune/common/fmatrix.hh>
57
58#include <sstream>
59#include <string>
60
61namespace Opm {
62template <class TypeTag>
63class CO2PTProblem;
64} // namespace Opm */
65
66namespace Opm::Properties {
67
68namespace TTag {
70} // end namespace TTag
71
72template <class TypeTag, class MyTypeTag>
73struct NumComp { using type = UndefinedProperty; };
74
75template <class TypeTag>
76struct NumComp<TypeTag, TTag::CO2PTBaseProblem> {
77 static constexpr int value = 3;
78};
79
80template <class TypeTag, class MyTypeTag>
82
83template <class TypeTag>
84struct EnableDummyWater<TypeTag, TTag::CO2PTBaseProblem> {
85 static constexpr bool value = true;
86};
87
88// Set the grid type: --->2D
89template <class TypeTag>
90struct Grid<TypeTag, TTag::CO2PTBaseProblem> { using type = Dune::YaspGrid</*dim=*/2>; };
91
92// Set the problem property
93template <class TypeTag>
94struct Problem<TypeTag, TTag::CO2PTBaseProblem>
96
97// Set flash solver
98template <class TypeTag>
99struct FlashSolver<TypeTag, TTag::CO2PTBaseProblem> {
100private:
104
105public:
106 using type = Opm::PTFlash<Scalar, FluidSystem>;
107};
108
109// Set fluid configuration
110template <class TypeTag>
111struct FluidSystem<TypeTag, TTag::CO2PTBaseProblem>
112{
113private:
115 static constexpr int num_comp = getPropValue<TypeTag, Properties::NumComp>();
116 static constexpr bool enable_water = getPropValue<TypeTag, Properties::EnableDummyWater>();
117
118public:
119 using type = Opm::GenericOilGasWaterFluidSystem<Scalar, num_comp, enable_water>;
120};
121
122// Set the material Law
123template <class TypeTag>
124struct MaterialLaw<TypeTag, TTag::CO2PTBaseProblem> {
125private:
127 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
128 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
129
131 using Traits = Opm::ThreePhaseMaterialTraits<Scalar,
132 /*wettingPhaseIdx=*/FluidSystem::waterPhaseIdx,
133 /*nonWettingPhaseIdx=*/FluidSystem::oilPhaseIdx,
134 /*gasPhaseIdx=*/FluidSystem::gasPhaseIdx>;
135
136 // define the material law which is parameterized by effective saturation
137 using EffMaterialLaw = Opm::NullMaterial<Traits>;
138 //using EffMaterialLaw = Opm::BrooksCorey<Traits>;
139
140public:
141 using type = EffMaterialLaw;
142};
143
144// mesh grid
145template <class TypeTag>
146struct Vanguard<TypeTag, TTag::CO2PTBaseProblem> {
148};
149
150template <class TypeTag>
151struct EnableEnergy<TypeTag, TTag::CO2PTBaseProblem> {
152 static constexpr bool value = false;
153};
154
155} // namespace Opm::Properties
156
157namespace Opm::Parameters {
158
159// this is kinds of telling the report step length
160template<class Scalar>
161struct EpisodeLength { static constexpr Scalar value = 0.1 * 60. * 60.; };
162
163template<class Scalar>
164struct Initialpressure { static constexpr Scalar value = 75e5; };
165
166struct SimulationName { static constexpr auto value = "co2_ptflash"; };
167
168// set the defaults for the problem specific properties
169template<class Scalar>
170struct Temperature { static constexpr Scalar value = 423.25; };
171
172} // namespace Opm::Parameters
173
174namespace Opm {
181template <class TypeTag>
182class CO2PTProblem : public GetPropType<TypeTag, Properties::BaseProblem>
183{
185
190 enum { dim = GridView::dimension };
191 enum { dimWorld = GridView::dimensionworld };
200
201 using Toolbox = Opm::MathToolbox<Evaluation>;
202 using CoordScalar = typename GridView::ctype;
203
204 enum { numPhases = FluidSystem::numPhases };
205 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
206 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
207 enum { conti0EqIdx = Indices::conti0EqIdx };
208 enum { pressure0Idx = Indices::pressure0Idx };
209 enum { z0Idx = Indices::z0Idx };
210 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
211 enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
212 enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
213
214 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
215 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
216 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
217 using ComponentVector = Dune::FieldVector<Evaluation, numComponents>;
219
220public:
221 using FluidState = Opm::CompositionalFluidState<Evaluation, FluidSystem, enableEnergy>;
225 explicit CO2PTProblem(Simulator& simulator)
226 : ParentType(simulator)
227 {
228 const Scalar epi_len = Parameters::Get<Parameters::EpisodeLength<Scalar>>();
229 simulator.setEpisodeLength(epi_len);
230 FluidSystem::init();
231 using CompParm = typename FluidSystem::ComponentParam;
232 using CO2 = Opm::SimpleCO2<Scalar>;
233 using C1 = Opm::C1<Scalar>;
234 using C10 = Opm::C10<Scalar>;
235 FluidSystem::addComponent(CompParm {CO2::name(), CO2::molarMass(), CO2::criticalTemperature(),
236 CO2::criticalPressure(), CO2::criticalVolume(), CO2::acentricFactor()});
237 FluidSystem::addComponent(CompParm {C1::name(), C1::molarMass(), C1::criticalTemperature(),
238 C1::criticalPressure(), C1::criticalVolume(), C1::acentricFactor()});
239 FluidSystem::addComponent(CompParm{C10::name(), C10::molarMass(), C10::criticalTemperature(),
240 C10::criticalPressure(), C10::criticalVolume(), C10::acentricFactor()});
241 // FluidSystem::add
242 }
243
245 {
246 temperature_ = Parameters::Get<Parameters::Temperature<Scalar>>();
247 K_ = this->toDimMatrix_(9.869232667160131e-14);
248
249 porosity_ = 0.1;
250 }
251
253 {
254 using WaterPvt = typename FluidSystem::WaterPvt;
255 std::shared_ptr<WaterPvt> waterPvt = std::make_shared<WaterPvt>();
256 waterPvt->setApproach(WaterPvtApproach::ConstantCompressibilityWater);
257 auto& ccWaterPvt = waterPvt->template getRealPvt<WaterPvtApproach::ConstantCompressibilityWater>();
258 ccWaterPvt.setNumRegions(/*numPvtRegions=*/1);
259 Scalar rhoRefW = 1037.0; // [kg]
260 ccWaterPvt.setReferenceDensities(/*regionIdx=*/0, /*rhoRefO=*/Scalar(0.0), /*rhoRefG=*/Scalar(0.0), rhoRefW);
261 ccWaterPvt.setViscosity(/*regionIdx=*/0, 9.6e-4);
262 ccWaterPvt.setCompressibility(/*regionIdx=*/0, 1.450377e-10);
263 waterPvt->initEnd();
264 FluidSystem::setWaterPvt(waterPvt);
265 }
266
267 template <class Context>
268 const DimVector&
269 gravity([[maybe_unused]]const Context& context,
270 [[maybe_unused]] unsigned spaceIdx,
271 [[maybe_unused]] unsigned timeIdx) const
272 {
273 return gravity();
274 }
275
276 const DimVector& gravity() const
277 {
278 return gravity_;
279 }
280
281 Opm::CompositionalConfig::EOSType getEosType() const
282 {
283 return Opm::CompositionalConfig::EOSType::PR;
284 }
285
290 {
291 ParentType::finishInit();
292
293 // initialize fixed parameters; temperature, permeability, porosity
295
296 // Initialize water pvt
297 initWaterPVT();
298 }
299
303 static void registerParameters()
304 {
305 ParentType::registerParameters();
306
307 Parameters::Register<Parameters::Temperature<Scalar>>
308 ("The temperature [K] in the reservoir");
309 Parameters::Register<Parameters::Initialpressure<Scalar>>
310 ("The initial pressure [Pa s] in the reservoir");
311 Parameters::Register<Parameters::SimulationName>
312 ("The name of the simulation used for the output files");
313 Parameters::Register<Parameters::EpisodeLength<Scalar>>
314 ("Time interval [s] for episode length");
315
316 Parameters::SetDefault<Parameters::CellsX>(30);
317 Parameters::SetDefault<Parameters::DomainSizeX<Scalar>>(300.0);
318
319 if constexpr (dim > 1) {
320 Parameters::SetDefault<Parameters::CellsY>(1);
321 Parameters::SetDefault<Parameters::DomainSizeY<Scalar>>(1.0);
322 }
323 if constexpr (dim == 3) {
324 Parameters::SetDefault<Parameters::CellsZ>(1);
325 Parameters::SetDefault<Parameters::DomainSizeZ<Scalar>>(1.0);
326 }
327
328 Parameters::SetDefault<Parameters::EndTime<Scalar>>(60. * 60.);
329 Parameters::SetDefault<Parameters::InitialTimeStepSize<Scalar>>(0.1 * 60. * 60.);
330 Parameters::SetDefault<Parameters::NewtonMaxIterations>(30);
331 Parameters::SetDefault<Parameters::NewtonTargetIterations>(6);
332 Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(1e-3);
333 Parameters::SetDefault<Parameters::VtkWriteFilterVelocities>(true);
334 Parameters::SetDefault<Parameters::VtkWriteFugacityCoeffs>(true);
335 Parameters::SetDefault<Parameters::VtkWritePotentialGradients>(true);
336 Parameters::SetDefault<Parameters::VtkWriteTotalMassFractions>(true);
337 Parameters::SetDefault<Parameters::VtkWriteTotalMoleFractions>(true);
338 Parameters::SetDefault<Parameters::VtkWriteEquilibriumConstants>(true);
339 Parameters::SetDefault<Parameters::VtkWriteLiquidMoleFractions>(true);
340
341 Parameters::SetDefault<Parameters::LinearSolverAbsTolerance<Scalar>>(0.0);
342 Parameters::SetDefault<Parameters::LinearSolverTolerance<Scalar>>(1e-3);
343 }
344
348 std::string name() const
349 {
350 std::ostringstream oss;
351 oss << Parameters::Get<Parameters::SimulationName>();
352 return oss.str();
353 }
354
355 // This method must be overridden for the simulator to continue with
356 // a new episode. We just start a new episode with the same length as
357 // the old one.
359 {
360 Scalar epi_len = Parameters::Get<Parameters::EpisodeLength<Scalar>>();
361 this->simulator().startNextEpisode(epi_len);
362 }
363
364 // only write output when episodes change, aka. report steps, and
365 // include the initial timestep too
367 {
368 return this->simulator().episodeWillBeOver() || (this->simulator().timeStepIndex() == -1);
369 }
370
371 // we don't care about doing restarts from every fifth timestep, it
372 // will just slow us down
374 {
375 return false;
376 }
377
382 {
383 Scalar tol = this->model().newtonMethod().tolerance() * 1e5;
384 this->model().checkConservativeness(tol);
385
386 // Calculate storage terms
387 PrimaryVariables storageO, storageW;
388 this->model().globalPhaseStorage(storageO, oilPhaseIdx);
389
390 // Calculate storage terms
391 PrimaryVariables storageL, storageG;
392 this->model().globalPhaseStorage(storageL, /*phaseIdx=*/oilPhaseIdx);
393 this->model().globalPhaseStorage(storageG, /*phaseIdx=*/gasPhaseIdx);
394
395 // Write mass balance information for rank 0
396 // if (this->gridView().comm().rank() == 0) {
397 // std::cout << "Storage: liquid=[" << storageL << "]"
398 // << " gas=[" << storageG << "]\n" << std::flush;
399 // }
400 }
401
405 template <class Context>
406 void initial(PrimaryVariables& values, const Context& context, unsigned spaceIdx, unsigned timeIdx) const
407 {
408 Opm::CompositionalFluidState<Evaluation, FluidSystem> fs;
409 initialFluidState(fs, context, spaceIdx, timeIdx);
410 values.assignNaive(fs);
411 }
412
413 // Constant temperature
414 template <class Context>
415 Scalar temperature([[maybe_unused]] const Context& context, [[maybe_unused]] unsigned spaceIdx, [[maybe_unused]] unsigned timeIdx) const
416 {
417 return temperature_;
418 }
419
420
421 // Constant permeability
422 template <class Context>
423 const DimMatrix& intrinsicPermeability([[maybe_unused]] const Context& context,
424 [[maybe_unused]] unsigned spaceIdx,
425 [[maybe_unused]] unsigned timeIdx) const
426 {
427 return K_;
428 }
429
430 // Constant porosity
431 template <class Context>
432 Scalar porosity([[maybe_unused]] const Context& context, [[maybe_unused]] unsigned spaceIdx, [[maybe_unused]] unsigned timeIdx) const
433 {
434 int spatialIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
435 int inj = 0;
436 int prod = Parameters::Get<Parameters::CellsX>() - 1;
437 if (spatialIdx == inj || spatialIdx == prod) {
438 return 1.0;
439 } else {
440 return porosity_;
441 }
442 }
443
447 template <class Context>
448 const MaterialLawParams& materialLawParams([[maybe_unused]] const Context& context,
449 [[maybe_unused]] unsigned spaceIdx,
450 [[maybe_unused]] unsigned timeIdx) const
451 {
452 return this->mat_;
453 }
454
455
456 // No flow (introduce fake wells instead)
457 template <class Context>
458 void boundary(BoundaryRateVector& values,
459 const Context& /*context*/,
460 unsigned /*spaceIdx*/,
461 unsigned /*timeIdx*/) const
462 { values.setNoFlow(); }
463
464 // No source terms
465 template <class Context>
466 void source(RateVector& source_rate,
467 [[maybe_unused]] const Context& context,
468 [[maybe_unused]] unsigned spaceIdx,
469 [[maybe_unused]] unsigned timeIdx) const
470 {
471 source_rate = Scalar(0.0);
472 }
473
474private:
475
479 template <class FluidState, class Context>
480 void initialFluidState(FluidState& fs, const Context& context, unsigned spaceIdx, unsigned timeIdx) const
481 {
482 // z0 = [0.5, 0.3, 0.2]
483 // zi = [0.99, 0.01-1e-3, 1e-3]
484 // p0 = 75e5
485 // T0 = 423.25
486 int inj = 0;
487 int prod = Parameters::Get<Parameters::CellsX>() - 1;
488 int spatialIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
489 ComponentVector comp;
490 comp[0] = Evaluation::createVariable(0.5, z0Idx);
491 comp[1] = Evaluation::createVariable(0.3, z0Idx + 1);
492 comp[2] = 1. - comp[0] - comp[1];
493 if (spatialIdx == inj) {
494 comp[0] = Evaluation::createVariable(0.99, z0Idx);
495 comp[1] = Evaluation::createVariable(0.01 - 1e-3, z0Idx + 1);
496 comp[2] = 1. - comp[0] - comp[1];
497 }
498
499 Scalar p0 = Parameters::Get<Parameters::Initialpressure<Scalar>>();
500
501 //\Note, for an AD variable, if we multiply it with 2, the derivative will also be scalced with 2,
502 //\Note, so we should not do it.
503 if (spatialIdx == inj) {
504 p0 *= 2.0;
505 }
506 if (spatialIdx == prod) {
507 p0 *= 0.5;
508 }
509 Evaluation p_init = Evaluation::createVariable(p0, pressure0Idx);
510
511 fs.setPressure(FluidSystem::oilPhaseIdx, p_init);
512 fs.setPressure(FluidSystem::gasPhaseIdx, p_init);
513 fs.setPressure(FluidSystem::waterPhaseIdx, p_init);
514
515 fs.setTemperature(temperature_);
516
517 for (unsigned compIdx = 0; compIdx < numComponents - 1; ++compIdx) {
518 fs.setMoleFraction(compIdx, comp[compIdx]);
519 }
520
521 // Set initial K and L
522 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
523 const Evaluation Ktmp = fs.wilsonK_(compIdx);
524 fs.setKvalue(compIdx, Ktmp);
525 }
526
527 const Evaluation& Ltmp = -1.0;
528 fs.setLvalue(Ltmp);
529 }
530
531 DimMatrix K_;
532 Scalar porosity_;
533 Scalar temperature_;
534 MaterialLawParams mat_;
535 DimVector gravity_;
536};
537
538} // namespace Opm
539
540#endif
3 component simple testproblem with ["CO2", "C1", "C10"]
Definition: co2ptflashproblem.hh:183
bool shouldWriteRestartFile()
Definition: co2ptflashproblem.hh:373
std::string name() const
The problem name.
Definition: co2ptflashproblem.hh:348
const DimMatrix & intrinsicPermeability(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: co2ptflashproblem.hh:423
Scalar porosity(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: co2ptflashproblem.hh:432
const MaterialLawParams & materialLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: co2ptflashproblem.hh:448
Opm::CompositionalConfig::EOSType getEosType() const
Definition: co2ptflashproblem.hh:281
CO2PTProblem(Simulator &simulator)
Definition: co2ptflashproblem.hh:225
void source(RateVector &source_rate, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: co2ptflashproblem.hh:466
void initial(PrimaryVariables &values, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluate the initial value for a control volume.
Definition: co2ptflashproblem.hh:406
Scalar temperature(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: co2ptflashproblem.hh:415
static void registerParameters()
Definition: co2ptflashproblem.hh:303
const DimVector & gravity() const
Definition: co2ptflashproblem.hh:276
void boundary(BoundaryRateVector &values, const Context &, unsigned, unsigned) const
Definition: co2ptflashproblem.hh:458
void endTimeStep()
Called by the simulator after each time integration.
Definition: co2ptflashproblem.hh:381
Opm::CompositionalFluidState< Evaluation, FluidSystem, enableEnergy > FluidState
Definition: co2ptflashproblem.hh:221
bool shouldWriteOutput()
Definition: co2ptflashproblem.hh:366
void initPetrophysics()
Definition: co2ptflashproblem.hh:244
const DimVector & gravity(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: co2ptflashproblem.hh:269
void initWaterPVT()
Definition: co2ptflashproblem.hh:252
void finishInit()
Called by the Opm::Simulator in order to initialize the problem.
Definition: co2ptflashproblem.hh:289
void endEpisode()
Definition: co2ptflashproblem.hh:358
Helper class for grid instantiation of the lens problem.
Definition: structuredgridvanguard.hh:99
Definition: blackoilnewtonmethodparams.hpp:31
Definition: blackoilmodel.hh:79
Definition: blackoilboundaryratevector.hh:39
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:233
The Opm property system, traits with inheritance.
Provides convenience routines to bring up the simulation at runtime.
Definition: co2ptflashproblem.hh:161
static constexpr Scalar value
Definition: co2ptflashproblem.hh:161
Definition: co2ptflashproblem.hh:164
static constexpr Scalar value
Definition: co2ptflashproblem.hh:164
Definition: co2injectionproblem.hh:162
static constexpr auto value
Definition: co2injectionproblem.hh:162
static constexpr Scalar value
Definition: co2injectionproblem.hh:165
Definition: co2ptflashproblem.hh:81
Specify whether energy should be considered as a conservation quantity or not.
Definition: multiphasebaseproperties.hh:87
Opm::PTFlash< Scalar, FluidSystem > type
Definition: co2ptflashproblem.hh:106
The type of the flash constraint solver.
Definition: flashproperties.hh:39
Opm::GenericOilGasWaterFluidSystem< Scalar, num_comp, enable_water > type
Definition: co2ptflashproblem.hh:119
The fluid systems including the information about the phases.
Definition: multiphasebaseproperties.hh:79
Dune::YaspGrid< 2 > type
Definition: co2ptflashproblem.hh:90
The type of the DUNE grid.
Definition: basicproperties.hh:100
EffMaterialLaw type
Definition: co2ptflashproblem.hh:141
The material law which ought to be used (extracted from the spatial parameters)
Definition: multiphasebaseproperties.hh:55
Definition: co2ptflashproblem.hh:73
The type of the problem.
Definition: fvbaseproperties.hh:81
Definition: co2ptflashproblem.hh:69
a tag to mark properties as undefined
Definition: propertysystem.hh:38
Property which provides a Vanguard (manages grids)
Definition: basicproperties.hh:96