OGS
SpecificHeatCapacityWithLatentHeat.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
5
7
9{
11 std::string name, double const l)
12 : l_(l)
13{
14 name_ = std::move(name);
15}
16
18{
19 if (!std::holds_alternative<Medium*>(scale_))
20 {
22 "The property 'SpecificHeatCapacityWithLatentHeat' is "
23 "implemented on the 'medium' scale only.");
24 }
25}
26
28 std::vector<std::unique_ptr<Phase>> const& phases)
29{
30 // run over phases, identify them and get properties
31 for (auto const& phase : phases)
32 {
33 if (phase == nullptr)
34 {
36 "One of the required phases (AqueousLiquid/FrozenLiquid/Solid) "
37 "does not exist!");
38 }
39
40 auto const& density_property =
42 auto const& specific_heat_capacity_property = phase->property(
44
45 if (phase->phaseName == PhaseName::AqueousLiquid)
46 {
47 densities_.liquid = &density_property;
48 spec_heat_capacities_.liquid = &specific_heat_capacity_property;
49 }
50 else if (phase->phaseName == PhaseName::FrozenLiquid)
51 {
52 densities_.frozen = &density_property;
53 spec_heat_capacities_.frozen = &specific_heat_capacity_property;
54 }
55 else if (phase->phaseName == PhaseName::Solid)
56 {
57 densities_.porous = &density_property;
58 spec_heat_capacities_.porous = &specific_heat_capacity_property;
59 }
60 }
61}
62
64 VariableArray const& variable_array,
65 ParameterLib::SpatialPosition const& pos, double const t,
66 double const dt) const
67{
68 auto const& medium = *std::get<Medium*>(scale_);
69 auto const& porosity_property = medium[PropertyType::porosity];
70 auto const& frozen_fraction_property =
72
73 auto const phi =
74 std::get<double>(porosity_property.value(variable_array, pos, t, dt));
75 auto const phi_fr = std::get<double>(
76 frozen_fraction_property.value(variable_array, pos, t, dt));
77 auto const phi_li = phi - phi_fr;
78 auto const phi_po = 1 - phi;
79
80 auto const rho_li =
81 std::get<double>(densities_.liquid->value(variable_array, pos, t, dt));
82 auto const rho_fr =
83 std::get<double>(densities_.frozen->value(variable_array, pos, t, dt));
84 auto const rho_po =
85 std::get<double>(densities_.porous->value(variable_array, pos, t, dt));
86
87 auto const c_li = std::get<double>(
88 spec_heat_capacities_.liquid->value(variable_array, pos, t, dt));
89 auto const c_fr = std::get<double>(
90 spec_heat_capacities_.frozen->value(variable_array, pos, t, dt));
91 auto const c_po = std::get<double>(
92 spec_heat_capacities_.porous->value(variable_array, pos, t, dt));
93
94 // rule of mixtures for resulting volumetric heat capacity
95 // (mass fraction average of specific heat capacities!)
96 return phi_li * rho_li * c_li + phi_fr * rho_fr * c_fr +
97 phi_po * rho_po * c_po;
98}
99
101 VariableArray const& variable_array,
102 ParameterLib::SpatialPosition const& pos, double const t,
103 double const dt) const
104{
105 auto const& medium = *std::get<Medium*>(scale_);
106 auto const& effective_density_property = medium[PropertyType::density];
107 auto const& frozen_fraction_property =
109
110 auto const rho_eff = effective_density_property.template value<double>(
111 variable_array, pos, t, dt);
112 auto const rho_fr =
113 std::get<double>(densities_.frozen->value(variable_array, pos, t, dt));
114 auto const dphi_fr_dT = frozen_fraction_property.template dValue<double>(
115 variable_array, Variable::temperature, pos, t, dt);
116
117 auto const Cvol =
118 effectiveVolumetricHeatCapacity(variable_array, pos, t, dt);
119 auto const Lvol = l_ * rho_fr;
120 auto const Cvol_app = Cvol - Lvol * dphi_fr_dT;
121 // divide volumetric quantity by density in order to obtain specific value
122 return Cvol_app / rho_eff;
123}
124
126 VariableArray const& variable_array, Variable const variable,
127 ParameterLib::SpatialPosition const& pos, double const t,
128 double const dt) const
129{
130 (void)variable;
131 assert((variable == Variable::temperature) &&
132 "SpecificHeatCapacityWithLatentHeat::dvalue is implemented for "
133 "derivatives with respect to temperature only.");
134
135 auto const& medium = *std::get<Medium*>(scale_);
136 auto const& effective_density_property = medium[PropertyType::density];
137 auto const& frozen_fraction_property =
139
140 auto const rho_eff = effective_density_property.template value<double>(
141 variable_array, pos, t, dt);
142 auto const rho_li =
143 std::get<double>(densities_.liquid->value(variable_array, pos, t, dt));
144 auto const rho_fr =
145 std::get<double>(densities_.frozen->value(variable_array, pos, t, dt));
146 auto const c_li = std::get<double>(
147 spec_heat_capacities_.liquid->value(variable_array, pos, t, dt));
148 auto const c_fr = std::get<double>(
149 spec_heat_capacities_.frozen->value(variable_array, pos, t, dt));
150 auto const drho_dT = effective_density_property.template dValue<double>(
151 variable_array, Variable::temperature, pos, t, dt);
152 auto const dphi_fr_dT = frozen_fraction_property.template dValue<double>(
153 variable_array, Variable::temperature, pos, t, dt);
154 auto const d2phi_fr_dT2 = frozen_fraction_property.template d2Value<double>(
155 variable_array, Variable::temperature, Variable::temperature, pos, t,
156 dt);
157 auto const Cvol =
158 effectiveVolumetricHeatCapacity(variable_array, pos, t, dt);
159 // TODO: avoid duplicate code, call value()?
160 auto const C_app = (Cvol - l_ * rho_eff * dphi_fr_dT) / rho_eff;
161 auto const dCvol_dphi_fr = rho_fr * c_fr - rho_li * c_li;
162 auto const dCvol_app_dT =
163 dCvol_dphi_fr * dphi_fr_dT - l_ * rho_eff * d2phi_fr_dT2;
164
165 return (dCvol_app_dT - drho_dT / rho_eff * C_app) / rho_eff;
166}
167} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual PropertyDataType d2Value(VariableArray const &variable_array, Variable const variable1, Variable const variable2, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
Default implementation: 2nd derivative of any constant property is zero.
virtual PropertyDataType value() const
std::variant< Medium *, Phase *, Component * > scale_
void setProperties(std::vector< std::unique_ptr< Phase > > const &phases) override
Default implementation:
PhaseProperties spec_heat_capacities_
Pointers to the properties in each phase.
PhaseProperties densities_
Pointers to the properties in each phase.
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
double effectiveVolumetricHeatCapacity(VariableArray const &variable_array, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const
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