MoonBit vapor-liquid equilibrium toolkit with Raoult, Henry, Wilson, NRTL and UNIQUAC helpers.
moon update
moon check --target all
moon test --target all///|
test {
let point = @moonbit-vle.bubble_temperature_k(
@moonbit-vle.benzene_toluene(),
[0.45, 0.55],
1.01325,
low_k=340.0,
high_k=390.0,
)
inspect(
point.temperature_k > 360.0 && point.temperature_k < 370.0,
content="true",
)
}moon run cmd/main --target wasm-gc///|
test {
let components = @moonbit-vle.ethanol_water()
let ideal = @moonbit-vle.bubble_pressure_bar(components, [0.4, 0.6], 351.15)
let wilson = @moonbit-vle.bubble_pressure_bar(
components,
[0.4, 0.6],
351.15,
model=@moonbit-vle.ethanol_water_wilson(),
)
inspect(ideal.pressure_bar > 0.0, content="true")
inspect(wilson.pressure_bar > ideal.pressure_bar, content="true")
}///|
test {
let matrix = @moonbit-vle.WilsonMatrix::new(
lambda=[[1.0, 0.8], [1.2, 1.0]],
source="example parameters",
)
let result = @moonbit-vle.flash_isothermal_activity(
@moonbit-vle.benzene_toluene(),
[0.5, 0.5],
370.0,
1.01325,
@moonbit-vle.MulticomponentActivityModel::Wilson(matrix),
)
inspect(result.converged, content="true")
}moon run cmd/main --target wasm-gcmoon fmt --check
moon check --deny-warn --target all
moon build --target all
moon test --deny-warn --target all
moon test --target native
moon info
git diff --exit-codemoon test --enable-coverage --target native
moon coverage report -f summary
moon coverage analyzepub(all) suberror VleError {
EmptyMixture
LengthMismatch(expected~ : Int, actual~ : Int)
InvalidFraction(index~ : Int, value~ : Double)
NonPositiveTemperature(Double)
NonPositivePressure(Double)
MissingBinaryParameter(i~ : Int, j~ : Int)
SolverDidNotBracket(low~ : Double, high~ : Double)
SolverDidNotConverge(iterations~ : Int)
InvalidSolverOptions(String)
InvalidParameter(String)
InvalidRange(low~ : Double, high~ : Double)
} derive(Eq, Debug)fn ActivityFlashResult::new(temperature_k~ : Double, pressure_bar~ : Double, vapor_fraction~ : Double, liquid~ : Array[Double], vapor~ : Array[Double], k_values~ : Array[Double], iterations~ : Int, converged~ : Bool, residual~ : Double) -> ActivityFlashResultpub(all) enum ActivityModel {
Ideal
Wilson(WilsonBinary)
Nrtl(NrtlBinary)
Uniquac(UniquacBinary)
} derive(Debug)pub struct Antoine {
a : Double
b : Double
c : Double
t_min_k : Double
t_max_k : Double
note : String
} derive(Debug)pub struct AntoineFitResult {
a : Double
b : Double
c : Double
rmse_bar : Double
max_error_bar : Double
points : Int
converged : Bool
} derive(Debug)fn BenchmarkPoint::new(system~ : String, temperature_k~ : Double, pressure_bar~ : Double, liquid~ : Array[Double], vapor~ : Array[Double], source~ : String, tolerance~ : Double) -> BenchmarkPoint raise VleErrorpub struct BenchmarkSummary {
total : Int
passed : Int
failed : Int
pass_rate : Double
mean_error : Double
max_error : Double
} derive(Debug)fn BinarySplitResult::new(feed~ : Array[Double], distillate~ : Array[Double], bottoms~ : Array[Double], distillate_total~ : Double, bottoms_total~ : Double, component_balance_error~ : Double) -> BinarySplitResultpub struct ClausiusClapeyron {
reference_pressure_bar : Double
reference_temperature_k : Double
enthalpy_vaporization_j_per_mol : Double
source : String
} derive(Debug)fn ClausiusClapeyron::boiling_temperature_k(self : ClausiusClapeyron, pressure_bar : Double, low_k? : Double, high_k? : Double) -> Double raise VleErrorfn ClausiusClapeyron::new(reference_pressure_bar~ : Double, reference_temperature_k~ : Double, enthalpy_vaporization_j_per_mol~ : Double, source~ : String) -> ClausiusClapeyronfn ClausiusClapeyron::pressure_bar(self : ClausiusClapeyron, temperature_k : Double) -> Double raise VleErrorfn ClausiusClapeyron::pressure_change_ratio(self : ClausiusClapeyron, low_temperature_k : Double, high_temperature_k : Double) -> Double raise VleErrorpub struct CorrelationComparison {
name : String
points : Int
mean_relative_difference : Double
maximum_relative_difference : Double
} derive(Debug)pub struct Dippr101 {
a : Double
b : Double
c : Double
d : Double
e : Double
t_min_k : Double
t_max_k : Double
source : String
} derive(Debug)fn EnergyFlashResult::new(temperature_k~ : Double, pressure_bar~ : Double, vapor_fraction~ : Double, liquid~ : Array[Double], vapor~ : Array[Double], enthalpy_j_per_mol~ : Double, iterations~ : Int) -> EnergyFlashResultfn EquilibriumPoint::new(temperature_k~ : Double, pressure_bar~ : Double, liquid~ : Array[Double], vapor~ : Array[Double], iterations~ : Int) -> EquilibriumPointpub struct EquilibriumProfilePoint {
liquid_fraction : Double
vapor_fraction : Double
relative_volatility : Double
} derive(Debug)pub struct ExtendedAntoine {
a : Double
b : Double
c : Double
d : Double
e : Double
t_min_k : Double
t_max_k : Double
source : String
} derive(Debug)fn ExtendedAntoine::boiling_temperature_k(self : ExtendedAntoine, pressure_bar : Double, low_k? : Double, high_k? : Double) -> Double raise VleErrorfn ExtendedAntoine::new(a~ : Double, b~ : Double, c~ : Double, d~ : Double, e~ : Double, t_min_k~ : Double, t_max_k~ : Double, source~ : String) -> ExtendedAntoinefn ExtendedAntoine::pressure_bar(self : ExtendedAntoine, temperature_k : Double) -> Double raise VleErrorfn ExtendedAntoine::pressure_bar_checked(self : ExtendedAntoine, temperature_k : Double) -> Double raise VleErrorfn FlashResult::new(temperature_k~ : Double, pressure_bar~ : Double, vapor_fraction~ : Double, liquid~ : Array[Double], vapor~ : Array[Double], iterations~ : Int) -> FlashResultfn HeatCapacityPolynomial::derivative(self : HeatCapacityPolynomial, temperature_k : Double) -> Double raise VleErrorfn HeatCapacityPolynomial::evaluate(self : HeatCapacityPolynomial, temperature_k : Double) -> Double raise VleErrorfn HeatCapacityPolynomial::integral(self : HeatCapacityPolynomial, low_k~ : Double, high_k~ : Double) -> Double raise VleErrorfn HeatCapacityPolynomial::is_in_range(self : HeatCapacityPolynomial, temperature_k : Double) -> Boolfn HeatCapacityPolynomial::new(coefficients~ : Array[Double], t_min_k~ : Double, t_max_k~ : Double, source~ : String) -> HeatCapacityPolynomial raise VleErrorpub struct KValueDiagnostics {
regime : PhaseRegime
f_at_zero : Double
f_at_one : Double
minimum_k : Double
maximum_k : Double
stability_margin : Double
} derive(Debug)pub struct MatrixStatistics {
dimension : Int
minimum : Double
maximum : Double
maximum_asymmetry : Double
diagonal_error : Double
} derive(Debug)pub(all) enum MulticomponentActivityModel {
Ideal
Wilson(WilsonMatrix)
Nrtl(NrtlMatrix)
Uniquac(UniquacMatrix)
} derive(Debug)fn NrtlBinary::new(tau12~ : Double, tau21~ : Double, alpha~ : Double, source~ : String) -> NrtlBinaryfn NrtlMatrix::new(tau~ : Array[Array[Double]], alpha~ : Array[Array[Double]], source~ : String) -> NrtlMatrixpub struct ParameterRecord {
name : String
value : Double
unit : String
lower_bound : Double
upper_bound : Double
source : String
} derive(Debug)fn ParameterRecord::new(name~ : String, value~ : Double, unit~ : String, lower_bound~ : Double, upper_bound~ : Double, source~ : String) -> ParameterRecordfn PhasePoint::new(temperature_k~ : Double, pressure_bar~ : Double, composition~ : Array[Double], phase~ : PhaseKind) -> PhasePointpub struct PurePressureBenchmark {
component : String
temperature_k : Double
pressure_bar : Double
source : String
tolerance : Double
} derive(Debug)fn PurePressureBenchmark::new(component~ : String, temperature_k~ : Double, pressure_bar~ : Double, source~ : String, tolerance~ : Double) -> PurePressureBenchmark raise VleErrorpub struct ResidualMetrics {
count : Int
mean_absolute_error : Double
rmse : Double
max_abs_error : Double
max_relative_error : Double
signed_bias : Double
} derive(Debug)pub struct SensitivityPoint {
temperature_k : Double
pressure_bar : Double
derivative_bar_per_k : Double
relative_sensitivity : Double
} derive(Debug)fn SolidSolubility::new(component~ : Component, solvent~ : Component, temperature_k~ : Double, mole_fraction~ : Double, source~ : String) -> SolidSolubilitypub struct SolverReport {
root : Double
residual : Double
iterations : Int
converged : Bool
} derive(Debug)fn SolverReport::new(root~ : Double, residual~ : Double, iterations~ : Int, converged~ : Bool) -> SolverReportpub struct ThermoProperty {
component : Component
molecular_weight_g_per_mol : Double
liquid_heat_capacity : HeatCapacityPolynomial
vapor_heat_capacity : HeatCapacityPolynomial
reference_temperature_k : Double
normal_boiling_temperature_k : Double
latent_heat_j_per_mol : Double
source : String
} derive(Debug)fn ThermoProperty::new(component~ : Component, molecular_weight_g_per_mol~ : Double, liquid_heat_capacity~ : HeatCapacityPolynomial, vapor_heat_capacity~ : HeatCapacityPolynomial, reference_temperature_k~ : Double, normal_boiling_temperature_k~ : Double, latent_heat_j_per_mol~ : Double, source~ : String) -> ThermoProperty raise VleErrorpub struct UniquacBinary {
comp1 : UniquacComponent
comp2 : UniquacComponent
tau12 : Double
tau21 : Double
source : String
} derive(Debug)fn UniquacBinary::new(comp1~ : UniquacComponent, comp2~ : UniquacComponent, tau12~ : Double, tau21~ : Double, source~ : String) -> UniquacBinaryfn UniquacMatrix::new(r~ : Array[Double], q~ : Array[Double], tau~ : Array[Array[Double]], source~ : String) -> UniquacMatrixpub struct Wagner {
a : Double
b : Double
c : Double
d : Double
critical_temperature_k : Double
critical_pressure_bar : Double
t_min_k : Double
t_max_k : Double
source : String
} derive(Debug)fn activity_coefficients(model : ActivityModel, liquid : Array[Double], temperature_k : Double) -> Array[Double] raise VleErrorfn activity_flash_k_error(result : ActivityFlashResult, components : Array[Component], temperature_k : Double, pressure_bar : Double, model : MulticomponentActivityModel) -> Double raise VleErrorfn activity_flash_material_balance_error(result : ActivityFlashResult, feed : Array[Double]) -> Double raise VleErrorfn antoine_fit_is_reasonable(result : AntoineFitResult, max_rmse_bar : Double) -> Bool raise VleErrorfn antoine_fit_mean_absolute_error(result : AntoineFitResult, observations : Array[AntoineObservation]) -> Double raise VleErrorfn antoine_fit_predict_many(result : AntoineFitResult, temperatures_k : Array[Double]) -> Array[Double] raise VleErrorfn antoine_fit_pressure_bar(a : Double, b : Double, c : Double, temperature_k : Double) -> Double raise VleErrorfn antoine_fit_residuals(result : AntoineFitResult, observations : Array[AntoineObservation]) -> Array[Double] raise VleErrorfn audit_activity_flash(result : ActivityFlashResult, feed : Array[Double]) -> EquilibriumAudit raise VleErrorfn audit_flash_result(result : FlashResult, feed : Array[Double]) -> EquilibriumAudit raise VleErrorfn average_heat_capacity(correlation : HeatCapacityPolynomial, low_k~ : Double, high_k~ : Double) -> Double raise VleErrorfn benchmark_is_within_pressure_tolerance(point : BenchmarkPoint, predicted_pressure_bar : Double) -> Boolfn benchmark_prediction_from_component(component : Component, point : PurePressureBenchmark) -> Double raise VleErrorfn benchmark_summary_error_budget(summary : BenchmarkSummary, maximum_allowed_error : Double) -> Bool raise VleErrorfn benchmark_summary_is_successful(summary : BenchmarkSummary, required_pass_rate : Double) -> Bool raise VleErrorfn binary_equilibrium_x(vapor_light_fraction : Double, relative_volatility : Double) -> Double raise VleErrorfn binary_equilibrium_y(liquid_light_fraction : Double, relative_volatility : Double) -> Double raise VleErrorfn bubble_curve_binary(components : Array[Component], model : MulticomponentActivityModel, pressure_bar~ : Double, points~ : Int, low_k~ : Double, high_k~ : Double) -> Array[EquilibriumPoint] raise VleErrorfn bubble_pressure_bar(components : Array[Component], liquid : Array[Double], temperature_k : Double, model? : ActivityModel) -> EquilibriumPoint raise VleErrorfn bubble_pressure_multicomponent(components : Array[Component], liquid : Array[Double], temperature_k : Double, model : MulticomponentActivityModel) -> EquilibriumPoint raise VleErrorfn bubble_pressure_temperature_sensitivity(components : Array[Component], liquid : Array[Double], temperature_k : Double, step_k : Double, model? : ActivityModel) -> SensitivityPoint raise VleErrorfn bubble_temperature_k(components : Array[Component], liquid : Array[Double], pressure_bar : Double, low_k? : Double, high_k? : Double, model? : ActivityModel) -> EquilibriumPoint raise VleErrorfn bubble_temperature_multicomponent(components : Array[Component], liquid : Array[Double], pressure_bar : Double, low_k? : Double, high_k? : Double, model : MulticomponentActivityModel) -> EquilibriumPoint raise VleErrorfn classify_phase_regime(k_values : Array[Double], feed : Array[Double]) -> PhaseRegime raise VleErrorfn compare_pressure_correlations(reference : Component, temperatures_k : Array[Double], correlations : Array[ExtendedAntoine]) -> Array[CorrelationComparison] raise VleErrorfn component_liquid_enthalpy(property : ThermoProperty, temperature_k : Double) -> Double raise VleErrorfn component_phase_enthalpy(property : ThermoProperty, temperature_k : Double, phase : PhaseKind) -> Double raise VleErrorfn component_vapor_enthalpy(property : ThermoProperty, temperature_k : Double) -> Double raise VleErrorfn correlation_relative_difference(reference_pressure_bar : Double, candidate_pressure_bar : Double) -> Double raise VleErrorfn curve_compositions_sum_to_one(curve : Array[EquilibriumPoint], tolerance : Double) -> Bool raise VleErrorfn dew_curve_binary(components : Array[Component], model : MulticomponentActivityModel, pressure_bar~ : Double, points~ : Int, low_k~ : Double, high_k~ : Double) -> Array[EquilibriumPoint] raise VleErrorfn dew_pressure_bar(components : Array[Component], vapor : Array[Double], temperature_k : Double, model? : ActivityModel) -> EquilibriumPoint raise VleErrorfn dew_pressure_multicomponent(components : Array[Component], vapor : Array[Double], temperature_k : Double, model : MulticomponentActivityModel) -> EquilibriumPoint raise VleErrorfn dew_temperature_k(components : Array[Component], vapor : Array[Double], pressure_bar : Double, low_k? : Double, high_k? : Double, model? : ActivityModel) -> EquilibriumPoint raise VleErrorfn dew_temperature_multicomponent(components : Array[Component], vapor : Array[Double], pressure_bar : Double, low_k? : Double, high_k? : Double, model : MulticomponentActivityModel) -> EquilibriumPoint raise VleErrorfn equilibrium_curve_slope(relative_volatility : Double, liquid_fraction : Double) -> Double raise VleErrorfn estimate_vapor_fraction_from_enthalpy(liquid_enthalpy : Double, vapor_enthalpy : Double, target_enthalpy : Double) -> Double raise VleErrorfn evaluate_pure_pressure_catalog(components : Array[Component], points : Array[PurePressureBenchmark]) -> BenchmarkSummary raise VleErrorfn fenske_minimum_stages(relative_volatility~ : Double, light_key_distillate_fraction~ : Double, light_key_bottoms_fraction~ : Double) -> Double raise VleErrorfn finite_difference_condition_number(base_value : Double, low_value : Double, high_value : Double, relative_step : Double) -> Double raise VleErrorfn fit_antoine(observations : Array[AntoineObservation], initial_c~ : Double, c_span~ : Double, c_steps~ : Int) -> AntoineFitResult raise VleErrorfn flash_enthalpy_at_temperature(properties : Array[ThermoProperty], feed : Array[Double], temperature_k : Double, pressure_bar : Double) -> Double raise VleErrorfn flash_isenthalpic_ideal(properties : Array[ThermoProperty], feed : Array[Double], feed_temperature_k~ : Double, pressure_bar~ : Double, target_enthalpy_j_per_mol~ : Double, low_k? : Double, high_k? : Double) -> EnergyFlashResult raise VleErrorfn flash_isothermal_activity(components : Array[Component], feed : Array[Double], temperature_k : Double, pressure_bar : Double, model : MulticomponentActivityModel, damping? : Double, tolerance? : Double, max_iterations? : Int) -> ActivityFlashResult raise VleErrorfn flash_isothermal_ideal(components : Array[Component], feed : Array[Double], temperature_k : Double, pressure_bar : Double) -> FlashResult raise VleErrorfn generate_equilibrium_profile(relative_volatility~ : Double, points~ : Int) -> Array[EquilibriumProfilePoint] raise VleErrorfn heat_capacity_change(correlation : HeatCapacityPolynomial, low_k~ : Double, high_k~ : Double) -> Double raise VleErrorfn k_value_diagnostics(k_values : Array[Double], feed : Array[Double]) -> KValueDiagnostics raise VleErrorfn latent_energy_fraction(property : ThermoProperty, temperature_k : Double, critical_temperature_k : Double) -> Double raise VleErrorfn latent_heat_at(property : ThermoProperty, temperature_k : Double, critical_temperature_k : Double) -> Double raise VleErrorfn lever_rule_fraction(feed : Double, raffinate : Double, extract : Double) -> Doublefn linear_interpolate(x0 : Double, y0 : Double, x1 : Double, y1 : Double, x : Double) -> Double raise VleErrorfn liquid_sensible_heat_capacity(property : ThermoProperty, temperature_k : Double) -> Double raise VleErrorfn mass_flow_to_molar_flow(mass_flow_kg_per_s : Double, molecular_weight_g_per_mol : Double) -> Double raise VleErrorfn merge_validation_summaries(first : ValidationSummary, second : ValidationSummary) -> ValidationSummaryfn minimum_reflux_ratio_binary(feed_light_fraction~ : Double, distillate_light_fraction~ : Double, relative_volatility~ : Double) -> Double raise VleErrorfn mixture_energy_gap(properties : Array[ThermoProperty], composition : Array[Double], temperature_k : Double) -> Double raise VleErrorfn mixture_liquid_enthalpy(properties : Array[ThermoProperty], composition : Array[Double], temperature_k : Double) -> Double raise VleErrorfn mixture_phase_enthalpy(properties : Array[ThermoProperty], composition : Array[Double], temperature_k : Double, phase : PhaseKind) -> Double raise VleErrorfn mixture_vapor_enthalpy(properties : Array[ThermoProperty], composition : Array[Double], temperature_k : Double) -> Double raise VleErrorfn molar_flow_to_mass_flow(molar_flow_mol_per_s : Double, molecular_weight_g_per_mol : Double) -> Double raise VleErrorfn multicomponent_activity_coefficients(model : MulticomponentActivityModel, liquid : Array[Double], temperature_k : Double) -> Array[Double] raise VleErrorfn normalized_sensitivity(derivative : Double, value : Double, scale : Double) -> Double raise VleErrorfn operating_line_gap(profile_point : EquilibriumProfilePoint, reflux_ratio : Double, distillate_fraction : Double) -> Double raise VleErrorfn operating_line_y(liquid_fraction : Double, reflux_ratio : Double, distillate_fraction : Double) -> Double raise VleErrorfn parameter_is_near_lower_bound(record : ParameterRecord, fraction : Double) -> Bool raise VleErrorfn parameter_is_near_upper_bound(record : ParameterRecord, fraction : Double) -> Bool raise VleErrorfn parameter_records_in_unit(records : Array[ParameterRecord], unit : String) -> Array[ParameterRecord]fn parameter_records_with_source(records : Array[ParameterRecord], source_fragment : String) -> Array[ParameterRecord]fn pressure_uncertainty_from_temperature(sensitivity : SensitivityPoint, temperature_uncertainty_k : Double) -> Double raise VleErrorfn profile_gap_integral(profile : Array[EquilibriumProfilePoint], low_fraction : Double, high_fraction : Double) -> Double raise VleErrorfn profile_interpolate(profile : Array[EquilibriumProfilePoint], liquid_fraction : Double) -> Double raise VleErrorfn profile_operating_line_crossings(profile : Array[EquilibriumProfilePoint], reflux_ratio : Double, distillate_fraction : Double) -> Int raise VleErrorfn profile_points_above_operating_line(profile : Array[EquilibriumProfilePoint], reflux_ratio : Double, distillate_fraction : Double) -> Int raise VleErrorfn q_line_intersection(feed_light_fraction : Double, q_value : Double, equilibrium_relative_volatility : Double) -> (Double, Double) raise VleErrorfn quality_gate(metrics : ResidualMetrics, max_rmse~ : Double, max_relative_error~ : Double) -> Boolfn relative_sensitivity_from_perturbation(base_value : Double, perturbed_value : Double, relative_perturbation : Double) -> Double raise VleErrorfn sample_polynomial(correlation : HeatCapacityPolynomial, low_k~ : Double, high_k~ : Double, count~ : Int) -> Array[Double] raise VleErrorfn saturation_pressure_sensitivity(component : Component, temperature_k : Double, step_k : Double) -> SensitivityPoint raise VleErrorfn sensible_energy_between(property : ThermoProperty, low_temperature_k : Double, high_temperature_k : Double, phase : PhaseKind) -> Double raise VleErrorfn sensitivity_profile_maximum(profile : Array[SensitivityPoint]) -> SensitivityPoint raise VleErrorfn shortcut_distillation_binary(feed : Array[Double], relative_volatility~ : Double, light_key_distillate_fraction~ : Double, light_key_bottoms_fraction~ : Double, reflux_multiplier? : Double) -> ShortcutColumnResult raise VleErrorfn solve_bisection(low~ : Double, high~ : Double, options~ : SolverOptions, f : (Double) -> Double raise VleError) -> SolverReport raise VleErrorfn solve_newton(initial~ : Double, low~ : Double, high~ : Double, options~ : SolverOptions, f : (Double) -> Double raise VleError, derivative : (Double) -> Double raise VleError) -> SolverReport raise VleErrorfn split_binary_stream(feed : Array[Double], light_key_recovery~ : Double, heavy_key_recovery~ : Double) -> BinarySplitResult raise VleErrorfn summarize_pressure_benchmarks(points : Array[PurePressureBenchmark], predicted_pressures_bar : Array[Double]) -> BenchmarkSummary raise VleErrorfn summarize_vle_benchmarks(points : Array[BenchmarkPoint], predicted_pressures_bar : Array[Double]) -> BenchmarkSummary raise VleErrorfn symmetric_perturbations(value : Double, relative_change : Double) -> (Double, Double) raise VleErrorfn temperature_sensitivity_profile(component : Component, temperatures_k : Array[Double], step_k : Double) -> Array[SensitivityPoint] raise VleErrorfn validate_binary_parameters(first : Double, second : Double, tolerance : Double) -> ValidationSummaryfn validate_composition_for_model(composition : Array[Double], expected_dimension : Int) -> ValidationSummaryfn validate_correlation_pair(lower_temperature_k : Double, upper_temperature_k : Double, lower_pressure_bar : Double, upper_pressure_bar : Double) -> ValidationSummaryfn validate_pressure_prediction(reference_pressure_bar : Double, predicted_pressure_bar : Double, tolerance_bar : Double) -> ValidationSummaryfn validate_pressure_range(pressure_bar : Double, low_bar : Double, high_bar : Double) -> ValidationSummaryfn validate_temperature_delta(temperature_delta_k : Double, maximum_delta_k : Double) -> ValidationSummaryfn validate_temperature_range(temperature_k : Double, low_k : Double, high_k : Double) -> ValidationSummaryfn validate_thermo_inputs(components~ : Array[Component], composition~ : Array[Double], temperature_k~ : Double, pressure_bar~ : Double) -> ValidationSummaryfn van_t_hoff_solid_solubility(melting_temperature_k~ : Double, fusion_enthalpy_j_per_mol~ : Double, temperature_k~ : Double) -> Double raise VleErrorfn vapor_sensible_heat_capacity(property : ThermoProperty, temperature_k : Double) -> Double raise VleErrorfn watson_latent_heat(reference_latent_heat_j_per_mol~ : Double, reference_temperature_k~ : Double, critical_temperature_k~ : Double, temperature_k~ : Double) -> Double raise VleErrorfn weighted_phase_enthalpy(liquid_enthalpy : Double, vapor_enthalpy : Double, vapor_fraction : Double) -> Double raise VleErrorMoonBit vapor-liquid equilibrium toolkit with Raoult, Henry, Wilson, NRTL and UNIQUAC helpers.