use crate::Thermodynamics::ChemEquilibrium::equilibrium_log_moles::EquilibriumSolverSettings;
use crate::Thermodynamics::ChemEquilibrium::equilibrium_multiphase_domain::MultiphaseInitialComposition;
use crate::Thermodynamics::ChemEquilibrium::equilibrium_nonlinear::ReactionExtentError;
use crate::Thermodynamics::ChemEquilibrium::equilibrium_problem::{
EquilibriumConditions, TraceSpeciesSeedPolicy,
};
use crate::Thermodynamics::ChemEquilibrium::phase_equilibrium_problem::{
PhaseEquilibriumBuildRequest, SupportedPhaseModelPolicy, build_phase_equilibrium_problem,
};
use crate::Thermodynamics::ChemEquilibrium::phase_equilibrium_solution::MultiphaseEquilibriumSolution;
use crate::Thermodynamics::User_PhaseOrSolution::ResolvedPhaseSystem;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PhaseEquilibriumSolveMode {
#[default]
FixedDeclaredPhases,
}
#[derive(Clone)]
pub struct ResolvedPhaseEquilibriumRequest<'a> {
resolved: &'a ResolvedPhaseSystem,
conditions: EquilibriumConditions,
initial_composition: MultiphaseInitialComposition,
trace_seed_policy: TraceSpeciesSeedPolicy,
model_policy: SupportedPhaseModelPolicy,
solver_settings: EquilibriumSolverSettings,
solve_mode: PhaseEquilibriumSolveMode,
}
impl<'a> ResolvedPhaseEquilibriumRequest<'a> {
pub fn new(
resolved: &'a ResolvedPhaseSystem,
conditions: EquilibriumConditions,
initial_composition: MultiphaseInitialComposition,
) -> Self {
Self {
resolved,
conditions,
initial_composition,
trace_seed_policy: TraceSpeciesSeedPolicy::Absolute {
floor: crate::Thermodynamics::ChemEquilibrium::equilibrium_problem::DEFAULT_TRACE_MOLE_FLOOR,
},
model_policy: SupportedPhaseModelPolicy::default(),
solver_settings: EquilibriumSolverSettings::default(),
solve_mode: PhaseEquilibriumSolveMode::default(),
}
}
pub fn with_trace_seed_policy(mut self, policy: TraceSpeciesSeedPolicy) -> Self {
self.trace_seed_policy = policy;
self
}
pub fn with_model_policy(mut self, policy: SupportedPhaseModelPolicy) -> Self {
self.model_policy = policy;
self
}
pub fn with_solver_settings(mut self, settings: EquilibriumSolverSettings) -> Self {
self.solver_settings = settings;
self
}
pub fn with_solve_mode(mut self, mode: PhaseEquilibriumSolveMode) -> Self {
self.solve_mode = mode;
self
}
pub fn resolved(&self) -> &'a ResolvedPhaseSystem {
self.resolved
}
pub fn conditions(&self) -> EquilibriumConditions {
self.conditions
}
pub fn initial_composition(&self) -> &MultiphaseInitialComposition {
&self.initial_composition
}
pub fn solver_settings(&self) -> &EquilibriumSolverSettings {
&self.solver_settings
}
}
pub fn solve_resolved_pt(
request: ResolvedPhaseEquilibriumRequest<'_>,
) -> Result<MultiphaseEquilibriumSolution, ReactionExtentError> {
match request.solve_mode {
PhaseEquilibriumSolveMode::FixedDeclaredPhases => {
let bundle = build_phase_equilibrium_problem(PhaseEquilibriumBuildRequest::new(
request.resolved,
request.conditions,
request.initial_composition,
request.trace_seed_policy,
request.model_policy,
)?)?;
bundle
.solve_with(|settings| *settings = request.solver_settings)
.and_then(|bundle| bundle.into_multiphase_solution())
}
}
}