34namespace TwoPhaseFlowWithPrho
38 std::vector<std::unique_ptr<
40 capillary_pressure_models,
42 std::unique_ptr<MaterialLib::PorousMedium::RelativePermeability>>&&
43 relative_permeability_models)
44 : _material_ids(material_ids),
45 _capillary_pressure_models(std::move(capillary_pressure_models)),
46 _relative_permeability_models(std::move(relative_permeability_models))
48 DBUG(
"Create material properties for Two-Phase flow with P-RHO model.");
52 const std::size_t element_id)
59 assert(element_id < _material_ids->size());
65 const double ,
const double ,
const double saturation)
const
72 const double ,
const double ,
const double saturation)
const
78 const int material_id,
const double ,
80 const double ,
const double saturation)
const
87 const int material_id,
const double ,
89 const double ,
const double saturation)
const
97 int const material_id,
109 using LocalJacobianMatrix =
110 Eigen::Matrix<double, 2, 2, Eigen::RowMajor>;
111 using LocalResidualVector = Eigen::Matrix<double, 2, 1>;
112 using LocalUnknownVector = Eigen::Matrix<double, 2, 1>;
113 LocalJacobianMatrix J_loc;
115 Eigen::PartialPivLU<LocalJacobianMatrix> linear_solver(2);
116 auto const update_residual = [&](LocalResidualVector& residual)
119 auto const update_jacobian = [&](LocalJacobianMatrix& jacobian)
125 auto const update_solution = [&](LocalUnknownVector
const& increment)
135 const int maximum_iterations(20);
136 const double residuum_tolerance(1.e-14);
137 const double increment_tolerance(0);
140 linear_solver, update_jacobian, update_residual, update_solution,
141 {maximum_iterations, residuum_tolerance, increment_tolerance});
143 auto const success_iterations = newton_solver.
solve(J_loc);
145 if (!success_iterations)
157 const int material_id,
double const pl,
double const X,
double const T,
162 const double rho_h2_nonwet = pg * H2 / IdealGasConstant / T;
170 const int material_id,
double const ,
172 double const ,
double const T,
JacobianMatrix& Jac,
double const Sw,
173 double const rho_h2_wet)
177 const double rho_h2_nonwet = pg * H2 / IdealGasConstant / T;
178 double const rho_equili_h2_wet = pg * HenryConstantH2 * H2;
179 double const dPC_dSw =
181 double const drhoh2wet_dpg = HenryConstantH2 * H2;
183 if ((1 - Sw) < (rho_equili_h2_wet - rho_h2_wet))
189 Jac(0, 0) = drhoh2wet_dpg * dPC_dSw;
193 Jac(1, 0) = rho_h2_nonwet - rho_h2_wet;
201 double const pg,
double const Sw,
double const rho_wet_h2)
203 double const rho_equilibrium_wet_h2 = pg * HenryConstantH2 * H2;
204 return std::min(1 - Sw, rho_equilibrium_wet_h2 - rho_wet_h2);
211 double ,
double X,
double Sw,
double rho_wet_h2,
double rho_nonwet_h2,
214 return X - (Sw * rho_wet_h2 + (1 - Sw) * rho_nonwet_h2);
221 double pl,
double S,
double rho_wet_h2,
double const T,
222 int current_material_id)
const
228 double const rho_equilibrium_wet_h2 = pg * HenryConstantH2 * H2;
229 if ((1 - S) < (rho_equilibrium_wet_h2 - rho_wet_h2))
233 double const drhoh2wet_dpg = HenryConstantH2 * H2;
234 double const drhoh2nonwet_dpg = H2 / IdealGasConstant / T;
236 ((drhoh2nonwet_dpg - drhoh2wet_dpg) * (1 - S) + drhoh2wet_dpg);
237 double const beta = (drhoh2nonwet_dpg - drhoh2wet_dpg) *
239 double const dPC_dSw =
241 return alpha / (beta - alpha * dPC_dSw);
247 double const pl,
const double ,
const double S,
248 const double rho_wet_h2,
double const T,
int current_material_id)
const
254 double const rho_equilibrium_wet_h2 = pg * HenryConstantH2 * H2;
255 if ((1 - S) < (rho_equilibrium_wet_h2 - rho_wet_h2))
259 double const drhoh2wet_dpg = HenryConstantH2 * H2;
260 double const drhoh2nonwet_dpg = H2 / IdealGasConstant / T;
262 ((drhoh2nonwet_dpg - drhoh2wet_dpg) * (1 - S) + drhoh2wet_dpg);
263 double const beta = (drhoh2nonwet_dpg - drhoh2wet_dpg) *
265 double const dPC_dSw =
267 return -1 / (beta - alpha * dPC_dSw);
273 double pl,
double Sw,
double rho_wet_h2,
double dSwdX,
274 int current_material_id)
const
280 double const rho_equilibrium_wet_h2 = pg * HenryConstantH2 * H2;
281 double const dPC_dSw =
283 if ((1 - Sw) < (rho_equilibrium_wet_h2 - rho_wet_h2))
287 return HenryConstantH2 * H2 * dPC_dSw * dSwdX;
293 double pl,
double Sw,
double rho_wet_h2,
double dSwdP,
294 int current_material_id)
const
300 double const rho_equilibrium_wet_h2 = pg * HenryConstantH2 * H2;
301 double const dPC_dSw =
303 if ((1 - Sw) < (rho_equilibrium_wet_h2 - rho_wet_h2))
307 return HenryConstantH2 * H2 * (1 + dPC_dSw * dSwdP);
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition of the Mesh class.
Definition of the PiecewiseLinearInterpolation class.
Base class of capillary pressure models.
std::optional< int > solve(JacobianMatrix &jacobian) const
static double calculateSaturation(double, double X, double Sw, double rho_wet_h2, double rho_nonwet_h2, double)
double calculatedXmdP(double pl, double Sw, double rho_wet_h2, double dSwdP, int current_material_id) const
std::vector< std::unique_ptr< MaterialLib::PorousMedium::CapillaryPressureSaturation > > _capillary_pressure_models
double calculatedSwdX(double const pl, const double, const double S, const double rho_wet_h2, double const T, int current_material_id) const
double getNonwetRelativePermeability(const double t, const ParameterLib::SpatialPosition &pos, const double p, const double T, const double saturation) const
void calculateResidual(const int material_id, double const pl, double const X, double const T, double Sw, double rho_h2_wet, ResidualVector &res)
Eigen::Matrix< double, jacobian_residual_size, 1 > ResidualVector
double getWetRelativePermeability(const double t, const ParameterLib::SpatialPosition &pos, const double p, const double T, const double saturation) const
void calculateJacobian(const int material_id, double const t, ParameterLib::SpatialPosition const &x, double const pl, double const X, double const T, JacobianMatrix &Jac, double Sw, double rho_h2_wet)
TwoPhaseFlowWithPrhoMaterialProperties(MeshLib::PropertyVector< int > const *material_ids, std::vector< std::unique_ptr< MaterialLib::PorousMedium::CapillaryPressureSaturation > > &&capillary_pressure_models, std::vector< std::unique_ptr< MaterialLib::PorousMedium::RelativePermeability > > &&relative_permeability_models)
static double calculateEquilibiumRhoWetLight(double const pg, double const Sw, double const rho_wet_h2)
double getCapillaryPressureDerivative(const int material_id, const double t, const ParameterLib::SpatialPosition &pos, const double p, const double T, const double saturation) const
Eigen::Matrix< double, jacobian_residual_size, jacobian_residual_size, Eigen::RowMajor > JacobianMatrix
double calculatedSwdP(double pl, double S, double rho_wet_h2, double const T, int current_material_id) const
int getMaterialID(const std::size_t element_id)
double getCapillaryPressure(const int material_id, const double t, const ParameterLib::SpatialPosition &pos, const double p, const double T, const double saturation) const
bool computeConstitutiveRelation(double const t, ParameterLib::SpatialPosition const &x, const int material_id, double const pg, double const X, double const T, double &Sw, double &X_m, double &dsw_dpg, double &dsw_dX, double &dxm_dpg, double &dxm_dX)
MeshLib::PropertyVector< int > const *const _material_ids
double calculatedXmdX(double pl, double Sw, double rho_wet_h2, double dSwdX, int current_material_id) const
std::vector< std::unique_ptr< MaterialLib::PorousMedium::RelativePermeability > > _relative_permeability_models
constexpr double HenryConstantH2
constexpr double H2
kg mol-1
constexpr double IdealGasConstant