124 if (capacity <= 0.0 || energyJ == 0.0 || !std::isfinite(energyJ))
return;
127 const double fusionEnergy = activeMass *
static_cast<double>(std::max(props.
latentHeatFusion, 0.0f));
128 const double vaporizationEnergy = activeMass *
static_cast<double>(std::max(props.
latentHeatVaporization, 0.0f));
129 const double meltingPoint =
static_cast<double>(std::max(props.
meltingPoint, 0.0f));
130 const double boilingPoint =
static_cast<double>(std::max(props.
boilingPoint, 0.0f));
132 auto applySensibleHeatToward = [&](
double targetTemp,
double& energy) {
133 const double initialTemp = props.
tempK;
135 const double required = (targetTemp - props.
tempK) * capacity;
136 if ((energy > 0.0 && required <= 0.0) || (energy < 0.0 && required >= 0.0))
return false;
137 if (std::abs(energy) < std::abs(required)) {
149 auto applyLatentHeat = [&](
double latentCapacity,
float& progress,
double& energy) {
150 if (latentCapacity <= 0.0 || energy == 0.0)
return;
151 const double phaseTemp = std::max(props.
tempK, 1.0e-9);
154 const double required = (1.0 -
static_cast<double>(progress)) * latentCapacity;
155 if (energy < required) {
156 progress =
static_cast<float>(std::clamp(
static_cast<double>(progress) + energy / latentCapacity, 0.0, 1.0));
165 const double released =
static_cast<double>(progress) * latentCapacity;
166 const double cooling = -energy;
167 if (cooling < released) {
168 progress =
static_cast<float>(std::clamp(
static_cast<double>(progress) - cooling / latentCapacity, 0.0, 1.0));
180 if (meltingPoint > 0.0 && props.
tempK < meltingPoint && applySensibleHeatToward(meltingPoint, energyJ))
return;
182 props.
tempK = meltingPoint;
184 if (energyJ == 0.0)
return;
187 if (boilingPoint > 0.0 && props.
tempK < boilingPoint && applySensibleHeatToward(boilingPoint, energyJ))
return;
189 props.
tempK = boilingPoint;
191 if (energyJ == 0.0)
return;
194 const double initialTemp = props.
tempK;
200 if (boilingPoint > 0.0 && props.
tempK > boilingPoint && applySensibleHeatToward(boilingPoint, energyJ))
return;
202 props.
tempK = boilingPoint;
204 if (energyJ == 0.0)
return;
207 if (meltingPoint > 0.0 && props.
tempK > meltingPoint && applySensibleHeatToward(meltingPoint, energyJ))
return;
209 props.
tempK = meltingPoint;
211 if (energyJ == 0.0)
return;
214 const double initialTemp = props.
tempK;