Skip to main content

conspire/physics/molecular/single_chain/
mod.rs

1mod arbitrary;
2mod efjc;
3mod efrc;
4mod fjc;
5mod frc;
6mod ideal;
7mod swfjc;
8mod ufjc;
9
10/// Single-chain models of polymer statistical thermodynamics.
11mod thermodynamics;
12
13pub use arbitrary::{ArbitraryDiscrete, ArbitraryDiscretePotential};
14pub use efjc::ExtensibleFreelyJointedChain;
15pub use efrc::ExtensibleFreelyRotatingChain;
16pub use fjc::FreelyJointedChain;
17pub use frc::FreelyRotatingChain;
18pub use ideal::IdealChain;
19pub use swfjc::SquareWellFreelyJointedChain;
20pub use thermodynamics::{
21    Configuration, Ensemble, Isometric, Isotensional, IsotensionalExtensible, Legendre, MonteCarlo,
22    MonteCarloExtensible, MonteCarloInextensible, Thermodynamics, ThermodynamicsExtensible,
23};
24pub use ufjc::ArbitraryPotentialFreelyJointedChain;
25
26use crate::math::{Scalar, TestError};
27use std::fmt::{self, Debug, Display, Formatter};
28
29pub trait SingleChain
30where
31    Self: Clone + Debug,
32{
33    fn link_length(&self) -> Scalar;
34    fn number_of_links(&self) -> u8;
35}
36
37pub trait Inextensible
38where
39    Self: SingleChain,
40{
41    fn maximum_nondimensional_extension(&self) -> Scalar;
42    fn nondimensional_extension_check(
43        &self,
44        nondimensional_extension: Scalar,
45    ) -> Result<(), SingleChainError> {
46        if nondimensional_extension.abs() >= self.maximum_nondimensional_extension() {
47            Err(SingleChainError::MaximumExtensibility(
48                format!("{:?}", self.maximum_nondimensional_extension()),
49                format!("{self:?}"),
50            ))
51        } else {
52            Ok(())
53        }
54    }
55}
56
57pub trait Extensible
58where
59    Self: SingleChain,
60{
61}
62
63#[derive(Debug)]
64pub enum SingleChainError {
65    MaximumExtensibility(String, String),
66    Upstream(String, String),
67}
68
69impl From<SingleChainError> for TestError {
70    fn from(error: SingleChainError) -> Self {
71        Self {
72            message: error.to_string(),
73        }
74    }
75}
76
77impl From<SingleChainError> for String {
78    fn from(error: SingleChainError) -> Self {
79        Self::from(&error)
80    }
81}
82
83impl From<&SingleChainError> for String {
84    fn from(error: &SingleChainError) -> Self {
85        match error {
86            SingleChainError::MaximumExtensibility(
87                maximum_nondimensional_extension,
88                single_chain_model,
89            ) => format!(
90                "\x1b[1;91mMaximum extensibility ({maximum_nondimensional_extension}) reached.\x1b[0;91m\n\
91                    In single-chain model: {single_chain_model}."
92            ),
93            SingleChainError::Upstream(error, single_chain_model) => format!(
94                "{error}\x1b[0;91m\n\
95                    In single-chain model: {single_chain_model}."
96            ),
97        }
98    }
99}
100
101impl Display for SingleChainError {
102    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
103        write!(f, "{}\x1b[0m", String::from(self))
104    }
105}