Chemical reactor design toolkit for CSTR, PFR, and batch calculations in MoonBit.
///|
test {
let reaction = Reaction::new(name="A -> B", order=First, k_ref=0.5)
let feed = Feed::new(
concentration=1.0,
volumetric_flow=2.0,
temperature=300.0,
)
let point = design_pfr(reaction, feed, 4.0)
assert_true(point.conversion > 0.63 && point.conversion < 0.64)
}pub(all) struct BenchmarkCase {
id : String
title : String
category : BenchmarkCategory
source : String
source_url : String
units : String
assumptions : String
expected : Double
tolerance : Double
} derive(ToJson, Debug)fn ControllerConfig::new(proportional~ : Double, integral~ : Double, derivative~ : Double, minimum~ : Double, maximum~ : Double) -> ControllerConfigpub(all) struct ControllerStep {
output : Double
state : ControllerState
saturated : Bool
} derive(ToJson, Debug)pub(all) struct DesignPoint {
kind : ReactorKind
thermal_mode : ThermalMode
volume : Double
residence_time : Double
conversion : Double
outlet_concentration : Double
outlet_temperature : Double
heat_removed : Double
rate_at_outlet : Double
} derive(ToJson, Debug)pub(all) struct NetworkResult {
stages : Array[DesignPoint]
final_conversion : Double
final_concentration : Double
final_temperature : Double
total_volume : Double
} derive(ToJson, Debug)pub(all) struct OperatingScenario {
name : String
reaction : Reaction
feed : Feed
volume : Double
thermal_mode : ThermalMode
exchange : HeatExchange?
} derive(ToJson, Debug)fn OperatingScenario::adiabatic(name~ : String, reaction~ : Reaction, feed~ : Feed, volume~ : Double) -> OperatingScenariofn OperatingScenario::isothermal(name~ : String, reaction~ : Reaction, feed~ : Feed, volume~ : Double) -> OperatingScenariofn OperatingScenario::jacketed(name~ : String, reaction~ : Reaction, feed~ : Feed, volume~ : Double, exchange~ : HeatExchange) -> OperatingScenariopub(all) struct Reaction {
name : String
order : KineticOrder
k_ref : Double
activation_energy : Double
reference_temperature : Double
reaction_enthalpy : Double
} derive(ToJson, Debug)fn Reaction::new(name~ : String, order~ : KineticOrder, k_ref~ : Double, activation_energy? : Double, reference_temperature? : Double, reaction_enthalpy? : Double) -> Reactionpub(all) struct ReactorStage {
kind : ReactorKind
volume : Double
thermal_mode : ThermalMode
exchange : HeatExchange?
} derive(ToJson, Debug)fn ReactorStage::batch(time~ : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> ReactorStagefn ReactorStage::cstr(volume~ : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> ReactorStagefn ReactorStage::pfr(volume~ : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> ReactorStagepub(all) struct SolverReport {
status : SolverStatus
root : Double
residual : Double
iterations : Int
} derive(ToJson, Debug)pub(all) struct TrainResult {
stages : Array[DesignPoint]
final_conversion : Double
total_volume : Double
total_residence_time : Double
} derive(ToJson, Debug)pub(all) struct ValidationMessage {
level : ValidationLevel
field : String
message : String
} derive(ToJson, Debug)fn ValidationReport::push(self : ValidationReport, level : ValidationLevel, field : String, message : String) -> ValidationReportfn adiabatic_rise(heat_release : Double, heat_capacity_flow : Double) -> Doublefn analyze_thermal_train(reaction : Reaction, feed : Feed, stages : ArrayView[ReactorStage], mode : ThermalMode, exchange : HeatExchange?) -> TrainResultfn arrhenius_multiplier(activation_energy : Double, temperature : Double, reference : Double) -> Doublefn balance_closure(inlet : Double, outlet : Double, side_products : Double) -> Doublefn batch_design_window(reaction : Reaction, feed : Feed, minimum_conversion : Double, maximum_temperature : Double, maximum_time : Double, points : Int) -> Array[EnvelopePoint]fn batch_productivity(feed : Feed, conversion : Double, cycle_time : Double, cleaning_time : Double) -> Doublefn batch_profile(reaction : Reaction, feed : Feed, final_time : Double, points~ : Int, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> Array[ProfilePoint]fn best_scenario(scenarios : ArrayView[OperatingScenario], target_conversion : Double, maximum_temperature : Double) -> OperatingScenario?fn bisect(lower : Double, upper : Double, f : (Double) -> Double, settings? : SolverSettings) -> BracketResultfn bisect_report(lower : Double, upper : Double, f : (Double) -> Double, settings? : SolverSettings) -> SolverReportfn bisection_budget(lower : Double, upper : Double, tolerance : Double) -> Intfn blasius_friction_factor(reynolds : Double) -> Doublefn bounded_actuator(value : Double, minimum : Double, maximum : Double) -> Doublefn bracket_condition_number(lower : Double, upper : Double, tolerance : Double) -> Doublefn celsius_to_kelvin(celsius : Double) -> Doublefn central_difference(x : Double, f : (Double) -> Double, step? : Double) -> Doublefn clamp_rate_constant(value : Double, minimum : Double, maximum : Double) -> Doublefn clamp_temperature(temperature : Double, minimum : Double, maximum : Double) -> Doublefn closest_target(scores : ArrayView[ObjectiveScore], target_conversion : Double, target_volume : Double, target_temperature : Double) -> ObjectiveScore?fn compare_scenarios(first : OperatingScenario, second : OperatingScenario, assumptions : CostAssumptions) -> Doublefn compare_train_to_single_pfr(reaction : Reaction, feed : Feed, stages : ArrayView[ReactorStage]) -> (TrainResult, DesignPoint, Double)fn concentration_trajectory(initial : Double, rate_constant : Double, order : KineticOrder, duration : Double, points : Int) -> Array[Double]fn controller_step(config : ControllerConfig, state : ControllerState, setpoint : Double, measurement : Double, dt : Double) -> ControllerStepfn controller_trace_is_bounded(trace : ArrayView[ControllerStep], config : ControllerConfig) -> Boolfn conversion_from_exposure(exposure : Double, order : KineticOrder, concentration : Double) -> Doublefn conversion_from_flows(inlet : Double, outlet : Double) -> Doublefn conversion_residual(expected : Double, actual : Double) -> Doublefn conversion_target_is_well_conditioned(target : Double) -> Boolfn conversion_time_first_order(k : Double, conversion : Double) -> Doublefn cstr_volume_from_endpoint(flow : Double, target_conversion : Double, endpoint_ordinate : Double) -> Doublefn curve_volume_for_target(curve : ArrayView[(Double, Double, Double)], target : Double, use_pfr : Bool) -> Double?fn damkohler_from_time(rate_constant : Double, residence : Double) -> Doublefn design_batch(reaction : Reaction, feed : Feed, time : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> DesignPointfn design_cstr(reaction : Reaction, feed : Feed, volume : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> DesignPointfn design_envelope(reaction : Reaction, feed : Feed, minimum_volume : Double, maximum_volume : Double, steps : Int, minimum_conversion : Double, maximum_temperature : Double) -> Array[EnvelopePoint]fn design_pfr(reaction : Reaction, feed : Feed, volume : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> DesignPointfn design_quality_score(conversion_error : Double, temperature_error : Double, mass_balance_error : Double, conversion_weight : Double, temperature_weight : Double, balance_weight : Double) -> Doublefn design_with_perturbation(reaction : Reaction, feed : Feed, volume : Double, perturbation : Perturbation) -> DesignPointfn equal_volume_cstr_train(stages : Int, total_volume : Double, thermal_mode? : ThermalMode) -> Array[ReactorStage]fn equal_volume_pfr_train(stages : Int, total_volume : Double, thermal_mode? : ThermalMode) -> Array[ReactorStage]fn equilibrium_conversion(forward : Double, reverse : Double) -> Doublefn estimate_order(first_concentration : Double, second_concentration : Double, first_rate : Double, second_rate : Double) -> Doublefn euler_integrate(initial : Double, dt : Double, steps : Int, derivative : (Double, Double) -> Double) -> Doublefn exchanger_duty(ua : Double, delta_hot : Double, delta_cold : Double) -> Doublefn feasible_scenario_count(scenarios : ArrayView[OperatingScenario], minimum_conversion : Double, maximum_temperature : Double) -> Intfn find_temperature_boundary(reaction : Reaction, feed : Feed, max_volume : Double, max_temperature : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> SafetyBoundaryfn first_order_concentration(initial : Double, rate_constant : Double, time : Double) -> Doublefn first_order_condition_number(damkohler : Double) -> Doublefn first_order_exposure(rate_constant : Double, time : Double) -> Doublefn first_order_time(rate_constant : Double, conversion : Double) -> Doublefn first_under_volume(scores : ArrayView[ObjectiveScore], maximum_volume : Double) -> ObjectiveScore?fn first_unsafe_sweep_point(points : ArrayView[ReactorSweepPoint], maximum_temperature : Double) -> ReactorSweepPoint?fn fit_first_order_rate(initial : Double, final_value : Double, time : Double) -> Doublefn fit_second_order_rate(initial : Double, final_value : Double, time : Double) -> Doublefn flow_velocity(volumetric_flow : Double, diameter : Double) -> Doublefn format_optional(value : Double?, digits : Int) -> Stringfn friction_factor(reynolds : Double) -> Doublefn half_life(rate_constant : Double) -> Doublefn has_standard_csv_header(report : String, header : String) -> Boolfn heat_capacity_constant(value : Double) -> Doublefn heat_capacity_flow(volumetric_flow : Double, density : Double, specific_heat : Double) -> Doublefn heat_capacity_linear(base : Double, slope : Double, temperature : Double, reference : Double) -> Doublefn integrate_adaptive(lower : Double, upper : Double, f : (Double) -> Double, tolerance? : Double, max_depth? : Int) -> IntegrationResultfn integrate_rk4(initial : Double, start : Double, end : Double, steps : Int, derivative : (Double, Double) -> Double) -> Doublefn integrate_simpson(lower : Double, upper : Double, steps : Int, f : (Double) -> Double) -> Doublefn integrate_trapezoid(lower : Double, upper : Double, steps : Int, f : (Double) -> Double) -> Doublefn integrate_trapezoid_report(lower : Double, upper : Double, steps : Int, f : (Double) -> Double) -> SolverReportfn jacket_duty(target_temperature : Double, reactor_temperature : Double, coolant_temperature : Double, gain : Double) -> Doublefn jacket_heat_removal(exchange : HeatExchange, reactor_temperature : Double, target_temperature : Double, gain : Double) -> Doublefn laminar_friction_factor(reynolds : Double) -> Doublefn last_over_conversion(scores : ArrayView[ObjectiveScore], minimum_conversion : Double) -> ObjectiveScore?fn last_safe_sweep_point(points : ArrayView[ReactorSweepPoint], maximum_temperature : Double) -> ReactorSweepPoint?fn liters_per_minute_to_m3_per_second(value : Double) -> Doublefn log_mean_temperature_difference(delta_hot : Double, delta_cold : Double) -> Doublefn m3_per_second_to_liters_per_minute(value : Double) -> Doublefn maximize_conversion_under_temperature(reaction : Reaction, feed : Feed, range : SearchRange, max_temperature : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> OptimizationResultfn maximum_temperature_margin(points : ArrayView[ReactorSweepPoint], maximum_temperature : Double) -> Doublefn minimize_volume_for_conversion(reaction : Reaction, feed : Feed, range : SearchRange, target_conversion : Double, kind? : ReactorKind) -> OptimizationResultfn minimum_temperature_margin(points : ArrayView[ReactorSweepPoint], maximum_temperature : Double) -> Doublefn mixed_temperature(first_flow : Double, first_temperature : Double, second_flow : Double, second_temperature : Double) -> Doublefn mixing_ratio(residence : Double, mixing_time : Double) -> Doublefn molar_liter_to_molar_meter(value : Double) -> Doublefn molar_meter_to_molar_liter(value : Double) -> Doublefn objective_surface(reaction : Reaction, feed : Feed, volumes : ArrayView[Double], conversion_weight : Double, volume_weight : Double, temperature_limit : Double) -> Array[ObjectiveScore]fn optimize_batch_cycle(reaction : Reaction, feed : Feed, maximum_time : Double, cleaning_time : Double, points : Int) -> ObjectiveScore?fn optimize_pfr_volume(reaction : Reaction, feed : Feed, config : SearchConfig, target_conversion : Double, maximum_temperature : Double) -> ObjectiveScore?fn optimize_rate_multiplier(reaction : Reaction, feed : Feed, volume : Double, config : SearchConfig, maximum_temperature : Double) -> ObjectiveScore?fn optimize_train_count(reaction : Reaction, feed : Feed, total_volume : Double, minimum_stages : Int, maximum_stages : Int) -> ObjectiveScore?fn parallel_first_order_rates(concentration : Double, product_a_rate_constant : Double, product_b_rate_constant : Double) -> ParallelReactionResultfn parallel_product_rate(concentration : Double, rate_constant : Double, order : KineticOrder) -> Doublefn parallel_selectivity(first_rate : Double, second_rate : Double) -> Doublefn parallel_split(concentration : Double, first_rate : Double, second_rate : Double, first_order : KineticOrder, second_order : KineticOrder) -> (Double, Double)fn penalty_score(score : Double, feasible : Bool, penalty : Double) -> Doublefn pfr_advantage_over_cstr(damkohler : Double) -> Doublefn pfr_profile(reaction : Reaction, feed : Feed, volume : Double, points~ : Int, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> Array[ProfilePoint]fn power_law_rate(rate_constant : Double, concentration : Double, order : Double) -> Doublefn pressure_drop(length : Double, diameter : Double, density : Double, velocity : Double, friction_factor : Double) -> Doublefn propagate_interval(reaction : Reaction, feed : Feed, volume : Double, rate_fraction : Double, temperature_delta : Double) -> ConversionIntervalfn rate_residual(reaction : Reaction, concentration : Double, temperature : Double, measured : Double) -> Doublefn rate_temperature_ratio(reaction : Reaction, first_temperature : Double, second_temperature : Double) -> Doublefn relative_rate_error(reaction : Reaction, concentration : Double, temperature : Double, measured : Double) -> Doublefn report_row_count(report : String) -> Intfn required_cstr_volume(reaction : Reaction, feed : Feed, target_conversion : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> Doublefn required_pfr_volume(reaction : Reaction, feed : Feed, target_conversion : Double, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> Doublefn required_ua(duty : Double, delta_hot : Double, delta_cold : Double) -> Doublefn residence_window_ok(residence : Double, minimum : Double, maximum : Double) -> Boolfn reversible_conversion(forward : Double, reverse : Double, time : Double) -> Doublefn reversible_first_order_rate(model : ReversibleFirstOrder, reactant_concentration : Double, product_concentration : Double) -> Doublefn reynolds_number(density : Double, velocity : Double, diameter : Double, viscosity : Double) -> Doublefn richardson_derivative(x : Double, f : (Double) -> Double, step? : Double) -> Doublefn rk4_step(time : Double, state : Double, step : Double, derivative : (Double, Double) -> Double) -> Doublefn safety_factor(limit : Double, observed : Double) -> Doublefn safety_factor_ok(limit : Double, observed : Double, minimum_factor : Double) -> Boolfn scenario_matrix(base : OperatingScenario, rate_multipliers : ArrayView[Double], temperature_offsets : ArrayView[Double]) -> Array[OperatingScenario]fn scenario_score(scenario : OperatingScenario, target_conversion : Double, maximum_temperature : Double) -> Doublefn scenario_volume_sweep(scenario : OperatingScenario, volumes : ArrayView[Double]) -> Array[ReactorSweepPoint]fn score_design(point : DesignPoint, conversion_weight : Double, volume_weight : Double, temperature_limit : Double) -> ObjectiveScorefn screen_scenario(scenario : OperatingScenario, minimum_conversion : Double, maximum_temperature : Double) -> Boolfn second_order_concentration(initial : Double, rate_constant : Double, time : Double) -> Doublefn second_order_exposure(rate_constant : Double, concentration : Double, time : Double) -> Doublefn second_order_half_life(rate_constant : Double, concentration : Double) -> Doublefn second_order_time(initial : Double, rate_constant : Double, conversion : Double) -> Doublefn selectivity_from_rates(desired : Double, undesired : Double) -> Doublefn selectivity_series_first_order(k1 : Double, k2 : Double, residence_time : Double) -> Doublefn sensible_enthalpy(capacity : Double, temperature : Double, reference : Double) -> Doublefn sensible_enthalpy_linear(base : Double, slope : Double, temperature : Double, reference : Double) -> Doublefn sensitivity_scan(reaction : Reaction, feed : Feed, volume : Double, multipliers : ArrayView[Double]) -> Array[DesignPoint]fn series_first_order_batch(initial_concentration : Double, first_rate : Double, second_rate : Double, time : Double) -> SeriesReactionResultfn series_intermediate(initial : Double, first_rate : Double, second_rate : Double, time : Double) -> Doublefn series_product(initial : Double, first_rate : Double, second_rate : Double, time : Double) -> Doublefn simulate_controller(config : ControllerConfig, setpoint : Double, initial_measurement : Double, process_gain : Double, process_time_constant : Double, dt : Double, steps : Int) -> Array[ControllerStep]fn sweep_cstr(reaction : Reaction, feed : Feed, max_volume : Double, points : Int, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> Array[ReactorSweepPoint]fn sweep_pfr(reaction : Reaction, feed : Feed, max_volume : Double, points : Int, thermal_mode? : ThermalMode, exchange? : HeatExchange) -> Array[ReactorSweepPoint]fn target_conversion_for_production(feed : Feed, production : Double, product_yield : Double) -> Doublefn target_distance(point : ObjectiveScore, target_conversion : Double, target_volume : Double, target_temperature : Double) -> Doublefn temperature_for_mode(mode : ThermalMode, feed : Feed, reaction : Reaction, conversion : Double, exchange : HeatExchange?) -> Doublefn temperature_for_multiplier(activation_energy : Double, multiplier : Double, reference : Double) -> Doublefn temperature_residual(expected : Double, actual : Double) -> Doublefn thermal_margin(temperature : Double, maximum : Double) -> Doublefn thermal_window_ok(temperature : Double, minimum : Double, maximum : Double) -> Boolfn uncertainty_summary(reaction : Reaction, feed : Feed, volume : Double, samples : Int) -> UncertaintySummaryfn validate_controller_settings(config : ControllerConfig, dt : Double, steps : Int) -> ValidationReportfn validate_feed_window(feed : Feed, minimum_temperature : Double, maximum_temperature : Double) -> ValidationReportfn velocity_window_ok(velocity : Double, minimum : Double, maximum : Double) -> Boolfn volumetric_heat_removal(exchange : HeatExchange, temperature : Double, coolant : Double) -> Doublefn yield_from_conversion_selectivity(conversion : Double, selectivity : Double) -> Doublefn yield_from_metrics(conversion : Double, selectivity : Double, stoichiometric_factor : Double) -> Doublefn zero_order_concentration(initial : Double, rate_constant : Double, time : Double) -> Doublefn zero_order_time(initial : Double, rate_constant : Double, conversion : Double) -> DoubleInstall
Download zipChemical reactor design toolkit for CSTR, PFR, and batch calculations in MoonBit.