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