OGS
PengRobinson.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "PengRobinson.h"
5
6#include <algorithm>
7#include <boost/math/special_functions/pow.hpp>
8#include <cmath>
9
11
12namespace MaterialPropertyLib
13{
14
16 MaterialPropertyLib::VariableArray const& variable_array,
17 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
18 double const /*dt*/) const
19{
20 const double gas_constant = MaterialLib::PhysicalConstant::IdealGasConstant;
21 const double pressure = variable_array.gas_phase_pressure;
22 const double temperature = variable_array.temperature;
23 const double molar_mass = variable_array.molar_mass;
24
25 const double Tr = temperature / Tc_; // reduced Temperature
26
27 const double kappa = 0.37464 + 1.5422 * omega_ - 0.26992 * omega_ * omega_;
28
29 const double alpha = boost::math::pow<2>(1 + kappa * (1 - std::sqrt(Tr)));
30
31 // EOS in the form: 0 = rho^3 + z1*rho^2 + z2*rho + z3
32 const double denominator =
33 b_ *
34 (pressure * b_ * b_ + b_ * gas_constant * temperature - a_ * alpha);
35
36 const double z1 =
37 (molar_mass * a_ * alpha - 3 * molar_mass * b_ * b_ * pressure -
38 2 * molar_mass * gas_constant * temperature * b_) /
39 denominator;
40 const auto z2 = (molar_mass * molar_mass *
41 (b_ * pressure - gas_constant * temperature)) /
42 denominator;
43 const auto z3 =
44 (molar_mass * molar_mass * molar_mass * pressure) / denominator;
45
46 MathLib::CubicSolver cubic_solver_(1., z1, z2, z3);
47 return cubic_solver_.smallestPositiveRealRoot();
48}
49
51 MaterialPropertyLib::VariableArray const& variable_array,
52 Variable const variable, ParameterLib::SpatialPosition const& pos,
53 double const t, double const dt) const
54{
55 if (variable == Variable::temperature)
56 {
57 const double temperature = variable_array.temperature;
58 const double epsilon = 1.e-6;
59
60 MaterialPropertyLib::VariableArray perturbed = variable_array;
61 // Increase temperature by +epsilon
62 perturbed.temperature = temperature + epsilon;
63 const double rho_plus = std::get<double>(value(perturbed, pos, t, dt));
64
65 // Decrease temperature by -epsilon
66 perturbed.temperature = temperature - epsilon;
67 const double rho_minus = std::get<double>(value(perturbed, pos, t, dt));
68
69 // Calculate the central difference quotient
70 return (rho_plus - rho_minus) / (2 * epsilon);
71 }
72
73 if (variable == Variable::gas_phase_pressure)
74 {
75 const double pressure = variable_array.gas_phase_pressure;
76 const double epsilon = 1.e-3;
77
78 MaterialPropertyLib::VariableArray perturbed = variable_array;
79 // Increase pressure by +epsilon
80 perturbed.gas_phase_pressure = pressure + epsilon;
81 const double rho_plus = std::get<double>(value(perturbed, pos, t, dt));
82
83 // Decrease pressure by -epsilon
84 perturbed.gas_phase_pressure = pressure - epsilon;
85 const double rho_minus = std::get<double>(value(perturbed, pos, t, dt));
86
87 // Calculate the central difference quotient
88 return (rho_plus - rho_minus) / (2 * epsilon);
89 }
90
92 "PengRobinson::dValue is implemented for derivatives with respect to "
93 "gas phase pressure or temperature only.");
94
95 return 0.;
96}
97
98} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
PropertyDataType dValue(MaterialPropertyLib::VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
const double Tc_
Critical temperature.
const double omega_
Acentric factor.
double b_
Parameter b (covolume)
double a_
Parameter a (cohesion pressure)
virtual PropertyDataType value() const
double smallestPositiveRealRoot()
Definition CubicRoots.h:62
std::variant< double, Eigen::Matrix< double, 2, 1 >, Eigen::Matrix< double, 3, 1 >, Eigen::Matrix< double, 2, 2 >, Eigen::Matrix< double, 3, 3 >, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 >, Eigen::MatrixXd > PropertyDataType