1use super::*;
2
3pub struct ReactionAnalyzer {
5 reaction_network: ReactionNetwork,
6 kinetics_calculator: KineticsCalculator,
7 thermodynamics_calculator: ThermodynamicsCalculator,
8}
9
10pub struct ReactionNetwork {
12 reactions: HashMap<String, Reaction>,
13 species: HashMap<String, Species>,
14 pathways: Vec<ReactionPathway>,
15}
16
17#[derive(Debug, Clone)]
19pub struct Reaction {
20 pub reaction_id: String,
21 pub reaction_name: String,
22 pub reactants: Vec<String>,
23 pub products: Vec<String>,
24 pub reaction_type: ReactionType,
25 pub mechanism: ReactionMechanism,
26}
27
28#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub enum ReactionType {
31 Elementary,
32 Complex,
33 Catalytic,
34 Chain,
35 Photochemical,
36 Electrochemical,
37}
38
39#[derive(Debug, Clone)]
41pub struct ReactionMechanism {
42 pub mechanism_id: String,
43 pub steps: Vec<ReactionStep>,
44 pub intermediates: Vec<String>,
45}
46
47#[derive(Debug, Clone)]
49pub struct ReactionStep {
50 pub step_id: String,
51 pub reactants: Vec<String>,
52 pub products: Vec<String>,
53 pub rate_constant: f64,
54 pub activation_energy: f64,
55}
56
57#[derive(Debug, Clone)]
59pub struct Species {
60 pub species_id: String,
61 pub species_name: String,
62 pub formula: String,
63 pub molecular_weight: f64,
64 pub properties: SpeciesProperties,
65}
66
67#[derive(Debug, Clone)]
69pub struct SpeciesProperties {
70 pub enthalpy: f64,
71 pub entropy: f64,
72 pub gibbs_free_energy: f64,
73 pub heat_capacity: f64,
74}
75
76#[derive(Debug, Clone)]
78pub struct ReactionPathway {
79 pub pathway_id: String,
80 pub pathway_name: String,
81 pub reactions: Vec<String>,
82 pub branching_ratios: Vec<f64>,
83}
84
85pub struct KineticsCalculator {
87 rate_laws: HashMap<String, RateLaw>,
88 rate_constants: HashMap<String, RateConstant>,
89 reaction_rates: HashMap<String, f64>,
90}
91
92#[derive(Debug, Clone)]
94pub struct RateLaw {
95 pub law_id: String,
96 pub law_type: RateLawType,
97 pub rate_expression: String,
98 pub parameters: RateLawParameters,
99}
100
101#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
103pub enum RateLawType {
104 Elementary,
105 MichaelisMenten,
106 Hill,
107 Custom,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct RateLawParameters {
113 pub rate_constant: f64,
114 pub reaction_orders: Vec<f64>,
115 pub saturation_constants: Vec<f64>,
116}
117
118#[derive(Debug, Clone)]
120pub struct RateConstant {
121 pub constant_id: String,
122 pub value: f64,
123 pub temperature_dependence: TemperatureDependence,
124 pub pressure_dependence: PressureDependence,
125}
126
127#[derive(Debug, Clone)]
129pub struct TemperatureDependence {
130 pub arrhenius_parameters: ArrheniusParameters,
131 pub modified_arrhenius: Option<ModifiedArrheniusParameters>,
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct ArrheniusParameters {
137 pub pre_exponential: f64,
138 pub activation_energy: f64,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct ModifiedArrheniusParameters {
144 pub pre_exponential: f64,
145 pub activation_energy: f64,
146 pub temperature_exponent: f64,
147}
148
149#[derive(Debug, Clone)]
151pub struct PressureDependence {
152 pub fall_off_parameters: FallOffParameters,
153 pub third_body_efficiency: f64,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct FallOffParameters {
159 pub low_pressure_limit: f64,
160 pub high_pressure_limit: f64,
161 pub fall_off_exponent: f64,
162}
163
164pub struct ThermodynamicsCalculator {
166 thermodynamic_data: HashMap<String, ThermodynamicData>,
167 equilibrium_calculator: EquilibriumCalculator,
168 phase_calculator: PhaseCalculator,
169}
170
171#[derive(Debug, Clone)]
173pub struct ThermodynamicData {
174 pub data_id: String,
175 pub temperature_range: (f64, f64),
176 pub enthalpy: f64,
177 pub entropy: f64,
178 pub gibbs_free_energy: f64,
179 pub heat_capacity: f64,
180}
181
182pub struct EquilibriumCalculator {
184 equilibrium_constant: EquilibriumConstant,
185 reaction_quotient: ReactionQuotient,
186 gibbs_energy: GibbsEnergy,
187}
188
189#[derive(Debug, Clone)]
191pub struct EquilibriumConstant {
192 pub value: f64,
193 pub temperature: f64,
194 pub pressure: f64,
195}
196
197#[derive(Debug, Clone)]
199pub struct ReactionQuotient {
200 pub value: f64,
201 pub concentrations: HashMap<String, f64>,
202}
203
204#[derive(Debug, Clone)]
206pub struct GibbsEnergy {
207 pub standard_gibbs: f64,
208 pub actual_gibbs: f64,
209 pub delta_g: f64,
210}
211
212pub struct PhaseCalculator {
214 phase_diagrams: HashMap<String, PhaseDiagram>,
215 phase_transitions: HashMap<String, PhaseTransition>,
216 phase_equilibria: HashMap<String, PhaseEquilibrium>,
217}
218
219#[derive(Debug, Clone)]
221pub struct PhaseDiagram {
222 pub diagram_id: String,
223 pub phases: Vec<Phase>,
224 pub boundaries: Vec<PhaseBoundary>,
225}
226
227#[derive(Debug, Clone)]
229pub struct Phase {
230 pub phase_id: String,
231 pub phase_name: String,
232 pub phase_type: PhaseType,
233 pub composition: HashMap<String, f64>,
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub enum PhaseType {
239 Solid,
240 Liquid,
241 Gas,
242 Plasma,
243 Supercritical,
244}
245
246#[derive(Debug, Clone)]
248pub struct PhaseBoundary {
249 pub boundary_id: String,
250 pub boundary_type: BoundaryType,
251 pub conditions: Vec<BoundaryCondition>,
252}
253
254#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
256pub enum PhaseBoundaryType {
257 Melting,
258 Boiling,
259 Sublimation,
260 Triple,
261 Critical,
262}
263
264#[derive(Debug, Clone)]
266pub struct BoundaryCondition {
267 pub temperature: f64,
268 pub pressure: f64,
269 pub composition: HashMap<String, f64>,
270}
271
272#[derive(Debug, Clone)]
274pub struct PhaseTransition {
275 pub transition_id: String,
276 pub transition_type: TransitionType,
277 pub enthalpy_change: f64,
278 pub entropy_change: f64,
279}
280
281#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
283pub enum TransitionType {
284 Fusion,
285 Vaporization,
286 Sublimation,
287 Deposition,
288 Ionization,
289}
290
291#[derive(Debug, Clone)]
293pub struct PhaseEquilibrium {
294 pub equilibrium_id: String,
295 pub phases: Vec<String>,
296 pub equilibrium_conditions: EquilibriumConditions,
297}
298
299#[derive(Debug, Clone)]
301pub struct EquilibriumConditions {
302 pub temperature: f64,
303 pub pressure: f64,
304 pub chemical_potentials: HashMap<String, f64>,
305}
306
307impl ReactionAnalyzer {
308 pub fn new() -> Self {
309 Self {
310 reaction_network: ReactionNetwork::new(),
311 kinetics_calculator: KineticsCalculator::new(),
312 thermodynamics_calculator: ThermodynamicsCalculator::new(),
313 }
314 }
315
316 pub fn reaction_network(&self) -> &ReactionNetwork {
318 &self.reaction_network
319 }
320
321 pub fn reaction_network_mut(&mut self) -> &mut ReactionNetwork {
323 &mut self.reaction_network
324 }
325
326 pub fn initialize(&mut self) -> Result<(), ChemistryError> {
327 self.kinetics_calculator.initialize()?;
328 self.thermodynamics_calculator.initialize()?;
329 Ok(())
330 }
331
332 pub fn validate_reaction(&self, reaction: &Reaction) -> Result<(), ChemistryError> {
333 if reaction.reactants.is_empty() {
334 return Err(ChemistryError::ValidationError(
335 "Reaction must have at least one reactant".to_string(),
336 ));
337 }
338 if reaction.products.is_empty() {
339 return Err(ChemistryError::ValidationError(
340 "Reaction must have at least one product".to_string(),
341 ));
342 }
343 Ok(())
344 }
345
346 pub fn analyze_kinetics(
347 &mut self,
348 reaction: &Reaction,
349 conditions: &ReactionConditions,
350 ) -> Result<KineticsResults, ChemistryError> {
351 const R: f64 = 8.314_462_618; let t = conditions.temperature; if !(t.is_finite() && t > 0.0) {
359 return Err(ChemistryError::ValidationError(
360 "temperature must be a positive value in Kelvin".to_string(),
361 ));
362 }
363
364 let rds = reaction
366 .mechanism
367 .steps
368 .iter()
369 .max_by(|a, b| {
370 a.activation_energy
371 .partial_cmp(&b.activation_energy)
372 .unwrap_or(std::cmp::Ordering::Equal)
373 })
374 .ok_or_else(|| {
375 ChemistryError::InsufficientData(
376 "reaction has no mechanism steps; cannot determine rate-determining step"
377 .to_string(),
378 )
379 })?;
380
381 let a_factor = rds.rate_constant; let ea_kj = rds.activation_energy; if !(a_factor.is_finite() && ea_kj.is_finite()) {
384 return Err(ChemistryError::ValidationError(
385 "rate-determining step has non-finite A or Ea".to_string(),
386 ));
387 }
388 let ea_j = ea_kj * 1000.0; let rate_constant = a_factor * (-ea_j / (R * t)).exp(); let reaction_order = reaction.reactants.len().max(1) as u32;
393
394 let c0 = reaction
396 .reactants
397 .first()
398 .and_then(|name| conditions.concentration.get(name).copied())
399 .unwrap_or(1.0);
400
401 let half_life = if rate_constant <= 0.0 {
403 f64::INFINITY
404 } else {
405 match reaction_order {
406 0 => c0 / (2.0 * rate_constant), 2 => {
408 if c0 > 0.0 {
409 1.0 / (rate_constant * c0)
410 } else {
411 f64::INFINITY
412 }
413 } _ => std::f64::consts::LN_2 / rate_constant, }
416 };
417
418 Ok(KineticsResults {
419 rate_constant,
420 activation_energy: ea_kj,
421 reaction_order,
422 half_life,
423 })
424 }
425}
426
427impl ReactionNetwork {
428 pub fn new() -> Self {
429 Self {
430 reactions: HashMap::new(),
431 species: HashMap::new(),
432 pathways: Vec::new(),
433 }
434 }
435
436 pub fn add_reaction(&mut self, reaction: Reaction) {
438 self.reactions
439 .insert(reaction.reaction_id.clone(), reaction);
440 }
441
442 pub fn get_reaction(&self, reaction_id: &str) -> Option<&Reaction> {
444 self.reactions.get(reaction_id)
445 }
446
447 pub fn list_reactions(&self) -> Vec<String> {
449 self.reactions.keys().cloned().collect()
450 }
451
452 pub fn remove_reaction(&mut self, reaction_id: &str) -> Option<Reaction> {
454 self.reactions.remove(reaction_id)
455 }
456
457 pub fn add_species(&mut self, species: Species) {
459 self.species.insert(species.species_id.clone(), species);
460 }
461
462 pub fn get_species(&self, species_id: &str) -> Option<&Species> {
464 self.species.get(species_id)
465 }
466
467 pub fn list_species(&self) -> Vec<String> {
469 self.species.keys().cloned().collect()
470 }
471
472 pub fn remove_species(&mut self, species_id: &str) -> Option<Species> {
474 self.species.remove(species_id)
475 }
476
477 pub fn add_pathway(&mut self, pathway: ReactionPathway) {
479 self.pathways.push(pathway);
480 }
481
482 pub fn pathways(&self) -> &Vec<ReactionPathway> {
484 &self.pathways
485 }
486
487 pub fn pathways_mut(&mut self) -> &mut Vec<ReactionPathway> {
489 &mut self.pathways
490 }
491}
492
493impl Reaction {
494 pub fn new() -> Self {
495 Self {
496 reaction_id: "rxn_1".to_string(),
497 reaction_name: "Test reaction".to_string(),
498 reactants: vec!["A".to_string()],
499 products: vec!["B".to_string()],
500 reaction_type: ReactionType::Elementary,
501 mechanism: ReactionMechanism::new(),
502 }
503 }
504}
505
506impl ReactionMechanism {
507 pub fn new() -> Self {
508 Self {
509 mechanism_id: "mech_1".to_string(),
510 steps: vec![ReactionStep::new()],
511 intermediates: Vec::new(),
512 }
513 }
514}
515
516impl ReactionStep {
517 pub fn new() -> Self {
518 Self {
519 step_id: "step_1".to_string(),
520 reactants: vec!["A".to_string()],
521 products: vec!["B".to_string()],
522 rate_constant: 1.0,
523 activation_energy: 10.0,
524 }
525 }
526}
527
528impl Species {
529 pub fn new() -> Self {
530 Self {
531 species_id: "species_1".to_string(),
532 species_name: "Test species".to_string(),
533 formula: "CH4".to_string(),
534 molecular_weight: 16.04,
535 properties: SpeciesProperties::new(),
536 }
537 }
538}
539
540impl SpeciesProperties {
541 pub fn new() -> Self {
542 Self {
543 enthalpy: -74.8,
544 entropy: 186.3,
545 gibbs_free_energy: -50.8,
546 heat_capacity: 35.7,
547 }
548 }
549}
550
551impl ReactionPathway {
552 pub fn new() -> Self {
553 Self {
554 pathway_id: "pathway_1".to_string(),
555 pathway_name: "Test pathway".to_string(),
556 reactions: vec!["rxn_1".to_string()],
557 branching_ratios: vec![1.0],
558 }
559 }
560}
561
562impl KineticsCalculator {
563 pub fn new() -> Self {
564 Self {
565 rate_laws: HashMap::new(),
566 rate_constants: HashMap::new(),
567 reaction_rates: HashMap::new(),
568 }
569 }
570
571 pub fn add_rate_law(&mut self, law: RateLaw) {
573 self.rate_laws.insert(law.law_id.clone(), law);
574 }
575
576 pub fn get_rate_law(&self, law_id: &str) -> Option<&RateLaw> {
578 self.rate_laws.get(law_id)
579 }
580
581 pub fn list_rate_laws(&self) -> Vec<String> {
583 self.rate_laws.keys().cloned().collect()
584 }
585
586 pub fn add_rate_constant(&mut self, constant: RateConstant) {
588 self.rate_constants
589 .insert(constant.constant_id.clone(), constant);
590 }
591
592 pub fn get_rate_constant(&self, constant_id: &str) -> Option<&RateConstant> {
594 self.rate_constants.get(constant_id)
595 }
596
597 pub fn list_rate_constants(&self) -> Vec<String> {
599 self.rate_constants.keys().cloned().collect()
600 }
601
602 pub fn set_reaction_rate(&mut self, reaction_id: &str, rate: f64) {
604 self.reaction_rates.insert(reaction_id.to_string(), rate);
605 }
606
607 pub fn get_reaction_rate(&self, reaction_id: &str) -> Option<&f64> {
609 self.reaction_rates.get(reaction_id)
610 }
611
612 pub fn list_reaction_rates(&self) -> Vec<String> {
614 self.reaction_rates.keys().cloned().collect()
615 }
616
617 pub fn initialize(&mut self) -> Result<(), ChemistryError> {
618 Ok(())
619 }
620}
621
622impl RateLaw {
623 pub fn new() -> Self {
624 Self {
625 law_id: "law_1".to_string(),
626 law_type: RateLawType::Elementary,
627 rate_expression: "k * [A]".to_string(),
628 parameters: RateLawParameters::new(),
629 }
630 }
631}
632
633impl RateLawParameters {
634 pub fn new() -> Self {
635 Self {
636 rate_constant: 1.0,
637 reaction_orders: vec![1.0],
638 saturation_constants: Vec::new(),
639 }
640 }
641}
642
643impl RateConstant {
644 pub fn new() -> Self {
645 Self {
646 constant_id: "const_1".to_string(),
647 value: 1.0,
648 temperature_dependence: TemperatureDependence::new(),
649 pressure_dependence: PressureDependence::new(),
650 }
651 }
652}
653
654impl TemperatureDependence {
655 pub fn new() -> Self {
656 Self {
657 arrhenius_parameters: ArrheniusParameters::new(),
658 modified_arrhenius: None,
659 }
660 }
661}
662
663impl ArrheniusParameters {
664 pub fn new() -> Self {
665 Self {
666 pre_exponential: 1.0e13,
667 activation_energy: 10000.0,
668 }
669 }
670}
671
672impl ModifiedArrheniusParameters {
673 pub fn new() -> Self {
674 Self {
675 pre_exponential: 1.0e13,
676 activation_energy: 10000.0,
677 temperature_exponent: 0.0,
678 }
679 }
680}
681
682impl PressureDependence {
683 pub fn new() -> Self {
684 Self {
685 fall_off_parameters: FallOffParameters::new(),
686 third_body_efficiency: 1.0,
687 }
688 }
689}
690
691impl FallOffParameters {
692 pub fn new() -> Self {
693 Self {
694 low_pressure_limit: 1.0,
695 high_pressure_limit: 1.0,
696 fall_off_exponent: 1.0,
697 }
698 }
699}
700
701impl ThermodynamicsCalculator {
702 pub fn new() -> Self {
703 Self {
704 thermodynamic_data: HashMap::new(),
705 equilibrium_calculator: EquilibriumCalculator::new(),
706 phase_calculator: PhaseCalculator::new(),
707 }
708 }
709
710 pub fn add_thermodynamic_data(&mut self, data: ThermodynamicData) {
712 self.thermodynamic_data.insert(data.data_id.clone(), data);
713 }
714
715 pub fn get_thermodynamic_data(&self, data_id: &str) -> Option<&ThermodynamicData> {
717 self.thermodynamic_data.get(data_id)
718 }
719
720 pub fn list_thermodynamic_data(&self) -> Vec<String> {
722 self.thermodynamic_data.keys().cloned().collect()
723 }
724
725 pub fn remove_thermodynamic_data(&mut self, data_id: &str) -> Option<ThermodynamicData> {
727 self.thermodynamic_data.remove(data_id)
728 }
729
730 pub fn initialize(&mut self) -> Result<(), ChemistryError> {
731 self.equilibrium_calculator.initialize()?;
732 self.phase_calculator.initialize()?;
733 Ok(())
734 }
735}
736
737impl ThermodynamicData {
738 pub fn new() -> Self {
739 Self {
740 data_id: "data_1".to_string(),
741 temperature_range: (200.0, 400.0),
742 enthalpy: -74.8,
743 entropy: 186.3,
744 gibbs_free_energy: -50.8,
745 heat_capacity: 35.7,
746 }
747 }
748}
749
750impl EquilibriumCalculator {
751 pub fn new() -> Self {
752 Self {
753 equilibrium_constant: EquilibriumConstant::new(),
754 reaction_quotient: ReactionQuotient::new(),
755 gibbs_energy: GibbsEnergy::new(),
756 }
757 }
758
759 pub fn equilibrium_constant(&self) -> &EquilibriumConstant {
761 &self.equilibrium_constant
762 }
763
764 pub fn equilibrium_constant_mut(&mut self) -> &mut EquilibriumConstant {
766 &mut self.equilibrium_constant
767 }
768
769 pub fn reaction_quotient(&self) -> &ReactionQuotient {
771 &self.reaction_quotient
772 }
773
774 pub fn reaction_quotient_mut(&mut self) -> &mut ReactionQuotient {
776 &mut self.reaction_quotient
777 }
778
779 pub fn gibbs_energy(&self) -> &GibbsEnergy {
781 &self.gibbs_energy
782 }
783
784 pub fn gibbs_energy_mut(&mut self) -> &mut GibbsEnergy {
786 &mut self.gibbs_energy
787 }
788
789 pub fn initialize(&mut self) -> Result<(), ChemistryError> {
790 Ok(())
791 }
792}
793
794impl EquilibriumConstant {
795 pub fn new() -> Self {
796 Self {
797 value: 1.0,
798 temperature: 298.15,
799 pressure: 1.0,
800 }
801 }
802}
803
804impl ReactionQuotient {
805 pub fn new() -> Self {
806 Self {
807 value: 1.0,
808 concentrations: HashMap::new(),
809 }
810 }
811}
812
813impl GibbsEnergy {
814 pub fn new() -> Self {
815 Self {
816 standard_gibbs: -50.8,
817 actual_gibbs: -50.8,
818 delta_g: 0.0,
819 }
820 }
821}
822
823impl PhaseCalculator {
824 pub fn new() -> Self {
825 Self {
826 phase_diagrams: HashMap::new(),
827 phase_transitions: HashMap::new(),
828 phase_equilibria: HashMap::new(),
829 }
830 }
831
832 pub fn add_phase_diagram(&mut self, diagram: PhaseDiagram) {
834 self.phase_diagrams
835 .insert(diagram.diagram_id.clone(), diagram);
836 }
837
838 pub fn get_phase_diagram(&self, diagram_id: &str) -> Option<&PhaseDiagram> {
840 self.phase_diagrams.get(diagram_id)
841 }
842
843 pub fn list_phase_diagrams(&self) -> Vec<String> {
845 self.phase_diagrams.keys().cloned().collect()
846 }
847
848 pub fn add_phase_transition(&mut self, transition: PhaseTransition) {
850 self.phase_transitions
851 .insert(transition.transition_id.clone(), transition);
852 }
853
854 pub fn get_phase_transition(&self, transition_id: &str) -> Option<&PhaseTransition> {
856 self.phase_transitions.get(transition_id)
857 }
858
859 pub fn list_phase_transitions(&self) -> Vec<String> {
861 self.phase_transitions.keys().cloned().collect()
862 }
863
864 pub fn add_phase_equilibrium(&mut self, equilibrium: PhaseEquilibrium) {
866 self.phase_equilibria
867 .insert(equilibrium.equilibrium_id.clone(), equilibrium);
868 }
869
870 pub fn get_phase_equilibrium(&self, equilibrium_id: &str) -> Option<&PhaseEquilibrium> {
872 self.phase_equilibria.get(equilibrium_id)
873 }
874
875 pub fn list_phase_equilibria(&self) -> Vec<String> {
877 self.phase_equilibria.keys().cloned().collect()
878 }
879
880 pub fn initialize(&mut self) -> Result<(), ChemistryError> {
881 Ok(())
882 }
883}
884
885impl PhaseDiagram {
886 pub fn new() -> Self {
887 Self {
888 diagram_id: "diagram_1".to_string(),
889 phases: vec![Phase::new()],
890 boundaries: Vec::new(),
891 }
892 }
893}
894
895impl Phase {
896 pub fn new() -> Self {
897 Self {
898 phase_id: "phase_1".to_string(),
899 phase_name: "Liquid".to_string(),
900 phase_type: PhaseType::Liquid,
901 composition: HashMap::new(),
902 }
903 }
904}
905
906impl PhaseBoundary {
907 pub fn new() -> Self {
908 Self {
909 boundary_id: "boundary_1".to_string(),
910 boundary_type: BoundaryType::Boiling,
911 conditions: vec![BoundaryCondition::new()],
912 }
913 }
914}
915
916impl BoundaryCondition {
917 pub fn new() -> Self {
918 Self {
919 temperature: 373.15,
920 pressure: 1.0,
921 composition: HashMap::new(),
922 }
923 }
924}
925
926impl PhaseTransition {
927 pub fn new() -> Self {
928 Self {
929 transition_id: "transition_1".to_string(),
930 transition_type: TransitionType::Fusion,
931 enthalpy_change: 6.01,
932 entropy_change: 22.0,
933 }
934 }
935}
936
937impl PhaseEquilibrium {
938 pub fn new() -> Self {
939 Self {
940 equilibrium_id: "eq_1".to_string(),
941 phases: vec!["phase_1".to_string()],
942 equilibrium_conditions: EquilibriumConditions::new(),
943 }
944 }
945}
946
947impl EquilibriumConditions {
948 pub fn new() -> Self {
949 Self {
950 temperature: 273.15,
951 pressure: 1.0,
952 chemical_potentials: HashMap::new(),
953 }
954 }
955}