conspire/physics/molecular/single_chain/ideal/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 math::Scalar,
6 physics::molecular::single_chain::{
7 Ensemble, Isometric, Isotensional, Legendre, SingleChain, SingleChainError, Thermodynamics,
8 },
9};
10use std::f64::consts::PI;
11
12#[derive(Clone, Debug)]
14pub struct IdealChain {
15 pub link_length: Scalar,
17 pub number_of_links: u8,
19 pub ensemble: Ensemble,
21}
22
23impl SingleChain for IdealChain {
24 fn link_length(&self) -> Scalar {
25 self.link_length
26 }
27 fn number_of_links(&self) -> u8 {
28 self.number_of_links
29 }
30}
31
32impl Thermodynamics for IdealChain {
33 fn ensemble(&self) -> Ensemble {
34 self.ensemble
35 }
36}
37
38impl Isometric for IdealChain {
39 fn nondimensional_helmholtz_free_energy(
43 &self,
44 nondimensional_extension: Scalar,
45 ) -> Result<Scalar, SingleChainError> {
46 Ok(1.5 * self.number_of_links() as Scalar * nondimensional_extension.powi(2))
47 }
48 fn nondimensional_force(
52 &self,
53 nondimensional_extension: Scalar,
54 ) -> Result<Scalar, SingleChainError> {
55 Ok(3.0 * nondimensional_extension)
56 }
57 fn nondimensional_stiffness(
61 &self,
62 _nondimensional_extension: Scalar,
63 ) -> Result<Scalar, SingleChainError> {
64 Ok(3.0)
65 }
66 fn nondimensional_spherical_distribution(
70 &self,
71 nondimensional_extension: Scalar,
72 ) -> Result<Scalar, SingleChainError> {
73 let number_of_links = self.number_of_links() as Scalar;
74 Ok((1.5 / PI / number_of_links).powf(1.5)
75 * (-1.5 * number_of_links * nondimensional_extension.powi(2)).exp())
76 }
77}
78
79impl Isotensional for IdealChain {
80 fn nondimensional_gibbs_free_energy(
84 &self,
85 nondimensional_force: Scalar,
86 ) -> Result<Scalar, SingleChainError> {
87 Ok(self.number_of_links() as Scalar / -6.0 * nondimensional_force.powi(2))
88 }
89 fn nondimensional_extension(
93 &self,
94 nondimensional_force: Scalar,
95 ) -> Result<Scalar, SingleChainError> {
96 Ok(nondimensional_force / 3.0)
97 }
98 fn nondimensional_compliance(
102 &self,
103 _nondimensional_force: Scalar,
104 ) -> Result<Scalar, SingleChainError> {
105 Ok(1.0 / 3.0)
106 }
107}
108
109impl Legendre for IdealChain {
110 fn nondimensional_force(
114 &self,
115 nondimensional_extension: Scalar,
116 ) -> Result<Scalar, SingleChainError> {
117 Isometric::nondimensional_force(self, nondimensional_extension)
118 }
119 fn nondimensional_extension(
123 &self,
124 nondimensional_force: Scalar,
125 ) -> Result<Scalar, SingleChainError> {
126 Isotensional::nondimensional_extension(self, nondimensional_force)
127 }
128 fn nondimensional_spherical_distribution(
132 &self,
133 nondimensional_extension: Scalar,
134 ) -> Result<Scalar, SingleChainError> {
135 Isometric::nondimensional_spherical_distribution(self, nondimensional_extension)
136 }
137}