///|
pub(all) enum ReactorKind {
Cstr
Pfr
Batch
} derive(Debug, Eq, ToJson)
///|
pub(all) enum ThermalMode {
Isothermal
Adiabatic
NonIsothermal
} derive(Debug, Eq, ToJson)
///|
pub(all) enum KineticOrder {
Zero
First
Second
} derive(Debug, Eq, ToJson)
///|
pub(all) struct Reaction {
name : String
order : KineticOrder
k_ref : Double
activation_energy : Double
reference_temperature : Double
reaction_enthalpy : Double
} derive(Debug, ToJson)
///|
pub(all) struct Feed {
concentration : Double
volumetric_flow : Double
temperature : Double
heat_capacity_flow : Double
} derive(Debug, ToJson)
///|
pub(all) struct HeatExchange {
ua : Double
coolant_temperature : Double
} derive(Debug, ToJson)
///|
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(Debug, ToJson)
///|
pub(all) struct SolverSettings {
tolerance : Double
max_iterations : Int
} derive(Debug, ToJson)
///|
pub(all) struct BracketResult {
root : Double
residual : Double
iterations : Int
converged : Bool
} derive(Debug, ToJson)
///|
pub(all) enum SolverStatus {
Converged
BracketFailure
IterationLimit
InvalidRange
} derive(Debug, Eq, ToJson)
///|
pub(all) struct SolverReport {
status : SolverStatus
root : Double
residual : Double
iterations : Int
} derive(Debug, ToJson)
///|
pub(all) struct ReversibleFirstOrder {
forward_rate : Double
reverse_rate : Double
equilibrium_concentration : Double
} derive(Debug, ToJson)
///|
pub(all) struct SeriesReactionResult {
intermediate_concentration : Double
product_concentration : Double
intermediate_selectivity : Double
} derive(Debug, ToJson)
///|
pub(all) struct ParallelReactionResult {
product_a_rate : Double
product_b_rate : Double
product_a_selectivity : Double
product_b_selectivity : Double
} derive(Debug, ToJson)
///|
pub(all) enum BenchmarkCategory {
Analytical
LiteratureKinetics
MeasuredProperty
Screening
} derive(Debug, Eq, ToJson)
///|
pub(all) struct BenchmarkCase {
id : String
title : String
category : BenchmarkCategory
source : String
source_url : String
units : String
assumptions : String
expected : Double
tolerance : Double
} derive(Debug, ToJson)
///|
pub(all) struct BenchmarkResult {
id : String
expected : Double
actual : Double
absolute_error : Double
tolerance : Double
passed : Bool
source_url : String
} derive(Debug, ToJson)
///|
pub(all) struct ReactorSweepPoint {
volume : Double
conversion : Double
outlet_temperature : Double
} derive(Debug, ToJson)
///|
pub(all) struct SafetyBoundary {
max_safe_volume : Double
max_safe_residence_time : Double
hot_spot_temperature : Double
conversion_at_boundary : Double
limited_by_temperature : Bool
} derive(Debug, ToJson)
///|
/// A numerical integration result with an explicit error estimate.
pub(all) struct IntegrationResult {
value : Double
estimated_error : Double
evaluations : Int
converged : Bool
} derive(Debug, ToJson)
///|
/// A sampled axial or temporal reactor state.
pub(all) struct ProfilePoint {
position : Double
time : Double
conversion : Double
concentration : Double
temperature : Double
rate : Double
} derive(Debug, ToJson)
///|
/// Local finite-difference sensitivities of a design point.
pub(all) struct SensitivityReport {
conversion_wrt_volume : Double
conversion_wrt_rate_constant : Double
conversion_wrt_temperature : Double
temperature_wrt_volume : Double
volume_wrt_target_conversion : Double
} derive(Debug, ToJson)
///|
/// A conservative interval for a screening calculation.
pub(all) struct ConversionInterval {
minimum_conversion : Double
maximum_conversion : Double
nominal_conversion : Double
minimum_temperature : Double
maximum_temperature : Double
} derive(Debug, ToJson)
///|
/// Summary statistics for deterministic uncertainty samples.
pub(all) struct UncertaintySummary {
samples : Int
minimum : Double
maximum : Double
mean : Double
standard_deviation : Double
p05 : Double
p50 : Double
p95 : Double
} derive(Debug, ToJson)
///|
/// PID gains and actuator limits.
pub(all) struct ControllerConfig {
proportional : Double
integral : Double
derivative : Double
minimum : Double
maximum : Double
} derive(Debug, ToJson)
///|
/// Persistent state for a discrete controller.
pub(all) struct ControllerState {
integral : Double
previous_error : Double
output : Double
} derive(Debug, ToJson)
///|
/// The controller output and updated state.
pub(all) struct ControllerStep {
output : Double
state : ControllerState
saturated : Bool
} derive(Debug, ToJson)
///|
/// Economic assumptions for early-stage design screening.
pub(all) struct CostAssumptions {
annual_hours : Double
electricity_price : Double
vessel_cost_per_volume : Double
pump_cost_per_flow : Double
maintenance_fraction : Double
} derive(Debug, ToJson)
///|
/// A transparent annualized cost estimate.
pub(all) struct CostEstimate {
capital : Double
utilities : Double
maintenance : Double
total : Double
} derive(Debug, ToJson)
///|
/// A design point annotated with feasibility checks.
pub(all) struct EnvelopePoint {
volume : Double
conversion : Double
temperature : Double
feasible : Bool
reason : String
} derive(Debug, ToJson)
///|
/// Per-stage and aggregate results for a train.
pub(all) struct TrainResult {
stages : Array[DesignPoint]
final_conversion : Double
total_volume : Double
total_residence_time : Double
} derive(Debug, ToJson)
///|
/// A reproducible input perturbation used by sensitivity analysis.
pub(all) struct Perturbation {
rate_multiplier : Double
temperature_offset : Double
flow_multiplier : Double
} derive(Debug, ToJson)
///|
/// A single design objective used by screening optimizers.
pub(all) struct ObjectiveScore {
volume : Double
conversion : Double
temperature : Double
score : Double
feasible : Bool
} derive(Debug, ToJson)
///|
pub fn Reaction::new(
name~ : String,
order~ : KineticOrder,
k_ref~ : Double,
activation_energy? : Double = 0.0,
reference_temperature? : Double = 298.15,
reaction_enthalpy? : Double = 0.0,
) -> Reaction {
{
name,
order,
k_ref,
activation_energy,
reference_temperature,
reaction_enthalpy,
}
}
///|
pub fn Feed::new(
concentration~ : Double,
volumetric_flow~ : Double,
temperature~ : Double,
heat_capacity_flow? : Double = 1.0,
) -> Feed {
{ concentration, volumetric_flow, temperature, heat_capacity_flow }
}
///|
pub fn HeatExchange::new(
ua~ : Double,
coolant_temperature~ : Double,
) -> HeatExchange {
{ ua, coolant_temperature }
}
///|
/// Construct conservative controller gains and actuator limits.
pub fn ControllerConfig::new(
proportional~ : Double,
integral~ : Double,
derivative~ : Double,
minimum~ : Double,
maximum~ : Double,
) -> ControllerConfig {
{
proportional: proportional.max(0.0),
integral: integral.max(0.0),
derivative: derivative.max(0.0),
minimum: minimum.min(maximum),
maximum: maximum.max(minimum),
}
}
///|
pub fn ControllerState::default() -> ControllerState {
{ integral: 0.0, previous_error: 0.0, output: 0.0 }
}
///|
pub fn ControllerConfig::validate(self : ControllerConfig) -> Bool {
self.minimum <= self.maximum &&
self.proportional >= 0.0 &&
self.integral >= 0.0 &&
self.derivative >= 0.0
}
///|
pub fn CostAssumptions::default() -> CostAssumptions {
{
annual_hours: 8000.0,
electricity_price: 0.12,
vessel_cost_per_volume: 1200.0,
pump_cost_per_flow: 80.0,
maintenance_fraction: 0.06,
}
}
///|
pub fn SolverSettings::default() -> SolverSettings {
{ tolerance: 1.0e-8, max_iterations: 80 }
}
///|
pub fn SolverSettings::loose() -> SolverSettings {
{ tolerance: 1.0e-6, max_iterations: 48 }
}
///|
pub fn ReactorKind::to_string(kind : ReactorKind) -> String {
match kind {
Cstr => "CSTR"
Pfr => "PFR"
Batch => "Batch"
}
}
///|
pub fn ThermalMode::to_string(mode : ThermalMode) -> String {
match mode {
Isothermal => "isothermal"
Adiabatic => "adiabatic"
NonIsothermal => "non-isothermal"
}
}
///|
pub fn KineticOrder::to_string(order : KineticOrder) -> String {
match order {
Zero => "zero-order"
First => "first-order"
Second => "second-order"
}
}