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 std::string const& phase_name = phase->name;
40
41 auto const& density_property =
43 auto const& specific_heat_capacity_property = phase->property(
45
46 if (phase_name == "AqueousLiquid")
47 {
48 densities_.liquid = &density_property;
49 spec_heat_capacities_.liquid = &specific_heat_capacity_property;
50 }
51 else if (phase_name == "FrozenLiquid")
52 {
53 densities_.frozen = &density_property;
54 spec_heat_capacities_.frozen = &specific_heat_capacity_property;
55 }
56 else if (phase_name == "Solid")
57 {
58 densities_.porous = &density_property;
59 spec_heat_capacities_.porous = &specific_heat_capacity_property;
60 }
61 }
62}
63
65 VariableArray const& variable_array,
66 ParameterLib::SpatialPosition const& pos, double const t,
67 double const dt) const
68{
69 auto const& medium = *std::get<Medium*>(scale_);
70 auto const& porosity_property = medium[PropertyType::porosity];
71 auto const& frozen_fraction_property =
73
74 auto const phi =
75 std::get<double>(porosity_property.value(variable_array, pos, t, dt));
76 auto const phi_fr = std::get<double>(
77 frozen_fraction_property.value(variable_array, pos, t, dt));
78 auto const phi_li = phi - phi_fr;
79 auto const phi_po = 1 - phi;
80
81 auto const rho_li =
82 std::get<double>(densities_.liquid->value(variable_array, pos, t, dt));
83 auto const rho_fr =
84 std::get<double>(densities_.frozen->value(variable_array, pos, t, dt));
85 auto const rho_po =
86 std::get<double>(densities_.porous->value(variable_array, pos, t, dt));
87
88 auto const c_li = std::get<double>(
89 spec_heat_capacities_.liquid->value(variable_array, pos, t, dt));
90 auto const c_fr = std::get<double>(
91 spec_heat_capacities_.frozen->value(variable_array, pos, t, dt));
92 auto const c_po = std::get<double>(
93 spec_heat_capacities_.porous->value(variable_array, pos, t, dt));
94
95 // rule of mixtures for resulting volumetric heat capacity
96 // (mass fraction average of specific heat capacities!)
97 return phi_li * rho_li * c_li + phi_fr * rho_fr * c_fr +
98 phi_po * rho_po * c_po;
99}
100
102 VariableArray const& variable_array,
103 ParameterLib::SpatialPosition const& pos, double const t,
104 double const dt) const
105{
106 auto const& medium = *std::get<Medium*>(scale_);
107 auto const& effective_density_property = medium[PropertyType::density];
108 auto const& frozen_fraction_property =
110
111 auto const rho_eff = effective_density_property.template value<double>(
112 variable_array, pos, t, dt);
113 auto const rho_fr =
114 std::get<double>(densities_.frozen->value(variable_array, pos, t, dt));
115 auto const dphi_fr_dT = frozen_fraction_property.template dValue<double>(
116 variable_array, Variable::temperature, pos, t, dt);
117
118 auto const Cvol =
119 effectiveVolumetricHeatCapacity(variable_array, pos, t, dt);
120 auto const Lvol = l_ * rho_fr;
121 auto const Cvol_app = Cvol - Lvol * dphi_fr_dT;
122 // divide volumetric quantity by density in order to obtain specific value
123 return Cvol_app / rho_eff;
124}
125
127 VariableArray const& variable_array, Variable const variable,
128 ParameterLib::SpatialPosition const& pos, double const t,
129 double const dt) const
130{
131 (void)variable;
132 assert((variable == Variable::temperature) &&
133 "SpecificHeatCapacityWithLatentHeat::dvalue is implemented for "
134 "derivatives with respect to temperature only.");
135
136 auto const& medium = *std::get<Medium*>(scale_);
137 auto const& effective_density_property = medium[PropertyType::density];
138 auto const& frozen_fraction_property =
140
141 auto const rho_eff = effective_density_property.template value<double>(
142 variable_array, pos, t, dt);
143 auto const rho_li =
144 std::get<double>(densities_.liquid->value(variable_array, pos, t, dt));
145 auto const rho_fr =
146 std::get<double>(densities_.frozen->value(variable_array, pos, t, dt));
147 auto const c_li = std::get<double>(
148 spec_heat_capacities_.liquid->value(variable_array, pos, t, dt));
149 auto const c_fr = std::get<double>(
150 spec_heat_capacities_.frozen->value(variable_array, pos, t, dt));
151 auto const drho_dT = effective_density_property.template dValue<double>(
152 variable_array, Variable::temperature, pos, t, dt);
153 auto const dphi_fr_dT = frozen_fraction_property.template dValue<double>(
154 variable_array, Variable::temperature, pos, t, dt);
155 auto const d2phi_fr_dT2 = frozen_fraction_property.template d2Value<double>(
156 variable_array, Variable::temperature, Variable::temperature, pos, t,
157 dt);
158 auto const Cvol =
159 effectiveVolumetricHeatCapacity(variable_array, pos, t, dt);
160 // TODO: avoid duplicate code, call value()?
161 auto const C_app = (Cvol - l_ * rho_eff * dphi_fr_dT) / rho_eff;
162 auto const dCvol_dphi_fr = rho_fr * c_fr - rho_li * c_li;
163 auto const dCvol_app_dT =
164 dCvol_dphi_fr * dphi_fr_dT - l_ * rho_eff * d2phi_fr_dT2;
165
166 return (dCvol_app_dT - drho_dT / rho_eff * C_app) / rho_eff;
167}
168} // 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