From 1486c2b7d8f6299e400ed74cd8bac7f791ac98a0 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Fri, 21 Apr 2023 16:49:57 -0600 Subject: [PATCH 01/21] use this (N.B. Becker et al.: The radial distribution of worm-like chains) for wlc/thermodynamics/isometric --- example.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 example.py diff --git a/example.py b/example.py new file mode 100644 index 00000000..84cf7a8f --- /dev/null +++ b/example.py @@ -0,0 +1,118 @@ +import numpy as np +import matplotlib.pyplot as plt +from scipy.special import iv + + +a = 14.054 +b = 0.473 +c_ = np.array([ + [-3/4, 23/64, -7/64], + [-1/2, 17/16, -9/16] +]) + + +def I_0(x): + return iv(0, x) + + +def I_1(x): + return iv(1, x) + + +def Q_G(r, kappa): + return (3/4/np.pi/kappa)**(3/2)*np.exp(-3*r**2/4/kappa) + + +def Q_D(r, kappa): + return Q_G(r, kappa)*(1 - 5*kappa/4 + 2*r**2 - 33*r**4/80/kappa) + + +def J_SY(kappa): + return 112.04*kappa**2*np.exp(0.246/kappa - a*kappa) + + +def J_SYD(kappa): + if kappa > 1/8: + return J_SY(kappa) + else: + return Q_D(0, kappa) + +def Q_I(r, kappa): + c = 1 - (1 + (0.38*kappa**(-0.95))**(-5))**(-1/5) + if kappa < 1/8: + d = 1 + else: + d = 1 - 1/(0.177/(kappa - 0.111) + 6.40*(kappa - 0.111)**0.783) + sum = 0 + for i in (-1, 0): + for j in (1, 2, 3): + sum += c_[i + 1, j - 1]*kappa**i*r**(2*j) + h = (1 - c*r**2)/(1 - r**2) + t = r/(1 - b**2*r**2) + arg = -d*kappa*a*(1 + b)*t + return J_SYD(kappa) * \ + (h)**(5/2) * \ + np.exp(sum/(1 - r**2)) * \ + np.exp(arg*b*r) * \ + I_0(arg) + + +def d_Q_I_d_r(r, kappa): + c = 1 - (1 + (0.38*kappa**(-0.95))**(-5))**(-1/5) + if kappa < 1/8: + d = 1 + else: + d = 1 - 1/(0.177/(kappa - 0.111) + 6.40*(kappa - 0.111)**0.783) + sum = 0 + d_sum_dr = 0 + for i in (-1, 0): + for j in (1, 2, 3): + sum += c_[i + 1, j - 1]*kappa**i*r**(2*j) + d_sum_dr += 2*j*c_[i + 1, j - 1]*kappa**i*r**(2*j - 1) + h = (1 - c*r**2)/(1 - r**2) + t = r/(1 - b**2*r**2) + arg = -d*kappa*a*(1 + b)*t + return J_SYD(kappa) * \ + (h)**(5/2) * \ + np.exp(sum/(1 - r**2)) * \ + np.exp(arg*b*r) * ( + ( + 5/2/h*(2*r*h/(1 - r**2) - 2*r*c/(1 - r**2)) + + d_sum_dr/(1 - r**2) + 2*r*sum/(1 - r**2)**2 + + 2*b*arg *( + 1 + r*b**2*t + ) + ) * I_0(arg) + + arg*( + 1/r + 2*b**2*t + ) * I_1(arg) + ) + + +gamma = np.linspace(0, 1, 10000)[1:-1] +kappas = (1/7, 5/27, 5/19, 5/11, 5/3) +for kappa in kappas: + P_eq = Q_I(gamma, kappa) + plt.plot(gamma, P_eq, label=kappa) +plt.legend() +plt.show() +for kappa in kappas: + P_eq = Q_I(gamma, kappa) + g_eq = 4*np.pi*gamma**2*P_eq + plt.plot(gamma, g_eq, label=kappa) +plt.legend() +plt.show() +for kappa in kappas: + P_eq = Q_I(gamma, kappa) + beta_Delta_psi = -np.log(P_eq/P_eq[0]) + plt.semilogy(gamma, beta_Delta_psi, label=kappa) +plt.legend() +plt.show() +for kappa in kappas: + plt.semilogy(gamma, -d_Q_I_d_r(gamma, kappa)/Q_I(gamma, kappa), label=kappa) + P_eq = Q_I(gamma, kappa) + beta_Delta_psi = -np.log(P_eq/P_eq[0]) + eta = np.gradient(beta_Delta_psi)/np.gradient(gamma) + plt.semilogy(gamma, eta, 'k--', label=kappa) +plt.legend() +plt.show() \ No newline at end of file From 7263528c409fce5395e3a15a58d0a92d93b3e1b3 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Sat, 22 Apr 2023 17:22:56 -0600 Subject: [PATCH 02/21] use this (N.B. Becker et al.: The radial distribution of worm-like chains) for wlc/thermodynamics/isometric --- example.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/example.py b/example.py index 84cf7a8f..e43ad4e1 100644 --- a/example.py +++ b/example.py @@ -1,6 +1,7 @@ import numpy as np import matplotlib.pyplot as plt from scipy.special import iv +from scipy.integrate import quad_vec a = 14.054 @@ -109,10 +110,18 @@ def d_Q_I_d_r(r, kappa): plt.legend() plt.show() for kappa in kappas: - plt.semilogy(gamma, -d_Q_I_d_r(gamma, kappa)/Q_I(gamma, kappa), label=kappa) + eta = -d_Q_I_d_r(gamma, kappa)/Q_I(gamma, kappa) + plt.semilogy(gamma, eta, label=kappa) P_eq = Q_I(gamma, kappa) beta_Delta_psi = -np.log(P_eq/P_eq[0]) - eta = np.gradient(beta_Delta_psi)/np.gradient(gamma) - plt.semilogy(gamma, eta, 'k--', label=kappa) + eta_numerical = np.gradient(beta_Delta_psi)/np.gradient(gamma) + plt.semilogy(gamma, eta_numerical, 'k:') + Z, _ = quad_vec( + lambda gamma: + Q_I(gamma, kappa)*np.sinh(eta*gamma)*gamma/eta, + 1e-6, 1 - 1e-6 + ) + gamma_isotensional = np.gradient(np.log(Z))/np.gradient(eta) + plt.semilogy(gamma_isotensional, eta, 'k--') plt.legend() plt.show() \ No newline at end of file From 63482eaf9cf188ebf2f7b086ae8f047e1a5b2f78 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 12:17:49 -0600 Subject: [PATCH 03/21] besseli0 besseli1 --- src/math/mod.rs | 151 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/src/math/mod.rs b/src/math/mod.rs index d89ab24a..94490637 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -74,6 +74,157 @@ pub fn lambert_w(x: &f64) -> f64 w } +pub fn bessel_i(nu: &u8, x: &f64) -> f64 +{ + if nu == &0 + { + bessel_i0(x) + } + else if nu == &1 + { + bessel_i1(x) + } + else + { + -1.0 + } +} + +fn bessel_i0(x: &f64) -> f64 +{ + if x < &7.75 + { + let coefficients = vec![ + 1.0, + 2.499_999_999_999_999e-1, + 2.777_777_777_777_822e-2, + 1.736_111_111_110_237e-3, + 6.944_444_444_533_525e-5, + 1.929_012_345_132_199e-6, + 3.936_759_911_025_107e-8, + 6.151_186_727_044_392e-10, + 7.594_070_020_589_734e-12, + 7.593_897_933_698_363e-14, + 6.277_677_736_362_926e-16, + 4.347_097_041_532_722e-18, + 2.634_177_426_901_091e-20, + 1.139_430_377_448_228e-22, + 9.079_269_200_856_248e-25 + ]; + let t = 0.25*x.powi(2); + 1.0 + t*coefficients.iter().enumerate().map(|(i, c)| c*t.powi(i.try_into().unwrap())).sum::() + } + else if x < &500.0 + { + let coefficients = vec![ + 3.989_422_804_014_25e-1, + 4.986_778_506_049_619e-2, + 2.805_062_339_283_126e-2, + 2.922_112_251_660_478e-2, + 4.442_072_994_936_595e-2, + 1.309_705_746_058_567e-1, + -3.350_522_802_317_27, + 2.330_257_115_835_147e2, + -1.133_663_506_971_723e4, + 4.240_576_743_178_673e5, + -1.231_570_285_956_987e7, + 2.802_319_381_552_675e8, + -5.018_839_997_137_779e9, + 7.080_292_430_151_091e10, + -7.842_610_821_248_111e11, + 6.768_257_378_540_965e12, + -4.490_348_496_961_38e13, + 2.241_552_399_669_589e14, + -8.134_264_678_656_593e14, + 2.023_910_973_916_877e15, + -3.086_757_152_953_708e15, + 2.175_875_438_638_19e15 + ]; + x.exp()/x.sqrt()*coefficients.iter().enumerate().map(|(i, c)| c/x.powi(i.try_into().unwrap())).sum::() + } + else + { + let coefficients = vec![ + 3.989_422_804_014_329e-1, + 4.986_778_504_914_345e-2, + 2.805_063_089_165_061e-2, + 2.921_790_968_539_151e-2, + 4.533_712_087_625_794e-2 + ]; + let expf = (0.5*x).exp(); + (expf/x.sqrt()*coefficients.iter().enumerate().map(|(i, c)| c/x.powi(i.try_into().unwrap())).sum::())*expf + } +} + +fn bessel_i1(x: &f64) -> f64 +{ + if x < &7.75 + { + let coefficients = vec![ + 8.333_333_333_333_333e-2, + 6.944_444_444_444_341e-3, + 3.472_222_222_225_921e-4, + 1.157_407_407_354_987e-5, + 2.755_731_926_254_79e-7, + 4.920_949_692_800_671e-9, + 6.834_657_311_305_621e-11, + 7.593_969_849_687_574e-13, + 6.904_822_652_741_917e-15, + 5.220_157_095_351_373e-17, + 3.410_720_494_727_771e-19, + 1.625_212_890_947_171e-21, + 1.332_898_928_162_29e-23 + ]; + let t = 0.25*x.powi(2); + let more_coefficients = vec![ + 1.0, + 0.5, + coefficients.iter().enumerate().map(|(i, c)| c*t.powi(i.try_into().unwrap())).sum::() + ]; + 0.5*x*more_coefficients.iter().enumerate().map(|(i, c)| c*t.powi(i.try_into().unwrap())).sum::() + } + else if x < &500.0 + { + let coefficients = vec![ + 3.989_422_804_014_406e-1, + -1.496_033_551_613_111e-1, + -4.675_104_253_598_537e-2, + -4.090_895_951_581_637e-2, + -5.719_036_414_430_205e-2, + -1.528_189_554_374_492e-1, + 3.458_284_470_977_172e0, + -2.426_181_371_595_021e2, + 1.178_785_865_993_44e4, + -4.404_655_582_443_487e5, + 1.277_677_779_341_446e7, + -2.903_390_398_236_656e8, + 5.192_386_898_222_206e9, + -7.313_784_438_967_834e10, + 8.087_824_484_994_859e11, + -6.967_602_516_005_787e12, + 4.614_040_809_616_582e13, + -2.298_849_639_457_172e14, + 8.325_554_073_334_618e14, + -2.067_285_045_778_906e15, + 3.146_401_654_361_325e15, + -2.213_318_202_179_221e15 + ]; + x.exp()/x.sqrt()*coefficients.iter().enumerate().map(|(i, c)| c/x.powi(i.try_into().unwrap())).sum::() + } + else + { + let coefficients = vec![ + 3.989_422_804_014_314e-1, + -1.496_033_551_467_584e-1, + -4.675_105_322_571_775e-2, + -4.090_421_597_376_992e-2, + -5.843_630_344_778_927e-2 + ]; + let expf = (0.5*x).exp(); + (expf/x.sqrt()*coefficients.iter().enumerate().map(|(i, c)| c/x.powi(i.try_into().unwrap())).sum::())*expf + } +} + pub fn erf(x: &f64) -> f64 { 1.0 - erfc(x) From 081cc43e222c5785faaf2bd0f6a711d0d82309da Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 12:35:24 -0600 Subject: [PATCH 04/21] skeleton for wlc --- src/physics/single_chain/mod.rs | 3 ++ src/physics/single_chain/wlc/__init__.py | 0 src/physics/single_chain/wlc/mod.jl | 0 src/physics/single_chain/wlc/mod.rs | 35 +++++++++++++++++ src/physics/single_chain/wlc/py.rs | 0 src/physics/single_chain/wlc/test.jl | 0 src/physics/single_chain/wlc/test.rs | 0 .../wlc/thermodynamics/__init__.py | 0 .../wlc/thermodynamics/isometric/__init__.py | 0 .../wlc/thermodynamics/isometric/ex.rs | 0 .../isometric/legendre/__init__.py | 0 .../thermodynamics/isometric/legendre/ex.rs | 0 .../thermodynamics/isometric/legendre/mod.jl | 0 .../thermodynamics/isometric/legendre/mod.rs | 31 +++++++++++++++ .../thermodynamics/isometric/legendre/py.rs | 0 .../thermodynamics/isometric/legendre/test.jl | 0 .../thermodynamics/isometric/legendre/test.rs | 0 .../wlc/thermodynamics/isometric/mod.jl | 0 .../wlc/thermodynamics/isometric/mod.rs | 38 +++++++++++++++++++ .../wlc/thermodynamics/isometric/py.rs | 0 .../wlc/thermodynamics/isometric/test.jl | 0 .../wlc/thermodynamics/isometric/test.rs | 0 .../single_chain/wlc/thermodynamics/mod.jl | 0 .../single_chain/wlc/thermodynamics/mod.rs | 35 +++++++++++++++++ .../single_chain/wlc/thermodynamics/py.rs | 0 .../single_chain/wlc/thermodynamics/test.jl | 0 .../single_chain/wlc/thermodynamics/test.rs | 0 27 files changed, 142 insertions(+) create mode 100644 src/physics/single_chain/wlc/__init__.py create mode 100644 src/physics/single_chain/wlc/mod.jl create mode 100644 src/physics/single_chain/wlc/mod.rs create mode 100644 src/physics/single_chain/wlc/py.rs create mode 100644 src/physics/single_chain/wlc/test.jl create mode 100644 src/physics/single_chain/wlc/test.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/__init__.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/__init__.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/__init__.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/py.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/test.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/test.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/mod.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/mod.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/py.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/test.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/test.rs diff --git a/src/physics/single_chain/mod.rs b/src/physics/single_chain/mod.rs index 2e8aec86..1f122f84 100644 --- a/src/physics/single_chain/mod.rs +++ b/src/physics/single_chain/mod.rs @@ -18,6 +18,9 @@ pub mod swfjc; /// The arbitrary link potential freely-jointed chain (uFJC) single-chain model. pub mod ufjc; +/// The worm-like chain (WLC) single-chain model. +pub mod wlc; + static ONE: f64 = 1.0; static ZERO: f64 = 1e-6; static POINTS: u128 = 64; diff --git a/src/physics/single_chain/wlc/__init__.py b/src/physics/single_chain/wlc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/mod.jl b/src/physics/single_chain/wlc/mod.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/mod.rs b/src/physics/single_chain/wlc/mod.rs new file mode 100644 index 00000000..702f1fbe --- /dev/null +++ b/src/physics/single_chain/wlc/mod.rs @@ -0,0 +1,35 @@ +#[cfg(feature = "python")] +pub mod py; + +mod test; + +/// The worm-like chain (WLC) model thermodynamics. +pub mod thermodynamics; + +/// The structure of the WLC model. +pub struct WLC +{ + /// The contour length of the chain in units of nm. + pub chain_length: f64, + + /// The persistance length of the chain in units of nm. + pub persistance_length: f64, + + /// The thermodynamic functions of the model. + pub thermodynamics: self::thermodynamics::WLC +} + +/// The implemented functionality of the WLC model. +impl WLC +{ + /// Initializes and returns an instance of the WLC model. + pub fn init(chain_length: f64, persistance_length: f64) -> Self + { + WLC + { + chain_length, + persistance_length, + thermodynamics: self::thermodynamics::WLC::init(chain_length, persistance_length), + } + } +} diff --git a/src/physics/single_chain/wlc/py.rs b/src/physics/single_chain/wlc/py.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/test.jl b/src/physics/single_chain/wlc/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/test.rs b/src/physics/single_chain/wlc/test.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/__init__.py b/src/physics/single_chain/wlc/thermodynamics/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/__init__.py b/src/physics/single_chain/wlc/thermodynamics/isometric/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/__init__.py b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs new file mode 100644 index 00000000..74efe6d9 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs @@ -0,0 +1,31 @@ +#[cfg(feature = "extern")] +pub mod ex; + +#[cfg(feature = "python")] +pub mod py; + +mod test; + +/// The structure of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. +pub struct WLC +{ + /// The contour length of the chain in units of nm. + pub chain_length: f64, + + /// The persistance length of the chain in units of nm. + pub persistance_length: f64 +} + +/// The implemented functionality of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. +impl WLC +{ + /// Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. + pub fn init(chain_length: f64, persistance_length: f64) -> Self + { + WLC + { + chain_length, + persistance_length + } + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs new file mode 100644 index 00000000..ac4cb365 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -0,0 +1,38 @@ +#[cfg(feature = "extern")] +pub mod ex; + +#[cfg(feature = "python")] +pub mod py; + +mod test; + +/// The worm-like chain (WLC) model thermodynamics in the isometric ensemble approximated using a Legendre transformation. +pub mod legendre; + +/// The structure of the thermodynamics of the WLC model in the isometric ensemble. +pub struct WLC +{ + /// The contour length of the chain in units of nm. + pub chain_length: f64, + + /// The persistance length of the chain in units of nm. + pub persistance_length: f64, + + /// The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. + pub legendre: self::legendre::WLC +} + +/// The implemented functionality of the thermodynamics of the WLC model in the isometric ensemble. +impl WLC +{ + /// Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble. + pub fn init(chain_length: f64, persistance_length: f64) -> Self + { + WLC + { + chain_length, + persistance_length, + legendre: self::legendre::WLC::init(chain_length, persistance_length), + } + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/py.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/py.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/mod.jl b/src/physics/single_chain/wlc/thermodynamics/mod.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/mod.rs b/src/physics/single_chain/wlc/thermodynamics/mod.rs new file mode 100644 index 00000000..8131ede2 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/mod.rs @@ -0,0 +1,35 @@ +#[cfg(feature = "python")] +pub mod py; + +mod test; + +/// The worm-like chain (WLC) model thermodynamics in the isometric ensemble. +pub mod isometric; + +/// The structure of the thermodynamics of the WLC model. +pub struct WLC +{ + /// The contour length of the chain in units of nm. + pub chain_length: f64, + + /// The persistance length of the chain in units of nm. + pub persistance_length: f64, + + /// The thermodynamic functions of the model in the isometric ensemble. + pub isometric: self::isometric::WLC +} + +/// The implemented functionality of the thermodynamics of the WLC model. +impl WLC +{ + /// Initializes and returns an instance of the thermodynamics of the WLC model. + pub fn init(chain_length: f64, persistance_length: f64) -> Self + { + WLC + { + chain_length, + persistance_length, + isometric: self::isometric::WLC::init(chain_length, persistance_length), + } + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/py.rs b/src/physics/single_chain/wlc/thermodynamics/py.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/test.jl b/src/physics/single_chain/wlc/thermodynamics/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/test.rs b/src/physics/single_chain/wlc/thermodynamics/test.rs new file mode 100644 index 00000000..e69de29b From e9037f591c721899b9fdb263c806b18ec46e803c Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 13:10:11 -0600 Subject: [PATCH 05/21] some setup --- src/physics/single_chain/wlc/mod.rs | 18 +++- .../thermodynamics/isometric/legendre/mod.rs | 16 ++- .../wlc/thermodynamics/isometric/mod.rs | 102 +++++++++++++++++- .../single_chain/wlc/thermodynamics/mod.rs | 18 +++- 4 files changed, 135 insertions(+), 19 deletions(-) diff --git a/src/physics/single_chain/wlc/mod.rs b/src/physics/single_chain/wlc/mod.rs index 702f1fbe..ed981db3 100644 --- a/src/physics/single_chain/wlc/mod.rs +++ b/src/physics/single_chain/wlc/mod.rs @@ -9,8 +9,14 @@ pub mod thermodynamics; /// The structure of the WLC model. pub struct WLC { - /// The contour length of the chain in units of nm. - pub chain_length: f64, + /// The mass of each hinge in the chain in units of kg/mol. + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + pub link_length: f64, + + /// The number of links in the chain. + pub number_of_links: u8, /// The persistance length of the chain in units of nm. pub persistance_length: f64, @@ -23,13 +29,15 @@ pub struct WLC impl WLC { /// Initializes and returns an instance of the WLC model. - pub fn init(chain_length: f64, persistance_length: f64) -> Self + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self { WLC { - chain_length, + hinge_mass, + link_length, + number_of_links, persistance_length, - thermodynamics: self::thermodynamics::WLC::init(chain_length, persistance_length), + thermodynamics: self::thermodynamics::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } } } diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs index 74efe6d9..6c1702f1 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs @@ -9,8 +9,14 @@ mod test; /// The structure of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. pub struct WLC { - /// The contour length of the chain in units of nm. - pub chain_length: f64, + /// The mass of each hinge in the chain in units of kg/mol. + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + pub link_length: f64, + + /// The number of links in the chain. + pub number_of_links: u8, /// The persistance length of the chain in units of nm. pub persistance_length: f64 @@ -20,11 +26,13 @@ pub struct WLC impl WLC { /// Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. - pub fn init(chain_length: f64, persistance_length: f64) -> Self + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self { WLC { - chain_length, + hinge_mass, + link_length, + number_of_links, persistance_length } } diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index ac4cb365..dc951147 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -9,30 +9,122 @@ mod test; /// The worm-like chain (WLC) model thermodynamics in the isometric ensemble approximated using a Legendre transformation. pub mod legendre; +use std::f64::consts::PI; +use crate::math::bessel_i; +use crate::physics::BOLTZMANN_CONSTANT; + /// The structure of the thermodynamics of the WLC model in the isometric ensemble. pub struct WLC { - /// The contour length of the chain in units of nm. - pub chain_length: f64, + /// The mass of each hinge in the chain in units of kg/mol. + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + pub link_length: f64, + + /// The number of links in the chain. + pub number_of_links: u8, /// The persistance length of the chain in units of nm. pub persistance_length: f64, + contour_length: f64, + + nondimensional_persistance_length: f64, + /// The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. pub legendre: self::legendre::WLC } +/// The expected force as a function of the applied end-to-end length and temperature, parameterized by the link length, contour length, and persistance length. +pub fn force(link_length: &f64, contour_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + nondimensional_force(&(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature/link_length +} + +/// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. +pub fn nondimensional_force(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +{ + bessel_i(&1, nondimensional_end_to_end_length_per_link)*nondimensional_persistance_length +} + +// +// +// +// use logarithm of distributions for free energies? +// +// +// + +/// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length, parameterized by the contour length and persistance length. +pub fn equilibrium_distribution(contour_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +{ + nondimensional_equilibrium_distribution(&(persistance_length/contour_length), &(end_to_end_length/contour_length))/contour_length.powi(3) +} + +/// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. +pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +{ + bessel_i(&0, nondimensional_end_to_end_length_per_link)*nondimensional_persistance_length +} + +/// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length, parameterized by the contour length and persistance length. +pub fn equilibrium_radial_distribution(contour_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +{ + nondimensional_equilibrium_radial_distribution(&(persistance_length/contour_length), &(end_to_end_length/contour_length))/contour_length +} + +/// The nondimensional equilibrium probability density of nondimensional end-to-end lengths per link as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. +pub fn nondimensional_equilibrium_radial_distribution(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +{ + 4.0*PI*nondimensional_end_to_end_length_per_link.powi(2)*nondimensional_equilibrium_distribution(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) +} + /// The implemented functionality of the thermodynamics of the WLC model in the isometric ensemble. impl WLC { /// Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble. - pub fn init(chain_length: f64, persistance_length: f64) -> Self + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self { WLC { - chain_length, + hinge_mass, + link_length, + number_of_links, persistance_length, - legendre: self::legendre::WLC::init(chain_length, persistance_length), + contour_length: (number_of_links as f64)*link_length, + nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length, + legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } } + /// The expected force as a function of the applied end-to-end length and temperature. + pub fn force(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + force(&self.link_length, &self.contour_length, &self.persistance_length, end_to_end_length, temperature) + } + /// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link. + pub fn nondimensional_force(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_force(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } + /// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length. + pub fn equilibrium_distribution(&self, end_to_end_length: &f64) -> f64 + { + equilibrium_distribution(&self.contour_length, &self.persistance_length, end_to_end_length) + } + /// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link. + pub fn nondimensional_equilibrium_distribution(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_equilibrium_distribution(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } + /// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length. + pub fn equilibrium_radial_distribution(&self, end_to_end_length: &f64) -> f64 + { + equilibrium_radial_distribution(&self.contour_length, &self.persistance_length, end_to_end_length) + } + /// The nondimensional equilibrium probability density of nondimensional end-to-end lengths per link as a function of the nondimensional end-to-end length per link. + pub fn nondimensional_equilibrium_radial_distribution(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_equilibrium_radial_distribution(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } } diff --git a/src/physics/single_chain/wlc/thermodynamics/mod.rs b/src/physics/single_chain/wlc/thermodynamics/mod.rs index 8131ede2..7163317f 100644 --- a/src/physics/single_chain/wlc/thermodynamics/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/mod.rs @@ -9,8 +9,14 @@ pub mod isometric; /// The structure of the thermodynamics of the WLC model. pub struct WLC { - /// The contour length of the chain in units of nm. - pub chain_length: f64, + /// The mass of each hinge in the chain in units of kg/mol. + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + pub link_length: f64, + + /// The number of links in the chain. + pub number_of_links: u8, /// The persistance length of the chain in units of nm. pub persistance_length: f64, @@ -23,13 +29,15 @@ pub struct WLC impl WLC { /// Initializes and returns an instance of the thermodynamics of the WLC model. - pub fn init(chain_length: f64, persistance_length: f64) -> Self + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self { WLC { - chain_length, + hinge_mass, + link_length, + number_of_links, persistance_length, - isometric: self::isometric::WLC::init(chain_length, persistance_length), + isometric: self::isometric::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } } } From 3a75f6980aefdd0d8c48453fb1677fc2fa7c1b26 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 13:10:59 -0600 Subject: [PATCH 06/21] some setup --- .../single_chain/wlc/thermodynamics/isometric/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index dc951147..32452eb9 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -11,7 +11,12 @@ pub mod legendre; use std::f64::consts::PI; use crate::math::bessel_i; -use crate::physics::BOLTZMANN_CONSTANT; +use crate::physics:: +{ + PLANCK_CONSTANT, + BOLTZMANN_CONSTANT +}; +use crate::physics::single_chain::ZERO; /// The structure of the thermodynamics of the WLC model in the isometric ensemble. pub struct WLC From 6eed226767484ebb30a68d0518525f9a1babe712 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 15:45:00 -0600 Subject: [PATCH 07/21] tests not passing --- example.py | 1 + src/main.rs | 5 + src/physics/single_chain/test.rs | 4 + src/physics/single_chain/wlc/test.rs | 76 ++ .../thermodynamics/isometric/legendre/test.rs | 76 ++ .../wlc/thermodynamics/isometric/mod.rs | 169 ++++- .../wlc/thermodynamics/isometric/test.rs | 678 ++++++++++++++++++ .../single_chain/wlc/thermodynamics/test.rs | 76 ++ 8 files changed, 1064 insertions(+), 21 deletions(-) create mode 100644 src/main.rs diff --git a/example.py b/example.py index e43ad4e1..43671e91 100644 --- a/example.py +++ b/example.py @@ -89,6 +89,7 @@ def d_Q_I_d_r(r, kappa): ) * I_1(arg) ) +print(-d_Q_I_d_r(0.9, 0.3)/Q_I(0.9, 0.3)) gamma = np.linspace(0, 1, 10000)[1:-1] kappas = (1/7, 5/27, 5/19, 5/11, 5/3) diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 00000000..d0b2912d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,5 @@ +use polymers::physics::single_chain::wlc::thermodynamics::isometric::nondimensional_force; +fn main() +{ + println!("{:?}", nondimensional_force(&0.3, &0.9)); +} \ No newline at end of file diff --git a/src/physics/single_chain/test.rs b/src/physics/single_chain/test.rs index 32832ab3..ed620304 100644 --- a/src/physics/single_chain/test.rs +++ b/src/physics/single_chain/test.rs @@ -18,6 +18,8 @@ pub struct Parameters pub hinge_mass_scale: f64, pub link_length_reference: f64, pub link_length_scale: f64, + pub persistance_length_reference: f64, + pub persistance_length_scale: f64, pub number_of_links_minimum: u8, pub number_of_links_maximum: u8, pub link_stiffness_reference: f64, @@ -64,6 +66,8 @@ impl Default for Parameters hinge_mass_scale: 1e0, link_length_reference: 1e0, link_length_scale: 1e0, + persistance_length_reference: 5e0, + persistance_length_scale: 1e1, number_of_links_minimum: 5, number_of_links_maximum: 25, link_stiffness_reference: 5e5, diff --git a/src/physics/single_chain/wlc/test.rs b/src/physics/single_chain/wlc/test.rs index e69de29b..45903223 100644 --- a/src/physics/single_chain/wlc/test.rs +++ b/src/physics/single_chain/wlc/test.rs @@ -0,0 +1,76 @@ +#![cfg(test)] +use super::*; +use crate::physics::single_chain::test::Parameters; +mod base +{ + use super::*; + use rand::Rng; + #[test] + fn init() + { + let parameters = Parameters::default(); + let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); + } + #[test] + fn number_of_links() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); + } + } + #[test] + fn link_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); + } + } + #[test] + fn hinge_mass() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); + } + } + #[test] + fn persistance_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); + } + } + #[test] + fn all_parameters() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + assert_eq!(number_of_links, model.number_of_links); + assert_eq!(link_length, model.link_length); + assert_eq!(hinge_mass, model.hinge_mass); + assert_eq!(persistance_length, model.persistance_length); + } + } +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs index e69de29b..45903223 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs @@ -0,0 +1,76 @@ +#![cfg(test)] +use super::*; +use crate::physics::single_chain::test::Parameters; +mod base +{ + use super::*; + use rand::Rng; + #[test] + fn init() + { + let parameters = Parameters::default(); + let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); + } + #[test] + fn number_of_links() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); + } + } + #[test] + fn link_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); + } + } + #[test] + fn hinge_mass() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); + } + } + #[test] + fn persistance_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); + } + } + #[test] + fn all_parameters() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + assert_eq!(number_of_links, model.number_of_links); + assert_eq!(link_length, model.link_length); + assert_eq!(hinge_mass, model.hinge_mass); + assert_eq!(persistance_length, model.persistance_length); + } + } +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index 32452eb9..e54df16a 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -33,49 +33,137 @@ pub struct WLC /// The persistance length of the chain in units of nm. pub persistance_length: f64, - contour_length: f64, - nondimensional_persistance_length: f64, /// The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. pub legendre: self::legendre::WLC } -/// The expected force as a function of the applied end-to-end length and temperature, parameterized by the link length, contour length, and persistance length. -pub fn force(link_length: &f64, contour_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +/// The expected force as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, and persistance length. +pub fn force(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 { + let contour_length = (*number_of_links as f64)*link_length; nondimensional_force(&(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature/link_length } /// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. pub fn nondimensional_force(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - bessel_i(&1, nondimensional_end_to_end_length_per_link)*nondimensional_persistance_length + let g2 = nondimensional_end_to_end_length_per_link.powi(2); + let a: f64 = 14.054; + let b: f64 = 0.473; + let c = vec![ + vec![-0.75, 0.359375, -0.109375], + vec![-0.5, 1.0625, -0.5625] + ]; + let c0: f64 = 1.0 - (1.0 + (0.38/nondimensional_persistance_length.powf(0.95)).powi(-5)).powf(-0.2); + let d: f64 = if nondimensional_persistance_length < &0.125 + { + 1.0 + } + else + { + 1.0 - 1.0/(0.177/(nondimensional_persistance_length - 0.111) + 6.40*(nondimensional_persistance_length - 0.111).powf(0.783)) + }; + let f = (1.0 - c0*g2)/(1.0 - g2); + let h = nondimensional_end_to_end_length_per_link/(1.0 - b.powi(2)*g2); + let arg = -d*nondimensional_persistance_length*a*(1.0 + b)*h; + let sum = (0..2).collect::>().iter().map(|i| (1..4).collect::>().iter().map(|j| c[*i][j - 1]*(nondimensional_persistance_length.powi(*i as i32 - 1)*g2.powi((*j).try_into().unwrap()))).sum::()).sum::(); + let d_sum_dg = (0..2).collect::>().iter().map(|i| (1..4).collect::>().iter().map(|j| (*j as f64)*c[*i][j - 1]*(nondimensional_persistance_length.powi(*i as i32 - 1)*g2.powi((*j).try_into().unwrap()))).sum::()).sum::()*2.0/nondimensional_end_to_end_length_per_link; + -((5.0*nondimensional_end_to_end_length_per_link*(1.0 - c0/f) + d_sum_dg + 2.0*nondimensional_end_to_end_length_per_link*sum/(1.0 - g2))/(1.0 - g2) + 2.0*b*arg *(1.0 + nondimensional_end_to_end_length_per_link*b.powi(2)*h) + arg*bessel_i(&1, &arg)/bessel_i(&0, &arg)*(1.0/nondimensional_end_to_end_length_per_link + 2.0*b.powi(2)*h)) +} + +/// The Helmholtz free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, persistance_length, &(end_to_end_length/((*number_of_links as f64)*link_length)), temperature)*BOLTZMANN_CONSTANT*temperature +} + +/// The Helmholtz free energy per link as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + nondimensional_helmholtz_free_energy_per_link(number_of_links, link_length, hinge_mass, persistance_length, &(end_to_end_length/((*number_of_links as f64)*link_length)), temperature)*BOLTZMANN_CONSTANT*temperature +} + +/// The relative Helmholtz free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, and persistance length. +pub fn relative_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_relative_helmholtz_free_energy(&(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature +} + +/// The relative Helmholtz free energy per link as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, and persistance length. +pub fn relative_helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_relative_helmholtz_free_energy_per_link(number_of_links, &(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature +} + +/// The nondimensional Helmholtz free energy as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 +{ + -(equilibrium_distribution(number_of_links, link_length, persistance_length, &(nondimensional_end_to_end_length_per_link*(*number_of_links as f64)*link_length))).ln() - ((*number_of_links as f64) - 1.0)*(8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() +} + +/// The nondimensional Helmholtz free energy per link as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and persistance length. +pub fn nondimensional_helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 +{ + nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, persistance_length, nondimensional_end_to_end_length_per_link, temperature)/(*number_of_links as f64) } -// -// -// -// use logarithm of distributions for free energies? -// -// -// +/// The nondimensional relative Helmholtz free energy as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. +pub fn nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +{ + (nondimensional_equilibrium_distribution(nondimensional_persistance_length, &ZERO)/nondimensional_equilibrium_distribution(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)).ln() +} -/// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length, parameterized by the contour length and persistance length. -pub fn equilibrium_distribution(contour_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +/// The nondimensional relative Helmholtz free energy per link as a function of the nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. +pub fn nondimensional_relative_helmholtz_free_energy_per_link(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { + nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)/(*number_of_links as f64) +} + +/// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length, parameterized by the number of links, link length, and persistance length. +pub fn equilibrium_distribution(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; nondimensional_equilibrium_distribution(&(persistance_length/contour_length), &(end_to_end_length/contour_length))/contour_length.powi(3) } /// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - bessel_i(&0, nondimensional_end_to_end_length_per_link)*nondimensional_persistance_length + let g2 = nondimensional_end_to_end_length_per_link.powi(2); + let a: f64 = 14.054; + let b: f64 = 0.473; + let c = vec![ + vec![-0.75, 0.359375, -0.109375], + vec![-0.5, 1.0625, -0.5625] + ]; + let c0: f64 = 1.0 - (1.0 + (0.38/nondimensional_persistance_length.powf(0.95)).powi(-5)).powf(-0.2); + let d: f64; + let e: f64; + if nondimensional_persistance_length < &0.125 + { + d = 1.0; + e = (0.75/PI/nondimensional_persistance_length).powf(1.5)*(-0.75*g2/nondimensional_persistance_length).exp()*(1.0 - 1.25*nondimensional_persistance_length + 2.0*g2 - 0.4125*g2.powi(2)/nondimensional_persistance_length); + } + else + { + d = 1.0 - 1.0/(0.177/(nondimensional_persistance_length - 0.111) + 6.40*(nondimensional_persistance_length - 0.111).powf(0.783)); + e = 112.04*nondimensional_persistance_length.powi(2)*(0.246/nondimensional_persistance_length - a*nondimensional_persistance_length).exp(); + } + let f = (1.0 - c0*g2)/(1.0 - g2); + let h = nondimensional_end_to_end_length_per_link/(1.0 - b.powi(2)*g2); + let arg = -d*nondimensional_persistance_length*a*(1.0 + b)*h; + let sum = (0..2).collect::>().iter().map(|i| (1..4).collect::>().iter().map(|j| c[*i][j - 1]*(nondimensional_persistance_length.powi(*i as i32 - 1)*g2.powi((*j).try_into().unwrap()))).sum::()).sum::(); + e*f.powf(2.5)*(sum/(1.0 - g2) + arg*b*nondimensional_end_to_end_length_per_link).exp()*bessel_i(&0, &arg) } -/// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length, parameterized by the contour length and persistance length. -pub fn equilibrium_radial_distribution(contour_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +/// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length, parameterized by the number of links, link length, and persistance length. +pub fn equilibrium_radial_distribution(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 { + let contour_length = (*number_of_links as f64)*link_length; nondimensional_equilibrium_radial_distribution(&(persistance_length/contour_length), &(end_to_end_length/contour_length))/contour_length } @@ -97,7 +185,6 @@ impl WLC link_length, number_of_links, persistance_length, - contour_length: (number_of_links as f64)*link_length, nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length, legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } @@ -105,17 +192,57 @@ impl WLC /// The expected force as a function of the applied end-to-end length and temperature. pub fn force(&self, end_to_end_length: &f64, temperature: &f64) -> f64 { - force(&self.link_length, &self.contour_length, &self.persistance_length, end_to_end_length, temperature) + force(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length, temperature) } /// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link. pub fn nondimensional_force(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 { nondimensional_force(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) } + /// The Helmholtz free energy as a function of the applied end-to-end length and temperature. + pub fn helmholtz_free_energy(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, end_to_end_length, temperature) + } + /// The Helmholtz free energy per link as a function of the applied end-to-end length and temperature. + pub fn helmholtz_free_energy_per_link(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, end_to_end_length, temperature) + } + /// The relative Helmholtz free energy as a function of the applied end-to-end length and temperature. + pub fn relative_helmholtz_free_energy(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + relative_helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length, temperature) + } + /// The relative Helmholtz free energy per link as a function of the applied end-to-end length and temperature. + pub fn relative_helmholtz_free_energy_per_link(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + relative_helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length, temperature) + } + /// The nondimensional Helmholtz free energy as a function of the applied nondimensional end-to-end length per link and temperature. + pub fn nondimensional_helmholtz_free_energy(&self, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 + { + nondimensional_helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, nondimensional_end_to_end_length_per_link, temperature) + } + /// The nondimensional Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link and temperature. + pub fn nondimensional_helmholtz_free_energy_per_link(&self, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 + { + nondimensional_helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, nondimensional_end_to_end_length_per_link, temperature) + } + /// The nondimensional relative Helmholtz free energy as a function of the applied nondimensional end-to-end length per link. + pub fn nondimensional_relative_helmholtz_free_energy(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_relative_helmholtz_free_energy(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } + /// The nondimensional relative Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link. + pub fn nondimensional_relative_helmholtz_free_energy_per_link(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_relative_helmholtz_free_energy_per_link(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } /// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length. pub fn equilibrium_distribution(&self, end_to_end_length: &f64) -> f64 { - equilibrium_distribution(&self.contour_length, &self.persistance_length, end_to_end_length) + equilibrium_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length) } /// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link. pub fn nondimensional_equilibrium_distribution(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 @@ -125,7 +252,7 @@ impl WLC /// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length. pub fn equilibrium_radial_distribution(&self, end_to_end_length: &f64) -> f64 { - equilibrium_radial_distribution(&self.contour_length, &self.persistance_length, end_to_end_length) + equilibrium_radial_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length) } /// The nondimensional equilibrium probability density of nondimensional end-to-end lengths per link as a function of the nondimensional end-to-end length per link. pub fn nondimensional_equilibrium_radial_distribution(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs index e69de29b..5ce91634 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs @@ -0,0 +1,678 @@ +#![cfg(test)] +use super::*; +use crate::physics::single_chain::test::Parameters; +mod base +{ + use super::*; + use rand::Rng; + #[test] + fn init() + { + let parameters = Parameters::default(); + let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); + } + #[test] + fn number_of_links() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); + } + } + #[test] + fn link_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); + } + } + #[test] + fn hinge_mass() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); + } + } + #[test] + fn persistance_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); + } + } + #[test] + fn all_parameters() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + assert_eq!(number_of_links, model.number_of_links); + assert_eq!(link_length, model.link_length); + assert_eq!(hinge_mass, model.hinge_mass); + assert_eq!(persistance_length, model.persistance_length); + } + } +} +mod normalization +{ + use super::*; + use rand::Rng; + use crate::math::integrate_1d; + use crate::physics::single_chain:: + { + ONE, + ZERO, + POINTS + }; + #[test] + fn equilibrium_distribution() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let integrand = |end_to_end_length: &f64| 4.0*PI*end_to_end_length.powi(2)*model.equilibrium_distribution(&end_to_end_length); + let integral = integrate_1d(&integrand, &(ZERO*(number_of_links as f64)*link_length), &(ONE*(number_of_links as f64)*link_length), &POINTS); + assert!((integral - 1.0).abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_equilibrium_distribution() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let integrand = |nondimensional_end_to_end_length_per_link_per_link: &f64| 4.0*PI*nondimensional_end_to_end_length_per_link_per_link.powi(2)*model.nondimensional_equilibrium_distribution(&nondimensional_end_to_end_length_per_link_per_link); + let integral = integrate_1d(&integrand, &ZERO, &ONE, &POINTS); + assert!((integral - 1.0).abs() <= parameters.rel_tol); + } + } + #[test] + fn equilibrium_radial_distribution() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let integrand = |end_to_end_length: &f64| model.equilibrium_radial_distribution(&end_to_end_length); + let integral = integrate_1d(&integrand, &(ZERO*(number_of_links as f64)*link_length), &(ONE*(number_of_links as f64)*link_length), &POINTS); + assert!((integral - 1.0).abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_equilibrium_radial_distribution() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let integrand = |nondimensional_end_to_end_length_per_link_per_link: &f64| model.nondimensional_equilibrium_radial_distribution(&nondimensional_end_to_end_length_per_link_per_link); + let integral = integrate_1d(&integrand, &ZERO, &ONE, &POINTS); + assert!((integral - 1.0).abs() <= parameters.rel_tol); + } + } +} +mod nondimensional +{ + use super::*; + use rand::Rng; + #[test] + fn force() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_force = model.nondimensional_force(&nondimensional_end_to_end_length_per_link); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let force = model.force(&end_to_end_length, &temperature); + let residual_abs = &force/BOLTZMANN_CONSTANT/temperature*link_length - &nondimensional_force; + let residual_rel = &residual_abs/&nondimensional_force; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let helmholtz_free_energy = model.helmholtz_free_energy(&end_to_end_length, &temperature); + let residual_abs = helmholtz_free_energy/BOLTZMANN_CONSTANT/temperature - nondimensional_helmholtz_free_energy; + let residual_rel = residual_abs/nondimensional_helmholtz_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let helmholtz_free_energy_per_link = model.helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = helmholtz_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - nondimensional_helmholtz_free_energy_per_link; + let residual_rel = residual_abs/nondimensional_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let relative_helmholtz_free_energy = model.relative_helmholtz_free_energy(&end_to_end_length, &temperature); + let residual_abs = relative_helmholtz_free_energy/BOLTZMANN_CONSTANT/temperature - nondimensional_relative_helmholtz_free_energy; + let residual_rel = residual_abs/nondimensional_relative_helmholtz_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let relative_helmholtz_free_energy_per_link = model.relative_helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = relative_helmholtz_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - nondimensional_relative_helmholtz_free_energy_per_link; + let residual_rel = residual_abs/nondimensional_relative_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod per_link +{ + use super::*; + use rand::Rng; + #[test] + fn helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let helmholtz_free_energy = model.helmholtz_free_energy(&end_to_end_length, &temperature); + let helmholtz_free_energy_per_link = model.helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = helmholtz_free_energy/(number_of_links as f64) - helmholtz_free_energy_per_link; + let residual_rel = residual_abs/helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_helmholtz_free_energy = model.relative_helmholtz_free_energy(&end_to_end_length, &temperature); + let relative_helmholtz_free_energy_per_link = model.relative_helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = relative_helmholtz_free_energy/(number_of_links as f64) - relative_helmholtz_free_energy_per_link; + let residual_rel = residual_abs/relative_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let residual_abs = nondimensional_helmholtz_free_energy/(number_of_links as f64) - nondimensional_helmholtz_free_energy_per_link; + let residual_rel = residual_abs/nondimensional_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link); + let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let residual_abs = nondimensional_relative_helmholtz_free_energy/(number_of_links as f64) - nondimensional_relative_helmholtz_free_energy_per_link; + let residual_rel = residual_abs/nondimensional_relative_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod relative +{ + use super::*; + use rand::Rng; + use crate::physics::single_chain::ZERO; + #[test] + fn helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let helmholtz_free_energy = model.helmholtz_free_energy(&end_to_end_length, &temperature); + let helmholtz_free_energy_0 = model.helmholtz_free_energy(&(ZERO*(number_of_links as f64)*link_length), &temperature); + let relative_helmholtz_free_energy = model.relative_helmholtz_free_energy(&end_to_end_length, &temperature); + let residual_abs = &helmholtz_free_energy - &helmholtz_free_energy_0 - &relative_helmholtz_free_energy; + let residual_rel = &residual_abs/&helmholtz_free_energy_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let helmholtz_free_energy_per_link = model.helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let helmholtz_free_energy_per_link_0 = model.helmholtz_free_energy_per_link(&(ZERO*(number_of_links as f64)*link_length), &temperature); + let relative_helmholtz_free_energy_per_link = model.relative_helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = &helmholtz_free_energy_per_link - &helmholtz_free_energy_per_link_0 - &relative_helmholtz_free_energy_per_link; + let residual_rel = &residual_abs/&helmholtz_free_energy_per_link_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_helmholtz_free_energy_0 = model.nondimensional_helmholtz_free_energy(&ZERO, &temperature); + let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link); + let residual_abs = &nondimensional_helmholtz_free_energy - &nondimensional_helmholtz_free_energy_0 - &nondimensional_relative_helmholtz_free_energy; + let residual_rel = &residual_abs/&nondimensional_helmholtz_free_energy_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_helmholtz_free_energy_per_link_0 = model.nondimensional_helmholtz_free_energy_per_link(&ZERO, &temperature); + let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let residual_abs = &nondimensional_helmholtz_free_energy_per_link - &nondimensional_helmholtz_free_energy_per_link_0 - &nondimensional_relative_helmholtz_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_helmholtz_free_energy_per_link_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod zero +{ + use super::*; + use rand::Rng; + use crate::physics::single_chain::ZERO; + #[test] + fn relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_helmholtz_free_energy_0 = model.relative_helmholtz_free_energy(&(ZERO*(number_of_links as f64)*link_length), &temperature); + assert!(relative_helmholtz_free_energy_0.abs() <= BOLTZMANN_CONSTANT*temperature*(number_of_links as f64)*ZERO); + } + } + #[test] + fn relative_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_helmholtz_free_energy_per_link_0 = model.relative_helmholtz_free_energy_per_link(&(ZERO*(number_of_links as f64)*link_length), &temperature); + assert!(relative_helmholtz_free_energy_per_link_0.abs() <= BOLTZMANN_CONSTANT*temperature*ZERO); + } + } + #[test] + fn nondimensional_relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_relative_helmholtz_free_energy_0 = model.nondimensional_relative_helmholtz_free_energy(&ZERO); + assert!(nondimensional_relative_helmholtz_free_energy_0.abs() <= (number_of_links as f64)*ZERO); + } + } + #[test] + fn nondimensional_relative_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_relative_helmholtz_free_energy_per_link_0 = model.nondimensional_relative_helmholtz_free_energy_per_link(&ZERO); + assert!(nondimensional_relative_helmholtz_free_energy_per_link_0.abs() <= ZERO); + } + } + #[test] + fn equilibrium_radial_distribution() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let equilibrium_radial_distribution_0 = model.equilibrium_radial_distribution(&(ZERO*(number_of_links as f64)*link_length)); + assert!(equilibrium_radial_distribution_0.abs() <= ZERO); + } + } + #[test] + fn nondimensional_equilibrium_radial_distribution() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_equilibrium_radial_distribution_0 = model.nondimensional_equilibrium_radial_distribution(&ZERO); + assert!(nondimensional_equilibrium_radial_distribution_0.abs() <= ZERO); + } + } +} +mod connection +{ + use super::*; + use rand::Rng; + use crate::physics::single_chain::ZERO; + #[test] + fn force() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + 0.5*parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = model.force(&end_to_end_length, &temperature); + let h = parameters.rel_tol*(number_of_links as f64)*link_length; + let force_from_derivative = (model.relative_helmholtz_free_energy(&(end_to_end_length + 0.5*h), &temperature) - model.relative_helmholtz_free_energy(&(end_to_end_length - 0.5*h), &temperature))/h; + let residual_abs = &force - &force_from_derivative; + let residual_rel = &residual_abs/&force; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn nondimensional_force() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + 0.5*parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_force = model.nondimensional_force(&nondimensional_end_to_end_length_per_link); + let h = parameters.rel_tol; + let nondimensional_force_from_derivative = (model.nondimensional_relative_helmholtz_free_energy_per_link(&(nondimensional_end_to_end_length_per_link + 0.5*h)) - model.nondimensional_relative_helmholtz_free_energy_per_link(&(nondimensional_end_to_end_length_per_link - 0.5*h)))/h; + let residual_abs = &nondimensional_force - &nondimensional_force_from_derivative; + let residual_rel = &residual_abs/&nondimensional_force; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + 0.5*parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_helmholtz_free_energy = model.relative_helmholtz_free_energy(&end_to_end_length, &temperature); + let relative_helmholtz_free_energy_from_connection = BOLTZMANN_CONSTANT*temperature*(model.equilibrium_distribution(&(ZERO*(number_of_links as f64)*link_length))/model.equilibrium_distribution(&end_to_end_length)).ln(); + let residual_abs = &relative_helmholtz_free_energy - &relative_helmholtz_free_energy_from_connection; + let residual_rel = &residual_abs/&relative_helmholtz_free_energy; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + 0.5*parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link); + let nondimensional_relative_helmholtz_free_energy_from_connection = (model.nondimensional_equilibrium_distribution(&ZERO)/model.nondimensional_equilibrium_distribution(&nondimensional_end_to_end_length_per_link)).ln(); + let residual_abs = &nondimensional_relative_helmholtz_free_energy - &nondimensional_relative_helmholtz_free_energy_from_connection; + let residual_rel = &residual_abs/&nondimensional_relative_helmholtz_free_energy; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod legendre +{ + #[test] + fn dummy() + { + assert!(0.0 == 1.0); + } +} +mod legendre_connection +{ + #[test] + fn dummy() + { + assert!(0.0 == 1.0); + } +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/test.rs b/src/physics/single_chain/wlc/thermodynamics/test.rs index e69de29b..45903223 100644 --- a/src/physics/single_chain/wlc/thermodynamics/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/test.rs @@ -0,0 +1,76 @@ +#![cfg(test)] +use super::*; +use crate::physics::single_chain::test::Parameters; +mod base +{ + use super::*; + use rand::Rng; + #[test] + fn init() + { + let parameters = Parameters::default(); + let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); + } + #[test] + fn number_of_links() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); + } + } + #[test] + fn link_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); + } + } + #[test] + fn hinge_mass() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); + } + } + #[test] + fn persistance_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); + } + } + #[test] + fn all_parameters() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + assert_eq!(number_of_links, model.number_of_links); + assert_eq!(link_length, model.link_length); + assert_eq!(hinge_mass, model.hinge_mass); + assert_eq!(persistance_length, model.persistance_length); + } + } +} \ No newline at end of file From 1c22d1f02dce50da469ba58913cdb93c462874a6 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 16:32:35 -0600 Subject: [PATCH 08/21] fixed bug, manual normalization (seems to even behave badly in python example for large nondim pers length, so maybe best to do this anyway) --- example.py | 128 ------------------ src/main.rs | 5 - src/physics/single_chain/test.rs | 8 +- .../wlc/thermodynamics/isometric/mod.rs | 60 ++++---- .../wlc/thermodynamics/isometric/test.rs | 2 +- 5 files changed, 42 insertions(+), 161 deletions(-) delete mode 100644 example.py delete mode 100644 src/main.rs diff --git a/example.py b/example.py deleted file mode 100644 index 43671e91..00000000 --- a/example.py +++ /dev/null @@ -1,128 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt -from scipy.special import iv -from scipy.integrate import quad_vec - - -a = 14.054 -b = 0.473 -c_ = np.array([ - [-3/4, 23/64, -7/64], - [-1/2, 17/16, -9/16] -]) - - -def I_0(x): - return iv(0, x) - - -def I_1(x): - return iv(1, x) - - -def Q_G(r, kappa): - return (3/4/np.pi/kappa)**(3/2)*np.exp(-3*r**2/4/kappa) - - -def Q_D(r, kappa): - return Q_G(r, kappa)*(1 - 5*kappa/4 + 2*r**2 - 33*r**4/80/kappa) - - -def J_SY(kappa): - return 112.04*kappa**2*np.exp(0.246/kappa - a*kappa) - - -def J_SYD(kappa): - if kappa > 1/8: - return J_SY(kappa) - else: - return Q_D(0, kappa) - -def Q_I(r, kappa): - c = 1 - (1 + (0.38*kappa**(-0.95))**(-5))**(-1/5) - if kappa < 1/8: - d = 1 - else: - d = 1 - 1/(0.177/(kappa - 0.111) + 6.40*(kappa - 0.111)**0.783) - sum = 0 - for i in (-1, 0): - for j in (1, 2, 3): - sum += c_[i + 1, j - 1]*kappa**i*r**(2*j) - h = (1 - c*r**2)/(1 - r**2) - t = r/(1 - b**2*r**2) - arg = -d*kappa*a*(1 + b)*t - return J_SYD(kappa) * \ - (h)**(5/2) * \ - np.exp(sum/(1 - r**2)) * \ - np.exp(arg*b*r) * \ - I_0(arg) - - -def d_Q_I_d_r(r, kappa): - c = 1 - (1 + (0.38*kappa**(-0.95))**(-5))**(-1/5) - if kappa < 1/8: - d = 1 - else: - d = 1 - 1/(0.177/(kappa - 0.111) + 6.40*(kappa - 0.111)**0.783) - sum = 0 - d_sum_dr = 0 - for i in (-1, 0): - for j in (1, 2, 3): - sum += c_[i + 1, j - 1]*kappa**i*r**(2*j) - d_sum_dr += 2*j*c_[i + 1, j - 1]*kappa**i*r**(2*j - 1) - h = (1 - c*r**2)/(1 - r**2) - t = r/(1 - b**2*r**2) - arg = -d*kappa*a*(1 + b)*t - return J_SYD(kappa) * \ - (h)**(5/2) * \ - np.exp(sum/(1 - r**2)) * \ - np.exp(arg*b*r) * ( - ( - 5/2/h*(2*r*h/(1 - r**2) - 2*r*c/(1 - r**2)) + - d_sum_dr/(1 - r**2) + 2*r*sum/(1 - r**2)**2 + - 2*b*arg *( - 1 + r*b**2*t - ) - ) * I_0(arg) - + arg*( - 1/r + 2*b**2*t - ) * I_1(arg) - ) - -print(-d_Q_I_d_r(0.9, 0.3)/Q_I(0.9, 0.3)) - -gamma = np.linspace(0, 1, 10000)[1:-1] -kappas = (1/7, 5/27, 5/19, 5/11, 5/3) -for kappa in kappas: - P_eq = Q_I(gamma, kappa) - plt.plot(gamma, P_eq, label=kappa) -plt.legend() -plt.show() -for kappa in kappas: - P_eq = Q_I(gamma, kappa) - g_eq = 4*np.pi*gamma**2*P_eq - plt.plot(gamma, g_eq, label=kappa) -plt.legend() -plt.show() -for kappa in kappas: - P_eq = Q_I(gamma, kappa) - beta_Delta_psi = -np.log(P_eq/P_eq[0]) - plt.semilogy(gamma, beta_Delta_psi, label=kappa) -plt.legend() -plt.show() -for kappa in kappas: - eta = -d_Q_I_d_r(gamma, kappa)/Q_I(gamma, kappa) - plt.semilogy(gamma, eta, label=kappa) - P_eq = Q_I(gamma, kappa) - beta_Delta_psi = -np.log(P_eq/P_eq[0]) - eta_numerical = np.gradient(beta_Delta_psi)/np.gradient(gamma) - plt.semilogy(gamma, eta_numerical, 'k:') - Z, _ = quad_vec( - lambda gamma: - Q_I(gamma, kappa)*np.sinh(eta*gamma)*gamma/eta, - 1e-6, 1 - 1e-6 - ) - gamma_isotensional = np.gradient(np.log(Z))/np.gradient(eta) - plt.semilogy(gamma_isotensional, eta, 'k--') -plt.legend() -plt.show() \ No newline at end of file diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index d0b2912d..00000000 --- a/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -use polymers::physics::single_chain::wlc::thermodynamics::isometric::nondimensional_force; -fn main() -{ - println!("{:?}", nondimensional_force(&0.3, &0.9)); -} \ No newline at end of file diff --git a/src/physics/single_chain/test.rs b/src/physics/single_chain/test.rs index ed620304..e07ced25 100644 --- a/src/physics/single_chain/test.rs +++ b/src/physics/single_chain/test.rs @@ -63,11 +63,11 @@ impl Default for Parameters log_log_scale: 12e-1, number_of_loops: 8, hinge_mass_reference: 1e0, - hinge_mass_scale: 1e0, + hinge_mass_scale: 1e-1, link_length_reference: 1e0, - link_length_scale: 1e0, - persistance_length_reference: 5e0, - persistance_length_scale: 1e1, + link_length_scale: 1e-2, + persistance_length_reference: 25e-1, + persistance_length_scale: 5e0, number_of_links_minimum: 5, number_of_links_maximum: 25, link_stiffness_reference: 5e5, diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index e54df16a..4896f630 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -10,13 +10,22 @@ mod test; pub mod legendre; use std::f64::consts::PI; -use crate::math::bessel_i; +use crate::math:: +{ + bessel_i, + integrate_1d +}; use crate::physics:: { PLANCK_CONSTANT, BOLTZMANN_CONSTANT }; -use crate::physics::single_chain::ZERO; +use crate::physics::single_chain:: +{ + ONE, + ZERO, + POINTS +}; /// The structure of the thermodynamics of the WLC model in the isometric ensemble. pub struct WLC @@ -35,6 +44,8 @@ pub struct WLC nondimensional_persistance_length: f64, + normalization_nondimensional_equilibrium_distribution: f64, + /// The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. pub legendre: self::legendre::WLC } @@ -43,11 +54,11 @@ pub struct WLC pub fn force(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 { let contour_length = (*number_of_links as f64)*link_length; - nondimensional_force(&(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature/link_length + nondimensional_force(number_of_links, &(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature/link_length } -/// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. -pub fn nondimensional_force(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +/// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. +pub fn nondimensional_force(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { let g2 = nondimensional_end_to_end_length_per_link.powi(2); let a: f64 = 14.054; @@ -70,7 +81,7 @@ pub fn nondimensional_force(nondimensional_persistance_length: &f64, nondimensio let arg = -d*nondimensional_persistance_length*a*(1.0 + b)*h; let sum = (0..2).collect::>().iter().map(|i| (1..4).collect::>().iter().map(|j| c[*i][j - 1]*(nondimensional_persistance_length.powi(*i as i32 - 1)*g2.powi((*j).try_into().unwrap()))).sum::()).sum::(); let d_sum_dg = (0..2).collect::>().iter().map(|i| (1..4).collect::>().iter().map(|j| (*j as f64)*c[*i][j - 1]*(nondimensional_persistance_length.powi(*i as i32 - 1)*g2.powi((*j).try_into().unwrap()))).sum::()).sum::()*2.0/nondimensional_end_to_end_length_per_link; - -((5.0*nondimensional_end_to_end_length_per_link*(1.0 - c0/f) + d_sum_dg + 2.0*nondimensional_end_to_end_length_per_link*sum/(1.0 - g2))/(1.0 - g2) + 2.0*b*arg *(1.0 + nondimensional_end_to_end_length_per_link*b.powi(2)*h) + arg*bessel_i(&1, &arg)/bessel_i(&0, &arg)*(1.0/nondimensional_end_to_end_length_per_link + 2.0*b.powi(2)*h)) + -((5.0*nondimensional_end_to_end_length_per_link*(1.0 - c0/f) + d_sum_dg + 2.0*nondimensional_end_to_end_length_per_link*sum/(1.0 - g2))/(1.0 - g2) + 2.0*b*arg *(1.0 + nondimensional_end_to_end_length_per_link*b.powi(2)*h) + arg*bessel_i(&1, &arg)/bessel_i(&0, &arg)*(1.0/nondimensional_end_to_end_length_per_link + 2.0*b.powi(2)*h))/(*number_of_links as f64) } /// The Helmholtz free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. @@ -102,7 +113,7 @@ pub fn relative_helmholtz_free_energy_per_link(number_of_links: &u8, link_length /// The nondimensional Helmholtz free energy as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { - -(equilibrium_distribution(number_of_links, link_length, persistance_length, &(nondimensional_end_to_end_length_per_link*(*number_of_links as f64)*link_length))).ln() - ((*number_of_links as f64) - 1.0)*(8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() + -(equilibrium_distribution(number_of_links, link_length, persistance_length, &1.0, &(nondimensional_end_to_end_length_per_link*(*number_of_links as f64)*link_length))).ln() - ((*number_of_links as f64) - 1.0)*(8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() } /// The nondimensional Helmholtz free energy per link as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and persistance length. @@ -114,7 +125,7 @@ pub fn nondimensional_helmholtz_free_energy_per_link(number_of_links: &u8, link_ /// The nondimensional relative Helmholtz free energy as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. pub fn nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - (nondimensional_equilibrium_distribution(nondimensional_persistance_length, &ZERO)/nondimensional_equilibrium_distribution(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)).ln() + (nondimensional_equilibrium_distribution(nondimensional_persistance_length, &1.0, &ZERO)/nondimensional_equilibrium_distribution(nondimensional_persistance_length, &1.0, nondimensional_end_to_end_length_per_link)).ln() } /// The nondimensional relative Helmholtz free energy per link as a function of the nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. @@ -124,14 +135,14 @@ pub fn nondimensional_relative_helmholtz_free_energy_per_link(number_of_links: & } /// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length, parameterized by the number of links, link length, and persistance length. -pub fn equilibrium_distribution(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +pub fn equilibrium_distribution(number_of_links: &u8, link_length: &f64, persistance_length: &f64, normalization_nondimensional_equilibrium_distribution: &f64, end_to_end_length: &f64) -> f64 { let contour_length = (*number_of_links as f64)*link_length; - nondimensional_equilibrium_distribution(&(persistance_length/contour_length), &(end_to_end_length/contour_length))/contour_length.powi(3) + nondimensional_equilibrium_distribution(&(persistance_length/contour_length), normalization_nondimensional_equilibrium_distribution, &(end_to_end_length/contour_length))/contour_length.powi(3) } /// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. -pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length: &f64, normalization_nondimensional_equilibrium_distribution: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { let g2 = nondimensional_end_to_end_length_per_link.powi(2); let a: f64 = 14.054; @@ -146,7 +157,7 @@ pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length if nondimensional_persistance_length < &0.125 { d = 1.0; - e = (0.75/PI/nondimensional_persistance_length).powf(1.5)*(-0.75*g2/nondimensional_persistance_length).exp()*(1.0 - 1.25*nondimensional_persistance_length + 2.0*g2 - 0.4125*g2.powi(2)/nondimensional_persistance_length); + e = (0.75/PI/nondimensional_persistance_length).powf(1.5)*(1.0 - 1.25*nondimensional_persistance_length); } else { @@ -157,20 +168,20 @@ pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length let h = nondimensional_end_to_end_length_per_link/(1.0 - b.powi(2)*g2); let arg = -d*nondimensional_persistance_length*a*(1.0 + b)*h; let sum = (0..2).collect::>().iter().map(|i| (1..4).collect::>().iter().map(|j| c[*i][j - 1]*(nondimensional_persistance_length.powi(*i as i32 - 1)*g2.powi((*j).try_into().unwrap()))).sum::()).sum::(); - e*f.powf(2.5)*(sum/(1.0 - g2) + arg*b*nondimensional_end_to_end_length_per_link).exp()*bessel_i(&0, &arg) + e*f.powf(2.5)*(sum/(1.0 - g2) + arg*b*nondimensional_end_to_end_length_per_link).exp()*bessel_i(&0, &arg)/normalization_nondimensional_equilibrium_distribution } /// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length, parameterized by the number of links, link length, and persistance length. -pub fn equilibrium_radial_distribution(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64) -> f64 +pub fn equilibrium_radial_distribution(number_of_links: &u8, link_length: &f64, persistance_length: &f64, normalization_nondimensional_equilibrium_distribution: &f64, end_to_end_length: &f64) -> f64 { let contour_length = (*number_of_links as f64)*link_length; - nondimensional_equilibrium_radial_distribution(&(persistance_length/contour_length), &(end_to_end_length/contour_length))/contour_length + nondimensional_equilibrium_radial_distribution(&(persistance_length/contour_length), normalization_nondimensional_equilibrium_distribution, &(end_to_end_length/contour_length))/contour_length } /// The nondimensional equilibrium probability density of nondimensional end-to-end lengths per link as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. -pub fn nondimensional_equilibrium_radial_distribution(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +pub fn nondimensional_equilibrium_radial_distribution(nondimensional_persistance_length: &f64, normalization_nondimensional_equilibrium_distribution: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - 4.0*PI*nondimensional_end_to_end_length_per_link.powi(2)*nondimensional_equilibrium_distribution(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + 4.0*PI*nondimensional_end_to_end_length_per_link.powi(2)*nondimensional_equilibrium_distribution(nondimensional_persistance_length, normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link) } /// The implemented functionality of the thermodynamics of the WLC model in the isometric ensemble. @@ -179,13 +190,16 @@ impl WLC /// Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble. pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self { + let nondimensional_persistance_length = persistance_length/(number_of_links as f64)/link_length; + let normalization = integrate_1d(&|nondimensional_end_to_end_length_per_link: &f64| nondimensional_equilibrium_radial_distribution(&nondimensional_persistance_length, &1.0, nondimensional_end_to_end_length_per_link), &ZERO, &ONE, &POINTS); WLC { hinge_mass, link_length, number_of_links, persistance_length, - nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length, + nondimensional_persistance_length: nondimensional_persistance_length, + normalization_nondimensional_equilibrium_distribution: normalization, legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } } @@ -197,7 +211,7 @@ impl WLC /// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link. pub fn nondimensional_force(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - nondimensional_force(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + nondimensional_force(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) } /// The Helmholtz free energy as a function of the applied end-to-end length and temperature. pub fn helmholtz_free_energy(&self, end_to_end_length: &f64, temperature: &f64) -> f64 @@ -242,21 +256,21 @@ impl WLC /// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length. pub fn equilibrium_distribution(&self, end_to_end_length: &f64) -> f64 { - equilibrium_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length) + equilibrium_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, &self.normalization_nondimensional_equilibrium_distribution, end_to_end_length) } /// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link. pub fn nondimensional_equilibrium_distribution(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - nondimensional_equilibrium_distribution(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + nondimensional_equilibrium_distribution(&self.nondimensional_persistance_length, &self.normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link) } /// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length. pub fn equilibrium_radial_distribution(&self, end_to_end_length: &f64) -> f64 { - equilibrium_radial_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length) + equilibrium_radial_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, &self.normalization_nondimensional_equilibrium_distribution, end_to_end_length) } /// The nondimensional equilibrium probability density of nondimensional end-to-end lengths per link as a function of the nondimensional end-to-end length per link. pub fn nondimensional_equilibrium_radial_distribution(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - nondimensional_equilibrium_radial_distribution(&self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + nondimensional_equilibrium_radial_distribution(&self.nondimensional_persistance_length, &self.normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link) } } diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs index 5ce91634..03e3b742 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs @@ -107,7 +107,7 @@ mod normalization { let parameters = Parameters::default(); let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops + for _ in 0..88//parameters.number_of_loops { let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); From 3c5717568c7538c332dc03537212c0acf8dba80d Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 17:20:33 -0600 Subject: [PATCH 09/21] passing, but finnicky --- src/physics/single_chain/test.rs | 2 +- .../thermodynamics/isometric/legendre/mod.rs | 107 +++++- .../thermodynamics/isometric/legendre/test.rs | 359 ++++++++++++++++++ .../wlc/thermodynamics/isometric/mod.rs | 25 +- .../wlc/thermodynamics/isometric/test.rs | 283 +++++++++++++- 5 files changed, 759 insertions(+), 17 deletions(-) diff --git a/src/physics/single_chain/test.rs b/src/physics/single_chain/test.rs index e07ced25..dd02f2bd 100644 --- a/src/physics/single_chain/test.rs +++ b/src/physics/single_chain/test.rs @@ -67,7 +67,7 @@ impl Default for Parameters link_length_reference: 1e0, link_length_scale: 1e-2, persistance_length_reference: 25e-1, - persistance_length_scale: 5e0, + persistance_length_scale: 49e-1, number_of_links_minimum: 5, number_of_links_maximum: 25, link_stiffness_reference: 5e5, diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs index 6c1702f1..b5763bff 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.rs @@ -6,6 +6,14 @@ pub mod py; mod test; +use super:: +{ + nondimensional_force, + nondimensional_helmholtz_free_energy +}; +use crate::physics::BOLTZMANN_CONSTANT; +use crate::physics::single_chain::ZERO; + /// The structure of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. pub struct WLC { @@ -19,7 +27,61 @@ pub struct WLC pub number_of_links: u8, /// The persistance length of the chain in units of nm. - pub persistance_length: f64 + pub persistance_length: f64, + + nondimensional_persistance_length: f64 +} + +/// The Gibbs free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, &(persistance_length/contour_length), &(end_to_end_length/contour_length), temperature)*BOLTZMANN_CONSTANT*temperature +} + +/// The Gibbs free energy per link as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_gibbs_free_energy_per_link(number_of_links, link_length, hinge_mass, &(persistance_length/contour_length), &(end_to_end_length/contour_length), temperature)*BOLTZMANN_CONSTANT*temperature +} + +/// The relative Gibbs free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, and persistance length. +pub fn relative_gibbs_free_energy(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_relative_gibbs_free_energy(number_of_links, &(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature +} + +/// The relative Gibbs free energy per link as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, and persistance length. +pub fn relative_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 +{ + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_relative_gibbs_free_energy_per_link(number_of_links, &(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature +} + +/// The nondimensional Gibbs free energy as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. +pub fn nondimensional_gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 +{ + nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature) - nondimensional_force(number_of_links, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)*nondimensional_end_to_end_length_per_link*(*number_of_links as f64) +} + +/// The nondimensional Gibbs free energy per link as a function of the applied nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and nondimensional persistance length. +pub fn nondimensional_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 +{ + nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)/(*number_of_links as f64) +} + +/// The nondimensional relative Gibbs free energy as a function of the nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. +pub fn nondimensional_relative_gibbs_free_energy(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +{ + nondimensional_gibbs_free_energy(number_of_links, &1.0, &1.0, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, &300.0) - nondimensional_gibbs_free_energy(number_of_links, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) +} + +/// The nondimensional relative Gibbs free energy as a function of the nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. +pub fn nondimensional_relative_gibbs_free_energy_per_link(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 +{ + nondimensional_gibbs_free_energy_per_link(number_of_links, &1.0, &1.0, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, &300.0) - nondimensional_gibbs_free_energy_per_link(number_of_links, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) } /// The implemented functionality of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. @@ -33,7 +95,48 @@ impl WLC hinge_mass, link_length, number_of_links, - persistance_length + persistance_length, + nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length } } + /// The Gibbs free energy as a function of the applied end-to-end length and temperature. + pub fn gibbs_free_energy(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, end_to_end_length, temperature) + } + /// The Gibbs free energy per link as a function of the applied end-to-end length and temperature. + pub fn gibbs_free_energy_per_link(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, end_to_end_length, temperature) + } + /// The relative Gibbs free energy as a function of the applied end-to-end length and temperature. + pub fn relative_gibbs_free_energy(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + relative_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length, temperature) + } + /// The relative Gibbs free energy per link as a function of the applied end-to-end length and temperature. + pub fn relative_gibbs_free_energy_per_link(&self, end_to_end_length: &f64, temperature: &f64) -> f64 + { + relative_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, end_to_end_length, temperature) + } + /// The nondimensional Gibbs free energy as a function of the applied nondimensional end-to-end length per link and temperature. + pub fn nondimensional_gibbs_free_energy(&self, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 + { + nondimensional_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature) + } + /// The nondimensional Gibbs free energy per link as a function of the applied nondimensional end-to-end length per link and temperature. + pub fn nondimensional_gibbs_free_energy_per_link(&self, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 + { + nondimensional_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature) + } + /// The nondimensional relative Gibbs free energy as a function of the applied nondimensional end-to-end length per link. + pub fn nondimensional_relative_gibbs_free_energy(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_relative_gibbs_free_energy(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } + /// The nondimensional relative Gibbs free energy per link as a function of the applied nondimensional end-to-end length per link. + pub fn nondimensional_relative_gibbs_free_energy_per_link(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 + { + nondimensional_relative_gibbs_free_energy_per_link(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) + } } diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs index 45903223..eabe9f0b 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.rs @@ -73,4 +73,363 @@ mod base assert_eq!(persistance_length, model.persistance_length); } } +} +mod nondimensional +{ + use super::*; + use rand::Rng; + #[test] + fn gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let gibbs_free_energy = model.gibbs_free_energy(&end_to_end_length, &temperature); + let residual_abs = &gibbs_free_energy/BOLTZMANN_CONSTANT/temperature - &nondimensional_gibbs_free_energy; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = &gibbs_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - &nondimensional_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_end_to_end_length_per_link); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&end_to_end_length, &temperature); + let residual_abs = &relative_gibbs_free_energy/BOLTZMANN_CONSTANT/temperature - &nondimensional_relative_gibbs_free_energy; + let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = &relative_gibbs_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - &nondimensional_relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod per_link +{ + use super::*; + use rand::Rng; + #[test] + fn gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let gibbs_free_energy = model.gibbs_free_energy(&end_to_end_length, &temperature); + let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = &gibbs_free_energy/(number_of_links as f64) - &gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&end_to_end_length, &temperature); + let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = &relative_gibbs_free_energy/(number_of_links as f64) - &relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&relative_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let residual_abs = &nondimensional_gibbs_free_energy/(number_of_links as f64) - &nondimensional_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_relative_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_end_to_end_length_per_link); + let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let residual_abs = &nondimensional_relative_gibbs_free_energy/(number_of_links as f64) - &nondimensional_relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod relative +{ + use super::*; + use rand::Rng; + use crate::physics::single_chain::ZERO; + #[test] + fn gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let gibbs_free_energy = model.gibbs_free_energy(&end_to_end_length, &temperature); + let gibbs_free_energy_0 = model.gibbs_free_energy(&(ZERO*(number_of_links as f64)*link_length), &temperature); + let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&end_to_end_length, &temperature); + let residual_abs = &gibbs_free_energy - &gibbs_free_energy_0 - &relative_gibbs_free_energy; + let residual_rel = &residual_abs/&gibbs_free_energy_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn gibbs_free_energy_per_link() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&end_to_end_length, &temperature); + let gibbs_free_energy_per_link_0 = model.gibbs_free_energy_per_link(&(ZERO*(number_of_links as f64)*link_length), &temperature); + let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&end_to_end_length, &temperature); + let residual_abs = &gibbs_free_energy_per_link - &gibbs_free_energy_per_link_0 - &relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&gibbs_free_energy_per_link_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_gibbs_free_energy_0 = model.nondimensional_gibbs_free_energy(&ZERO, &temperature); + let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_end_to_end_length_per_link); + let residual_abs = &nondimensional_gibbs_free_energy - &nondimensional_gibbs_free_energy_0 - &nondimensional_relative_gibbs_free_energy; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_gibbs_free_energy_per_link() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_gibbs_free_energy_per_link_0 = model.nondimensional_gibbs_free_energy_per_link(&ZERO, &temperature); + let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let residual_abs = &nondimensional_gibbs_free_energy_per_link - &nondimensional_gibbs_free_energy_per_link_0 - &nondimensional_relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link_0; + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod zero +{ + use super::*; + use rand::Rng; + use crate::physics::single_chain::ZERO; + #[test] + fn relative_gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_gibbs_free_energy_0 = model.relative_gibbs_free_energy(&(ZERO*(number_of_links as f64)*link_length), &temperature); + assert!(relative_gibbs_free_energy_0.abs() <= BOLTZMANN_CONSTANT*temperature*(number_of_links as f64)*ZERO); + } + } + #[test] + fn relative_gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_gibbs_free_energy_per_link_0 = model.relative_gibbs_free_energy_per_link(&(ZERO*(number_of_links as f64)*link_length), &temperature); + assert!(relative_gibbs_free_energy_per_link_0.abs() <= BOLTZMANN_CONSTANT*temperature*ZERO); + } + } + #[test] + fn nondimensional_relative_gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_relative_gibbs_free_energy_0 = model.nondimensional_relative_gibbs_free_energy(&ZERO); + assert!(nondimensional_relative_gibbs_free_energy_0.abs() <= (number_of_links as f64)*ZERO); + } + } + #[test] + fn nondimensional_relative_gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_relative_gibbs_free_energy_per_link_0 = model.nondimensional_relative_gibbs_free_energy_per_link(&ZERO); + assert!(nondimensional_relative_gibbs_free_energy_per_link_0.abs() <= ZERO); + } + } } \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index 4896f630..161acb58 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -87,13 +87,15 @@ pub fn nondimensional_force(number_of_links: &u8, nondimensional_persistance_len /// The Helmholtz free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. pub fn helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 { - nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, persistance_length, &(end_to_end_length/((*number_of_links as f64)*link_length)), temperature)*BOLTZMANN_CONSTANT*temperature + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, &(persistance_length/contour_length), &(end_to_end_length/contour_length), temperature)*BOLTZMANN_CONSTANT*temperature } /// The Helmholtz free energy per link as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. pub fn helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, end_to_end_length: &f64, temperature: &f64) -> f64 { - nondimensional_helmholtz_free_energy_per_link(number_of_links, link_length, hinge_mass, persistance_length, &(end_to_end_length/((*number_of_links as f64)*link_length)), temperature)*BOLTZMANN_CONSTANT*temperature + let contour_length = (*number_of_links as f64)*link_length; + nondimensional_helmholtz_free_energy_per_link(number_of_links, link_length, hinge_mass, &(persistance_length/contour_length), &(end_to_end_length/contour_length), temperature)*BOLTZMANN_CONSTANT*temperature } /// The relative Helmholtz free energy as a function of the applied end-to-end length and temperature, parameterized by the number of links, link length, and persistance length. @@ -110,16 +112,19 @@ pub fn relative_helmholtz_free_energy_per_link(number_of_links: &u8, link_length nondimensional_relative_helmholtz_free_energy_per_link(number_of_links, &(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature } -/// The nondimensional Helmholtz free energy as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. -pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 +/// The nondimensional Helmholtz free energy as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. +pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { - -(equilibrium_distribution(number_of_links, link_length, persistance_length, &1.0, &(nondimensional_end_to_end_length_per_link*(*number_of_links as f64)*link_length))).ln() - ((*number_of_links as f64) - 1.0)*(8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() + // + // is not entirely correct (not first part, nor second (normalization different for wlc)) and will fix later + // + nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) - ((*number_of_links as f64) - 1.0)*(8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() } -/// The nondimensional Helmholtz free energy per link as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and persistance length. -pub fn nondimensional_helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 +/// The nondimensional Helmholtz free energy per link as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. +pub fn nondimensional_helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { - nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, persistance_length, nondimensional_end_to_end_length_per_link, temperature)/(*number_of_links as f64) + nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)/(*number_of_links as f64) } /// The nondimensional relative Helmholtz free energy as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. @@ -236,12 +241,12 @@ impl WLC /// The nondimensional Helmholtz free energy as a function of the applied nondimensional end-to-end length per link and temperature. pub fn nondimensional_helmholtz_free_energy(&self, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { - nondimensional_helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, nondimensional_end_to_end_length_per_link, temperature) + nondimensional_helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature) } /// The nondimensional Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link and temperature. pub fn nondimensional_helmholtz_free_energy_per_link(&self, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { - nondimensional_helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, nondimensional_end_to_end_length_per_link, temperature) + nondimensional_helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature) } /// The nondimensional relative Helmholtz free energy as a function of the applied nondimensional end-to-end length per link. pub fn nondimensional_relative_helmholtz_free_energy(&self, nondimensional_end_to_end_length_per_link: &f64) -> f64 diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs index 03e3b742..0a47a643 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/test.rs @@ -662,17 +662,292 @@ mod connection } mod legendre { + use super::*; + use rand::Rng; + use crate::physics::single_chain::ZERO; + #[test] + fn helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let force = model.force(&end_to_end_length, &temperature); + let helmholtz_free_energy = model.helmholtz_free_energy(&end_to_end_length, &temperature); + let helmholtz_free_energy_legendre = model.legendre.gibbs_free_energy(&end_to_end_length, &temperature) + force*end_to_end_length; + let residual_abs = &helmholtz_free_energy - &helmholtz_free_energy_legendre; + let residual_rel = &residual_abs/&helmholtz_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let end_to_end_length_per_link = nondimensional_end_to_end_length_per_link*link_length; + let force = model.force(&end_to_end_length, &temperature); + let helmholtz_free_energy_per_link = model.helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let helmholtz_free_energy_per_link_legendre = model.legendre.gibbs_free_energy_per_link(&end_to_end_length, &temperature) + force*end_to_end_length_per_link; + let residual_abs = &helmholtz_free_energy_per_link - &helmholtz_free_energy_per_link_legendre; + let residual_rel = &residual_abs/&helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let force = model.force(&end_to_end_length, &temperature); + let force_0 = model.force(&(ZERO*(number_of_links as f64)*link_length), &temperature); + let relative_helmholtz_free_energy = model.relative_helmholtz_free_energy(&end_to_end_length, &temperature); + let relative_helmholtz_free_energy_legendre = model.legendre.relative_gibbs_free_energy(&end_to_end_length, &temperature) + force*end_to_end_length - force_0*ZERO*(number_of_links as f64)*link_length; + let residual_abs = &relative_helmholtz_free_energy - &relative_helmholtz_free_energy_legendre; + let residual_rel = &residual_abs/&relative_helmholtz_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let end_to_end_length_per_link = nondimensional_end_to_end_length_per_link*link_length; + let force = model.force(&end_to_end_length, &temperature); + let force_0 = model.force(&(ZERO*(number_of_links as f64)*link_length), &temperature); + let relative_helmholtz_free_energy_per_link = model.relative_helmholtz_free_energy_per_link(&end_to_end_length, &temperature); + let relative_helmholtz_free_energy_per_link_legendre = model.legendre.relative_gibbs_free_energy_per_link(&end_to_end_length, &temperature) + force*end_to_end_length_per_link - force_0*ZERO*link_length; + let residual_abs = &relative_helmholtz_free_energy_per_link - &relative_helmholtz_free_energy_per_link_legendre; + let residual_rel = &residual_abs/&relative_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } #[test] - fn dummy() + fn nondimensional_helmholtz_free_energy() { - assert!(0.0 == 1.0); + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64); + let nondimensional_force = model.nondimensional_force(&nondimensional_end_to_end_length_per_link); + let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_helmholtz_free_energy_legendre = model.legendre.nondimensional_gibbs_free_energy(&nondimensional_end_to_end_length_per_link, &temperature) + nondimensional_force*nondimensional_end_to_end_length; + let residual_abs = &nondimensional_helmholtz_free_energy - &nondimensional_helmholtz_free_energy_legendre; + let residual_rel = &residual_abs/&nondimensional_helmholtz_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_force = model.nondimensional_force(&nondimensional_end_to_end_length_per_link); + let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature); + let nondimensional_helmholtz_free_energy_per_link_legendre = model.legendre.nondimensional_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link, &temperature) + nondimensional_force*nondimensional_end_to_end_length_per_link; + let residual_abs = &nondimensional_helmholtz_free_energy_per_link - &nondimensional_helmholtz_free_energy_per_link_legendre; + let residual_rel = &residual_abs/&nondimensional_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_relative_helmholtz_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64); + let nondimensional_force = model.nondimensional_force(&nondimensional_end_to_end_length_per_link); + let nondimensional_force_0 = model.nondimensional_force(&ZERO); + let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_end_to_end_length_per_link); + let nondimensional_relative_helmholtz_free_energy_legendre = model.legendre.nondimensional_relative_gibbs_free_energy(&nondimensional_end_to_end_length_per_link) + nondimensional_force*nondimensional_end_to_end_length - nondimensional_force_0*(number_of_links as f64)*ZERO; + let residual_abs = &nondimensional_relative_helmholtz_free_energy - &nondimensional_relative_helmholtz_free_energy_legendre; + let residual_rel = &residual_abs/&nondimensional_relative_helmholtz_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_relative_helmholtz_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_force = model.nondimensional_force(&nondimensional_end_to_end_length_per_link); + let nondimensional_force_0 = model.nondimensional_force(&ZERO); + let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_end_to_end_length_per_link); + let nondimensional_relative_helmholtz_free_energy_per_link_legendre = model.legendre.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_end_to_end_length_per_link) + nondimensional_force*nondimensional_end_to_end_length_per_link - nondimensional_force_0*ZERO; + let residual_abs = &nondimensional_relative_helmholtz_free_energy_per_link - &nondimensional_relative_helmholtz_free_energy_per_link_legendre; + let residual_rel = &residual_abs/&nondimensional_relative_helmholtz_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } } } mod legendre_connection { + use super::*; + use rand::Rng; #[test] - fn dummy() + fn end_to_end_length() { - assert!(0.0 == 1.0); + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let h = parameters.rel_tol*(number_of_links as f64)*link_length; + let end_to_end_length_from_derivative = -(model.legendre.relative_gibbs_free_energy(&(end_to_end_length + 0.5*h), &temperature) - model.legendre.relative_gibbs_free_energy(&(end_to_end_length - 0.5*h), &temperature))/(model.force(&(end_to_end_length + 0.5*h), &temperature) - model.force(&(end_to_end_length - 0.5*h), &temperature)); + let residual_abs = &end_to_end_length - &end_to_end_length_from_derivative; + let residual_rel = &residual_abs/&end_to_end_length; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64)*link_length; + let end_to_end_length_per_link = nondimensional_end_to_end_length_per_link*link_length; + let h = parameters.rel_tol*(number_of_links as f64)*link_length; + let end_to_end_length_per_link_from_derivative = -(model.legendre.relative_gibbs_free_energy_per_link(&(end_to_end_length + 0.5*h), &temperature) - model.legendre.relative_gibbs_free_energy_per_link(&(end_to_end_length - 0.5*h), &temperature))/(model.force(&(end_to_end_length + 0.5*h), &temperature) - model.force(&(end_to_end_length - 0.5*h), &temperature)); + let residual_abs = &end_to_end_length_per_link - &end_to_end_length_per_link_from_derivative; + let residual_rel = &residual_abs/&end_to_end_length_per_link; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn nondimensional_end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length = nondimensional_end_to_end_length_per_link*(number_of_links as f64); + let h = parameters.rel_tol; + let nondimensional_end_to_end_length_from_derivative = -(model.legendre.nondimensional_relative_gibbs_free_energy(&(nondimensional_end_to_end_length_per_link + 0.5*h)) - model.legendre.nondimensional_relative_gibbs_free_energy(&(nondimensional_end_to_end_length_per_link - 0.5*h)))/(model.nondimensional_force(&(nondimensional_end_to_end_length_per_link + 0.5*h)) - model.nondimensional_force(&(nondimensional_end_to_end_length_per_link - 0.5*h))); + let residual_abs = &nondimensional_end_to_end_length - &nondimensional_end_to_end_length_from_derivative; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn nondimensional_end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link = parameters.nondimensional_end_to_end_length_per_link_reference + parameters.nondimensional_end_to_end_length_per_link_scale*(0.5 - rng.gen::()); + let h = parameters.rel_tol; + let nondimensional_end_to_end_length_per_link_from_derivative = -(model.legendre.nondimensional_relative_gibbs_free_energy_per_link(&(nondimensional_end_to_end_length_per_link + 0.5*h)) - model.legendre.nondimensional_relative_gibbs_free_energy_per_link(&(nondimensional_end_to_end_length_per_link - 0.5*h)))/(model.nondimensional_force(&(nondimensional_end_to_end_length_per_link + 0.5*h)) - model.nondimensional_force(&(nondimensional_end_to_end_length_per_link - 0.5*h))); + let residual_abs = &nondimensional_end_to_end_length_per_link - &nondimensional_end_to_end_length_per_link_from_derivative; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; + assert!(residual_rel.abs() <= h); + } } } \ No newline at end of file From 2c945eb500a871443e360c188c58babe3dc90ea3 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 17:23:02 -0600 Subject: [PATCH 10/21] passing, but finnicky --- src/physics/single_chain/mod.jl | 8 ++++++-- src/physics/single_chain/test.py | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/physics/single_chain/mod.jl b/src/physics/single_chain/mod.jl index 1a94e7e9..254647b2 100644 --- a/src/physics/single_chain/mod.jl +++ b/src/physics/single_chain/mod.jl @@ -28,6 +28,8 @@ struct Parameters hinge_mass_scale::Float64 link_length_reference::Float64 link_length_scale::Float64 + persistance_length_reference::Float64 + persistance_length_scale::Float64 number_of_links_minimum::UInt8 number_of_links_maximum::UInt8 link_stiffness_reference::Float64 @@ -67,9 +69,11 @@ parameters = Parameters( 12e-1, 8, 1e0, + 1e-1, 1e0, - 1e0, - 1e0, + 1e-2, + 25e-1, + 49e-1, 0x08, 0x19, 5e5, diff --git a/src/physics/single_chain/test.py b/src/physics/single_chain/test.py index 75484cd3..415c522b 100644 --- a/src/physics/single_chain/test.py +++ b/src/physics/single_chain/test.py @@ -28,9 +28,11 @@ def __init__(self): self.log_log_scale = 12e-1 self.number_of_loops = 8 self.hinge_mass_reference = 1e0 - self.hinge_mass_scale = 1e0 + self.hinge_mass_scale = 1e-1 self.link_length_reference = 1e0 - self.link_length_scale = 1e0 + self.link_length_scale = 1e-2 + self.persistance_length_reference = 25e-1 + self.persistance_length_scale = 49e-1 self.number_of_links_minimum = 5 self.number_of_links_maximum = 25 self.link_stiffness_reference = 5e5 From b580a1c7d6cf90a82af305575ca660146721c502 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 17:24:34 -0600 Subject: [PATCH 11/21] do isotensional next, and maybe extra legendre from isometric, and maybe visa-versa back to isometric --- src/physics/single_chain/wlc/thermodynamics/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/physics/single_chain/wlc/thermodynamics/mod.rs b/src/physics/single_chain/wlc/thermodynamics/mod.rs index 7163317f..ecf72d43 100644 --- a/src/physics/single_chain/wlc/thermodynamics/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/mod.rs @@ -6,6 +6,9 @@ mod test; /// The worm-like chain (WLC) model thermodynamics in the isometric ensemble. pub mod isometric; +/// The worm-like chain (WLC) model thermodynamics in the isotensional ensemble. +pub mod isotensional; + /// The structure of the thermodynamics of the WLC model. pub struct WLC { @@ -22,7 +25,10 @@ pub struct WLC pub persistance_length: f64, /// The thermodynamic functions of the model in the isometric ensemble. - pub isometric: self::isometric::WLC + pub isometric: self::isometric::WLC, + + /// The thermodynamic functions of the model in the isotensional ensemble. + pub isotensional: self::isotensional::WLC } /// The implemented functionality of the thermodynamics of the WLC model. @@ -38,6 +44,7 @@ impl WLC number_of_links, persistance_length, isometric: self::isometric::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), + isotensional: self::isotensional::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) } } } From fcdf31f60c827b5bf59ebf499d7b99496c515630 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 18:30:19 -0600 Subject: [PATCH 12/21] do isotensional next, and maybe extra legendre from isometric, and maybe visa-versa back to isometric --- src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index 161acb58..dc2c079b 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -116,9 +116,10 @@ pub fn relative_helmholtz_free_energy_per_link(number_of_links: &u8, link_length pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { // - // is not entirely correct (not first part, nor second (normalization different for wlc)) and will fix later + // not exactly correct unless P_eq is already normalized (see the &1.0) // - nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link) - ((*number_of_links as f64) - 1.0)*(8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() + let contour_length = (*number_of_links as f64)*link_length; + -(equilibrium_distribution(number_of_links, link_length, &(contour_length*nondimensional_persistance_length), &1.0, &(contour_length*nondimensional_end_to_end_length_per_link))).ln() - ((*number_of_links as f64) - 1.0)*(4.0*(-1.0/nondimensional_persistance_length).exp().acos().sin()*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() } /// The nondimensional Helmholtz free energy per link as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. From fdcbf5bed47e553026661c58d5a99ce0b253382b Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 19:00:10 -0600 Subject: [PATCH 13/21] fixed abs free energy (mostly), started isotensional --- .../thermodynamics/isotensional/__init__.py | 0 .../wlc/thermodynamics/isotensional/ex.rs | 0 .../isotensional/legendre/__init__.py | 0 .../isotensional/legendre/ex.rs | 0 .../isotensional/legendre/mod.jl | 0 .../isotensional/legendre/mod.rs | 45 ++++++ .../isotensional/legendre/py.rs | 0 .../isotensional/legendre/test.jl | 0 .../isotensional/legendre/test.rs | 76 +++++++++ .../wlc/thermodynamics/isotensional/mod.jl | 0 .../wlc/thermodynamics/isotensional/mod.rs | 153 ++++++++++++++++++ .../wlc/thermodynamics/isotensional/py.rs | 0 .../wlc/thermodynamics/isotensional/test.jl | 0 .../wlc/thermodynamics/isotensional/test.rs | 76 +++++++++ 14 files changed, 350 insertions(+) create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/__init__.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/ex.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/__init__.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/ex.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/py.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/mod.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/py.rs create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/test.jl create mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/__init__.py b/src/physics/single_chain/wlc/thermodynamics/isotensional/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/ex.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/__init__.py b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/ex.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs new file mode 100644 index 00000000..2eecabf4 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs @@ -0,0 +1,45 @@ +#[cfg(feature = "extern")] +pub mod ex; + +#[cfg(feature = "python")] +pub mod py; + +mod test; + +use crate::physics::BOLTZMANN_CONSTANT; +use crate::physics::single_chain::ZERO; + +/// The structure of the thermodynamics of the WLC model in the isotensional ensemble approximated using a Legendre transformation. +pub struct WLC +{ + /// The mass of each hinge in the chain in units of kg/mol. + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + pub link_length: f64, + + /// The number of links in the chain. + pub number_of_links: u8, + + /// The persistance length of the chain in units of nm. + pub persistance_length: f64, + + nondimensional_persistance_length: f64 +} + +/// The implemented functionality of the thermodynamics of the WLC model in the isotensional ensemble approximated using a Legendre transformation. +impl WLC +{ + /// Initializes and returns an instance of the thermodynamics of the WLC model in the isotensional ensemble approximated using a Legendre transformation. + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self + { + WLC + { + hinge_mass, + link_length, + number_of_links, + persistance_length, + nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length + } + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/py.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/py.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs new file mode 100644 index 00000000..45903223 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs @@ -0,0 +1,76 @@ +#![cfg(test)] +use super::*; +use crate::physics::single_chain::test::Parameters; +mod base +{ + use super::*; + use rand::Rng; + #[test] + fn init() + { + let parameters = Parameters::default(); + let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); + } + #[test] + fn number_of_links() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); + } + } + #[test] + fn link_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); + } + } + #[test] + fn hinge_mass() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); + } + } + #[test] + fn persistance_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); + } + } + #[test] + fn all_parameters() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + assert_eq!(number_of_links, model.number_of_links); + assert_eq!(link_length, model.link_length); + assert_eq!(hinge_mass, model.hinge_mass); + assert_eq!(persistance_length, model.persistance_length); + } + } +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs new file mode 100644 index 00000000..ec059c7a --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs @@ -0,0 +1,153 @@ +#[cfg(feature = "extern")] +pub mod ex; + +#[cfg(feature = "python")] +pub mod py; + +mod test; + +/// The worm-like chain (WLC) model thermodynamics in the isotensional ensemble approximated using a Legendre transformation. +pub mod legendre; + +use super::isometric::nondimensional_helmholtz_free_energy; + +use std::f64::consts::PI; +use crate::math::integrate_1d; +use crate::physics:: +{ + PLANCK_CONSTANT, + BOLTZMANN_CONSTANT +}; +use crate::physics::single_chain:: +{ + ONE, + ZERO, + POINTS +}; + +/// The structure of the thermodynamics of the WLC model in the isotensional ensemble. +pub struct WLC +{ + /// The mass of each hinge in the chain in units of kg/mol. + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + pub link_length: f64, + + /// The number of links in the chain. + pub number_of_links: u8, + + /// The persistance length of the chain in units of nm. + pub persistance_length: f64, + + nondimensional_persistance_length: f64, + + /// The thermodynamic functions of the model in the isotensional ensemble approximated using a Legendre transformation. + pub legendre: self::legendre::WLC +} + +/// The Gibbs free energy as a function of the applied force and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 +{ + nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature), temperature)*BOLTZMANN_CONSTANT*temperature +} + +/// The Gibbs free energy per link as a function of the applied force and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. +pub fn gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 +{ + nondimensional_gibbs_free_energy_per_link(number_of_links, link_length, hinge_mass, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature), temperature)*BOLTZMANN_CONSTANT*temperature +} + +/// The relative Gibbs free energy as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. +pub fn relative_gibbs_free_energy(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 +{ + nondimensional_relative_gibbs_free_energy(&(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature))*BOLTZMANN_CONSTANT*temperature +} + +/// The relative Gibbs free energy per link as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. +pub fn relative_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 +{ + nondimensional_relative_gibbs_free_energy_per_link(&(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature))*BOLTZMANN_CONSTANT*temperature +} +/// The nondimensional Gibbs free energy as a function of the nondimensional force and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. +pub fn nondimensional_gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_force: &f64, temperature: &f64) -> f64 +{ + let integrand = |nondimensional_end_to_end_length_per_link: &f64| (-nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)).exp()*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*nondimensional_end_to_end_length_per_link/nondimensional_force/(*number_of_links as f64); + 4.0*PI*integrate_1d(&integrand, &ZERO, &ONE, &POINTS).ln() - (4.0*(-1.0/nondimensional_persistance_length).exp().acos().sin()*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() +} + +/// The nondimensional Gibbs free energy per link as a function of the nondimensional force and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. +pub fn nondimensional_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_force: &f64, temperature: &f64) -> f64 +{ + nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_force, temperature)/(*number_of_links as f64) +} + +/// The nondimensional relative Gibbs free energy as a function of the nondimensional force, parameterized by the nondimensional persistance length. +pub fn nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 +{ + nondimensional_gibbs_free_energy(&8, &1.0, &1.0, nondimensional_persistance_length, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy(&8, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) +} + +/// The nondimensional relative Gibbs free energy per link as a function of the nondimensional force, parameterized by the nondimensional persistance length. +pub fn nondimensional_relative_gibbs_free_energy_per_link(nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 +{ + nondimensional_gibbs_free_energy_per_link(&8, &1.0, &1.0, nondimensional_persistance_length, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy_per_link(&8, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) +} + +/// The implemented functionality of the thermodynamics of the WLC model in the isotensional ensemble. +impl WLC +{ + /// Initializes and returns an instance of the thermodynamics of the WLC model in the isotensional ensemble. + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self + { + WLC + { + hinge_mass, + link_length, + number_of_links, + persistance_length, + nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length, + legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), + } + } + /// The Gibbs free energy as a function of the applied force and temperature. + pub fn gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 + { + gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, force, temperature) + } + /// The Gibbs free energy per link as a function of the applied force and temperature. + pub fn gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64 + { + gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, force, temperature) + } + /// The relative Gibbs free energy as a function of the applied force and temperature. + pub fn relative_gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 + { + relative_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) + } + /// The relative Gibbs free energy per link as a function of the applied force and temperature. + pub fn relative_gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64 + { + relative_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) + } + /// The nondimensional Gibbs free energy as a function of the applied force and temperature. + pub fn nondimensional_gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 + { + nondimensional_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, force, temperature) + } + /// The nondimensional Gibbs free energy per link as a function of the applied force and temperature. + pub fn nondimensional_gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64 + { + nondimensional_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, force, temperature) + } + /// The nondimensional relative Gibbs free energy as a function of the applied force. + pub fn nondimensional_relative_gibbs_free_energy(&self, force: &f64) -> f64 + { + nondimensional_relative_gibbs_free_energy(&self.nondimensional_persistance_length, force) + } + /// The nondimensional relative Gibbs free energy per link as a function of the applied force. + pub fn nondimensional_relative_gibbs_free_energy_per_link(&self, force: &f64) -> f64 + { + nondimensional_relative_gibbs_free_energy_per_link(&self.nondimensional_persistance_length, force) + } +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/py.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/py.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs new file mode 100644 index 00000000..45903223 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs @@ -0,0 +1,76 @@ +#![cfg(test)] +use super::*; +use crate::physics::single_chain::test::Parameters; +mod base +{ + use super::*; + use rand::Rng; + #[test] + fn init() + { + let parameters = Parameters::default(); + let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); + } + #[test] + fn number_of_links() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); + } + } + #[test] + fn link_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); + } + } + #[test] + fn hinge_mass() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); + } + } + #[test] + fn persistance_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); + } + } + #[test] + fn all_parameters() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + assert_eq!(number_of_links, model.number_of_links); + assert_eq!(link_length, model.link_length); + assert_eq!(hinge_mass, model.hinge_mass); + assert_eq!(persistance_length, model.persistance_length); + } + } +} \ No newline at end of file From 75687ce92387920b70894bd3aa76b647185b58ff Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 24 Apr 2023 22:57:15 -0600 Subject: [PATCH 14/21] getting nans, not sure why --- .../wlc/thermodynamics/isometric/mod.rs | 10 +- .../wlc/thermodynamics/isotensional/mod.rs | 86 +- .../wlc/thermodynamics/isotensional/test.rs | 847 +++++++++++++++++- 3 files changed, 919 insertions(+), 24 deletions(-) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index dc2c079b..cb73c140 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -112,7 +112,7 @@ pub fn relative_helmholtz_free_energy_per_link(number_of_links: &u8, link_length nondimensional_relative_helmholtz_free_energy_per_link(number_of_links, &(persistance_length/contour_length), &(end_to_end_length/contour_length))*BOLTZMANN_CONSTANT*temperature } -/// The nondimensional Helmholtz free energy as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. +/// The nondimensional Helmholtz free energy as a function of the applied nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { // @@ -122,19 +122,19 @@ pub fn nondimensional_helmholtz_free_energy(number_of_links: &u8, link_length: & -(equilibrium_distribution(number_of_links, link_length, &(contour_length*nondimensional_persistance_length), &1.0, &(contour_length*nondimensional_end_to_end_length_per_link))).ln() - ((*number_of_links as f64) - 1.0)*(4.0*(-1.0/nondimensional_persistance_length).exp().acos().sin()*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() } -/// The nondimensional Helmholtz free energy per link as a function of the nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. +/// The nondimensional Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. pub fn nondimensional_helmholtz_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64, temperature: &f64) -> f64 { nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)/(*number_of_links as f64) } -/// The nondimensional relative Helmholtz free energy as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. +/// The nondimensional relative Helmholtz free energy as a function of the applied nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. pub fn nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { (nondimensional_equilibrium_distribution(nondimensional_persistance_length, &1.0, &ZERO)/nondimensional_equilibrium_distribution(nondimensional_persistance_length, &1.0, nondimensional_end_to_end_length_per_link)).ln() } -/// The nondimensional relative Helmholtz free energy per link as a function of the nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. +/// The nondimensional relative Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link, parameterized by the number of links and nondimensional persistance length. pub fn nondimensional_relative_helmholtz_free_energy_per_link(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)/(*number_of_links as f64) @@ -147,7 +147,7 @@ pub fn equilibrium_distribution(number_of_links: &u8, link_length: &f64, persist nondimensional_equilibrium_distribution(&(persistance_length/contour_length), normalization_nondimensional_equilibrium_distribution, &(end_to_end_length/contour_length))/contour_length.powi(3) } -/// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. +/// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the applied nondimensional end-to-end length per link, parameterized by the nondimensional persistance length. pub fn nondimensional_equilibrium_distribution(nondimensional_persistance_length: &f64, normalization_nondimensional_equilibrium_distribution: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { let g2 = nondimensional_end_to_end_length_per_link.powi(2); diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs index ec059c7a..25d063f6 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs @@ -46,6 +46,32 @@ pub struct WLC pub legendre: self::legendre::WLC } +/// The expected end-to-end length as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. +pub fn end_to_end_length(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 +{ + link_length*nondimensional_end_to_end_length(number_of_links, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature)) +} + +/// The expected end-to-end length per link as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. +pub fn end_to_end_length_per_link(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 +{ + link_length*nondimensional_end_to_end_length_per_link(number_of_links, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature)) +} + +/// The expected nondimensional end-to-end length as a function of the applied nondimensional force, parameterized by the number of links and nondimensional persistance length. +pub fn nondimensional_end_to_end_length(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 +{ + let integrand_numerator = |nondimensional_end_to_end_length_per_link: &f64| (-nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)).exp()*((*number_of_links as f64)*nondimensional_end_to_end_length_per_link*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).cosh()*nondimensional_end_to_end_length_per_link - ((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*nondimensional_end_to_end_length_per_link/nondimensional_force)/nondimensional_force; + let integrand_denominator = |nondimensional_end_to_end_length_per_link: &f64| (-nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)).exp()*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*nondimensional_end_to_end_length_per_link/nondimensional_force; + integrate_1d(&integrand_numerator, &ZERO, &ONE, &POINTS).ln()/integrate_1d(&integrand_denominator, &ZERO, &ONE, &POINTS).ln() +} + +/// The expected nondimensional end-to-end length per link as a function of the applied nondimensional force, parameterized by the number of links and nondimensional persistance length. +pub fn nondimensional_end_to_end_length_per_link(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 +{ + (*number_of_links as f64)*nondimensional_end_to_end_length(number_of_links, nondimensional_persistance_length, nondimensional_force) +} + /// The Gibbs free energy as a function of the applied force and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. pub fn gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 { @@ -69,26 +95,30 @@ pub fn relative_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f { nondimensional_relative_gibbs_free_energy_per_link(&(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature))*BOLTZMANN_CONSTANT*temperature } -/// The nondimensional Gibbs free energy as a function of the nondimensional force and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. + +/// The nondimensional Gibbs free energy as a function of the applied nondimensional force and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. pub fn nondimensional_gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_force: &f64, temperature: &f64) -> f64 { - let integrand = |nondimensional_end_to_end_length_per_link: &f64| (-nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)).exp()*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*nondimensional_end_to_end_length_per_link/nondimensional_force/(*number_of_links as f64); - 4.0*PI*integrate_1d(&integrand, &ZERO, &ONE, &POINTS).ln() - (4.0*(-1.0/nondimensional_persistance_length).exp().acos().sin()*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() + let integrand = |nondimensional_end_to_end_length_per_link: &f64| + { + (-nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)).exp()*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*(*number_of_links as f64)*nondimensional_end_to_end_length_per_link/nondimensional_force + }; + (4.0*PI*integrate_1d(&integrand, &ZERO, &ONE, &POINTS)).ln() - (4.0*(-1.0/nondimensional_persistance_length).exp().acos().sin()*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() } -/// The nondimensional Gibbs free energy per link as a function of the nondimensional force and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. +/// The nondimensional Gibbs free energy per link as a function of the applied nondimensional force and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. pub fn nondimensional_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_force: &f64, temperature: &f64) -> f64 { nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_force, temperature)/(*number_of_links as f64) } -/// The nondimensional relative Gibbs free energy as a function of the nondimensional force, parameterized by the nondimensional persistance length. +/// The nondimensional relative Gibbs free energy as a function of the applied nondimensional force, parameterized by the nondimensional persistance length. pub fn nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 { nondimensional_gibbs_free_energy(&8, &1.0, &1.0, nondimensional_persistance_length, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy(&8, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) } -/// The nondimensional relative Gibbs free energy per link as a function of the nondimensional force, parameterized by the nondimensional persistance length. +/// The nondimensional relative Gibbs free energy per link as a function of the applied nondimensional force, parameterized by the nondimensional persistance length. pub fn nondimensional_relative_gibbs_free_energy_per_link(nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 { nondimensional_gibbs_free_energy_per_link(&8, &1.0, &1.0, nondimensional_persistance_length, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy_per_link(&8, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) @@ -110,6 +140,26 @@ impl WLC legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } } + /// The expected end-to-end length as a function of the applied force and temperature. + pub fn end_to_end_length(&self, force: &f64, temperature: &f64) -> f64 + { + end_to_end_length(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) + } + /// The expected end-to-end length per link as a function of the applied force and temperature. + pub fn end_to_end_length_per_link(&self, force: &f64, temperature: &f64) -> f64 + { + end_to_end_length_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) + } + /// The expected nondimensional end-to-end length as a function of the applied nondimensional force. + pub fn nondimensional_end_to_end_length(&self, nondimensional_force: &f64) -> f64 + { + nondimensional_end_to_end_length(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_force) + } + /// The expected nondimensional end-to-end length per link as a function of the applied nondimensional force. + pub fn nondimensional_end_to_end_length_per_link(&self, nondimensional_force: &f64) -> f64 + { + nondimensional_end_to_end_length_per_link(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_force) + } /// The Gibbs free energy as a function of the applied force and temperature. pub fn gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 { @@ -130,24 +180,24 @@ impl WLC { relative_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) } - /// The nondimensional Gibbs free energy as a function of the applied force and temperature. - pub fn nondimensional_gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 + /// The nondimensional Gibbs free energy as a function of the applied nondimensional force and temperature. + pub fn nondimensional_gibbs_free_energy(&self, nondimensional_force: &f64, temperature: &f64) -> f64 { - nondimensional_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, force, temperature) + nondimensional_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_force, temperature) } - /// The nondimensional Gibbs free energy per link as a function of the applied force and temperature. - pub fn nondimensional_gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64 + /// The nondimensional Gibbs free energy per link as a function of the applied nondimensional force and temperature. + pub fn nondimensional_gibbs_free_energy_per_link(&self, nondimensional_force: &f64, temperature: &f64) -> f64 { - nondimensional_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, force, temperature) + nondimensional_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_force, temperature) } - /// The nondimensional relative Gibbs free energy as a function of the applied force. - pub fn nondimensional_relative_gibbs_free_energy(&self, force: &f64) -> f64 + /// The nondimensional relative Gibbs free energy as a function of the applied nondimensional force. + pub fn nondimensional_relative_gibbs_free_energy(&self, nondimensional_force: &f64) -> f64 { - nondimensional_relative_gibbs_free_energy(&self.nondimensional_persistance_length, force) + nondimensional_relative_gibbs_free_energy(&self.nondimensional_persistance_length, nondimensional_force) } - /// The nondimensional relative Gibbs free energy per link as a function of the applied force. - pub fn nondimensional_relative_gibbs_free_energy_per_link(&self, force: &f64) -> f64 + /// The nondimensional relative Gibbs free energy per link as a function of the applied nondimensional force. + pub fn nondimensional_relative_gibbs_free_energy_per_link(&self, nondimensional_force: &f64) -> f64 { - nondimensional_relative_gibbs_free_energy_per_link(&self.nondimensional_persistance_length, force) + nondimensional_relative_gibbs_free_energy_per_link(&self.nondimensional_persistance_length, nondimensional_force) } } \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs index 45903223..21334b33 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs @@ -73,4 +73,849 @@ mod base assert_eq!(persistance_length, model.persistance_length); } } -} \ No newline at end of file +} +mod nondimensional +{ + use super::*; + use rand::Rng; + #[test] + fn end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length = model.end_to_end_length(&force, &temperature); + let residual_abs = &end_to_end_length/link_length - &nondimensional_end_to_end_length; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); + let residual_abs = &end_to_end_length_per_link/link_length - &nondimensional_end_to_end_length_per_link; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); + let residual_abs = &gibbs_free_energy/BOLTZMANN_CONSTANT/temperature - &nondimensional_gibbs_free_energy; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); + let residual_abs = &gibbs_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - &nondimensional_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); + let residual_abs = &relative_gibbs_free_energy/BOLTZMANN_CONSTANT/temperature - &nondimensional_relative_gibbs_free_energy; + let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); + let residual_abs = &relative_gibbs_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - &nondimensional_relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod per_link +{ + use super::*; + use rand::Rng; + #[test] + fn end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length = model.end_to_end_length(&force, &temperature); + let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); + let residual_abs = &end_to_end_length/(number_of_links as f64) - &end_to_end_length_per_link; + let residual_rel = &residual_abs/&end_to_end_length_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); + let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); + let residual_abs = &nondimensional_end_to_end_length/(number_of_links as f64) - &nondimensional_end_to_end_length_per_link; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); + let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); + let residual_abs = &gibbs_free_energy/(number_of_links as f64) - &gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn relative_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); + let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); + let residual_abs = &relative_gibbs_free_energy/(number_of_links as f64) - &relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&relative_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); + let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); + let residual_abs = &nondimensional_gibbs_free_energy/(number_of_links as f64) - &nondimensional_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_relative_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); + let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); + let residual_abs = &nondimensional_relative_gibbs_free_energy/(number_of_links as f64) - &nondimensional_relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod relative +{ + use super::*; + use crate::physics::single_chain::ZERO; + use rand::Rng; + #[test] + fn gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); + let gibbs_free_energy_0 = model.gibbs_free_energy(&ZERO, &temperature); + let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); + let residual_abs = &gibbs_free_energy - &gibbs_free_energy_0 - &relative_gibbs_free_energy; + let residual_rel = &residual_abs/&gibbs_free_energy_0; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn gibbs_free_energy_per_link() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); + let gibbs_free_energy_per_link_0 = model.gibbs_free_energy_per_link(&ZERO, &temperature); + let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); + let residual_abs = &gibbs_free_energy_per_link - &gibbs_free_energy_per_link_0 - &relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&gibbs_free_energy_per_link_0; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_gibbs_free_energy() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); + let nondimensional_gibbs_free_energy_0 = model.nondimensional_gibbs_free_energy(&ZERO, &temperature); + let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); + let residual_abs = &nondimensional_gibbs_free_energy - &nondimensional_gibbs_free_energy_0 - &nondimensional_relative_gibbs_free_energy; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_0; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } + #[test] + fn nondimensional_gibbs_free_energy_per_link() + { + let parameters = Parameters::default(); + let mut rng = rand::thread_rng(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); + let nondimensional_gibbs_free_energy_per_link_0 = model.nondimensional_gibbs_free_energy_per_link(&ZERO, &temperature); + let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); + let residual_abs = &nondimensional_gibbs_free_energy_per_link - &nondimensional_gibbs_free_energy_per_link_0 - &nondimensional_relative_gibbs_free_energy_per_link; + let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link_0; + assert!(residual_abs.abs() <= parameters.abs_tol); + assert!(residual_rel.abs() <= parameters.rel_tol); + } + } +} +mod zero +{ + use super::*; + use crate::physics::single_chain::ZERO; + use rand::Rng; + #[test] + fn end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length_0 = model.end_to_end_length(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); + assert!(end_to_end_length_0.abs() <= ZERO*(number_of_links as f64)*link_length); + } + } + #[test] + fn end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let end_to_end_length_per_link_0 = model.end_to_end_length_per_link(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); + assert!(end_to_end_length_per_link_0.abs() <= ZERO*link_length); + } + } + #[test] + fn nondimensional_end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_0 = model.nondimensional_end_to_end_length(&ZERO); + assert!(nondimensional_end_to_end_length_0.abs() <= ZERO*(number_of_links as f64)); + } + } + #[test] + fn nondimensional_end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_end_to_end_length_per_link_0 = model.nondimensional_end_to_end_length_per_link(&ZERO); + assert!(nondimensional_end_to_end_length_per_link_0.abs() <= ZERO); + } + } + #[test] + fn relative_gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_gibbs_free_energy_0 = model.relative_gibbs_free_energy(&ZERO, &temperature); + assert!(relative_gibbs_free_energy_0.abs() <= ZERO); + } + } + #[test] + fn relative_gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let relative_gibbs_free_energy_per_link_0 = model.relative_gibbs_free_energy_per_link(&ZERO, &temperature); + assert!(relative_gibbs_free_energy_per_link_0.abs() <= ZERO); + } + } + #[test] + fn nondimensional_relative_gibbs_free_energy() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_relative_gibbs_free_energy_0 = model.nondimensional_relative_gibbs_free_energy(&ZERO); + assert!(nondimensional_relative_gibbs_free_energy_0.abs() <= ZERO); + } + } + #[test] + fn nondimensional_relative_gibbs_free_energy_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_relative_gibbs_free_energy_per_link_0 = model.nondimensional_relative_gibbs_free_energy_per_link(&ZERO); + assert!(nondimensional_relative_gibbs_free_energy_per_link_0.abs() <= ZERO); + } + } +} +mod connection +{ + use super::*; + use rand::Rng; + #[test] + fn end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length = model.end_to_end_length(&force, &temperature); + let h = parameters.rel_tol*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length_from_derivative = -(model.relative_gibbs_free_energy(&(force + 0.5*h), &temperature) - model.relative_gibbs_free_energy(&(force - 0.5*h), &temperature))/h; + let residual_abs = &end_to_end_length - &end_to_end_length_from_derivative; + let residual_rel = &residual_abs/&end_to_end_length; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); + let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); + let h = parameters.rel_tol*BOLTZMANN_CONSTANT*temperature/link_length; + let end_to_end_length_per_link_from_derivative = -(model.relative_gibbs_free_energy_per_link(&(force + 0.5*h), &temperature) - model.relative_gibbs_free_energy_per_link(&(force - 0.5*h), &temperature))/h; + let residual_abs = &end_to_end_length_per_link - &end_to_end_length_per_link_from_derivative; + let residual_rel = &residual_abs/&end_to_end_length_per_link; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn nondimensional_end_to_end_length() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); + let h = parameters.rel_tol; + let nondimensional_end_to_end_length_from_derivative = -(model.nondimensional_relative_gibbs_free_energy(&(nondimensional_force + 0.5*h)) - model.nondimensional_relative_gibbs_free_energy(&(nondimensional_force - 0.5*h)))/h; + let residual_abs = &nondimensional_end_to_end_length - &nondimensional_end_to_end_length_from_derivative; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length; + assert!(residual_rel.abs() <= h); + } + } + #[test] + fn nondimensional_end_to_end_length_per_link() + { + let mut rng = rand::thread_rng(); + let parameters = Parameters::default(); + for _ in 0..parameters.number_of_loops + { + let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); + let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); + let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); + let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); + let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); + let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); + let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); + let h = parameters.rel_tol; + let nondimensional_end_to_end_length_per_link_from_derivative = -(model.nondimensional_relative_gibbs_free_energy_per_link(&(nondimensional_force + 0.5*h)) - model.nondimensional_relative_gibbs_free_energy_per_link(&(nondimensional_force - 0.5*h)))/h; + let residual_abs = &nondimensional_end_to_end_length_per_link - &nondimensional_end_to_end_length_per_link_from_derivative; + let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; + assert!(residual_rel.abs() <= h); + } + } +} +// mod legendre +// { +// use super::*; +// use crate::physics::single_chain::ZERO; +// use rand::Rng; +// #[test] +// fn gibbs_free_energy() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; +// let end_to_end_length = model.end_to_end_length(&force, &temperature); +// let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); +// let gibbs_free_energy_legendre = model.legendre.helmholtz_free_energy(&force, &temperature) - force*end_to_end_length; +// let residual_abs = &gibbs_free_energy - &gibbs_free_energy_legendre; +// let residual_rel = &residual_abs/&gibbs_free_energy; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn gibbs_free_energy_per_link() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; +// let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); +// let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); +// let gibbs_free_energy_per_link_legendre = model.legendre.helmholtz_free_energy_per_link(&force, &temperature) - force*end_to_end_length_per_link; +// let residual_abs = &gibbs_free_energy_per_link - &gibbs_free_energy_per_link_legendre; +// let residual_rel = &residual_abs/&gibbs_free_energy_per_link; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn relative_gibbs_free_energy() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; +// let end_to_end_length = model.end_to_end_length(&force, &temperature); +// let end_to_end_length_0 = model.end_to_end_length(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); +// let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); +// let relative_gibbs_free_energy_legendre = model.legendre.relative_helmholtz_free_energy(&force, &temperature) - force*end_to_end_length + ZERO*BOLTZMANN_CONSTANT*temperature/link_length*end_to_end_length_0; +// let residual_abs = &relative_gibbs_free_energy - &relative_gibbs_free_energy_legendre; +// let residual_rel = &residual_abs/&relative_gibbs_free_energy; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn relative_gibbs_free_energy_per_link() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; +// let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); +// let end_to_end_length_per_link_0 = model.end_to_end_length_per_link(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); +// let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); +// let relative_gibbs_free_energy_per_link_legendre = model.legendre.relative_helmholtz_free_energy_per_link(&force, &temperature) - force*end_to_end_length_per_link + ZERO*BOLTZMANN_CONSTANT*temperature/link_length*end_to_end_length_per_link_0; +// let residual_abs = &relative_gibbs_free_energy_per_link - &relative_gibbs_free_energy_per_link_legendre; +// let residual_rel = &residual_abs/&relative_gibbs_free_energy_per_link; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn nondimensional_gibbs_free_energy() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); +// let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); +// let nondimensional_gibbs_free_energy_legendre = model.legendre.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature) - nondimensional_force*nondimensional_end_to_end_length; +// let residual_abs = &nondimensional_gibbs_free_energy - &nondimensional_gibbs_free_energy_legendre; +// let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn nondimensional_gibbs_free_energy_per_link() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); +// let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); +// let nondimensional_gibbs_free_energy_per_link_legendre = model.legendre.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature) - nondimensional_force*nondimensional_end_to_end_length_per_link; +// let residual_abs = &nondimensional_gibbs_free_energy_per_link - &nondimensional_gibbs_free_energy_per_link_legendre; +// let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn nondimensional_relative_gibbs_free_energy() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); +// let nondimensional_end_to_end_length_0 = model.nondimensional_end_to_end_length(&ZERO); +// let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); +// let nondimensional_relative_gibbs_free_energy_legendre = model.legendre.nondimensional_relative_helmholtz_free_energy(&nondimensional_force) - nondimensional_force*nondimensional_end_to_end_length + ZERO*nondimensional_end_to_end_length_0; +// let residual_abs = &nondimensional_relative_gibbs_free_energy - &nondimensional_relative_gibbs_free_energy_legendre; +// let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// #[test] +// fn nondimensional_relative_gibbs_free_energy_per_link() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); +// let nondimensional_end_to_end_length_per_link_0 = model.nondimensional_end_to_end_length_per_link(&ZERO); +// let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); +// let nondimensional_relative_gibbs_free_energy_per_link_legendre = model.legendre.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_force) - nondimensional_force*nondimensional_end_to_end_length_per_link + ZERO*nondimensional_end_to_end_length_per_link_0; +// let residual_abs = &nondimensional_relative_gibbs_free_energy_per_link - &nondimensional_relative_gibbs_free_energy_per_link_legendre; +// let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; +// assert!(residual_abs.abs() <= parameters.abs_tol); +// assert!(residual_rel.abs() <= parameters.rel_tol); +// } +// } +// } +// mod legendre_connection +// { +// use super::*; +// use rand::Rng; +// #[test] +// fn force() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); +// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; +// let h = parameters.rel_tol*BOLTZMANN_CONSTANT*temperature/link_length; +// let force_from_derivative = (model.legendre.relative_helmholtz_free_energy(&(force + 0.5*h), &temperature) - model.legendre.relative_helmholtz_free_energy(&(force - 0.5*h), &temperature))/(model.end_to_end_length(&(force + 0.5*h), &temperature) - model.end_to_end_length(&(force - 0.5*h), &temperature)); +// let residual_abs = &force - &force_from_derivative; +// let residual_rel = &residual_abs/&force; +// assert!(residual_rel.abs() <= h); +// } +// } +// #[test] +// fn nondimensional_force() +// { +// let mut rng = rand::thread_rng(); +// let parameters = Parameters::default(); +// for _ in 0..parameters.number_of_loops +// { +// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); +// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); +// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); +// let model = FJC::init(number_of_links, link_length, hinge_mass); +// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); +// let h = parameters.rel_tol; +// let nondimensional_force_from_derivative = (model.legendre.nondimensional_relative_helmholtz_free_energy_per_link(&(nondimensional_force + 0.5*h)) - model.legendre.nondimensional_relative_helmholtz_free_energy_per_link(&(nondimensional_force - 0.5*h)))/(model.nondimensional_end_to_end_length_per_link(&(nondimensional_force + 0.5*h)) - model.nondimensional_end_to_end_length_per_link(&(nondimensional_force - 0.5*h))); +// let residual_abs = &nondimensional_force - &nondimensional_force_from_derivative; +// let residual_rel = &residual_abs/&nondimensional_force; +// assert!(residual_rel.abs() <= h); +// } +// } +// } \ No newline at end of file From 814274d602fe0fd7576f0cd32d2e8da1a1545dc3 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Thu, 27 Apr 2023 13:03:09 -0600 Subject: [PATCH 15/21] bump --- Cargo.toml | 2 +- Project.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 30ecd200..abb5b029 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polymers" -version = "0.3.3" +version = "0.4.0" edition = "2021" description = "Polymers Modeling Library" license = "BSD-3-Clause" diff --git a/Project.toml b/Project.toml index 61f2c388..19d2273b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Polymers" uuid = "8aef037c-a721-4e8a-9d81-eb7093daef2c" authors = ["mrbuche "] -version = "0.3.3" +version = "0.4.0" [deps] DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" From 609481be645372350247981bf2b23e340df118e3 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Thu, 27 Apr 2023 13:05:44 -0600 Subject: [PATCH 16/21] clippy --- .../isometric/asymptotic/legendre/mod.rs | 2 +- .../isometric/asymptotic/legendre/test.rs | 30 ++++---- .../asymptotic/reduced/legendre/mod.rs | 2 +- .../asymptotic/reduced/legendre/test.rs | 30 ++++---- .../isotensional/asymptotic/legendre/test.rs | 24 +++---- .../asymptotic/reduced/legendre/test.rs | 24 +++---- .../isotensional/asymptotic/reduced/test.rs | 60 ++++++++-------- .../isotensional/asymptotic/test.rs | 68 +++++++++---------- .../isotensional/legendre/test.rs | 24 +++---- .../ufjc/lennard_jones/thermodynamics/test.rs | 40 +++++------ 10 files changed, 152 insertions(+), 152 deletions(-) diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/mod.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/mod.rs index 7082cbb9..b8dd6eec 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/mod.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/mod.rs @@ -46,7 +46,7 @@ pub fn force(number_of_links: &u8, link_length: &f64, link_stiffness: &f64, end_ pub fn nondimensional_force(nondimensional_link_stiffness: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { let c: f64 = 2.0/23.0; - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = nondimensional_link_stiffness/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let mut guess: f64 = if nondimensional_end_to_end_length_per_link < &1.0 { diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.rs index a2c1d45e..80dcfcf6 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.rs @@ -92,7 +92,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -118,7 +118,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -144,7 +144,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -170,7 +170,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -196,7 +196,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -227,7 +227,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -253,7 +253,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -279,7 +279,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -304,7 +304,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -334,7 +334,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -361,7 +361,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -388,7 +388,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -414,7 +414,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -553,7 +553,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -579,7 +579,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/mod.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/mod.rs index c769c1ee..0dec1740 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/mod.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/mod.rs @@ -45,7 +45,7 @@ pub fn force(number_of_links: &u8, link_length: &f64, link_stiffness: &f64, end_ /// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link, parameterized by the nondimensional link stiffness. pub fn nondimensional_force(nondimensional_link_stiffness: &f64, nondimensional_end_to_end_length_per_link: &f64) -> f64 { - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = nondimensional_link_stiffness/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let mut guess: f64 = if nondimensional_end_to_end_length_per_link < &1.0 { diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.rs index c0cd0cfc..232918a1 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.rs @@ -92,7 +92,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -118,7 +118,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -144,7 +144,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -170,7 +170,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -196,7 +196,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -227,7 +227,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -253,7 +253,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -279,7 +279,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -304,7 +304,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -334,7 +334,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -361,7 +361,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -388,7 +388,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -414,7 +414,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -553,7 +553,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); @@ -579,7 +579,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_end_to_end_length_per_link_max = isotensional_nondimensional_end_to_end_length_per_link( &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(0.999*nondimensional_force_max)); let nondimensional_end_to_end_length_per_link = nondimensional_end_to_end_length_per_link_max*rng.gen::(); diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.rs index 66faf4b6..2b8a48bb 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.rs @@ -91,7 +91,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -116,7 +116,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); @@ -141,7 +141,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -166,7 +166,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); @@ -196,7 +196,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -221,7 +221,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -246,7 +246,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -270,7 +270,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -299,7 +299,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -325,7 +325,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -351,7 +351,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -376,7 +376,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.rs index 66faf4b6..2b8a48bb 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.rs @@ -91,7 +91,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -116,7 +116,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); @@ -141,7 +141,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -166,7 +166,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); @@ -196,7 +196,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -221,7 +221,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -246,7 +246,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -270,7 +270,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -299,7 +299,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -325,7 +325,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -351,7 +351,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -376,7 +376,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.rs index b579c149..2cee9dc5 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.rs @@ -91,7 +91,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -116,7 +116,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -141,7 +141,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); @@ -166,7 +166,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); @@ -191,7 +191,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force, &temperature); @@ -216,7 +216,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force, &temperature); @@ -246,7 +246,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -271,7 +271,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -295,7 +295,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -320,7 +320,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -345,7 +345,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); @@ -369,7 +369,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force, &temperature); @@ -398,7 +398,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -424,7 +424,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -450,7 +450,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); @@ -475,7 +475,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); @@ -578,7 +578,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -603,7 +603,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -628,7 +628,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -652,7 +652,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -682,7 +682,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -708,7 +708,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -734,7 +734,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -761,7 +761,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -788,7 +788,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -813,7 +813,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -838,7 +838,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -864,7 +864,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -895,7 +895,7 @@ mod legendre_connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -919,7 +919,7 @@ mod legendre_connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let h = parameters.rel_tol; diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.rs index 3be9bd0b..042d8c10 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.rs @@ -91,7 +91,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -116,7 +116,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -141,7 +141,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); @@ -166,7 +166,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); @@ -191,7 +191,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force, &temperature); @@ -216,7 +216,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force, &temperature); @@ -246,7 +246,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -271,7 +271,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -295,7 +295,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -320,7 +320,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -345,7 +345,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); @@ -369,7 +369,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force, &temperature); @@ -398,7 +398,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -424,7 +424,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -450,7 +450,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); @@ -475,7 +475,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); @@ -578,7 +578,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -603,7 +603,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -628,7 +628,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -652,7 +652,7 @@ mod connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -682,7 +682,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -708,7 +708,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -734,7 +734,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -761,7 +761,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -788,7 +788,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -813,7 +813,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -838,7 +838,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -864,7 +864,7 @@ mod legendre let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -895,7 +895,7 @@ mod legendre_connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -919,7 +919,7 @@ mod legendre_connection let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let h = parameters.rel_tol; @@ -961,7 +961,7 @@ mod asymptotic_reduced let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; model.end_to_end_length(&force, &temperature).powi(2) }; - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let numerator = integrate_1d(&integrand_numerator, &ZERO, &nondimensional_force_max, &POINTS); let denominator = integrate_1d(&integrand_denominator, &ZERO, &nondimensional_force_max, &POINTS); @@ -1000,7 +1000,7 @@ mod asymptotic_reduced let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; model.end_to_end_length_per_link(&force, &temperature).powi(2) }; - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let numerator = integrate_1d(&integrand_numerator, &ZERO, &nondimensional_force_max, &POINTS); let denominator = integrate_1d(&integrand_denominator, &ZERO, &nondimensional_force_max, &POINTS); @@ -1037,7 +1037,7 @@ mod asymptotic_reduced { model.nondimensional_end_to_end_length(&nondimensional_force, &temperature).powi(2) }; - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let numerator = integrate_1d(&integrand_numerator, &ZERO, &nondimensional_force_max, &POINTS); let denominator = integrate_1d(&integrand_denominator, &ZERO, &nondimensional_force_max, &POINTS); @@ -1074,7 +1074,7 @@ mod asymptotic_reduced { model.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature).powi(2) }; - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let numerator = integrate_1d(&integrand_numerator, &ZERO, &nondimensional_force_max, &POINTS); let denominator = integrate_1d(&integrand_denominator, &ZERO, &nondimensional_force_max, &POINTS); diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.rs index 66faf4b6..2b8a48bb 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.rs @@ -91,7 +91,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -116,7 +116,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); @@ -141,7 +141,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -166,7 +166,7 @@ mod nondimensional let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy_per_link = model.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); @@ -196,7 +196,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -221,7 +221,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -246,7 +246,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -270,7 +270,7 @@ mod per_link let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_relative_helmholtz_free_energy = model.nondimensional_relative_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -299,7 +299,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -325,7 +325,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -351,7 +351,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature); @@ -376,7 +376,7 @@ mod relative let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_helmholtz_free_energy_per_link = model.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature); diff --git a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.rs b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.rs index 2f65850d..e43036d2 100644 --- a/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.rs +++ b/src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.rs @@ -97,7 +97,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -121,7 +121,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link= model.isotensional.asymptotic.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -144,7 +144,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -169,7 +169,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -195,7 +195,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -220,7 +220,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -246,7 +246,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.isotensional.asymptotic.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -271,7 +271,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.isotensional.asymptotic.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -295,7 +295,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.isotensional.asymptotic.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -320,7 +320,7 @@ mod legendre_asymptotic let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.isotensional.asymptotic.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -349,7 +349,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -373,7 +373,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link= model.isotensional.asymptotic.reduced.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -396,7 +396,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -421,7 +421,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -447,7 +447,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -472,7 +472,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; @@ -498,7 +498,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.isotensional.asymptotic.reduced.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -523,7 +523,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.isotensional.asymptotic.reduced.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); @@ -547,7 +547,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length = model.isotensional.asymptotic.reduced.nondimensional_end_to_end_length(&nondimensional_force, &temperature); @@ -572,7 +572,7 @@ mod legendre_asymptotic_reduced let link_stiffness = parameters.link_stiffness_reference + parameters.link_stiffness_scale*(0.5 - rng.gen::()); let model = LENNARDJONESFJC::init(number_of_links, link_length, hinge_mass, link_stiffness); let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let lambda_max = (13.0/7.0 as f64).powf(1.0/6.0); + let lambda_max = (13.0/7.0_f64).powf(1.0/6.0); let nondimensional_force_max = link_stiffness/BOLTZMANN_CONSTANT/temperature*link_length.powi(2)/6.0*(lambda_max.powi(-7) - lambda_max.powi(-13)); let nondimensional_force = nondimensional_force_max*rng.gen::(); let nondimensional_end_to_end_length_per_link = model.isotensional.asymptotic.reduced.nondimensional_end_to_end_length_per_link(&nondimensional_force, &temperature); From fae79fd48158c199366491713d248895b4552761 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 1 May 2023 10:05:39 -0600 Subject: [PATCH 17/21] just do this first; seems like trouble trying to integrate over end-to-end lengths for inextensible chain models to get isotensional --- .../wlc/thermodynamics/isometric/mod.rs | 6 +- .../thermodynamics/isotensional/__init__.py | 0 .../wlc/thermodynamics/isotensional/ex.rs | 0 .../isotensional/legendre/__init__.py | 0 .../isotensional/legendre/ex.rs | 0 .../isotensional/legendre/mod.jl | 0 .../isotensional/legendre/mod.rs | 45 - .../isotensional/legendre/py.rs | 0 .../isotensional/legendre/test.jl | 0 .../isotensional/legendre/test.rs | 76 -- .../wlc/thermodynamics/isotensional/mod.jl | 0 .../wlc/thermodynamics/isotensional/mod.rs | 203 ---- .../wlc/thermodynamics/isotensional/py.rs | 0 .../wlc/thermodynamics/isotensional/test.jl | 0 .../wlc/thermodynamics/isotensional/test.rs | 921 ------------------ .../single_chain/wlc/thermodynamics/mod.rs | 11 +- 16 files changed, 5 insertions(+), 1257 deletions(-) delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/__init__.py delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/ex.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/__init__.py delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/ex.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.jl delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/py.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.jl delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/mod.jl delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/py.rs delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/test.jl delete mode 100644 src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index cb73c140..63bf29bb 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -197,15 +197,15 @@ impl WLC pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self { let nondimensional_persistance_length = persistance_length/(number_of_links as f64)/link_length; - let normalization = integrate_1d(&|nondimensional_end_to_end_length_per_link: &f64| nondimensional_equilibrium_radial_distribution(&nondimensional_persistance_length, &1.0, nondimensional_end_to_end_length_per_link), &ZERO, &ONE, &POINTS); + let normalization_nondimensional_equilibrium_distribution = integrate_1d(&|nondimensional_end_to_end_length_per_link: &f64| nondimensional_equilibrium_radial_distribution(&nondimensional_persistance_length, &1.0, nondimensional_end_to_end_length_per_link), &ZERO, &ONE, &POINTS); WLC { hinge_mass, link_length, number_of_links, persistance_length, - nondimensional_persistance_length: nondimensional_persistance_length, - normalization_nondimensional_equilibrium_distribution: normalization, + nondimensional_persistance_length, + normalization_nondimensional_equilibrium_distribution, legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), } } diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/__init__.py b/src/physics/single_chain/wlc/thermodynamics/isotensional/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/ex.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/__init__.py b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/ex.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs deleted file mode 100644 index 2eecabf4..00000000 --- a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/mod.rs +++ /dev/null @@ -1,45 +0,0 @@ -#[cfg(feature = "extern")] -pub mod ex; - -#[cfg(feature = "python")] -pub mod py; - -mod test; - -use crate::physics::BOLTZMANN_CONSTANT; -use crate::physics::single_chain::ZERO; - -/// The structure of the thermodynamics of the WLC model in the isotensional ensemble approximated using a Legendre transformation. -pub struct WLC -{ - /// The mass of each hinge in the chain in units of kg/mol. - pub hinge_mass: f64, - - /// The length of each link in the chain in units of nm. - pub link_length: f64, - - /// The number of links in the chain. - pub number_of_links: u8, - - /// The persistance length of the chain in units of nm. - pub persistance_length: f64, - - nondimensional_persistance_length: f64 -} - -/// The implemented functionality of the thermodynamics of the WLC model in the isotensional ensemble approximated using a Legendre transformation. -impl WLC -{ - /// Initializes and returns an instance of the thermodynamics of the WLC model in the isotensional ensemble approximated using a Legendre transformation. - pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self - { - WLC - { - hinge_mass, - link_length, - number_of_links, - persistance_length, - nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length - } - } -} diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/py.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/py.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs deleted file mode 100644 index 45903223..00000000 --- a/src/physics/single_chain/wlc/thermodynamics/isotensional/legendre/test.rs +++ /dev/null @@ -1,76 +0,0 @@ -#![cfg(test)] -use super::*; -use crate::physics::single_chain::test::Parameters; -mod base -{ - use super::*; - use rand::Rng; - #[test] - fn init() - { - let parameters = Parameters::default(); - let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); - } - #[test] - fn number_of_links() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); - } - } - #[test] - fn link_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); - } - } - #[test] - fn hinge_mass() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); - } - } - #[test] - fn persistance_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); - } - } - #[test] - fn all_parameters() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - assert_eq!(number_of_links, model.number_of_links); - assert_eq!(link_length, model.link_length); - assert_eq!(hinge_mass, model.hinge_mass); - assert_eq!(persistance_length, model.persistance_length); - } - } -} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs deleted file mode 100644 index 25d063f6..00000000 --- a/src/physics/single_chain/wlc/thermodynamics/isotensional/mod.rs +++ /dev/null @@ -1,203 +0,0 @@ -#[cfg(feature = "extern")] -pub mod ex; - -#[cfg(feature = "python")] -pub mod py; - -mod test; - -/// The worm-like chain (WLC) model thermodynamics in the isotensional ensemble approximated using a Legendre transformation. -pub mod legendre; - -use super::isometric::nondimensional_helmholtz_free_energy; - -use std::f64::consts::PI; -use crate::math::integrate_1d; -use crate::physics:: -{ - PLANCK_CONSTANT, - BOLTZMANN_CONSTANT -}; -use crate::physics::single_chain:: -{ - ONE, - ZERO, - POINTS -}; - -/// The structure of the thermodynamics of the WLC model in the isotensional ensemble. -pub struct WLC -{ - /// The mass of each hinge in the chain in units of kg/mol. - pub hinge_mass: f64, - - /// The length of each link in the chain in units of nm. - pub link_length: f64, - - /// The number of links in the chain. - pub number_of_links: u8, - - /// The persistance length of the chain in units of nm. - pub persistance_length: f64, - - nondimensional_persistance_length: f64, - - /// The thermodynamic functions of the model in the isotensional ensemble approximated using a Legendre transformation. - pub legendre: self::legendre::WLC -} - -/// The expected end-to-end length as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. -pub fn end_to_end_length(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 -{ - link_length*nondimensional_end_to_end_length(number_of_links, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature)) -} - -/// The expected end-to-end length per link as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. -pub fn end_to_end_length_per_link(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 -{ - link_length*nondimensional_end_to_end_length_per_link(number_of_links, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature)) -} - -/// The expected nondimensional end-to-end length as a function of the applied nondimensional force, parameterized by the number of links and nondimensional persistance length. -pub fn nondimensional_end_to_end_length(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 -{ - let integrand_numerator = |nondimensional_end_to_end_length_per_link: &f64| (-nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)).exp()*((*number_of_links as f64)*nondimensional_end_to_end_length_per_link*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).cosh()*nondimensional_end_to_end_length_per_link - ((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*nondimensional_end_to_end_length_per_link/nondimensional_force)/nondimensional_force; - let integrand_denominator = |nondimensional_end_to_end_length_per_link: &f64| (-nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length, nondimensional_end_to_end_length_per_link)).exp()*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*nondimensional_end_to_end_length_per_link/nondimensional_force; - integrate_1d(&integrand_numerator, &ZERO, &ONE, &POINTS).ln()/integrate_1d(&integrand_denominator, &ZERO, &ONE, &POINTS).ln() -} - -/// The expected nondimensional end-to-end length per link as a function of the applied nondimensional force, parameterized by the number of links and nondimensional persistance length. -pub fn nondimensional_end_to_end_length_per_link(number_of_links: &u8, nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 -{ - (*number_of_links as f64)*nondimensional_end_to_end_length(number_of_links, nondimensional_persistance_length, nondimensional_force) -} - -/// The Gibbs free energy as a function of the applied force and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. -pub fn gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 -{ - nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature), temperature)*BOLTZMANN_CONSTANT*temperature -} - -/// The Gibbs free energy per link as a function of the applied force and temperature, parameterized by the number of links, link length, hinge mass, and persistance length. -pub fn gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 -{ - nondimensional_gibbs_free_energy_per_link(number_of_links, link_length, hinge_mass, &(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature), temperature)*BOLTZMANN_CONSTANT*temperature -} - -/// The relative Gibbs free energy as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. -pub fn relative_gibbs_free_energy(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 -{ - nondimensional_relative_gibbs_free_energy(&(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature))*BOLTZMANN_CONSTANT*temperature -} - -/// The relative Gibbs free energy per link as a function of the applied force and temperature, parameterized by the number of links, link length, and persistance length. -pub fn relative_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, persistance_length: &f64, force: &f64, temperature: &f64) -> f64 -{ - nondimensional_relative_gibbs_free_energy_per_link(&(persistance_length/((*number_of_links as f64)*link_length)), &(force*link_length/BOLTZMANN_CONSTANT/temperature))*BOLTZMANN_CONSTANT*temperature -} - -/// The nondimensional Gibbs free energy as a function of the applied nondimensional force and temperature, parameterized by the number of links, link length, hinge mass, and nondimensional persistance length. -pub fn nondimensional_gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_force: &f64, temperature: &f64) -> f64 -{ - let integrand = |nondimensional_end_to_end_length_per_link: &f64| - { - (-nondimensional_helmholtz_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature)).exp()*((*number_of_links as f64)*nondimensional_force*nondimensional_end_to_end_length_per_link).sinh()*(*number_of_links as f64)*nondimensional_end_to_end_length_per_link/nondimensional_force - }; - (4.0*PI*integrate_1d(&integrand, &ZERO, &ONE, &POINTS)).ln() - (4.0*(-1.0/nondimensional_persistance_length).exp().acos().sin()*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln() -} - -/// The nondimensional Gibbs free energy per link as a function of the applied nondimensional force and temperature, parameterized by the number of links, link length, and hinge mass, and nondimensional persistance length. -pub fn nondimensional_gibbs_free_energy_per_link(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_persistance_length: &f64, nondimensional_force: &f64, temperature: &f64) -> f64 -{ - nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, nondimensional_persistance_length, nondimensional_force, temperature)/(*number_of_links as f64) -} - -/// The nondimensional relative Gibbs free energy as a function of the applied nondimensional force, parameterized by the nondimensional persistance length. -pub fn nondimensional_relative_gibbs_free_energy(nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 -{ - nondimensional_gibbs_free_energy(&8, &1.0, &1.0, nondimensional_persistance_length, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy(&8, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) -} - -/// The nondimensional relative Gibbs free energy per link as a function of the applied nondimensional force, parameterized by the nondimensional persistance length. -pub fn nondimensional_relative_gibbs_free_energy_per_link(nondimensional_persistance_length: &f64, nondimensional_force: &f64) -> f64 -{ - nondimensional_gibbs_free_energy_per_link(&8, &1.0, &1.0, nondimensional_persistance_length, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy_per_link(&8, &1.0, &1.0, nondimensional_persistance_length, &ZERO, &300.0) -} - -/// The implemented functionality of the thermodynamics of the WLC model in the isotensional ensemble. -impl WLC -{ - /// Initializes and returns an instance of the thermodynamics of the WLC model in the isotensional ensemble. - pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self - { - WLC - { - hinge_mass, - link_length, - number_of_links, - persistance_length, - nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length, - legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), - } - } - /// The expected end-to-end length as a function of the applied force and temperature. - pub fn end_to_end_length(&self, force: &f64, temperature: &f64) -> f64 - { - end_to_end_length(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) - } - /// The expected end-to-end length per link as a function of the applied force and temperature. - pub fn end_to_end_length_per_link(&self, force: &f64, temperature: &f64) -> f64 - { - end_to_end_length_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) - } - /// The expected nondimensional end-to-end length as a function of the applied nondimensional force. - pub fn nondimensional_end_to_end_length(&self, nondimensional_force: &f64) -> f64 - { - nondimensional_end_to_end_length(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_force) - } - /// The expected nondimensional end-to-end length per link as a function of the applied nondimensional force. - pub fn nondimensional_end_to_end_length_per_link(&self, nondimensional_force: &f64) -> f64 - { - nondimensional_end_to_end_length_per_link(&self.number_of_links, &self.nondimensional_persistance_length, nondimensional_force) - } - /// The Gibbs free energy as a function of the applied force and temperature. - pub fn gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 - { - gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, force, temperature) - } - /// The Gibbs free energy per link as a function of the applied force and temperature. - pub fn gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64 - { - gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, force, temperature) - } - /// The relative Gibbs free energy as a function of the applied force and temperature. - pub fn relative_gibbs_free_energy(&self, force: &f64, temperature: &f64) -> f64 - { - relative_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) - } - /// The relative Gibbs free energy per link as a function of the applied force and temperature. - pub fn relative_gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64 - { - relative_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, force, temperature) - } - /// The nondimensional Gibbs free energy as a function of the applied nondimensional force and temperature. - pub fn nondimensional_gibbs_free_energy(&self, nondimensional_force: &f64, temperature: &f64) -> f64 - { - nondimensional_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_force, temperature) - } - /// The nondimensional Gibbs free energy per link as a function of the applied nondimensional force and temperature. - pub fn nondimensional_gibbs_free_energy_per_link(&self, nondimensional_force: &f64, temperature: &f64) -> f64 - { - nondimensional_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, nondimensional_force, temperature) - } - /// The nondimensional relative Gibbs free energy as a function of the applied nondimensional force. - pub fn nondimensional_relative_gibbs_free_energy(&self, nondimensional_force: &f64) -> f64 - { - nondimensional_relative_gibbs_free_energy(&self.nondimensional_persistance_length, nondimensional_force) - } - /// The nondimensional relative Gibbs free energy per link as a function of the applied nondimensional force. - pub fn nondimensional_relative_gibbs_free_energy_per_link(&self, nondimensional_force: &f64) -> f64 - { - nondimensional_relative_gibbs_free_energy_per_link(&self.nondimensional_persistance_length, nondimensional_force) - } -} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/py.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/py.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.jl b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs b/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs deleted file mode 100644 index 21334b33..00000000 --- a/src/physics/single_chain/wlc/thermodynamics/isotensional/test.rs +++ /dev/null @@ -1,921 +0,0 @@ -#![cfg(test)] -use super::*; -use crate::physics::single_chain::test::Parameters; -mod base -{ - use super::*; - use rand::Rng; - #[test] - fn init() - { - let parameters = Parameters::default(); - let _ = WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference); - } - #[test] - fn number_of_links() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - assert_eq!(number_of_links, WLC::init(number_of_links, parameters.link_length_reference, parameters.hinge_mass_reference, parameters.persistance_length_reference).number_of_links); - } - } - #[test] - fn link_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - assert_eq!(link_length, WLC::init(parameters.number_of_links_minimum, link_length, parameters.hinge_mass_reference, parameters.persistance_length_reference).link_length); - } - } - #[test] - fn hinge_mass() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - assert_eq!(hinge_mass, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, hinge_mass, parameters.persistance_length_reference).hinge_mass); - } - } - #[test] - fn persistance_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - assert_eq!(persistance_length, WLC::init(parameters.number_of_links_minimum, parameters.link_length_reference, parameters.hinge_mass_reference, persistance_length).persistance_length); - } - } - #[test] - fn all_parameters() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - assert_eq!(number_of_links, model.number_of_links); - assert_eq!(link_length, model.link_length); - assert_eq!(hinge_mass, model.hinge_mass); - assert_eq!(persistance_length, model.persistance_length); - } - } -} -mod nondimensional -{ - use super::*; - use rand::Rng; - #[test] - fn end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length = model.end_to_end_length(&force, &temperature); - let residual_abs = &end_to_end_length/link_length - &nondimensional_end_to_end_length; - let residual_rel = &residual_abs/&nondimensional_end_to_end_length; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn end_to_end_length_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); - let residual_abs = &end_to_end_length_per_link/link_length - &nondimensional_end_to_end_length_per_link; - let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn gibbs_free_energy() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); - let residual_abs = &gibbs_free_energy/BOLTZMANN_CONSTANT/temperature - &nondimensional_gibbs_free_energy; - let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn gibbs_free_energy_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); - let residual_abs = &gibbs_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - &nondimensional_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn relative_gibbs_free_energy() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); - let residual_abs = &relative_gibbs_free_energy/BOLTZMANN_CONSTANT/temperature - &nondimensional_relative_gibbs_free_energy; - let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn relative_gibbs_free_energy_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); - let residual_abs = &relative_gibbs_free_energy_per_link/BOLTZMANN_CONSTANT/temperature - &nondimensional_relative_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } -} -mod per_link -{ - use super::*; - use rand::Rng; - #[test] - fn end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length = model.end_to_end_length(&force, &temperature); - let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); - let residual_abs = &end_to_end_length/(number_of_links as f64) - &end_to_end_length_per_link; - let residual_rel = &residual_abs/&end_to_end_length_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn nondimensional_end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); - let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); - let residual_abs = &nondimensional_end_to_end_length/(number_of_links as f64) - &nondimensional_end_to_end_length_per_link; - let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn gibbs_free_energy() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); - let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); - let residual_abs = &gibbs_free_energy/(number_of_links as f64) - &gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&gibbs_free_energy_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn relative_gibbs_free_energy() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); - let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); - let residual_abs = &relative_gibbs_free_energy/(number_of_links as f64) - &relative_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&relative_gibbs_free_energy_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn nondimensional_gibbs_free_energy() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); - let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); - let residual_abs = &nondimensional_gibbs_free_energy/(number_of_links as f64) - &nondimensional_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn nondimensional_relative_gibbs_free_energy() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); - let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); - let residual_abs = &nondimensional_relative_gibbs_free_energy/(number_of_links as f64) - &nondimensional_relative_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } -} -mod relative -{ - use super::*; - use crate::physics::single_chain::ZERO; - use rand::Rng; - #[test] - fn gibbs_free_energy() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); - let gibbs_free_energy_0 = model.gibbs_free_energy(&ZERO, &temperature); - let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); - let residual_abs = &gibbs_free_energy - &gibbs_free_energy_0 - &relative_gibbs_free_energy; - let residual_rel = &residual_abs/&gibbs_free_energy_0; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn gibbs_free_energy_per_link() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); - let gibbs_free_energy_per_link_0 = model.gibbs_free_energy_per_link(&ZERO, &temperature); - let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); - let residual_abs = &gibbs_free_energy_per_link - &gibbs_free_energy_per_link_0 - &relative_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&gibbs_free_energy_per_link_0; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn nondimensional_gibbs_free_energy() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); - let nondimensional_gibbs_free_energy_0 = model.nondimensional_gibbs_free_energy(&ZERO, &temperature); - let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); - let residual_abs = &nondimensional_gibbs_free_energy - &nondimensional_gibbs_free_energy_0 - &nondimensional_relative_gibbs_free_energy; - let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_0; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } - #[test] - fn nondimensional_gibbs_free_energy_per_link() - { - let parameters = Parameters::default(); - let mut rng = rand::thread_rng(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); - let nondimensional_gibbs_free_energy_per_link_0 = model.nondimensional_gibbs_free_energy_per_link(&ZERO, &temperature); - let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); - let residual_abs = &nondimensional_gibbs_free_energy_per_link - &nondimensional_gibbs_free_energy_per_link_0 - &nondimensional_relative_gibbs_free_energy_per_link; - let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link_0; - assert!(residual_abs.abs() <= parameters.abs_tol); - assert!(residual_rel.abs() <= parameters.rel_tol); - } - } -} -mod zero -{ - use super::*; - use crate::physics::single_chain::ZERO; - use rand::Rng; - #[test] - fn end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let end_to_end_length_0 = model.end_to_end_length(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); - assert!(end_to_end_length_0.abs() <= ZERO*(number_of_links as f64)*link_length); - } - } - #[test] - fn end_to_end_length_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let end_to_end_length_per_link_0 = model.end_to_end_length_per_link(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); - assert!(end_to_end_length_per_link_0.abs() <= ZERO*link_length); - } - } - #[test] - fn nondimensional_end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_end_to_end_length_0 = model.nondimensional_end_to_end_length(&ZERO); - assert!(nondimensional_end_to_end_length_0.abs() <= ZERO*(number_of_links as f64)); - } - } - #[test] - fn nondimensional_end_to_end_length_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_end_to_end_length_per_link_0 = model.nondimensional_end_to_end_length_per_link(&ZERO); - assert!(nondimensional_end_to_end_length_per_link_0.abs() <= ZERO); - } - } - #[test] - fn relative_gibbs_free_energy() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let relative_gibbs_free_energy_0 = model.relative_gibbs_free_energy(&ZERO, &temperature); - assert!(relative_gibbs_free_energy_0.abs() <= ZERO); - } - } - #[test] - fn relative_gibbs_free_energy_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let relative_gibbs_free_energy_per_link_0 = model.relative_gibbs_free_energy_per_link(&ZERO, &temperature); - assert!(relative_gibbs_free_energy_per_link_0.abs() <= ZERO); - } - } - #[test] - fn nondimensional_relative_gibbs_free_energy() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_relative_gibbs_free_energy_0 = model.nondimensional_relative_gibbs_free_energy(&ZERO); - assert!(nondimensional_relative_gibbs_free_energy_0.abs() <= ZERO); - } - } - #[test] - fn nondimensional_relative_gibbs_free_energy_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_relative_gibbs_free_energy_per_link_0 = model.nondimensional_relative_gibbs_free_energy_per_link(&ZERO); - assert!(nondimensional_relative_gibbs_free_energy_per_link_0.abs() <= ZERO); - } - } -} -mod connection -{ - use super::*; - use rand::Rng; - #[test] - fn end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length = model.end_to_end_length(&force, &temperature); - let h = parameters.rel_tol*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length_from_derivative = -(model.relative_gibbs_free_energy(&(force + 0.5*h), &temperature) - model.relative_gibbs_free_energy(&(force - 0.5*h), &temperature))/h; - let residual_abs = &end_to_end_length - &end_to_end_length_from_derivative; - let residual_rel = &residual_abs/&end_to_end_length; - assert!(residual_rel.abs() <= h); - } - } - #[test] - fn end_to_end_length_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); - let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); - let h = parameters.rel_tol*BOLTZMANN_CONSTANT*temperature/link_length; - let end_to_end_length_per_link_from_derivative = -(model.relative_gibbs_free_energy_per_link(&(force + 0.5*h), &temperature) - model.relative_gibbs_free_energy_per_link(&(force - 0.5*h), &temperature))/h; - let residual_abs = &end_to_end_length_per_link - &end_to_end_length_per_link_from_derivative; - let residual_rel = &residual_abs/&end_to_end_length_per_link; - assert!(residual_rel.abs() <= h); - } - } - #[test] - fn nondimensional_end_to_end_length() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); - let h = parameters.rel_tol; - let nondimensional_end_to_end_length_from_derivative = -(model.nondimensional_relative_gibbs_free_energy(&(nondimensional_force + 0.5*h)) - model.nondimensional_relative_gibbs_free_energy(&(nondimensional_force - 0.5*h)))/h; - let residual_abs = &nondimensional_end_to_end_length - &nondimensional_end_to_end_length_from_derivative; - let residual_rel = &residual_abs/&nondimensional_end_to_end_length; - assert!(residual_rel.abs() <= h); - } - } - #[test] - fn nondimensional_end_to_end_length_per_link() - { - let mut rng = rand::thread_rng(); - let parameters = Parameters::default(); - for _ in 0..parameters.number_of_loops - { - let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); - let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); - let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); - let persistance_length = parameters.persistance_length_reference + parameters.persistance_length_scale*(0.5 - rng.gen::()); - let model = WLC::init(number_of_links, link_length, hinge_mass, persistance_length); - let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); - let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); - let h = parameters.rel_tol; - let nondimensional_end_to_end_length_per_link_from_derivative = -(model.nondimensional_relative_gibbs_free_energy_per_link(&(nondimensional_force + 0.5*h)) - model.nondimensional_relative_gibbs_free_energy_per_link(&(nondimensional_force - 0.5*h)))/h; - let residual_abs = &nondimensional_end_to_end_length_per_link - &nondimensional_end_to_end_length_per_link_from_derivative; - let residual_rel = &residual_abs/&nondimensional_end_to_end_length_per_link; - assert!(residual_rel.abs() <= h); - } - } -} -// mod legendre -// { -// use super::*; -// use crate::physics::single_chain::ZERO; -// use rand::Rng; -// #[test] -// fn gibbs_free_energy() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; -// let end_to_end_length = model.end_to_end_length(&force, &temperature); -// let gibbs_free_energy = model.gibbs_free_energy(&force, &temperature); -// let gibbs_free_energy_legendre = model.legendre.helmholtz_free_energy(&force, &temperature) - force*end_to_end_length; -// let residual_abs = &gibbs_free_energy - &gibbs_free_energy_legendre; -// let residual_rel = &residual_abs/&gibbs_free_energy; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn gibbs_free_energy_per_link() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; -// let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); -// let gibbs_free_energy_per_link = model.gibbs_free_energy_per_link(&force, &temperature); -// let gibbs_free_energy_per_link_legendre = model.legendre.helmholtz_free_energy_per_link(&force, &temperature) - force*end_to_end_length_per_link; -// let residual_abs = &gibbs_free_energy_per_link - &gibbs_free_energy_per_link_legendre; -// let residual_rel = &residual_abs/&gibbs_free_energy_per_link; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn relative_gibbs_free_energy() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; -// let end_to_end_length = model.end_to_end_length(&force, &temperature); -// let end_to_end_length_0 = model.end_to_end_length(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); -// let relative_gibbs_free_energy = model.relative_gibbs_free_energy(&force, &temperature); -// let relative_gibbs_free_energy_legendre = model.legendre.relative_helmholtz_free_energy(&force, &temperature) - force*end_to_end_length + ZERO*BOLTZMANN_CONSTANT*temperature/link_length*end_to_end_length_0; -// let residual_abs = &relative_gibbs_free_energy - &relative_gibbs_free_energy_legendre; -// let residual_rel = &residual_abs/&relative_gibbs_free_energy; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn relative_gibbs_free_energy_per_link() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; -// let end_to_end_length_per_link = model.end_to_end_length_per_link(&force, &temperature); -// let end_to_end_length_per_link_0 = model.end_to_end_length_per_link(&(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), &temperature); -// let relative_gibbs_free_energy_per_link = model.relative_gibbs_free_energy_per_link(&force, &temperature); -// let relative_gibbs_free_energy_per_link_legendre = model.legendre.relative_helmholtz_free_energy_per_link(&force, &temperature) - force*end_to_end_length_per_link + ZERO*BOLTZMANN_CONSTANT*temperature/link_length*end_to_end_length_per_link_0; -// let residual_abs = &relative_gibbs_free_energy_per_link - &relative_gibbs_free_energy_per_link_legendre; -// let residual_rel = &residual_abs/&relative_gibbs_free_energy_per_link; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn nondimensional_gibbs_free_energy() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); -// let nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy(&nondimensional_force, &temperature); -// let nondimensional_gibbs_free_energy_legendre = model.legendre.nondimensional_helmholtz_free_energy(&nondimensional_force, &temperature) - nondimensional_force*nondimensional_end_to_end_length; -// let residual_abs = &nondimensional_gibbs_free_energy - &nondimensional_gibbs_free_energy_legendre; -// let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn nondimensional_gibbs_free_energy_per_link() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); -// let nondimensional_gibbs_free_energy_per_link = model.nondimensional_gibbs_free_energy_per_link(&nondimensional_force, &temperature); -// let nondimensional_gibbs_free_energy_per_link_legendre = model.legendre.nondimensional_helmholtz_free_energy_per_link(&nondimensional_force, &temperature) - nondimensional_force*nondimensional_end_to_end_length_per_link; -// let residual_abs = &nondimensional_gibbs_free_energy_per_link - &nondimensional_gibbs_free_energy_per_link_legendre; -// let residual_rel = &residual_abs/&nondimensional_gibbs_free_energy_per_link; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn nondimensional_relative_gibbs_free_energy() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let nondimensional_end_to_end_length = model.nondimensional_end_to_end_length(&nondimensional_force); -// let nondimensional_end_to_end_length_0 = model.nondimensional_end_to_end_length(&ZERO); -// let nondimensional_relative_gibbs_free_energy = model.nondimensional_relative_gibbs_free_energy(&nondimensional_force); -// let nondimensional_relative_gibbs_free_energy_legendre = model.legendre.nondimensional_relative_helmholtz_free_energy(&nondimensional_force) - nondimensional_force*nondimensional_end_to_end_length + ZERO*nondimensional_end_to_end_length_0; -// let residual_abs = &nondimensional_relative_gibbs_free_energy - &nondimensional_relative_gibbs_free_energy_legendre; -// let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// #[test] -// fn nondimensional_relative_gibbs_free_energy_per_link() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let nondimensional_end_to_end_length_per_link = model.nondimensional_end_to_end_length_per_link(&nondimensional_force); -// let nondimensional_end_to_end_length_per_link_0 = model.nondimensional_end_to_end_length_per_link(&ZERO); -// let nondimensional_relative_gibbs_free_energy_per_link = model.nondimensional_relative_gibbs_free_energy_per_link(&nondimensional_force); -// let nondimensional_relative_gibbs_free_energy_per_link_legendre = model.legendre.nondimensional_relative_helmholtz_free_energy_per_link(&nondimensional_force) - nondimensional_force*nondimensional_end_to_end_length_per_link + ZERO*nondimensional_end_to_end_length_per_link_0; -// let residual_abs = &nondimensional_relative_gibbs_free_energy_per_link - &nondimensional_relative_gibbs_free_energy_per_link_legendre; -// let residual_rel = &residual_abs/&nondimensional_relative_gibbs_free_energy_per_link; -// assert!(residual_abs.abs() <= parameters.abs_tol); -// assert!(residual_rel.abs() <= parameters.rel_tol); -// } -// } -// } -// mod legendre_connection -// { -// use super::*; -// use rand::Rng; -// #[test] -// fn force() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let temperature = parameters.temperature_reference + parameters.temperature_scale*(0.5 - rng.gen::()); -// let force = nondimensional_force*BOLTZMANN_CONSTANT*temperature/link_length; -// let h = parameters.rel_tol*BOLTZMANN_CONSTANT*temperature/link_length; -// let force_from_derivative = (model.legendre.relative_helmholtz_free_energy(&(force + 0.5*h), &temperature) - model.legendre.relative_helmholtz_free_energy(&(force - 0.5*h), &temperature))/(model.end_to_end_length(&(force + 0.5*h), &temperature) - model.end_to_end_length(&(force - 0.5*h), &temperature)); -// let residual_abs = &force - &force_from_derivative; -// let residual_rel = &residual_abs/&force; -// assert!(residual_rel.abs() <= h); -// } -// } -// #[test] -// fn nondimensional_force() -// { -// let mut rng = rand::thread_rng(); -// let parameters = Parameters::default(); -// for _ in 0..parameters.number_of_loops -// { -// let number_of_links: u8 = rng.gen_range(parameters.number_of_links_minimum..parameters.number_of_links_maximum); -// let link_length = parameters.link_length_reference + parameters.link_length_scale*(0.5 - rng.gen::()); -// let hinge_mass = parameters.hinge_mass_reference + parameters.hinge_mass_scale*(0.5 - rng.gen::()); -// let model = FJC::init(number_of_links, link_length, hinge_mass); -// let nondimensional_force = parameters.nondimensional_force_reference + 0.5*parameters.nondimensional_force_scale*(0.5 - rng.gen::()); -// let h = parameters.rel_tol; -// let nondimensional_force_from_derivative = (model.legendre.nondimensional_relative_helmholtz_free_energy_per_link(&(nondimensional_force + 0.5*h)) - model.legendre.nondimensional_relative_helmholtz_free_energy_per_link(&(nondimensional_force - 0.5*h)))/(model.nondimensional_end_to_end_length_per_link(&(nondimensional_force + 0.5*h)) - model.nondimensional_end_to_end_length_per_link(&(nondimensional_force - 0.5*h))); -// let residual_abs = &nondimensional_force - &nondimensional_force_from_derivative; -// let residual_rel = &residual_abs/&nondimensional_force; -// assert!(residual_rel.abs() <= h); -// } -// } -// } \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/mod.rs b/src/physics/single_chain/wlc/thermodynamics/mod.rs index ecf72d43..39a0375e 100644 --- a/src/physics/single_chain/wlc/thermodynamics/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/mod.rs @@ -6,9 +6,6 @@ mod test; /// The worm-like chain (WLC) model thermodynamics in the isometric ensemble. pub mod isometric; -/// The worm-like chain (WLC) model thermodynamics in the isotensional ensemble. -pub mod isotensional; - /// The structure of the thermodynamics of the WLC model. pub struct WLC { @@ -25,10 +22,7 @@ pub struct WLC pub persistance_length: f64, /// The thermodynamic functions of the model in the isometric ensemble. - pub isometric: self::isometric::WLC, - - /// The thermodynamic functions of the model in the isotensional ensemble. - pub isotensional: self::isotensional::WLC + pub isometric: self::isometric::WLC } /// The implemented functionality of the thermodynamics of the WLC model. @@ -43,8 +37,7 @@ impl WLC link_length, number_of_links, persistance_length, - isometric: self::isometric::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), - isotensional: self::isotensional::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) + isometric: self::isometric::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) } } } From a00017b2f9b5e0980de30f15580bcc956d2bad0a Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 1 May 2023 10:53:22 -0600 Subject: [PATCH 18/21] py --- src/physics/single_chain/mod.jl | 1 + src/physics/single_chain/py.rs | 1 + src/physics/single_chain/wlc/py.rs | 52 + src/physics/single_chain/wlc/test.py | 143 + .../thermodynamics/isometric/legendre/py.rs | 163 ++ .../thermodynamics/isometric/legendre/test.py | 1057 +++++++ .../wlc/thermodynamics/isometric/mod.rs | 2 +- .../wlc/thermodynamics/isometric/py.rs | 273 ++ .../wlc/thermodynamics/isometric/test.py | 2434 +++++++++++++++++ .../single_chain/wlc/thermodynamics/py.rs | 53 + .../single_chain/wlc/thermodynamics/test.py | 143 + 11 files changed, 4321 insertions(+), 1 deletion(-) create mode 100644 src/physics/single_chain/wlc/test.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/isometric/test.py create mode 100644 src/physics/single_chain/wlc/thermodynamics/test.py diff --git a/src/physics/single_chain/mod.jl b/src/physics/single_chain/mod.jl index 254647b2..86beee54 100644 --- a/src/physics/single_chain/mod.jl +++ b/src/physics/single_chain/mod.jl @@ -110,5 +110,6 @@ include("fjc/mod.jl") include("efjc/mod.jl") include("swfjc/mod.jl") include("ufjc/mod.jl") +include("wlc/mod.jl") end diff --git a/src/physics/single_chain/py.rs b/src/physics/single_chain/py.rs index bf845446..60066ea6 100644 --- a/src/physics/single_chain/py.rs +++ b/src/physics/single_chain/py.rs @@ -8,6 +8,7 @@ pub fn register_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> super::efjc::py::register_module(py, single_chain)?; super::swfjc::py::register_module(py, single_chain)?; super::ufjc::py::register_module(py, single_chain)?; + super::wlc::py::register_module(py, single_chain)?; parent_module.add_submodule(single_chain)?; Ok(()) } diff --git a/src/physics/single_chain/wlc/py.rs b/src/physics/single_chain/wlc/py.rs index e69de29b..5eb7facb 100644 --- a/src/physics/single_chain/wlc/py.rs +++ b/src/physics/single_chain/wlc/py.rs @@ -0,0 +1,52 @@ +use pyo3::prelude::*; + +pub fn register_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> +{ + let wlc = PyModule::new(py, "wlc")?; + super::thermodynamics::py::register_module(py, wlc)?; + parent_module.add_submodule(wlc)?; + wlc.add_class::()?; + Ok(()) +} + +/// The worm-like chain (WLC) model. +#[pyclass] +pub struct WLC +{ + /// The mass of each hinge in the chain in units of kg/mol. + #[pyo3(get)] + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + #[pyo3(get)] + pub link_length: f64, + + /// The number of links in the chain. + #[pyo3(get)] + pub number_of_links: u8, + + /// The persistance length of the chain in units of nm. + #[pyo3(get)] + pub persistance_length: f64, + + /// The thermodynamic functions of the model. + #[pyo3(get)] + pub thermodynamics: super::thermodynamics::py::WLC +} + +#[pymethods] +impl WLC +{ + #[new] + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self + { + WLC + { + hinge_mass, + link_length, + number_of_links, + persistance_length, + thermodynamics: super::thermodynamics::py::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) + } + } +} diff --git a/src/physics/single_chain/wlc/test.py b/src/physics/single_chain/wlc/test.py new file mode 100644 index 00000000..d4ba5d79 --- /dev/null +++ b/src/physics/single_chain/wlc/test.py @@ -0,0 +1,143 @@ +"""Module to test the local module. + +""" +import unittest +import numpy as np +from polymers import physics +from ..test import Parameters + +parameters = Parameters() +WLC = physics.single_chain.wlc.WLC + + +class Base(unittest.TestCase): + """Class for basic tests. + + """ + def test_init(self): + """Function to test instantiation. + + """ + for _ in range(parameters.number_of_loops): + _ = WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ) + + def test_number_of_links(self): + """Function to test the number of links during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + self.assertEqual( + number_of_links, + WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).number_of_links + ) + + def test_link_length(self): + """Function to test the link length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + link_length, + WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).link_length + ) + + def test_hinge_mass(self): + """Function to test the hinge mass during instantiation. + + """ + for _ in range(parameters.number_of_loops): + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + self.assertEqual( + hinge_mass, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference + ).hinge_mass + ) + + def test_persistance_length(self): + """Function to test the persistance length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + persistance_length, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length + ).persistance_length + ) + + def test_all_parameters(self): + """Function to test all parameters during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + self.assertEqual( + number_of_links, + model.number_of_links + ) + self.assertEqual( + link_length, + model.link_length + ) + self.assertEqual( + hinge_mass, + model.hinge_mass + ) + self.assertEqual( + persistance_length, + model.persistance_length + ) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs index e69de29b..7b5ccd44 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/py.rs @@ -0,0 +1,163 @@ +use pyo3::prelude::*; +use numpy:: +{ + IntoPyArray, + PyArrayDyn, + PyReadonlyArrayDyn +}; + +pub fn register_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> +{ + let legendre = PyModule::new(py, "legendre")?; + parent_module.add_submodule(legendre)?; + legendre.add_class::()?; + Ok(()) +} + +/// The worm-like chain (WLC) model thermodynamics in the isometric ensemble approximated using a Legendre transformation. +#[pyclass] +#[derive(Copy, Clone)] +pub struct WLC +{ + /// The mass of each hinge in the chain in units of kg/mol. + #[pyo3(get)] + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + #[pyo3(get)] + pub link_length: f64, + + /// The number of links in the chain. + #[pyo3(get)] + pub number_of_links: u8, + + /// The persistance length of the chain in units of nm. + #[pyo3(get)] + pub persistance_length: f64, + + nondimensional_persistance_length: f64 +} + +#[pymethods] +impl WLC +{ + #[new] + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self + { + WLC + { + hinge_mass, + link_length, + number_of_links, + persistance_length, + nondimensional_persistance_length: persistance_length/(number_of_links as f64)/link_length + } + } + /// The Gibbs free energy as a function of the applied end-to-end length and temperature, + /// + /// .. math:: + /// \varphi(\xi, T) \sim \psi(\xi, T) - \xi f(\xi, T) \quad \text{for } N_b\gg 1, + /// + /// where :math:`f(\xi, T)` is given by the Legendre transformation approximation above. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The Gibbs free energy :math:`\varphi`. + /// + pub fn gibbs_free_energy<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The Gibbs free energy per link as a function of the applied end-to-end length and temperature. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The Gibbs free energy per link :math:`\varphi/N_b`. + /// + pub fn gibbs_free_energy_per_link<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The relative Gibbs free energy as a function of the applied end-to-end length and temperature. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The relative Gibbs free energy :math:`\Delta\varphi\equiv\varphi(\xi,T)-\varphi(0,T)`. + /// + pub fn relative_gibbs_free_energy<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::relative_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The relative Gibbs free energy per link as a function of the applied end-to-end length and temperature. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The relative Gibbs free energy per link :math:`\Delta\varphi/N_b`. + /// + pub fn relative_gibbs_free_energy_per_link<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::relative_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The nondimensional Gibbs free energy as a function of the applied nondimensional end-to-end length per link and temperature. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional Gibbs free energy :math:`N_b\varrho=\beta\varphi`. + /// + pub fn nondimensional_gibbs_free_energy<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_gibbs_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature)).into_pyarray(py) + } + /// The nondimensional Gibbs free energy per link as a function of the applied nondimensional end-to-end length per link and temperature. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional Gibbs free energy per link :math:`\varrho\equiv\beta\varphi/N_b`. + /// + pub fn nondimensional_gibbs_free_energy_per_link<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_gibbs_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature)).into_pyarray(py) + } + /// The nondimensional relative Gibbs free energy as a function of the applied nondimensional end-to-end length per link. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional relative Gibbs free energy :math:`\beta\Delta\varphi=N_b\Delta\varrho`. + /// + pub fn nondimensional_relative_gibbs_free_energy<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_relative_gibbs_free_energy(&self.number_of_links, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } + /// The nondimensional relative Gibbs free energy per link as a function of the applied nondimensional end-to-end length per link. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional relative Gibbs free energy per link :math:`\Delta\varrho\equiv\beta\Delta\varphi/N_b`. + /// + pub fn nondimensional_relative_gibbs_free_energy_per_link<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_relative_gibbs_free_energy_per_link(&self.number_of_links, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.py b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.py new file mode 100644 index 00000000..833a6b2e --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.py @@ -0,0 +1,1057 @@ +"""Module to test the local module. + +""" +import unittest +import numpy as np +from polymers import physics +from ..test import Parameters + +parameters = Parameters() +WLC = physics.single_chain.wlc.thermodynamics.isometric.legendre.WLC + + +class Base(unittest.TestCase): + """Class for basic tests. + + """ + def test_init(self): + """Function to test instantiation. + + """ + for _ in range(parameters.number_of_loops): + _ = WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ) + + def test_number_of_links(self): + """Function to test the number of links during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + self.assertEqual( + number_of_links, + WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).number_of_links + ) + + def test_link_length(self): + """Function to test the link length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + link_length, + WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).link_length + ) + + def test_hinge_mass(self): + """Function to test the hinge mass during instantiation. + + """ + for _ in range(parameters.number_of_loops): + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + self.assertEqual( + hinge_mass, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference + ).hinge_mass + ) + + def test_persistance_length(self): + """Function to test the persistance length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + persistance_length, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length + ).persistance_length + ) + + def test_all_parameters(self): + """Function to test all parameters during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + self.assertEqual( + number_of_links, + model.number_of_links + ) + self.assertEqual( + link_length, + model.link_length + ) + self.assertEqual( + hinge_mass, + model.hinge_mass + ) + self.assertEqual( + persistance_length, + model.persistance_length + ) + + +class Nondimensional(unittest.TestCase): + """Class for nondimensionalization tests. + + """ + def test_gibbs_free_energy(self): + """Function to test the nondimensionalization + of the Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_gibbs_free_energy = \ + model.nondimensional_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + gibbs_free_energy = \ + model.gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + gibbs_free_energy / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_gibbs_free_energy + residual_rel = \ + residual_abs / \ + nondimensional_gibbs_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_gibbs_free_energy_per_link(self): + """Function to test the nondimensionalization + of the Gibbs free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_gibbs_free_energy_per_link = \ + model.nondimensional_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + gibbs_free_energy_per_link = \ + model.gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + gibbs_free_energy_per_link / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_gibbs_free_energy(self): + """Function to test the nondimensionalization + of the relative Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_relative_gibbs_free_energy = \ + model.nondimensional_relative_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_gibbs_free_energy = \ + model.relative_gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + relative_gibbs_free_energy / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_relative_gibbs_free_energy + residual_rel = \ + residual_abs / \ + nondimensional_relative_gibbs_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_gibbs_free_energy_per_link(self): + """Function to test the nondimensionalization + of the relative Gibbs free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_relative_gibbs_free_energy_per_link = \ + model.nondimensional_relative_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_gibbs_free_energy_per_link = \ + model.relative_gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + relative_gibbs_free_energy_per_link / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_relative_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_relative_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class PerLink(unittest.TestCase): + """Class for per-linkness tests. + + """ + def test_gibbs_free_energy(self): + """Function to test the per-linkness + of the Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + gibbs_free_energy = \ + model.gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + gibbs_free_energy_per_link = \ + model.gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + gibbs_free_energy / \ + number_of_links \ + - gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_gibbs_free_energy(self): + """Function to test the per-linkness + of the relative Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_gibbs_free_energy = \ + model.relative_gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + relative_gibbs_free_energy_per_link = \ + model.relative_gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + relative_gibbs_free_energy / \ + number_of_links \ + - relative_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + relative_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_gibbs_free_energy(self): + """Function to test the per-linkness + of the nondimensional Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_gibbs_free_energy = \ + model.nondimensional_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_gibbs_free_energy_per_link = \ + model.nondimensional_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + residual_abs = \ + nondimensional_gibbs_free_energy / \ + number_of_links \ + - nondimensional_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_relative_gibbs_free_energy(self): + """Function to test the per-linkness + of the nondimensional relative Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_relative_gibbs_free_energy = \ + model.nondimensional_relative_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_relative_gibbs_free_energy_per_link = \ + model.nondimensional_relative_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + residual_abs = \ + nondimensional_relative_gibbs_free_energy / \ + number_of_links \ + - nondimensional_relative_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_relative_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class Relative(unittest.TestCase): + """Class for relativeness tests. + + """ + def test_gibbs_free_energy(self): + """Function to test the relativeness + of the Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + gibbs_free_energy = \ + model.gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + gibbs_free_energy_0 = \ + model.gibbs_free_energy( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + relative_gibbs_free_energy = \ + model.relative_gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + gibbs_free_energy \ + - gibbs_free_energy_0 \ + - relative_gibbs_free_energy + residual_rel = \ + residual_abs / \ + relative_gibbs_free_energy + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_gibbs_free_energy_per_link(self): + """Function to test the relativeness + of the Gibbs free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + gibbs_free_energy_per_link = \ + model.gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + gibbs_free_energy_per_link_0 = \ + model.gibbs_free_energy_per_link( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + relative_gibbs_free_energy_per_link = \ + model.relative_gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + gibbs_free_energy_per_link \ + - gibbs_free_energy_per_link_0 \ + - relative_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + relative_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_gibbs_free_energy(self): + """Function to test the relativeness + of the nondimensional Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_gibbs_free_energy = \ + model.nondimensional_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_gibbs_free_energy_0 = \ + model.nondimensional_gibbs_free_energy( + np.array(parameters.zero), + temperature + ) + nondimensional_relative_gibbs_free_energy = \ + model.nondimensional_relative_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + residual_abs = \ + nondimensional_gibbs_free_energy \ + - nondimensional_gibbs_free_energy_0 \ + - nondimensional_relative_gibbs_free_energy + residual_rel = \ + residual_abs / \ + nondimensional_relative_gibbs_free_energy + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_gibbs_free_energy_per_link(self): + """Function to test the relativeness + of the nondimensional Gibbs free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_gibbs_free_energy_per_link = \ + model.nondimensional_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_gibbs_free_energy_per_link_0 = \ + model.nondimensional_gibbs_free_energy_per_link( + np.array(parameters.zero), + temperature + ) + nondimensional_relative_gibbs_free_energy_per_link = \ + model.nondimensional_relative_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + residual_abs = \ + nondimensional_gibbs_free_energy_per_link \ + - nondimensional_gibbs_free_energy_per_link_0 \ + - nondimensional_relative_gibbs_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_relative_gibbs_free_energy_per_link + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class Zero(unittest.TestCase): + """Class for zero tests. + + """ + def test_relative_gibbs_free_energy(self): + """Function to test the zero + of the relative Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + relative_gibbs_free_energy_0 = \ + model.relative_gibbs_free_energy( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + self.assertLessEqual( + np.abs(relative_gibbs_free_energy_0), + parameters.boltzmann_constant*temperature * + number_of_links*parameters.zero + ) + + def test_relative_gibbs_free_energy_per_link(self): + """Function to test the zero + of the relative Gibbs free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + relative_gibbs_free_energy_per_link_0 = \ + model.relative_gibbs_free_energy_per_link( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + self.assertLessEqual( + np.abs(relative_gibbs_free_energy_per_link_0), + parameters.boltzmann_constant*temperature * + parameters.zero + ) + + def test_nondimensional_relative_gibbs_free_energy(self): + """Function to test the zero + of the nondimensional relative Gibbs free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_relative_gibbs_free_energy_0 = \ + model.nondimensional_relative_gibbs_free_energy( + np.array(parameters.zero) + ) + self.assertLessEqual( + np.abs(nondimensional_relative_gibbs_free_energy_0), + number_of_links*parameters.zero + ) + + def test_nondimensional_relative_gibbs_free_energy_per_link(self): + """Function to test the zero + of the nondimensional relative Gibbs free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_relative_gibbs_free_energy_per_link_0 = \ + model.nondimensional_relative_gibbs_free_energy_per_link( + np.array(parameters.zero) + ) + self.assertLessEqual( + np.abs( + nondimensional_relative_gibbs_free_energy_per_link_0 + ), parameters.zero + ) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs index 63bf29bb..38cd517e 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.rs @@ -206,7 +206,7 @@ impl WLC persistance_length, nondimensional_persistance_length, normalization_nondimensional_equilibrium_distribution, - legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length), + legendre: self::legendre::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) } } /// The expected force as a function of the applied end-to-end length and temperature. diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/py.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/py.rs index e69de29b..27823e29 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/py.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/py.rs @@ -0,0 +1,273 @@ +use pyo3::prelude::*; +use numpy:: +{ + IntoPyArray, + PyArrayDyn, + PyReadonlyArrayDyn +}; +use crate::math::integrate_1d; +use crate::physics::single_chain:: +{ + ONE, + ZERO, + POINTS +}; + +pub fn register_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> +{ + let isometric = PyModule::new(py, "isometric")?; + super::legendre::py::register_module(py, isometric)?; + parent_module.add_submodule(isometric)?; + isometric.add_class::()?; + Ok(()) +} + +/// The worm-like chain (WLC) model thermodynamics in the isometric ensemble. +#[pyclass] +#[derive(Copy, Clone)] +pub struct WLC +{ + /// The mass of each hinge in the chain in units of kg/mol. + #[pyo3(get)] + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + #[pyo3(get)] + pub link_length: f64, + + /// The number of links in the chain. + #[pyo3(get)] + pub number_of_links: u8, + + /// The persistance length of the chain in units of nm. + #[pyo3(get)] + pub persistance_length: f64, + + nondimensional_persistance_length: f64, + + normalization_nondimensional_equilibrium_distribution: f64, + + /// The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. + #[pyo3(get)] + pub legendre: super::legendre::py::WLC +} + +#[pymethods] +impl WLC +{ + #[new] + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self + { + let nondimensional_persistance_length = persistance_length/(number_of_links as f64)/link_length; + let normalization_nondimensional_equilibrium_distribution = integrate_1d(&|nondimensional_end_to_end_length_per_link: &f64| super::nondimensional_equilibrium_radial_distribution(&nondimensional_persistance_length, &1.0, nondimensional_end_to_end_length_per_link), &ZERO, &ONE, &POINTS); + WLC + { + hinge_mass, + link_length, + number_of_links, + persistance_length, + nondimensional_persistance_length, + normalization_nondimensional_equilibrium_distribution, + legendre: super::legendre::py::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) + } + } + /// The expected force as a function of the applied end-to-end length and temperature. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The force :math:`f`. + /// + pub fn force<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::force(&self.number_of_links, &self.link_length, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The expected nondimensional force as a function of the applied nondimensional end-to-end length per link. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional force :math:`\eta\equiv\beta f\ell_b`. + /// + pub fn nondimensional_force<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_force(&self.number_of_links, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } + /// The Helmholtz free energy as a function of the applied end-to-end length and temperature, + /// + /// .. math:: + /// \psi(\xi, T) = -kT\ln Q(\xi, T). + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The Helmholtz free energy :math:`\psi`. + /// + pub fn helmholtz_free_energy<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The Helmholtz free energy per link as a function of the applied end-to-end length and temperature. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The Helmholtz free energy per link :math:`\psi/N_b`. + /// + pub fn helmholtz_free_energy_per_link<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The relative Helmholtz free energy as a function of the applied end-to-end length and temperature, + /// + /// .. math:: + /// \Delta\psi(\xi, T) = kT\ln\left[\frac{P_\mathrm{eq}(0)}{P_\mathrm{eq}(\xi)}\right]. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The relative Helmholtz free energy :math:`\Delta\psi\equiv\psi(\xi,T)-\psi(0,T)`. + /// + pub fn relative_helmholtz_free_energy<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::relative_helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The relative Helmholtz free energy per link as a function of the applied end-to-end length and temperature. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The relative Helmholtz free energy per link :math:`\Delta\psi/N_b`. + /// + pub fn relative_helmholtz_free_energy_per_link<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::relative_helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.persistance_length, &end_to_end_length, &temperature)).into_pyarray(py) + } + /// The nondimensional Helmholtz free energy as a function of the applied nondimensional end-to-end length per link and temperature. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional Helmholtz free energy :math:`N_b\vartheta=\beta\psi`. + /// + pub fn nondimensional_helmholtz_free_energy<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_helmholtz_free_energy(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature)).into_pyarray(py) + } + /// The nondimensional Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link and temperature. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// temperature (float): The temperature :math:`T`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional Helmholtz free energy per link :math:`\vartheta\equiv\beta\psi/N_b`. + /// + pub fn nondimensional_helmholtz_free_energy_per_link<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn, temperature: f64) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_helmholtz_free_energy_per_link(&self.number_of_links, &self.link_length, &self.hinge_mass, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature)).into_pyarray(py) + } + /// The nondimensional relative Helmholtz free energy as a function of the applied nondimensional end-to-end length per link, + /// + /// .. math:: + /// \beta\Delta\psi(\gamma) = \ln\left[\frac{\mathscr{P}_\mathrm{eq}(0)}{\mathscr{P}_\mathrm{eq}(\gamma)}\right]. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional relative Helmholtz free energy :math:`N_b\Delta\vartheta=\beta\Delta\psi`. + /// + pub fn nondimensional_relative_helmholtz_free_energy<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_relative_helmholtz_free_energy(&self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } + /// The nondimensional relative Helmholtz free energy per link as a function of the applied nondimensional end-to-end length per link, + /// + /// .. math:: + /// \Delta\vartheta(\gamma) = \ln\left[\frac{\mathscr{P}_\mathrm{eq}(0)}{\mathscr{P}_\mathrm{eq}(\gamma)}\right]^{1/N_b}. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional relative Helmholtz free energy per link :math:`\Delta\vartheta\equiv\beta\Delta\psi/N_b`. + /// + pub fn nondimensional_relative_helmholtz_free_energy_per_link<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_relative_helmholtz_free_energy_per_link(&self.number_of_links, &self.nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } + /// The equilibrium probability density of end-to-end vectors as a function of the end-to-end length, + /// + /// .. math:: + /// P_\mathrm{eq}(\xi) = \frac{e^{-\beta\psi(\xi, T)}}{4\pi\int e^{-\beta\psi(\xi', T)} \,{\xi'}{}^2 d\xi'}. + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// + /// Returns: + /// numpy.ndarray: The equilibrium probability density :math:`P_\mathrm{eq}`. + /// + pub fn equilibrium_distribution<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::equilibrium_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, &self.normalization_nondimensional_equilibrium_distribution, &end_to_end_length)).into_pyarray(py) + } + /// The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link as a function of the nondimensional end-to-end length per link, + /// + /// .. math:: + /// \mathscr{P}_\mathrm{eq}(\gamma) = \frac{e^{-\Delta\vartheta(\gamma)}}{4\pi\int e^{-\Delta\vartheta(\gamma')} \,{\gamma'}{}^2 d\gamma'}. + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional equilibrium probability density :math:`\mathscr{P}_\mathrm{eq}\equiv (N_b\ell_b)^3 P_\mathrm{eq}`. + /// + pub fn nondimensional_equilibrium_distribution<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_equilibrium_distribution(&self.nondimensional_persistance_length, &self.normalization_nondimensional_equilibrium_distribution, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } + /// The equilibrium probability density of end-to-end lengths as a function of the end-to-end length, given by :footcite:t:`treloar1949physics` as + /// + /// .. math:: + /// g_\mathrm{eq}(\xi) = 4\pi\xi^2 P_\mathrm{eq}(\xi). + /// + /// Args: + /// end_to_end_length (numpy.ndarray): The end-to-end length :math:`\xi`. + /// + /// Returns: + /// numpy.ndarray: The equilibrium probability density :math:`g_\mathrm{eq}`. + /// + pub fn equilibrium_radial_distribution<'py>(&self, py: Python<'py>, end_to_end_length: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + end_to_end_length.as_array().mapv(|end_to_end_length: f64| super::equilibrium_radial_distribution(&self.number_of_links, &self.link_length, &self.persistance_length, &self.normalization_nondimensional_equilibrium_distribution, &end_to_end_length)).into_pyarray(py) + } + /// The nondimensional equilibrium probability density of nondimensional end-to-end lengths per link as a function of the nondimensional end-to-end length per link, + /// + /// .. math:: + /// \mathscr{g}_\mathrm{eq}(\gamma) = 4\pi\gamma^2 \mathscr{P}_\mathrm{eq}(\gamma). + /// + /// Args: + /// nondimensional_end_to_end_length_per_link (numpy.ndarray): The nondimensional end-to-end length per link :math:`\gamma\equiv \xi/N_b\ell_b`. + /// + /// Returns: + /// numpy.ndarray: The nondimensional equilibrium probability density :math:`\mathscr{g}_\mathrm{eq}\equiv N_b\ell_b g_\mathrm{eq}`. + /// + pub fn nondimensional_equilibrium_radial_distribution<'py>(&self, py: Python<'py>, nondimensional_end_to_end_length_per_link: PyReadonlyArrayDyn) -> &'py PyArrayDyn + { + nondimensional_end_to_end_length_per_link.as_array().mapv(|nondimensional_end_to_end_length_per_link: f64| super::nondimensional_equilibrium_radial_distribution(&self.nondimensional_persistance_length, &self.normalization_nondimensional_equilibrium_distribution, &nondimensional_end_to_end_length_per_link)).into_pyarray(py) + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.py b/src/physics/single_chain/wlc/thermodynamics/isometric/test.py new file mode 100644 index 00000000..9cdc1ced --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/test.py @@ -0,0 +1,2434 @@ +"""Module to test the local module. + +""" +import unittest +import numpy as np +from polymers import physics +from ..test import Parameters +from ....test import integrate + +parameters = Parameters() +WLC = physics.single_chain.wlc.thermodynamics.isometric.WLC + + +class Base(unittest.TestCase): + """Class for basic tests. + + """ + def test_init(self): + """Function to test instantiation. + + """ + for _ in range(parameters.number_of_loops): + _ = WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ) + + def test_number_of_links(self): + """Function to test the number of links during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + self.assertEqual( + number_of_links, + WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).number_of_links + ) + + def test_link_length(self): + """Function to test the link length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + link_length, + WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).link_length + ) + + def test_hinge_mass(self): + """Function to test the hinge mass during instantiation. + + """ + for _ in range(parameters.number_of_loops): + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + self.assertEqual( + hinge_mass, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference + ).hinge_mass + ) + + def test_persistance_length(self): + """Function to test the persistance length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + persistance_length, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length + ).persistance_length + ) + + def test_all_parameters(self): + """Function to test all parameters during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + self.assertEqual( + number_of_links, + model.number_of_links + ) + self.assertEqual( + link_length, + model.link_length + ) + self.assertEqual( + hinge_mass, + model.hinge_mass + ) + self.assertEqual( + persistance_length, + model.persistance_length + ) + + +class Normalization(unittest.TestCase): + """Class for normalization tests. + + """ + def test_equilibrium_distribution(self): + """Function to test the normalization + of the equilibrium distribution. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + + def integrand(end_to_end_length): + return 4.0*np.pi*end_to_end_length**2 * \ + model.equilibrium_distribution( + end_to_end_length + ) + + integral = integrate( + integrand, + parameters.zero*number_of_links*link_length, + parameters.one*number_of_links*link_length, + parameters.points + ) + self.assertLessEqual( + np.abs(integral - 1.0), + parameters.rel_tol + ) + + def test_nondimensional_equilibrium_distribution(self): + """Function to test the normalization + of the nondimensional equilibrium distribution. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + + def integrand(nondimensional_end_to_end_length_per_link_per_link): + return 4.0*np.pi * \ + nondimensional_end_to_end_length_per_link_per_link**2 * \ + model.nondimensional_equilibrium_distribution( + nondimensional_end_to_end_length_per_link_per_link + ) + + integral = integrate( + integrand, + parameters.zero, + parameters.one, + parameters.points + ) + self.assertLessEqual( + np.abs(integral - 1.0), + parameters.rel_tol + ) + + def test_equilibrium_radial_distribution(self): + """Function to test the normalization + of the equilibrium radial distribution. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + + def integrand(end_to_end_length): + return model.equilibrium_radial_distribution( + end_to_end_length + ) + + integral = integrate( + integrand, + parameters.zero*number_of_links*link_length, + parameters.one*number_of_links*link_length, + parameters.points + ) + self.assertLessEqual( + np.abs(integral - 1.0), + parameters.rel_tol + ) + + def test_nondimensional_equilibrium_radial_distribution(self): + """Function to test the normalization + of the nondimensional equilibrium radial distribution. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + + def integrand(nondimensional_end_to_end_length_per_link_per_link): + return model.nondimensional_equilibrium_radial_distribution( + nondimensional_end_to_end_length_per_link_per_link + ) + + integral = integrate( + integrand, + parameters.zero, + parameters.one, + parameters.points + ) + self.assertLessEqual( + np.abs(integral - 1.0), + parameters.rel_tol + ) + + +class Nondimensional(unittest.TestCase): + """Class for nondimensionalization tests. + + """ + def test_force(self): + """Function to test the nondimensionalization + of the force. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_force = \ + model.nondimensional_force( + np.array(nondimensional_end_to_end_length_per_link) + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + force = \ + model.force( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + force / \ + parameters.boltzmann_constant/temperature*link_length \ + - nondimensional_force + residual_rel = \ + residual_abs / \ + nondimensional_force + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_helmholtz_free_energy(self): + """Function to test the nondimensionalization + of the Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_helmholtz_free_energy = \ + model.nondimensional_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + helmholtz_free_energy = \ + model.helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + helmholtz_free_energy / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_helmholtz_free_energy + residual_rel = \ + residual_abs / \ + nondimensional_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_helmholtz_free_energy_per_link(self): + """Function to test the nondimensionalization + of the Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_helmholtz_free_energy_per_link = \ + model.nondimensional_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + helmholtz_free_energy_per_link = \ + model.helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + helmholtz_free_energy_per_link / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_helmholtz_free_energy(self): + """Function to test the nondimensionalization + of the relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_relative_helmholtz_free_energy = \ + model.nondimensional_relative_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_helmholtz_free_energy = \ + model.relative_helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + relative_helmholtz_free_energy / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_relative_helmholtz_free_energy + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_helmholtz_free_energy_per_link(self): + """Function to test the nondimensionalization + of the relative Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_relative_helmholtz_free_energy_per_link = \ + model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_helmholtz_free_energy_per_link = \ + model.relative_helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + relative_helmholtz_free_energy_per_link / \ + parameters.boltzmann_constant/temperature \ + - nondimensional_relative_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class PerLink(unittest.TestCase): + """Class for per-linkness tests. + + """ + def test_helmholtz_free_energy(self): + """Function to test the per-linkness + of the Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + helmholtz_free_energy = \ + model.helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy_per_link = \ + model.helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + helmholtz_free_energy / \ + number_of_links \ + - helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_helmholtz_free_energy(self): + """Function to test the per-linkness + of the relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_helmholtz_free_energy = \ + model.relative_helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + relative_helmholtz_free_energy_per_link = \ + model.relative_helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + relative_helmholtz_free_energy / \ + number_of_links \ + - relative_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_helmholtz_free_energy(self): + """Function to test the per-linkness + of the nondimensional Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_helmholtz_free_energy = \ + model.nondimensional_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_helmholtz_free_energy_per_link = \ + model.nondimensional_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + residual_abs = \ + nondimensional_helmholtz_free_energy / \ + number_of_links \ + - nondimensional_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_relative_helmholtz_free_energy(self): + """Function to test the per-linkness + of the nondimensional relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_relative_helmholtz_free_energy = \ + model.nondimensional_relative_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_relative_helmholtz_free_energy_per_link = \ + model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + residual_abs = \ + nondimensional_relative_helmholtz_free_energy / \ + number_of_links \ + - nondimensional_relative_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class Relative(unittest.TestCase): + """Class for relativeness tests. + + """ + def test_helmholtz_free_energy(self): + """Function to test the relativeness + of the Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + helmholtz_free_energy = \ + model.helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy_0 = \ + model.helmholtz_free_energy( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + relative_helmholtz_free_energy = \ + model.relative_helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + helmholtz_free_energy \ + - helmholtz_free_energy_0 \ + - relative_helmholtz_free_energy + residual_rel = \ + residual_abs / \ + relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_helmholtz_free_energy_per_link(self): + """Function to test the relativeness + of the Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + helmholtz_free_energy_per_link = \ + model.helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy_per_link_0 = \ + model.helmholtz_free_energy_per_link( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + relative_helmholtz_free_energy_per_link = \ + model.relative_helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + residual_abs = \ + helmholtz_free_energy_per_link \ + - helmholtz_free_energy_per_link_0 \ + - relative_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_helmholtz_free_energy(self): + """Function to test the relativeness + of the nondimensional Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_helmholtz_free_energy = \ + model.nondimensional_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_helmholtz_free_energy_0 = \ + model.nondimensional_helmholtz_free_energy( + np.array(parameters.zero), + temperature + ) + nondimensional_relative_helmholtz_free_energy = \ + model.nondimensional_relative_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + residual_abs = \ + nondimensional_helmholtz_free_energy \ + - nondimensional_helmholtz_free_energy_0 \ + - nondimensional_relative_helmholtz_free_energy + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_helmholtz_free_energy_per_link(self): + """Function to test the relativeness + of the nondimensional Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_helmholtz_free_energy_per_link = \ + model.nondimensional_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_helmholtz_free_energy_per_link_0 = \ + model.nondimensional_helmholtz_free_energy_per_link( + np.array(parameters.zero), + temperature + ) + nondimensional_relative_helmholtz_free_energy_per_link = \ + model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + residual_abs = \ + nondimensional_helmholtz_free_energy_per_link \ + - nondimensional_helmholtz_free_energy_per_link_0 \ + - nondimensional_relative_helmholtz_free_energy_per_link + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class Zero(unittest.TestCase): + """Class for zero tests. + + """ + def test_relative_helmholtz_free_energy(self): + """Function to test the zero + of the relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + relative_helmholtz_free_energy_0 = \ + model.relative_helmholtz_free_energy( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + self.assertLessEqual( + np.abs(relative_helmholtz_free_energy_0), + parameters.boltzmann_constant*temperature * + number_of_links*parameters.zero + ) + + def test_relative_helmholtz_free_energy_per_link(self): + """Function to test the zero + of the relative Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + relative_helmholtz_free_energy_per_link_0 = \ + model.relative_helmholtz_free_energy_per_link( + np.array(parameters.zero*number_of_links*link_length), + temperature + ) + self.assertLessEqual( + np.abs(relative_helmholtz_free_energy_per_link_0), + parameters.boltzmann_constant*temperature * + parameters.zero + ) + + def test_nondimensional_relative_helmholtz_free_energy(self): + """Function to test the zero + of the nondimensional relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_relative_helmholtz_free_energy_0 = \ + model.nondimensional_relative_helmholtz_free_energy( + np.array(parameters.zero*number_of_links*link_length) + ) + self.assertLessEqual( + np.abs(nondimensional_relative_helmholtz_free_energy_0), + number_of_links*parameters.zero + ) + + def test_nondimensional_relative_helmholtz_free_energy_per_link(self): + """Function to test the zero + of the nondimensional relative Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_relative_helmholtz_free_energy_per_link_0 = \ + model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array(parameters.zero*number_of_links*link_length) + ) + self.assertLessEqual( + np.abs( + nondimensional_relative_helmholtz_free_energy_per_link_0 + ), parameters.zero + ) + + def test_equilibrium_radial_distribution(self): + """Function to test the zero + of the equilibrium radial distribution. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + equilibrium_radial_distribution_0 = \ + model.equilibrium_radial_distribution( + np.array(parameters.zero*number_of_links*link_length) + ) + self.assertLessEqual( + np.abs(equilibrium_radial_distribution_0), + parameters.zero + ) + + def test_nondimensional_equilibrium_radial_distribution(self): + """Function to test the zero + of the nondimensional equilibrium radial distribution. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_equilibrium_radial_distribution_0 = \ + model.nondimensional_equilibrium_radial_distribution( + np.array(parameters.zero) + ) + self.assertLessEqual( + np.abs(nondimensional_equilibrium_radial_distribution_0), + parameters.zero + ) + + +class Connection(unittest.TestCase): + """Class for connection tests. + + """ + def test_force(self): + """Function to test the connection + of the force. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + force = \ + model.force( + np.array(end_to_end_length), + temperature + ) + h_step = parameters.rel_tol * \ + number_of_links*link_length + force_from_derivative = ( + model.relative_helmholtz_free_energy( + np.array(end_to_end_length + 0.5*h_step), + temperature + ) + - model.relative_helmholtz_free_energy( + np.array(end_to_end_length - 0.5*h_step), + temperature + ))/h_step + residual_abs = \ + force \ + - force_from_derivative + residual_rel = residual_abs/force + self.assertLessEqual( + np.abs(residual_rel), h_step + ) + + def test_nondimensional_force(self): + """Function to test the connection + of the nondimensional force. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_force = \ + model.nondimensional_force( + np.array(nondimensional_end_to_end_length_per_link) + ) + h_step = parameters.rel_tol * \ + number_of_links*link_length + nondimensional_force_from_derivative = ( + model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array( + nondimensional_end_to_end_length_per_link + 0.5*h_step + ) + ) + - model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array( + nondimensional_end_to_end_length_per_link - 0.5*h_step + ) + ))/h_step + residual_abs = \ + nondimensional_force \ + - nondimensional_force_from_derivative + residual_rel = residual_abs/nondimensional_force + self.assertLessEqual( + np.abs(residual_rel), h_step + ) + + def test_relative_helmholtz_free_energy(self): + """Function to test the connection + of the relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + relative_helmholtz_free_energy = \ + model.relative_helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + relative_helmholtz_free_energy_from_connection = \ + parameters.boltzmann_constant*temperature * np.log( + model.equilibrium_distribution(np.array( + parameters.zero*number_of_links*link_length + )) / + model.equilibrium_distribution(np.array( + end_to_end_length + )) + ) + residual_abs = \ + relative_helmholtz_free_energy \ + - relative_helmholtz_free_energy_from_connection + residual_rel = residual_abs/relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_rel), parameters.rel_tol + ) + + def test_nondimensional_relative_helmholtz_free_energy(self): + """Function to test the connection + of the nondimensional relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_relative_helmholtz_free_energy = \ + model.nondimensional_relative_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_relative_helmholtz_free_energy_from_connection = \ + np.log( + model.nondimensional_equilibrium_distribution(np.array( + parameters.zero + )) / + model.nondimensional_equilibrium_distribution(np.array( + nondimensional_end_to_end_length_per_link + )) + ) + residual_abs = \ + nondimensional_relative_helmholtz_free_energy \ + - nondimensional_relative_helmholtz_free_energy_from_connection + residual_rel = residual_abs / \ + nondimensional_relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_rel), parameters.rel_tol + ) + + +class Legendre(unittest.TestCase): + """Class for Legendre tests. + + """ + def test_helmholtz_free_energy(self): + """Function to test the Legendre transformation + of the Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + force = \ + model.force( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy = \ + model.helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy_legendre = \ + model.legendre.gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + force*end_to_end_length + residual_abs = \ + helmholtz_free_energy \ + - helmholtz_free_energy_legendre + residual_rel = \ + residual_abs / \ + helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_helmholtz_free_energy_per_link(self): + """Function to test the Legendre transformation + of the Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + end_to_end_length_per_link = end_to_end_length/number_of_links + force = \ + model.force( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy_per_link = \ + model.helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + helmholtz_free_energy_per_link_legendre = \ + model.legendre.gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + force*end_to_end_length_per_link + residual_abs = \ + helmholtz_free_energy_per_link \ + - helmholtz_free_energy_per_link_legendre + residual_rel = \ + residual_abs / \ + helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_helmholtz_free_energy(self): + """Function to test the Legendre transformation + of the relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + force = \ + model.force( + np.array(end_to_end_length), + temperature + ) + force_0 = \ + model.force( + np.array(number_of_links*link_length*parameters.zero), + temperature + ) + relative_helmholtz_free_energy = \ + model.relative_helmholtz_free_energy( + np.array(end_to_end_length), + temperature + ) + relative_helmholtz_free_energy_legendre = \ + model.legendre.relative_gibbs_free_energy( + np.array(end_to_end_length), + temperature + ) + force*end_to_end_length \ + - force_0*number_of_links*link_length*parameters.zero + residual_abs = \ + relative_helmholtz_free_energy \ + - relative_helmholtz_free_energy_legendre + residual_rel = \ + residual_abs / \ + relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_relative_helmholtz_free_energy_per_link(self): + """Function to test the Legendre transformation + of the relative Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + end_to_end_length_per_link = end_to_end_length/number_of_links + force = \ + model.force( + np.array(end_to_end_length), + temperature + ) + force_0 = \ + model.force( + np.array(number_of_links*link_length*parameters.zero), + temperature + ) + relative_helmholtz_free_energy_per_link = \ + model.relative_helmholtz_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + relative_helmholtz_free_energy_per_link_legendre = \ + model.legendre.relative_gibbs_free_energy_per_link( + np.array(end_to_end_length), + temperature + ) + force*end_to_end_length_per_link \ + - force_0*link_length*parameters.zero + residual_abs = \ + relative_helmholtz_free_energy_per_link \ + - relative_helmholtz_free_energy_per_link_legendre + residual_rel = \ + residual_abs / \ + relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_helmholtz_free_energy(self): + """Function to test the Legendre transformation + of the nondimensional Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_end_to_end_length = \ + nondimensional_end_to_end_length_per_link * \ + number_of_links + nondimensional_force = \ + model.nondimensional_force( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_helmholtz_free_energy = \ + model.nondimensional_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_helmholtz_free_energy_legendre = \ + model.legendre.nondimensional_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_force * \ + nondimensional_end_to_end_length + residual_abs = \ + nondimensional_helmholtz_free_energy \ + - nondimensional_helmholtz_free_energy_legendre + residual_rel = \ + residual_abs / \ + nondimensional_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_helmholtz_free_energy_per_link(self): + """Function to test the Legendre transformation + of the nondimensional Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + nondimensional_force = \ + model.nondimensional_force( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_helmholtz_free_energy_per_link = \ + model.nondimensional_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_helmholtz_free_energy_per_link_legendre = \ + model.legendre.nondimensional_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link), + temperature + ) + nondimensional_force * \ + nondimensional_end_to_end_length_per_link + residual_abs = \ + nondimensional_helmholtz_free_energy_per_link \ + - nondimensional_helmholtz_free_energy_per_link_legendre + residual_rel = \ + residual_abs / \ + nondimensional_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_relative_helmholtz_free_energy(self): + """Function to test the Legendre transformation + of the nondimensional relative Helmholtz free energy. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_end_to_end_length = \ + nondimensional_end_to_end_length_per_link * \ + number_of_links + nondimensional_force = \ + model.nondimensional_force( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_force_0 = \ + model.nondimensional_force( + np.array(parameters.zero) + ) + nondimensional_relative_helmholtz_free_energy = \ + model.nondimensional_relative_helmholtz_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_relative_helmholtz_free_energy_legendre = \ + model.legendre.nondimensional_relative_gibbs_free_energy( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_force * \ + nondimensional_end_to_end_length \ + - nondimensional_force_0*parameters.zero*number_of_links + residual_abs = \ + nondimensional_relative_helmholtz_free_energy \ + - nondimensional_relative_helmholtz_free_energy_legendre + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + def test_nondimensional_relative_helmholtz_free_energy_per_link(self): + """Function to test the Legendre transformation + of the nondimensional relative Helmholtz free energy per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_force = \ + model.nondimensional_force( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_force_0 = \ + model.nondimensional_force( + np.array(parameters.zero) + ) + nondimensional_relative_helmholtz_free_energy_per_link = \ + model.nondimensional_relative_helmholtz_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_relative_helmholtz_free_energy_per_link_legendre = \ + model.legendre. \ + nondimensional_relative_gibbs_free_energy_per_link( + np.array(nondimensional_end_to_end_length_per_link) + ) + nondimensional_force * \ + nondimensional_end_to_end_length_per_link \ + - nondimensional_force_0*parameters.zero + residual_abs = \ + nondimensional_relative_helmholtz_free_energy_per_link - \ + nondimensional_relative_helmholtz_free_energy_per_link_legendre + residual_rel = \ + residual_abs / \ + nondimensional_relative_helmholtz_free_energy_per_link + self.assertLessEqual( + np.abs(residual_abs), + parameters.abs_tol + ) + self.assertLessEqual( + np.abs(residual_rel), + parameters.rel_tol + ) + + +class LegendreConnection(unittest.TestCase): + """Class for Legendre connection tests. + + """ + def test_end_to_end_length(self): + """Function to test the Legendre transformation connection + of the end-to-end length. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + h_step = parameters.rel_tol * \ + number_of_links*link_length + end_to_end_length_from_derivative = -( + model.legendre.relative_gibbs_free_energy( + np.array( + end_to_end_length + 0.5*h_step + ), temperature + ) + - model.legendre.relative_gibbs_free_energy( + np.array( + end_to_end_length - 0.5*h_step + ), temperature + ))/( + model.force( + np.array( + end_to_end_length + 0.5*h_step + ), temperature + ) + - model.force( + np.array( + end_to_end_length - 0.5*h_step + ), temperature + )) + residual_abs = \ + end_to_end_length \ + - end_to_end_length_from_derivative + residual_rel = residual_abs/end_to_end_length + self.assertLessEqual( + np.abs(residual_rel), h_step + ) + + def test_end_to_end_length_per_link(self): + """Function to test the Legendre transformation connection + of the end-to-end length per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + temperature = \ + parameters.temperature_reference + \ + parameters.temperature_scale*(0.5 - np.random.rand()) + end_to_end_length = nondimensional_end_to_end_length_per_link * \ + number_of_links*link_length + end_to_end_length_per_link = \ + nondimensional_end_to_end_length_per_link * \ + link_length + h_step = parameters.rel_tol * \ + number_of_links*link_length + end_to_end_length_per_link_from_derivative = -( + model.legendre.relative_gibbs_free_energy_per_link( + np.array( + end_to_end_length + 0.5*h_step + ), temperature + ) + - model.legendre.relative_gibbs_free_energy_per_link( + np.array( + end_to_end_length - 0.5*h_step + ), temperature + ))/( + model.force( + np.array( + end_to_end_length + 0.5*h_step + ), temperature + ) + - model.force( + np.array( + end_to_end_length - 0.5*h_step + ), temperature + )) + residual_abs = \ + end_to_end_length_per_link \ + - end_to_end_length_per_link_from_derivative + residual_rel = residual_abs/end_to_end_length_per_link + self.assertLessEqual( + np.abs(residual_rel), h_step + ) + + def test_nondimensional_end_to_end_length(self): + """Function to test the Legendre transformation connection + of the nondimensional end-to-end length. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + nondimensional_end_to_end_length = \ + nondimensional_end_to_end_length_per_link * \ + number_of_links + h_step = parameters.rel_tol + nondimensional_end_to_end_length_from_derivative = -( + model.legendre.nondimensional_relative_gibbs_free_energy( + np.array( + nondimensional_end_to_end_length_per_link + 0.5*h_step + ) + ) + - model.legendre.nondimensional_relative_gibbs_free_energy( + np.array( + nondimensional_end_to_end_length_per_link - 0.5*h_step + ) + ))/( + model.nondimensional_force( + np.array( + nondimensional_end_to_end_length_per_link + 0.5*h_step + ) + ) + - model.nondimensional_force( + np.array( + nondimensional_end_to_end_length_per_link - 0.5*h_step + ) + )) + residual_abs = \ + nondimensional_end_to_end_length \ + - nondimensional_end_to_end_length_from_derivative + residual_rel = residual_abs/nondimensional_end_to_end_length + self.assertLessEqual( + np.abs(residual_rel), h_step + ) + + def test_nondimensional_end_to_end_length_per_link(self): + """Function to test the Legendre transformation connection + of the nondimensional end-to-end length per link. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + nondimensional_end_to_end_length_per_link = \ + parameters. \ + nondimensional_end_to_end_length_per_link_reference + \ + parameters. \ + nondimensional_end_to_end_length_per_link_scale * \ + (0.5 - np.random.rand()) + h_step = parameters.rel_tol + nondimensional_end_to_end_length_per_link_from_derivative = -( + model.legendre. + nondimensional_relative_gibbs_free_energy_per_link( + np.array( + nondimensional_end_to_end_length_per_link + 0.5*h_step + ) + ) + - model.legendre. + nondimensional_relative_gibbs_free_energy_per_link( + np.array( + nondimensional_end_to_end_length_per_link - 0.5*h_step + ) + ))/( + model.nondimensional_force( + np.array( + nondimensional_end_to_end_length_per_link + 0.5*h_step + ) + ) + - model.nondimensional_force( + np.array( + nondimensional_end_to_end_length_per_link - 0.5*h_step + ) + )) + residual_abs = \ + nondimensional_end_to_end_length_per_link \ + - nondimensional_end_to_end_length_per_link_from_derivative + residual_rel = residual_abs / \ + nondimensional_end_to_end_length_per_link + self.assertLessEqual( + np.abs(residual_rel), h_step + ) diff --git a/src/physics/single_chain/wlc/thermodynamics/py.rs b/src/physics/single_chain/wlc/thermodynamics/py.rs index e69de29b..b5952f45 100644 --- a/src/physics/single_chain/wlc/thermodynamics/py.rs +++ b/src/physics/single_chain/wlc/thermodynamics/py.rs @@ -0,0 +1,53 @@ +use pyo3::prelude::*; + +pub fn register_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> +{ + let thermodynamics = PyModule::new(py, "thermodynamics")?; + super::isometric::py::register_module(py, thermodynamics)?; + parent_module.add_submodule(thermodynamics)?; + thermodynamics.add_class::()?; + Ok(()) +} + +/// The worm-like chain (WLC) model thermodynamics. +#[pyclass] +#[derive(Copy, Clone)] +pub struct WLC +{ + /// The mass of each hinge in the chain in units of kg/mol. + #[pyo3(get)] + pub hinge_mass: f64, + + /// The length of each link in the chain in units of nm. + #[pyo3(get)] + pub link_length: f64, + + /// The number of links in the chain. + #[pyo3(get)] + pub number_of_links: u8, + + /// The persistance length of the chain in units of nm. + #[pyo3(get)] + pub persistance_length: f64, + + /// The thermodynamic functions of the model in the isometric ensemble. + #[pyo3(get)] + pub isometric: super::isometric::py::WLC +} + +#[pymethods] +impl WLC +{ + #[new] + pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64) -> Self + { + WLC + { + hinge_mass, + link_length, + number_of_links, + persistance_length, + isometric: super::isometric::py::WLC::init(number_of_links, link_length, hinge_mass, persistance_length) + } + } +} diff --git a/src/physics/single_chain/wlc/thermodynamics/test.py b/src/physics/single_chain/wlc/thermodynamics/test.py new file mode 100644 index 00000000..9325ffe0 --- /dev/null +++ b/src/physics/single_chain/wlc/thermodynamics/test.py @@ -0,0 +1,143 @@ +"""Module to test the local module. + +""" +import unittest +import numpy as np +from polymers import physics +from ..test import Parameters + +parameters = Parameters() +WLC = physics.single_chain.wlc.thermodynamics.WLC + + +class Base(unittest.TestCase): + """Class for basic tests. + + """ + def test_init(self): + """Function to test instantiation. + + """ + for _ in range(parameters.number_of_loops): + _ = WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ) + + def test_number_of_links(self): + """Function to test the number of links during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + self.assertEqual( + number_of_links, + WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).number_of_links + ) + + def test_link_length(self): + """Function to test the link length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + link_length, + WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference + ).link_length + ) + + def test_hinge_mass(self): + """Function to test the hinge mass during instantiation. + + """ + for _ in range(parameters.number_of_loops): + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + self.assertEqual( + hinge_mass, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference + ).hinge_mass + ) + + def test_persistance_length(self): + """Function to test the persistance length during instantiation. + + """ + for _ in range(parameters.number_of_loops): + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + self.assertEqual( + persistance_length, + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length + ).persistance_length + ) + + def test_all_parameters(self): + """Function to test all parameters during instantiation. + + """ + for _ in range(parameters.number_of_loops): + number_of_links = \ + np.random.randint( + parameters.number_of_links_minimum, + high=parameters.number_of_links_maximum + ) + link_length = \ + parameters.link_length_reference + \ + parameters.link_length_scale*(0.5 - np.random.rand()) + hinge_mass = \ + parameters.hinge_mass_reference + \ + parameters.hinge_mass_scale*(0.5 - np.random.rand()) + persistance_length = \ + parameters.persistance_length_reference + \ + parameters.persistance_length_scale*(0.5 - np.random.rand()) + model = WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length + ) + self.assertEqual( + number_of_links, + model.number_of_links + ) + self.assertEqual( + link_length, + model.link_length + ) + self.assertEqual( + hinge_mass, + model.hinge_mass + ) + self.assertEqual( + persistance_length, + model.persistance_length + ) From 36e5d5327ac23f43cd5305f4d24c7f58cc9928d5 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 1 May 2023 10:59:11 -0600 Subject: [PATCH 19/21] docs setup --- docs/source/physics/single_chain.rst | 1 + docs/source/physics/single_chain/wlc.rst | 15 ++++++++ .../single_chain/wlc/thermodynamics.rst | 15 ++++++++ .../wlc/thermodynamics/isometric.rst | 36 +++++++++++++++++++ .../wlc/thermodynamics/isometric/legendre.rst | 17 +++++++++ docs/src/physics/single_chain.md | 1 + docs/src/physics/single_chain/wlc.md | 7 ++++ .../single_chain/wlc/thermodynamics.md | 7 ++++ .../wlc/thermodynamics/isometric.md | 7 ++++ .../wlc/thermodynamics/isometric/legendre.md | 5 +++ 10 files changed, 111 insertions(+) create mode 100644 docs/source/physics/single_chain/wlc.rst create mode 100644 docs/source/physics/single_chain/wlc/thermodynamics.rst create mode 100644 docs/source/physics/single_chain/wlc/thermodynamics/isometric.rst create mode 100644 docs/source/physics/single_chain/wlc/thermodynamics/isometric/legendre.rst create mode 100644 docs/src/physics/single_chain/wlc.md create mode 100644 docs/src/physics/single_chain/wlc/thermodynamics.md create mode 100644 docs/src/physics/single_chain/wlc/thermodynamics/isometric.md create mode 100644 docs/src/physics/single_chain/wlc/thermodynamics/isometric/legendre.md diff --git a/docs/source/physics/single_chain.rst b/docs/source/physics/single_chain.rst index da192d43..cf15eca9 100644 --- a/docs/source/physics/single_chain.rst +++ b/docs/source/physics/single_chain.rst @@ -9,6 +9,7 @@ Single-chain models for polymer physics EFJC SWFJC uFJC + WLC .. automodule:: polymers.physics.single_chain :members: diff --git a/docs/source/physics/single_chain/wlc.rst b/docs/source/physics/single_chain/wlc.rst new file mode 100644 index 00000000..c88a8e0b --- /dev/null +++ b/docs/source/physics/single_chain/wlc.rst @@ -0,0 +1,15 @@ +WLC model +========= + +.. toctree:: + :maxdepth: 1 + + Thermodynamics + +.. autoclass:: polymers.physics.single_chain.fjc::WLC(number_of_links, link_length, hinge_mass, persistance_length) + + .. autoattribute:: number_of_links + .. autoattribute:: link_length + .. autoattribute:: hinge_mass + .. autoattribute:: persistance_length + .. autoattribute:: thermodynamics diff --git a/docs/source/physics/single_chain/wlc/thermodynamics.rst b/docs/source/physics/single_chain/wlc/thermodynamics.rst new file mode 100644 index 00000000..ab1ee11a --- /dev/null +++ b/docs/source/physics/single_chain/wlc/thermodynamics.rst @@ -0,0 +1,15 @@ +WLC model thermodynamics +======================== + +.. toctree:: + :maxdepth: 1 + + Isometric + +.. autoclass:: polymers.physics.single_chain.wlc.thermodynamics::WLC(number_of_links, link_length, hinge_mass, persistance_length) + + .. autoattribute:: number_of_links + .. autoattribute:: link_length + .. autoattribute:: hinge_mass + .. autoattribute:: persistance_length + .. autoattribute:: isometric diff --git a/docs/source/physics/single_chain/wlc/thermodynamics/isometric.rst b/docs/source/physics/single_chain/wlc/thermodynamics/isometric.rst new file mode 100644 index 00000000..4f6aa9af --- /dev/null +++ b/docs/source/physics/single_chain/wlc/thermodynamics/isometric.rst @@ -0,0 +1,36 @@ +WLC model thermodynamics (isometric) +==================================== + +.. toctree:: + :maxdepth: 1 + + Legendre + +.. autoclass:: polymers.physics.single_chain.wlc.thermodynamics.isometric::WLC(number_of_links, link_length, hinge_mass, persistance_length) + + .. autoattribute:: number_of_links + .. autoattribute:: link_length + .. autoattribute:: hinge_mass + .. autoattribute:: persistance_length + .. autoattribute:: legendre + .. automethod:: force(end_to_end_length, temperature) + .. automethod:: nondimensional_force(nondimensional_end_to_end_length_per_link) + .. automethod:: helmholtz_free_energy(end_to_end_length, temperature) + .. automethod:: helmholtz_free_energy_per_link(end_to_end_length, temperature) + .. automethod:: relative_helmholtz_free_energy(end_to_end_length, temperature) + .. automethod:: relative_helmholtz_free_energy_per_link(end_to_end_length, temperature) + .. automethod:: nondimensional_helmholtz_free_energy(nondimensional_end_to_end_length_per_link, temperature) + .. automethod:: nondimensional_helmholtz_free_energy_per_link(nondimensional_end_to_end_length_per_link, temperature) + .. automethod:: nondimensional_relative_helmholtz_free_energy(nondimensional_end_to_end_length_per_link) + .. automethod:: nondimensional_relative_helmholtz_free_energy_per_link(nondimensional_end_to_end_length_per_link) + .. automethod:: equilibrium_distribution(end_to_end_length) + .. automethod:: nondimensional_equilibrium_distribution(nondimensional_end_to_end_length_per_link) + .. automethod:: equilibrium_radial_distribution(end_to_end_length) + .. automethod:: nondimensional_equilibrium_radial_distribution(nondimensional_end_to_end_length_per_link) + +.. raw:: + html + +
+ +.. footbibliography:: diff --git a/docs/source/physics/single_chain/wlc/thermodynamics/isometric/legendre.rst b/docs/source/physics/single_chain/wlc/thermodynamics/isometric/legendre.rst new file mode 100644 index 00000000..6dd4d61f --- /dev/null +++ b/docs/source/physics/single_chain/wlc/thermodynamics/isometric/legendre.rst @@ -0,0 +1,17 @@ +WLC model thermodynamics (isometric/legendre) +============================================= + +.. autoclass:: polymers.physics.single_chain.wlc.thermodynamics.isometric.legendre::WLC(number_of_links, link_length, hinge_mass, persistance_length) + + .. autoattribute:: number_of_links + .. autoattribute:: link_length + .. autoattribute:: hinge_mass + .. autoattribute:: persistance_length + .. automethod:: gibbs_free_energy(end_to_end_length, temperature) + .. automethod:: gibbs_free_energy_per_link(end_to_end_length, temperature) + .. automethod:: relative_gibbs_free_energy(end_to_end_length, temperature) + .. automethod:: relative_gibbs_free_energy_per_link(end_to_end_length, temperature) + .. automethod:: nondimensional_gibbs_free_energy(nondimensional_end_to_end_length_per_link, temperature) + .. automethod:: nondimensional_gibbs_free_energy_per_link(nondimensional_end_to_end_length_per_link, temperature) + .. automethod:: nondimensional_relative_gibbs_free_energy(nondimensional_end_to_end_length_per_link) + .. automethod:: nondimensional_relative_gibbs_free_energy_per_link(nondimensional_end_to_end_length_per_link) diff --git a/docs/src/physics/single_chain.md b/docs/src/physics/single_chain.md index 790d0880..48a23052 100644 --- a/docs/src/physics/single_chain.md +++ b/docs/src/physics/single_chain.md @@ -5,6 +5,7 @@ * [Extensible freely-jointed chain (EFJC) model](../efjc) * [Square-well freely-jointed chain (SWFJC) model](../swfjc) * [Arbitrary link potential freely-jointed chain (uFJC) model](../ufjc) + * [Worm-like chain (WLC) model](../wlc) ```@autodocs Modules = [Polymers.Physics.SingleChain] diff --git a/docs/src/physics/single_chain/wlc.md b/docs/src/physics/single_chain/wlc.md new file mode 100644 index 00000000..03707932 --- /dev/null +++ b/docs/src/physics/single_chain/wlc.md @@ -0,0 +1,7 @@ +# Worm-like chain (WLC) model + + * [WLC model thermodynamics](../../thermodynamics) + +```@autodocs +Modules = [Polymers.Physics.SingleChain.WLC] +``` diff --git a/docs/src/physics/single_chain/wlc/thermodynamics.md b/docs/src/physics/single_chain/wlc/thermodynamics.md new file mode 100644 index 00000000..36e7b4ae --- /dev/null +++ b/docs/src/physics/single_chain/wlc/thermodynamics.md @@ -0,0 +1,7 @@ +# WLC model thermodynamics + + * [WLC model thermodynamics (isometric)](../../../isometric) + +```@autodocs +Modules = [Polymers.Physics.SingleChain.WLC.Thermodynamics] +``` diff --git a/docs/src/physics/single_chain/wlc/thermodynamics/isometric.md b/docs/src/physics/single_chain/wlc/thermodynamics/isometric.md new file mode 100644 index 00000000..f2be6e4d --- /dev/null +++ b/docs/src/physics/single_chain/wlc/thermodynamics/isometric.md @@ -0,0 +1,7 @@ +# WLC model thermodynamics (isometric) + + * [WLC model thermodynamics (isometric/legendre)](../../../../legendre) + +```@autodocs +Modules = [Polymers.Physics.SingleChain.WLC.Thermodynamics.Isometric] +``` diff --git a/docs/src/physics/single_chain/wlc/thermodynamics/isometric/legendre.md b/docs/src/physics/single_chain/wlc/thermodynamics/isometric/legendre.md new file mode 100644 index 00000000..df84b9ce --- /dev/null +++ b/docs/src/physics/single_chain/wlc/thermodynamics/isometric/legendre.md @@ -0,0 +1,5 @@ +# WLC model thermodynamics (isometric/legendre) + +```@autodocs +Modules = [Polymers.Physics.SingleChain.WLC.Thermodynamics.Isometric.Legendre] +``` From 857d8e2bc42989ef19faa1328a69151905b5b742 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 1 May 2023 13:59:44 -0600 Subject: [PATCH 20/21] jl work --- src/physics/single_chain/wlc/mod.jl | 58 ++ src/physics/single_chain/wlc/test.jl | 104 +++ .../wlc/thermodynamics/isometric/ex.rs | 70 ++ .../thermodynamics/isometric/legendre/ex.rs | 40 + .../thermodynamics/isometric/legendre/mod.jl | 422 +++++++++++ .../thermodynamics/isometric/legendre/test.jl | 104 +++ .../wlc/thermodynamics/isometric/mod.jl | 692 ++++++++++++++++++ .../wlc/thermodynamics/isometric/test.jl | 104 +++ .../single_chain/wlc/thermodynamics/mod.jl | 58 ++ .../single_chain/wlc/thermodynamics/test.jl | 104 +++ test/runtests.jl | 324 ++++---- 11 files changed, 1920 insertions(+), 160 deletions(-) diff --git a/src/physics/single_chain/wlc/mod.jl b/src/physics/single_chain/wlc/mod.jl index e69de29b..92c67f31 100644 --- a/src/physics/single_chain/wlc/mod.jl +++ b/src/physics/single_chain/wlc/mod.jl @@ -0,0 +1,58 @@ +""" +The worm-like chain (WLC) single-chain model. +""" +module Wlc + +using DocStringExtensions + +include("thermodynamics/mod.jl") + +""" +The structure of the WLC model. + +$(FIELDS) +""" +struct WLC + """ + The number of links in the chain ``N_b``. + """ + number_of_links::UInt8 + """ + The length of each link in the chain ``\\ell_b`` in units of nm. + """ + link_length::Float64 + """ + The mass of each hinge in the chain ``m`` in units of kg/mol. + """ + hinge_mass::Float64 + """ + The persistance length of the chain in units of nm. + """ + persistance_length::Float64 + """ + The thermodynamic functions of the model. + """ + thermodynamics::Any +end + +""" +Initializes and returns an instance of the WLC model. + +$(TYPEDSIGNATURES) +""" +function WLC( + number_of_links::UInt8, + link_length::Float64, + hinge_mass::Float64, + persistance_length::Float64, +) + return WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + Thermodynamics.WLC(number_of_links, link_length, hinge_mass, persistance_length), + ) +end + +end diff --git a/src/physics/single_chain/wlc/test.jl b/src/physics/single_chain/wlc/test.jl index e69de29b..bb4f02a3 100644 --- a/src/physics/single_chain/wlc/test.jl +++ b/src/physics/single_chain/wlc/test.jl @@ -0,0 +1,104 @@ +module Test + +using Test +using Polymers.Physics.SingleChain: parameters +using Polymers.Physics.SingleChain.Wlc: WLC + +@testset "physics::single_chain::wlc::test::base::init" begin + @test isa( + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ), + Any, + ) +end + +@testset "physics::single_chain::wlc::test::base::number_of_links" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + @test WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).number_of_links == number_of_links + end +end + +@testset "physics::single_chain::wlc::test::base::link_length" begin + for _ = 1:parameters.number_of_loops + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).link_length == link_length + end +end + +@testset "physics::single_chain::wlc::test::base::hinge_mass" begin + for _ = 1:parameters.number_of_loops + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference, + ).hinge_mass == hinge_mass + end +end + +@testset "physics::single_chain::wlc::test::base::persistance_length" begin + for _ = 1:parameters.number_of_loops + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length, + ).persistance_length == persistance_length + end +end + +@testset "physics::single_chain::wlc::test::base::all_parameters" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test all( + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).number_of_links == number_of_links && + WLC(number_of_links, link_length, hinge_mass, persistance_length).link_length == + link_length && + WLC(number_of_links, link_length, hinge_mass, persistance_length).hinge_mass == + hinge_mass && + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).persistance_length == persistance_length, + ) + end +end + +end diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs index e69de29b..9950d97b 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/ex.rs @@ -0,0 +1,70 @@ +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_force(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::force(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_force(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_force(&number_of_links, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_helmholtz_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::helmholtz_free_energy(&number_of_links, &link_length, &hinge_mass, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_helmholtz_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::helmholtz_free_energy_per_link(&number_of_links, &link_length, &hinge_mass, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_relative_helmholtz_free_energy(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::relative_helmholtz_free_energy(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_relative_helmholtz_free_energy_per_link(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::relative_helmholtz_free_energy_per_link(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_helmholtz_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 +{ + super::nondimensional_helmholtz_free_energy(&number_of_links, &link_length, &hinge_mass, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_helmholtz_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 +{ + super::nondimensional_helmholtz_free_energy_per_link(&number_of_links, &link_length, &hinge_mass, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_helmholtz_free_energy(nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_relative_helmholtz_free_energy(&nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_helmholtz_free_energy_per_link(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_relative_helmholtz_free_energy_per_link(&number_of_links, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_equilibrium_distribution(number_of_links: u8, link_length: f64, persistance_length: f64, normalization_nondimensional_equilibrium_distribution: f64, end_to_end_length: f64) -> f64 +{ + super::equilibrium_distribution(&number_of_links, &link_length, &persistance_length, &normalization_nondimensional_equilibrium_distribution, &end_to_end_length) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_equilibrium_distribution(nondimensional_persistance_length: f64, normalization_nondimensional_equilibrium_distribution: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_equilibrium_distribution(&nondimensional_persistance_length, &normalization_nondimensional_equilibrium_distribution, &nondimensional_end_to_end_length_per_link) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_equilibrium_radial_distribution(number_of_links: u8, link_length: f64, persistance_length: f64, normalization_nondimensional_equilibrium_distribution: f64, end_to_end_length: f64) -> f64 +{ + super::equilibrium_radial_distribution(&number_of_links, &link_length, &persistance_length, &normalization_nondimensional_equilibrium_distribution, &end_to_end_length) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_equilibrium_radial_distribution(nondimensional_persistance_length: f64, normalization_nondimensional_equilibrium_distribution: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_equilibrium_radial_distribution(&nondimensional_persistance_length, &normalization_nondimensional_equilibrium_distribution, &nondimensional_end_to_end_length_per_link) +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs index e69de29b..7c087bf2 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs @@ -0,0 +1,40 @@ +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_gibbs_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::gibbs_free_energy(&number_of_links, &link_length, &hinge_mass, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::gibbs_free_energy_per_link(&number_of_links, &link_length, &hinge_mass, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_relative_gibbs_free_energy(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::relative_gibbs_free_energy(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_relative_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +{ + super::relative_gibbs_free_energy_per_link(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_gibbs_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 +{ + super::nondimensional_gibbs_free_energy(&number_of_links, &link_length, &hinge_mass, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 +{ + super::nondimensional_gibbs_free_energy_per_link(&number_of_links, &link_length, &hinge_mass, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_gibbs_free_energy(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_relative_gibbs_free_energy(&number_of_links, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) +} +#[no_mangle] +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_gibbs_free_energy_per_link(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +{ + super::nondimensional_relative_gibbs_free_energy_per_link(&number_of_links, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) +} \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl index e69de29b..d3f20078 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl @@ -0,0 +1,422 @@ +""" +The worm-like chain (FJC) model thermodynamics in the isometric ensemble approximated using a Legendre transformation. +""" +module Legendre + +using DocStringExtensions +using .......Polymers: PROJECT_ROOT + +""" +The structure of the thermodynamics of the FJC model in the isometric ensemble approximated using a Legendre transformation. +$(FIELDS) +""" +struct FJC + """ + The number of links in the chain ``N_b``. + """ + number_of_links::UInt8 + """ + The length of each link in the chain ``\\ell_b`` in units of nm. + """ + link_length::Float64 + """ + The mass of each hinge in the chain ``m`` in units of kg/mol. + """ + hinge_mass::Float64 + """ + The persistance length of the chain in units of nm. + """ + persistance_length::Float64 + normalization_nondimensional_equilibrium_distribution::Float64 + """ + The Gibbs free energy ``\\varphi`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + gibbs_free_energy::Function + """ + The Gibbs free energy per link ``\\varphi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + gibbs_free_energy_per_link::Function + """ + The relative Gibbs free energy ``\\Delta\\varphi`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + relative_gibbs_free_energy::Function + """ + The relative Gibbs free energy per link ``\\Delta\\varphi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + relative_gibbs_free_energy_per_link::Function + """ + The nondimensional Gibbs free energy ``N_b\\varrho=\\beta\\varphi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``. + """ + nondimensional_gibbs_free_energy::Function + """ + The nondimensional Gibbs free energy per link ``\\varrho\\equiv\\beta\\varphi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``. + """ + nondimensional_gibbs_free_energy_per_link::Function + """ + The nondimensional relative Gibbs free energy ``N_b\\Delta\\varrho=\\beta\\Delta\\varphi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``. + """ + nondimensional_relative_gibbs_free_energy::Function + """ + The nondimensional relative Gibbs free energy per link ``\\Delta\\varrho\\equiv\\beta\\Delta\\varphi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` + """ + nondimensional_relative_gibbs_free_energy_per_link::Function +end + +""" +The Gibbs free energy ``\\varphi`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``, + +```math +\\varphi(\\xi, T) \\sim \\psi(\\xi, T) - \\xi f(\\xi, T) \\quad \\text{for } N_b\\gg 1, +``` + +where ``f(\\xi, T)`` is given by the Legendre transformation approximation above. + +$(TYPEDSIGNATURES) +""" +function gibbs_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_gibbs_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ) +end + +""" +The Gibbs free energy per link ``\\varphi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``. + +$(TYPEDSIGNATURES) +""" +function gibbs_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_gibbs_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ) +end + +""" +The relative Helmholtz free energy ``\\Delta\\varphi\\equiv\\varphi(\\xi,T)-\\varphi(0,T)`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``. + +$(TYPEDSIGNATURES) +""" +function relative_gibbs_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_relative_gibbs_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + end_to_end_length, + temperature, + ) +end + +""" +The relative Gibbs free energy per link ``\\Delta\\varphi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``. + +$(TYPEDSIGNATURES) +""" +function relative_gibbs_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_relative_gibbs_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + end_to_end_length, + temperature, + ) +end + +""" +The nondimensional Gibbs free energy ``N_b\\varrho=\\beta\\varphi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``. + +$(TYPEDSIGNATURES) +""" +function nondimensional_gibbs_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_gibbs_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ) +end + +""" +The nondimensional Gibbs free energy per link ``\\varrho\\equiv\\beta\\varphi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``. + +$(TYPEDSIGNATURES) +""" +function nondimensional_gibbs_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_gibbs_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ) +end + +""" +The nondimensional relative Gibbs free energy ``N_b\\Delta\\varrho=\\beta\\Delta\\varphi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``, +parameterized by the number of links ``N_b``. + +$(TYPEDSIGNATURES) +""" +function nondimensional_relative_gibbs_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_relative_gibbs_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +The nondimensional relative Helmholtz free energy per link ``\\Delta\\varrho\\equiv\\beta\\Delta\\varphi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``, +parameterized by the number of links ``N_b``. + +$(TYPEDSIGNATURES) +""" +function nondimensional_relative_gibbs_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_relative_gibbs_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +Initializes and returns an instance of the thermodynamics of the FJC model in the isometric ensemble approximated using a Legendre transformation. + +$(TYPEDSIGNATURES) +""" +function FJC( + number_of_links::UInt8, + link_length::Float64, + hinge_mass::Float64, + persistance_length::Float64, +) + return FJC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + (end_to_end_length, temperature) -> gibbs_free_energy( + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ), + (end_to_end_length, temperature) -> gibbs_free_energy_per_link( + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ), + (end_to_end_length, temperature) -> relative_gibbs_free_energy( + number_of_links, + link_length, + end_to_end_length, + temperature, + ), + (end_to_end_length, temperature) -> relative_gibbs_free_energy_per_link( + number_of_links, + link_length, + end_to_end_length, + temperature, + ), + (nondimensional_end_to_end_length_per_link, temperature) -> + nondimensional_gibbs_free_energy( + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ), + (nondimensional_end_to_end_length_per_link, temperature) -> + nondimensional_gibbs_free_energy_per_link( + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ), + (nondimensional_end_to_end_length_per_link) -> + nondimensional_relative_gibbs_free_energy( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + (nondimensional_end_to_end_length_per_link) -> + nondimensional_relative_gibbs_free_energy_per_link( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + ) +end + +end diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl index e69de29b..d79868bc 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl @@ -0,0 +1,104 @@ +module Test + +using Test +using Polymers.Physics.SingleChain: parameters +using Polymers.Physics.SingleChain.Wlc.Thermodynamics.Isometric.Legendre: WLC + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::init" begin + @test isa( + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ), + Any, + ) +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::number_of_links" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + @test WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).number_of_links == number_of_links + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::link_length" begin + for _ = 1:parameters.number_of_loops + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).link_length == link_length + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::hinge_mass" begin + for _ = 1:parameters.number_of_loops + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference, + ).hinge_mass == hinge_mass + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::persistance_length" begin + for _ = 1:parameters.number_of_loops + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length, + ).persistance_length == persistance_length + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::all_parameters" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test all( + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).number_of_links == number_of_links && + WLC(number_of_links, link_length, hinge_mass, persistance_length).link_length == + link_length && + WLC(number_of_links, link_length, hinge_mass, persistance_length).hinge_mass == + hinge_mass && + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).persistance_length == persistance_length, + ) + end +end + +end diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl index e69de29b..6f64ca4a 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl @@ -0,0 +1,692 @@ +""" +The worm-like chain (WLC) model thermodynamics in the isometric ensemble. +""" +module Isometric + +using DocStringExtensions +using ......Polymers: PROJECT_ROOT +using ....SingleChain: ONE, ZERO, POINTS, integrate + +include("legendre/mod.jl") + +""" +The structure of the thermodynamics of the WLC model in the isometric ensemble. + +$(FIELDS) +""" +struct WLC + """ + The number of links in the chain ``N_b``. + """ + number_of_links::UInt8 + """ + The length of each link in the chain ``\\ell_b`` in units of nm. + """ + link_length::Float64 + """ + The mass of each hinge in the chain ``m`` in units of kg/mol. + """ + hinge_mass::Float64 + """ + The persistance length of the chain in units of nm. + """ + persistance_length::Float64 + normalization_nondimensional_equilibrium_distribution::Float64 + """ + The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. + """ + legendre::Any + """ + The expected force ``f`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + force::Function + """ + The expected nondimensional force ``\\eta`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``. + """ + nondimensional_force::Function + """ + The Helmholtz free energy ``\\psi`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + helmholtz_free_energy::Function + """ + The Helmholtz free energy per link ``\\psi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + helmholtz_free_energy_per_link::Function + """ + The relative Helmholtz free energy ``\\Delta\\psi\\equiv\\psi(\\xi,T)-\\psi(0,T)`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + relative_helmholtz_free_energy::Function + """ + The relative Helmholtz free energy per link ``\\Delta\\psi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. + """ + relative_helmholtz_free_energy_per_link::Function + """ + The nondimensional Helmholtz free energy ``N_b\\vartheta=\\beta\\psi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``. + """ + nondimensional_helmholtz_free_energy::Function + """ + The nondimensional Helmholtz free energy per link ``\\vartheta\\equiv\\beta\\psi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``. + """ + nondimensional_helmholtz_free_energy_per_link::Function + """ + The nondimensional relative Helmholtz free energy ``N_b\\Delta\\vartheta=\\beta\\Delta\\psi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``. + """ + nondimensional_relative_helmholtz_free_energy::Function + """ + The nondimensional relative Helmholtz free energy per link ``\\Delta\\vartheta\\equiv\\beta\\Delta\\psi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``. + """ + nondimensional_relative_helmholtz_free_energy_per_link::Function + """ + The equilibrium probability density of end-to-end vectors ``P_\\mathrm{eq}`` as a function of the end-to-end length ``\\xi``. + """ + equilibrium_distribution::Function + """ + The nondimensional equilibrium probability density of end-to-end vectors ``\\mathscr{P}_\\mathrm{eq}`` as a function of the nondimensional end-to-end length per link ``\\gamma``. + """ + nondimensional_equilibrium_distribution::Function + """ + The equilibrium probability density of end-to-end lengths ``g_\\mathrm{eq}`` as a function of the end-to-end length ``\\xi``. + """ + equilibrium_radial_distribution::Function + """ + The nondimensional equilibrium probability density of end-to-end lengths ``\\mathscr{g}_\\mathrm{eq}`` as a function of the nondimensional end-to-end length per link ``\\gamma``. + """ + nondimensional_equilibrium_radial_distribution::Function +end + +""" +The expected force ``f`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``, + +```math +f(\\xi, T) = \\frac{\\partial \\psi}{\\partial\\xi}. +``` + +$(TYPEDSIGNATURES) +""" +function force( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_force, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + end_to_end_length, + temperature, + ) +end + +""" +The expected nondimensional force ``\\eta`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``, +parameterized by the number of links ``N_b``, + +```math +\\eta(\\gamma) = \\frac{\\partial\\vartheta}{\\partial\\gamma}. +``` + +$(TYPEDSIGNATURES) +""" +function nondimensional_force( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_force, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +The Helmholtz free energy ``\\psi`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``, + +```math +\\psi(\\xi, T) = -kT\\ln Q(\\xi, T). +``` + +$(TYPEDSIGNATURES) +""" +function helmholtz_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_helmholtz_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ) +end + +""" +The Helmholtz free energy per link ``\\psi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``. + +$(TYPEDSIGNATURES) +""" +function helmholtz_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_helmholtz_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ) +end + +""" +The relative Helmholtz free energy ``\\Delta\\psi\\equiv\\psi(\\xi,T)-\\psi(0,T)`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``, + +```math +\\Delta\\psi(\\xi, T) = kT\\ln\\left[\\frac{P_\\mathrm{eq}(0)}{P_\\mathrm{eq}(\\xi)}\\right]. +``` + +$(TYPEDSIGNATURES) +""" +function relative_helmholtz_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_relative_helmholtz_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + end_to_end_length, + temperature, + ) +end + +""" +The relative Helmholtz free energy per link ``\\Delta\\psi/N_b`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``. + +$(TYPEDSIGNATURES) +""" +function relative_helmholtz_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_relative_helmholtz_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + temperature_i, + ), + number_of_links, + link_length, + end_to_end_length, + temperature, + ) +end + +""" +The nondimensional Helmholtz free energy ``N_b\\vartheta=\\beta\\psi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``. + +$(TYPEDSIGNATURES) +""" +function nondimensional_helmholtz_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_helmholtz_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ) +end + +""" +The nondimensional Helmholtz free energy per link ``\\vartheta\\equiv\\beta\\psi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma`` and temperature ``T``, +parameterized by the number of links ``N_b``, link length ``\\ell_b``, and hinge mass ``m``. + +$(TYPEDSIGNATURES) +""" +function nondimensional_helmholtz_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, + temperature::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + ( + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_helmholtz_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + hinge_mass_i, + nondimensional_end_to_end_length_per_link_i, + temperature_i, + ), + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ) +end + +""" +The nondimensional relative Helmholtz free energy ``N_b\\Delta\\vartheta=\\beta\\Delta\\psi`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``, +parameterized by the number of links ``N_b``, + +```math +\\beta\\Delta\\psi(\\gamma) = \\ln\\left[\\frac{\\mathscr{P}_\\mathrm{eq}(0)}{\\mathscr{P}_\\mathrm{eq}(\\gamma)}\\right]. +``` + +$(TYPEDSIGNATURES) +""" +function nondimensional_relative_helmholtz_free_energy( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_helmholtz_free_energy, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +The nondimensional relative Helmholtz free energy per link ``\\Delta\\vartheta\\equiv\\beta\\Delta\\psi/N_b`` as a function of the applied nondimensional end-to-end length per link ``\\gamma``, +parameterized by the number of links ``N_b``, + +```math +\\Delta\\vartheta(\\gamma) = \\ln\\left[\\frac{\\mathscr{P}_\\mathrm{eq}(0)}{\\mathscr{P}_\\mathrm{eq}(\\gamma)}\\right]^{1/N_b}. +``` + +$(TYPEDSIGNATURES) +""" +function nondimensional_relative_helmholtz_free_energy_per_link( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_helmholtz_free_energy_per_link, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +The equilibrium probability density of end-to-end vectors ``P_\\mathrm{eq}`` as a function of the end-to-end length ``\\xi``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``, + +```math +P_\\mathrm{eq}(\\xi) = \\frac{e^{-\\beta\\psi(\\xi, T)}}{4\\pi\\int e^{-\\beta\\psi(\\xi', T)} \\,{\\xi'}{}^2 d\\xi'}, +``` + +$(TYPEDSIGNATURES) +""" +function equilibrium_distribution( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_equilibrium_distribution, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + ), + number_of_links, + link_length, + end_to_end_length, + ) +end + +""" +The nondimensional equilibrium probability density of nondimensional end-to-end vectors per link ``\\mathscr{P}_\\mathrm{eq}`` as a function of the nondimensional end-to-end length per link ``\\gamma``, +parameterized by the number of links ``N_b``, + +```math +\\mathscr{P}_\\mathrm{eq}(\\gamma) = \\frac{e^{-\\Delta\\vartheta(\\gamma)}}{4\\pi\\int e^{-\\Delta\\vartheta(\\gamma')} \\,{\\gamma'}{}^2 d\\gamma'}. +``` + +$(TYPEDSIGNATURES) +""" +function nondimensional_equilibrium_distribution( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_equilibrium_distribution, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +The equilibrium probability density of end-to-end lengths ``g_\\mathrm{eq}`` as a function of the end-to-end length ``\\xi``, +parameterized by the number of links ``N_b`` and link length ``\\ell_b``, + +```math +g_\\mathrm{eq}(\\xi) = 4\\pi\\xi^2 P_\\mathrm{eq}(\\xi). +``` + +$(TYPEDSIGNATURES) +""" +function equilibrium_radial_distribution( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + link_length::Union{Float64,Vector,Matrix,Array}, + end_to_end_length::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, link_length_i, end_to_end_length_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_equilibrium_radial_distribution, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64), + number_of_links_i, + link_length_i, + end_to_end_length_i, + ), + number_of_links, + link_length, + end_to_end_length, + ) +end + +""" +The nondimensional equilibrium probability density of nondimensional end-to-end lenghts per link ``\\mathscr{g}_\\mathrm{eq}`` as a function of the nondimensional end-to-end length per link ``\\gamma``, +parameterized by the number of links ``N_b``, + +```math +\\mathscr{g}_\\mathrm{eq}(\\gamma) = 4\\pi\\gamma^2 \\mathscr{P}_\\mathrm{eq}(\\gamma). +``` + +$(TYPEDSIGNATURES) +""" +function nondimensional_equilibrium_radial_distribution( + number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, +)::Union{Float64,Vector,Matrix,Array} + return broadcast( + (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_equilibrium_radial_distribution, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64), + number_of_links_i, + nondimensional_end_to_end_length_per_link_i, + ), + number_of_links, + nondimensional_end_to_end_length_per_link, + ) +end + +""" +Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble. + +$(TYPEDSIGNATURES) +""" +function WLC( + number_of_links::UInt8, + link_length::Float64, + hinge_mass::Float64, + persistance_length::Float64, +) + normalization_nondimensional_equilibrium_distribution = integrate( + nondimensional_end_to_end_length_per_link -> + nondimensional_equilibrium_radial_distribution( + number_of_links, + 1.0, + nondimensional_end_to_end_length_per_link, + ), + ZERO, + ONE, + POINTS, + ) + return WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + normalization_nondimensional_equilibrium_distribution, + Legendre.WLC(number_of_links, link_length, hinge_mass, persistance_length), + (end_to_end_length, temperature) -> + force(number_of_links, link_length, end_to_end_length, temperature), + (nondimensional_end_to_end_length_per_link) -> nondimensional_force( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + (end_to_end_length, temperature) -> helmholtz_free_energy( + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ), + (end_to_end_length, temperature) -> helmholtz_free_energy_per_link( + number_of_links, + link_length, + hinge_mass, + end_to_end_length, + temperature, + ), + (end_to_end_length, temperature) -> relative_helmholtz_free_energy( + number_of_links, + link_length, + end_to_end_length, + temperature, + ), + (end_to_end_length, temperature) -> relative_helmholtz_free_energy_per_link( + number_of_links, + link_length, + end_to_end_length, + temperature, + ), + (nondimensional_end_to_end_length_per_link, temperature) -> + nondimensional_helmholtz_free_energy( + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ), + (nondimensional_end_to_end_length_per_link, temperature) -> + nondimensional_helmholtz_free_energy_per_link( + number_of_links, + link_length, + hinge_mass, + nondimensional_end_to_end_length_per_link, + temperature, + ), + (nondimensional_end_to_end_length_per_link) -> + nondimensional_relative_helmholtz_free_energy( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + (nondimensional_end_to_end_length_per_link) -> + nondimensional_relative_helmholtz_free_energy_per_link( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + (end_to_end_length) -> + equilibrium_distribution(number_of_links, link_length, end_to_end_length), + (nondimensional_end_to_end_length_per_link) -> + nondimensional_equilibrium_distribution( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + (end_to_end_length) -> equilibrium_radial_distribution( + number_of_links, + link_length, + end_to_end_length, + ), + (nondimensional_end_to_end_length_per_link) -> + nondimensional_equilibrium_radial_distribution( + number_of_links, + nondimensional_end_to_end_length_per_link, + ), + ) +end + +end diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl index e69de29b..bdfcc637 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl @@ -0,0 +1,104 @@ +module Test + +using Test +using Polymers.Physics.SingleChain: parameters +using Polymers.Physics.SingleChain.Wlc.Thermodynamics.Isometric: WLC + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::init" begin + @test isa( + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ), + Any, + ) +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::number_of_links" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + @test WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).number_of_links == number_of_links + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::link_length" begin + for _ = 1:parameters.number_of_loops + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).link_length == link_length + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::hinge_mass" begin + for _ = 1:parameters.number_of_loops + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference, + ).hinge_mass == hinge_mass + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::persistance_length" begin + for _ = 1:parameters.number_of_loops + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length, + ).persistance_length == persistance_length + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::all_parameters" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test all( + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).number_of_links == number_of_links && + WLC(number_of_links, link_length, hinge_mass, persistance_length).link_length == + link_length && + WLC(number_of_links, link_length, hinge_mass, persistance_length).hinge_mass == + hinge_mass && + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).persistance_length == persistance_length, + ) + end +end + +end diff --git a/src/physics/single_chain/wlc/thermodynamics/mod.jl b/src/physics/single_chain/wlc/thermodynamics/mod.jl index e69de29b..945dbfe3 100644 --- a/src/physics/single_chain/wlc/thermodynamics/mod.jl +++ b/src/physics/single_chain/wlc/thermodynamics/mod.jl @@ -0,0 +1,58 @@ +""" +The worm-like chain (WLC) model thermodynamics. +""" +module Thermodynamics + +using DocStringExtensions + +include("isometric/mod.jl") + +""" +The structure of the thermodynamics of the WLC model. + +$(FIELDS) +""" +struct WLC + """ + The number of links in the chain ``N_b``. + """ + number_of_links::UInt8 + """ + The length of each link in the chain ``\\ell_b`` in units of nm. + """ + link_length::Float64 + """ + The mass of each hinge in the chain ``m`` in units of kg/mol. + """ + hinge_mass::Float64 + """ + The persistance length of the chain in units of nm. + """ + persistance_length::Float64 + """ + The thermodynamic functions of the model in the isometric ensemble. + """ + isometric::Any +end + +""" +Initializes and returns an instance of the thermodynamics of the WLC model. + +$(TYPEDSIGNATURES) +""" +function WLC( + number_of_links::UInt8, + link_length::Float64, + hinge_mass::Float64, + persistance_length::Float64, +) + return WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + Isometric.WLC(number_of_links, link_length, hinge_mass, persistance_length), + ) +end + +end diff --git a/src/physics/single_chain/wlc/thermodynamics/test.jl b/src/physics/single_chain/wlc/thermodynamics/test.jl index e69de29b..2f26dcd1 100644 --- a/src/physics/single_chain/wlc/thermodynamics/test.jl +++ b/src/physics/single_chain/wlc/thermodynamics/test.jl @@ -0,0 +1,104 @@ +module Test + +using Test +using Polymers.Physics.SingleChain: parameters +using Polymers.Physics.SingleChain.Wlc.Thermodynamics: WLC + +@testset "physics::single_chain::wlc::thermodynamics::test::base::init" begin + @test isa( + WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ), + Any, + ) +end + +@testset "physics::single_chain::wlc::thermodynamics::test::base::number_of_links" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + @test WLC( + number_of_links, + parameters.link_length_reference, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).number_of_links == number_of_links + end +end + +@testset "physics::single_chain::wlc::thermodynamics::test::base::link_length" begin + for _ = 1:parameters.number_of_loops + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + link_length, + parameters.hinge_mass_reference, + parameters.persistance_length_reference, + ).link_length == link_length + end +end + +@testset "physics::single_chain::wlc::thermodynamics::test::base::hinge_mass" begin + for _ = 1:parameters.number_of_loops + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + hinge_mass, + parameters.persistance_length_reference, + ).hinge_mass == hinge_mass + end +end + +@testset "physics::single_chain::wlc::thermodynamics::test::base::persistance_length" begin + for _ = 1:parameters.number_of_loops + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test WLC( + parameters.number_of_links_minimum, + parameters.link_length_reference, + parameters.hinge_mass_reference, + persistance_length, + ).persistance_length == persistance_length + end +end + +@testset "physics::single_chain::wlc::thermodynamics::test::base::all_parameters" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + @test all( + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).number_of_links == number_of_links && + WLC(number_of_links, link_length, hinge_mass, persistance_length).link_length == + link_length && + WLC(number_of_links, link_length, hinge_mass, persistance_length).hinge_mass == + hinge_mass && + WLC( + number_of_links, + link_length, + hinge_mass, + persistance_length, + ).persistance_length == persistance_length, + ) + end +end + +end diff --git a/test/runtests.jl b/test/runtests.jl index 639950be..b699138a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,163 +1,167 @@ using Test using Polymers -include("../src/physics/single_chain/test.jl") -include("../src/physics/single_chain/ideal/test.jl") -include("../src/physics/single_chain/ideal/thermodynamics/test.jl") -include("../src/physics/single_chain/ideal/thermodynamics/isometric/test.jl") -include("../src/physics/single_chain/ideal/thermodynamics/isotensional/test.jl") -include("../src/physics/single_chain/fjc/test.jl") -include("../src/physics/single_chain/fjc/thermodynamics/test.jl") -include("../src/physics/single_chain/fjc/thermodynamics/isometric/test.jl") -include("../src/physics/single_chain/fjc/thermodynamics/isometric/legendre/test.jl") -include("../src/physics/single_chain/fjc/thermodynamics/isotensional/test.jl") -include("../src/physics/single_chain/fjc/thermodynamics/isotensional/legendre/test.jl") -include("../src/physics/single_chain/fjc/thermodynamics/modified_canonical/test.jl") -include( - "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/strong_potential/test.jl", -) -include( - "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/weak_potential/test.jl", -) -include("../src/physics/single_chain/efjc/test.jl") -include("../src/physics/single_chain/efjc/thermodynamics/test.jl") -include("../src/physics/single_chain/efjc/thermodynamics/isometric/test.jl") -include("../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/test.jl") -include( - "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/legendre/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -) -include("../src/physics/single_chain/efjc/thermodynamics/isotensional/test.jl") -include("../src/physics/single_chain/efjc/thermodynamics/isotensional/legendre/test.jl") -include("../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/test.jl") -include( - "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/legendre/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -) -include("../src/physics/single_chain/swfjc/test.jl") -include("../src/physics/single_chain/swfjc/thermodynamics/test.jl") -include("../src/physics/single_chain/swfjc/thermodynamics/isometric/test.jl") -include("../src/physics/single_chain/swfjc/thermodynamics/isometric/legendre/test.jl") -include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/test.jl") -include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/legendre/test.jl") -include("../src/physics/single_chain/ufjc/test.jl") -include("../src/physics/single_chain/ufjc/lennard_jones/test.jl") -include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.jl") -include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/test.jl") -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -) -include("../src/physics/single_chain/ufjc/log_squared/test.jl") -include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/test.jl") -include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/test.jl") -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -) -include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/test.jl") -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -) -include("../src/physics/single_chain/ufjc/morse/test.jl") -include("../src/physics/single_chain/ufjc/morse/thermodynamics/test.jl") -include("../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/test.jl") -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -) -include("../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/test.jl") -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/legendre/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/test.jl", -) -include( - "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -) +# include("../src/physics/single_chain/test.jl") +# include("../src/physics/single_chain/ideal/test.jl") +# include("../src/physics/single_chain/ideal/thermodynamics/test.jl") +# include("../src/physics/single_chain/ideal/thermodynamics/isometric/test.jl") +# include("../src/physics/single_chain/ideal/thermodynamics/isotensional/test.jl") +# include("../src/physics/single_chain/fjc/test.jl") +# include("../src/physics/single_chain/fjc/thermodynamics/test.jl") +# include("../src/physics/single_chain/fjc/thermodynamics/isometric/test.jl") +# include("../src/physics/single_chain/fjc/thermodynamics/isometric/legendre/test.jl") +# include("../src/physics/single_chain/fjc/thermodynamics/isotensional/test.jl") +# include("../src/physics/single_chain/fjc/thermodynamics/isotensional/legendre/test.jl") +# include("../src/physics/single_chain/fjc/thermodynamics/modified_canonical/test.jl") +# include( +# "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/strong_potential/test.jl", +# ) +# include( +# "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/weak_potential/test.jl", +# ) +# include("../src/physics/single_chain/efjc/test.jl") +# include("../src/physics/single_chain/efjc/thermodynamics/test.jl") +# include("../src/physics/single_chain/efjc/thermodynamics/isometric/test.jl") +# include("../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/test.jl") +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +# ) +# include("../src/physics/single_chain/efjc/thermodynamics/isotensional/test.jl") +# include("../src/physics/single_chain/efjc/thermodynamics/isotensional/legendre/test.jl") +# include("../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/test.jl") +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +# ) +# include("../src/physics/single_chain/swfjc/test.jl") +# include("../src/physics/single_chain/swfjc/thermodynamics/test.jl") +# include("../src/physics/single_chain/swfjc/thermodynamics/isometric/test.jl") +# include("../src/physics/single_chain/swfjc/thermodynamics/isometric/legendre/test.jl") +# include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/test.jl") +# include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/legendre/test.jl") +# include("../src/physics/single_chain/ufjc/test.jl") +# include("../src/physics/single_chain/ufjc/lennard_jones/test.jl") +# include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.jl") +# include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/test.jl") +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +# ) +# include("../src/physics/single_chain/ufjc/log_squared/test.jl") +# include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/test.jl") +# include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/test.jl") +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +# ) +# include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/test.jl") +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +# ) +# include("../src/physics/single_chain/ufjc/morse/test.jl") +# include("../src/physics/single_chain/ufjc/morse/thermodynamics/test.jl") +# include("../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/test.jl") +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +# ) +# include("../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/test.jl") +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/legendre/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/test.jl", +# ) +# include( +# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +# ) +include("../src/physics/single_chain/wlc/test.jl") +include("../src/physics/single_chain/wlc/thermodynamics/test.jl") +include("../src/physics/single_chain/wlc/thermodynamics/isometric/test.jl") +include("../src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl") From 92d5dc5862c5bee27b5696d69333a66d7d1e0a20 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 1 May 2023 15:22:19 -0600 Subject: [PATCH 21/21] jl --- Cargo.toml | 2 +- Project.toml | 2 +- .../fjc/thermodynamics/isometric/test.jl | 1 + .../thermodynamics/isometric/legendre/ex.rs | 16 +- .../thermodynamics/isometric/legendre/mod.jl | 96 +- .../thermodynamics/isometric/legendre/test.jl | 488 ++++++- .../wlc/thermodynamics/isometric/mod.jl | 214 ++- .../wlc/thermodynamics/isometric/test.jl | 1244 ++++++++++++++++- test/runtests.jl | 320 ++--- 9 files changed, 2144 insertions(+), 239 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index abb5b029..51f08011 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polymers" -version = "0.4.0" +version = "0.3.4" edition = "2021" description = "Polymers Modeling Library" license = "BSD-3-Clause" diff --git a/Project.toml b/Project.toml index 19d2273b..dec6f096 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Polymers" uuid = "8aef037c-a721-4e8a-9d81-eb7093daef2c" authors = ["mrbuche "] -version = "0.4.0" +version = "0.3.4" [deps] DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" diff --git a/src/physics/single_chain/fjc/thermodynamics/isometric/test.jl b/src/physics/single_chain/fjc/thermodynamics/isometric/test.jl index 58b9c3db..45bb8381 100644 --- a/src/physics/single_chain/fjc/thermodynamics/isometric/test.jl +++ b/src/physics/single_chain/fjc/thermodynamics/isometric/test.jl @@ -1557,4 +1557,5 @@ end abs(residual_rel) <= 1.0 / sqrt(number_of_links) end end + end diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs index 7c087bf2..06a13819 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/ex.rs @@ -1,40 +1,40 @@ #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_gibbs_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_gibbs_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 { super::gibbs_free_energy(&number_of_links, &link_length, &hinge_mass, &persistance_length, &end_to_end_length, &temperature) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 { super::gibbs_free_energy_per_link(&number_of_links, &link_length, &hinge_mass, &persistance_length, &end_to_end_length, &temperature) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_relative_gibbs_free_energy(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_relative_gibbs_free_energy(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 { super::relative_gibbs_free_energy(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_relative_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_relative_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, persistance_length: f64, end_to_end_length: f64, temperature: f64) -> f64 { super::relative_gibbs_free_energy_per_link(&number_of_links, &link_length, &persistance_length, &end_to_end_length, &temperature) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_gibbs_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_gibbs_free_energy(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 { super::nondimensional_gibbs_free_energy(&number_of_links, &link_length, &hinge_mass, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_gibbs_free_energy_per_link(number_of_links: u8, link_length: f64, hinge_mass: f64, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64, temperature: f64) -> f64 { super::nondimensional_gibbs_free_energy_per_link(&number_of_links, &link_length, &hinge_mass, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link, &temperature) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_gibbs_free_energy(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_relative_gibbs_free_energy(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 { super::nondimensional_relative_gibbs_free_energy(&number_of_links, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) } #[no_mangle] -pub extern fn physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_gibbs_free_energy_per_link(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 +pub extern fn physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_relative_gibbs_free_energy_per_link(number_of_links: u8, nondimensional_persistance_length: f64, nondimensional_end_to_end_length_per_link: f64) -> f64 { super::nondimensional_relative_gibbs_free_energy_per_link(&number_of_links, &nondimensional_persistance_length, &nondimensional_end_to_end_length_per_link) } \ No newline at end of file diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl index d3f20078..5eb53628 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/mod.jl @@ -1,5 +1,5 @@ """ -The worm-like chain (FJC) model thermodynamics in the isometric ensemble approximated using a Legendre transformation. +The worm-like chain (WLC) model thermodynamics in the isometric ensemble approximated using a Legendre transformation. """ module Legendre @@ -7,10 +7,10 @@ using DocStringExtensions using .......Polymers: PROJECT_ROOT """ -The structure of the thermodynamics of the FJC model in the isometric ensemble approximated using a Legendre transformation. +The structure of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. $(FIELDS) """ -struct FJC +struct WLC """ The number of links in the chain ``N_b``. """ @@ -27,7 +27,7 @@ struct FJC The persistance length of the chain in units of nm. """ persistance_length::Float64 - normalization_nondimensional_equilibrium_distribution::Float64 + nondimensional_persistance_length::Float64 """ The Gibbs free energy ``\\varphi`` as a function of the applied end-to-end length ``\\xi`` and temperature ``T``. """ @@ -78,6 +78,7 @@ function gibbs_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -86,6 +87,7 @@ function gibbs_free_energy( number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ) -> ccall( @@ -94,16 +96,18 @@ function gibbs_free_energy( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ) @@ -119,6 +123,7 @@ function gibbs_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -127,6 +132,7 @@ function gibbs_free_energy_per_link( number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ) -> ccall( @@ -135,16 +141,18 @@ function gibbs_free_energy_per_link( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ) @@ -159,24 +167,33 @@ $(TYPEDSIGNATURES) function relative_gibbs_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + number_of_links_i, + link_length_i, + persistance_length_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_legendre_relative_gibbs_free_energy, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ) @@ -191,24 +208,33 @@ $(TYPEDSIGNATURES) function relative_gibbs_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + number_of_links_i, + link_length_i, + persistance_length_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_legendre_relative_gibbs_free_energy_per_link, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ) @@ -224,6 +250,7 @@ function nondimensional_gibbs_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -232,6 +259,7 @@ function nondimensional_gibbs_free_energy( number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ) -> ccall( @@ -240,16 +268,18 @@ function nondimensional_gibbs_free_energy( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ), number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ) @@ -265,6 +295,7 @@ function nondimensional_gibbs_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -273,6 +304,7 @@ function nondimensional_gibbs_free_energy_per_link( number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ) -> ccall( @@ -281,16 +313,18 @@ function nondimensional_gibbs_free_energy_per_link( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ), number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ) @@ -304,20 +338,27 @@ $(TYPEDSIGNATURES) """ function nondimensional_relative_gibbs_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + number_of_links_i, + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_relative_gibbs_free_energy, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), + (UInt8, Float64, Float64), number_of_links_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, ), number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end @@ -330,44 +371,54 @@ $(TYPEDSIGNATURES) """ function nondimensional_relative_gibbs_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + number_of_links_i, + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_legendre_nondimensional_relative_gibbs_free_energy_per_link, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), + (UInt8, Float64, Float64), number_of_links_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, ), number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end """ -Initializes and returns an instance of the thermodynamics of the FJC model in the isometric ensemble approximated using a Legendre transformation. +Initializes and returns an instance of the thermodynamics of the WLC model in the isometric ensemble approximated using a Legendre transformation. $(TYPEDSIGNATURES) """ -function FJC( +function WLC( number_of_links::UInt8, link_length::Float64, hinge_mass::Float64, persistance_length::Float64, ) - return FJC( + nondimensional_persistance_length = persistance_length / number_of_links / link_length + return WLC( number_of_links, link_length, hinge_mass, persistance_length, + nondimensional_persistance_length, (end_to_end_length, temperature) -> gibbs_free_energy( number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ), @@ -375,18 +426,21 @@ function FJC( number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ), (end_to_end_length, temperature) -> relative_gibbs_free_energy( number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ), (end_to_end_length, temperature) -> relative_gibbs_free_energy_per_link( number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ), @@ -395,6 +449,7 @@ function FJC( number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ), @@ -403,17 +458,20 @@ function FJC( number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ), (nondimensional_end_to_end_length_per_link) -> nondimensional_relative_gibbs_free_energy( number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ), (nondimensional_end_to_end_length_per_link) -> nondimensional_relative_gibbs_free_energy_per_link( number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ), ) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl index d79868bc..b852aacb 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/legendre/test.jl @@ -1,7 +1,8 @@ module Test using Test -using Polymers.Physics.SingleChain: parameters +using Polymers.Physics: BOLTZMANN_CONSTANT +using Polymers.Physics.SingleChain: ZERO, parameters using Polymers.Physics.SingleChain.Wlc.Thermodynamics.Isometric.Legendre: WLC @testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::base::init" begin @@ -101,4 +102,489 @@ end end end +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::nondimensional::gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + gibbs_free_energy = model.gibbs_free_energy(end_to_end_length, temperature) + residual_abs = + gibbs_free_energy / BOLTZMANN_CONSTANT / temperature - + nondimensional_gibbs_free_energy + residual_rel = residual_abs / nondimensional_gibbs_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::nondimensional::gibbs_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_gibbs_free_energy_per_link = + model.nondimensional_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + gibbs_free_energy_per_link = + model.gibbs_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + gibbs_free_energy_per_link / BOLTZMANN_CONSTANT / temperature - + nondimensional_gibbs_free_energy_per_link + residual_rel = residual_abs / nondimensional_gibbs_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::nondimensional::relative_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_relative_gibbs_free_energy = + model.nondimensional_relative_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_gibbs_free_energy = + model.relative_gibbs_free_energy(end_to_end_length, temperature) + residual_abs = + relative_gibbs_free_energy / BOLTZMANN_CONSTANT / temperature - + nondimensional_relative_gibbs_free_energy + residual_rel = residual_abs / nondimensional_relative_gibbs_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::nondimensional::relative_gibbs_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_relative_gibbs_free_energy_per_link = + model.nondimensional_relative_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_gibbs_free_energy_per_link = + model.relative_gibbs_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + relative_gibbs_free_energy_per_link / BOLTZMANN_CONSTANT / temperature - + nondimensional_relative_gibbs_free_energy_per_link + residual_rel = residual_abs / nondimensional_relative_gibbs_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::per_link::gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + gibbs_free_energy = model.gibbs_free_energy(end_to_end_length, temperature) + gibbs_free_energy_per_link = + model.gibbs_free_energy_per_link(end_to_end_length, temperature) + residual_abs = gibbs_free_energy / number_of_links - gibbs_free_energy_per_link + residual_rel = residual_abs / gibbs_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::per_link::relative_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_gibbs_free_energy = + model.relative_gibbs_free_energy(end_to_end_length, temperature) + relative_gibbs_free_energy_per_link = + model.relative_gibbs_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + relative_gibbs_free_energy / number_of_links - + relative_gibbs_free_energy_per_link + residual_rel = residual_abs / relative_gibbs_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::per_link::nondimensional_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_gibbs_free_energy_per_link = + model.nondimensional_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + residual_abs = + nondimensional_gibbs_free_energy / number_of_links - + nondimensional_gibbs_free_energy_per_link + residual_rel = residual_abs / nondimensional_gibbs_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::per_link::nondimensional_relative_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_relative_gibbs_free_energy = + model.nondimensional_relative_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_relative_gibbs_free_energy_per_link = + model.nondimensional_relative_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + residual_abs = + nondimensional_relative_gibbs_free_energy / number_of_links - + nondimensional_relative_gibbs_free_energy_per_link + residual_rel = residual_abs / nondimensional_relative_gibbs_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::relative::gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + gibbs_free_energy = model.gibbs_free_energy(end_to_end_length, temperature) + gibbs_free_energy_0 = + model.gibbs_free_energy(ZERO * number_of_links * link_length, temperature) + relative_gibbs_free_energy = + model.relative_gibbs_free_energy(end_to_end_length, temperature) + residual_abs = gibbs_free_energy - gibbs_free_energy_0 - relative_gibbs_free_energy + residual_rel = residual_abs / relative_gibbs_free_energy + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::relative::gibbs_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + gibbs_free_energy_per_link = + model.gibbs_free_energy_per_link(end_to_end_length, temperature) + gibbs_free_energy_per_link_0 = model.gibbs_free_energy_per_link( + ZERO * number_of_links * link_length, + temperature, + ) + relative_gibbs_free_energy_per_link = + model.relative_gibbs_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + gibbs_free_energy_per_link - gibbs_free_energy_per_link_0 - + relative_gibbs_free_energy_per_link + residual_rel = residual_abs / relative_gibbs_free_energy_per_link + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::relative::nondimensional_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_gibbs_free_energy = model.nondimensional_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_gibbs_free_energy_0 = + model.nondimensional_gibbs_free_energy(ZERO, temperature) + nondimensional_relative_gibbs_free_energy = + model.nondimensional_relative_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + ) + residual_abs = + nondimensional_gibbs_free_energy - nondimensional_gibbs_free_energy_0 - + nondimensional_relative_gibbs_free_energy + residual_rel = residual_abs / nondimensional_relative_gibbs_free_energy + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::relative::nondimensional_gibbs_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_gibbs_free_energy_per_link = + model.nondimensional_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_gibbs_free_energy_per_link_0 = + model.nondimensional_gibbs_free_energy_per_link(ZERO, temperature) + nondimensional_relative_gibbs_free_energy_per_link = + model.nondimensional_relative_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + residual_abs = + nondimensional_gibbs_free_energy_per_link - + nondimensional_gibbs_free_energy_per_link_0 - + nondimensional_relative_gibbs_free_energy_per_link + residual_rel = residual_abs / nondimensional_relative_gibbs_free_energy_per_link + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::zero::relative_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + relative_gibbs_free_energy_0 = model.relative_gibbs_free_energy( + ZERO * number_of_links * link_length, + temperature, + ) + @test abs(relative_gibbs_free_energy_0) <= + ZERO * number_of_links * BOLTZMANN_CONSTANT * temperature + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::zero::relative_gibbs_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + relative_gibbs_free_energy_per_link_0 = model.relative_gibbs_free_energy_per_link( + ZERO * number_of_links * link_length, + temperature, + ) + @test abs(relative_gibbs_free_energy_per_link_0) <= + ZERO * BOLTZMANN_CONSTANT * temperature + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::zero::nondimensional_relative_gibbs_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_relative_gibbs_free_energy_0 = + model.nondimensional_relative_gibbs_free_energy(ZERO) + @test abs(nondimensional_relative_gibbs_free_energy_0) <= ZERO * number_of_links + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::legendre::test::zero::nondimensional_relative_gibbs_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_relative_gibbs_free_energy_per_link_0 = + model.nondimensional_relative_gibbs_free_energy_per_link(ZERO) + @test abs(nondimensional_relative_gibbs_free_energy_per_link_0) <= ZERO + end +end + end diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl index 6f64ca4a..48eb64da 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/mod.jl @@ -31,6 +31,7 @@ struct WLC The persistance length of the chain in units of nm. """ persistance_length::Float64 + nondimensional_persistance_length::Float64 normalization_nondimensional_equilibrium_distribution::Float64 """ The thermodynamic functions of the model in the isometric ensemble approximated using a Legendre transformation. @@ -107,24 +108,33 @@ $(TYPEDSIGNATURES) function force( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + number_of_links_i, + link_length_i, + persistance_length_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_force, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ) @@ -142,20 +152,27 @@ $(TYPEDSIGNATURES) """ function nondimensional_force( number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + number_of_links_i, + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_force, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), + (UInt8, Float64, Float64), number_of_links_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, ), number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end @@ -174,6 +191,7 @@ function helmholtz_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -182,6 +200,7 @@ function helmholtz_free_energy( number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ) -> ccall( @@ -190,16 +209,18 @@ function helmholtz_free_energy( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ) @@ -215,6 +236,7 @@ function helmholtz_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -223,6 +245,7 @@ function helmholtz_free_energy_per_link( number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ) -> ccall( @@ -231,16 +254,18 @@ function helmholtz_free_energy_per_link( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ) @@ -259,24 +284,33 @@ $(TYPEDSIGNATURES) function relative_helmholtz_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + number_of_links_i, + link_length_i, + persistance_length_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_relative_helmholtz_free_energy, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ) @@ -291,24 +325,33 @@ $(TYPEDSIGNATURES) function relative_helmholtz_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, end_to_end_length::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i, temperature_i) -> ccall( + ( + number_of_links_i, + link_length_i, + persistance_length_i, + end_to_end_length_i, + temperature_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_relative_helmholtz_free_energy_per_link, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, + persistance_length_i, end_to_end_length_i, temperature_i, ), number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ) @@ -324,6 +367,7 @@ function nondimensional_helmholtz_free_energy( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -332,6 +376,7 @@ function nondimensional_helmholtz_free_energy( number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ) -> ccall( @@ -340,16 +385,18 @@ function nondimensional_helmholtz_free_energy( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ), number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ) @@ -365,6 +412,7 @@ function nondimensional_helmholtz_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, hinge_mass::Union{Float64,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, temperature::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} @@ -373,6 +421,7 @@ function nondimensional_helmholtz_free_energy_per_link( number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ) -> ccall( @@ -381,16 +430,18 @@ function nondimensional_helmholtz_free_energy_per_link( string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64, Float64, Float64, Float64), + (UInt8, Float64, Float64, Float64, Float64, Float64), number_of_links_i, link_length_i, hinge_mass_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, temperature_i, ), number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ) @@ -407,21 +458,24 @@ parameterized by the number of links ``N_b``, $(TYPEDSIGNATURES) """ function nondimensional_relative_helmholtz_free_energy( - number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_helmholtz_free_energy, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), - number_of_links_i, + (Float64, Float64), + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, ), - number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end @@ -438,20 +492,27 @@ $(TYPEDSIGNATURES) """ function nondimensional_relative_helmholtz_free_energy_per_link( number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + number_of_links_i, + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_relative_helmholtz_free_energy_per_link, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), + (UInt8, Float64, Float64), number_of_links_i, + nondimensional_persistance_length_i, nondimensional_end_to_end_length_per_link_i, ), number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end @@ -469,22 +530,28 @@ $(TYPEDSIGNATURES) function equilibrium_distribution( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, + normalization_nondimensional_equilibrium_distribution::Float64, end_to_end_length::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i) -> ccall( - ( - :physics_single_chain_wlc_thermodynamics_isometric_equilibrium_distribution, - string(PROJECT_ROOT, "target/debug/libpolymers"), + (number_of_links_i, link_length_i, persistance_length_i, end_to_end_length_i) -> + ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_equilibrium_distribution, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + persistance_length_i, + normalization_nondimensional_equilibrium_distribution, + end_to_end_length_i, ), - Float64, - (UInt8, Float64, Float64), - number_of_links_i, - link_length_i, - end_to_end_length_i, - ), number_of_links, link_length, + persistance_length, end_to_end_length, ) end @@ -501,20 +568,29 @@ $(TYPEDSIGNATURES) """ function nondimensional_equilibrium_distribution( number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, + normalization_nondimensional_equilibrium_distribution::Float64, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + number_of_links_i, + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_equilibrium_distribution, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), + (UInt8, Float64, Float64, Float64), number_of_links_i, + nondimensional_persistance_length_i, + normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link_i, ), number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end @@ -532,22 +608,28 @@ $(TYPEDSIGNATURES) function equilibrium_radial_distribution( number_of_links::Union{UInt8,Vector,Matrix,Array}, link_length::Union{Float64,Vector,Matrix,Array}, + persistance_length::Union{Float64,Vector,Matrix,Array}, + normalization_nondimensional_equilibrium_distribution::Float64, end_to_end_length::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, link_length_i, end_to_end_length_i) -> ccall( - ( - :physics_single_chain_wlc_thermodynamics_isometric_equilibrium_radial_distribution, - string(PROJECT_ROOT, "target/debug/libpolymers"), + (number_of_links_i, link_length_i, persistance_length_i, end_to_end_length_i) -> + ccall( + ( + :physics_single_chain_wlc_thermodynamics_isometric_equilibrium_radial_distribution, + string(PROJECT_ROOT, "target/debug/libpolymers"), + ), + Float64, + (UInt8, Float64, Float64, Float64, Float64), + number_of_links_i, + link_length_i, + persistance_length_i, + normalization_nondimensional_equilibrium_distribution, + end_to_end_length_i, ), - Float64, - (UInt8, Float64, Float64), - number_of_links_i, - link_length_i, - end_to_end_length_i, - ), number_of_links, link_length, + persistance_length, end_to_end_length, ) end @@ -564,20 +646,29 @@ $(TYPEDSIGNATURES) """ function nondimensional_equilibrium_radial_distribution( number_of_links::Union{UInt8,Vector,Matrix,Array}, + nondimensional_persistance_length::Union{Float64,Vector,Matrix,Array}, + normalization_nondimensional_equilibrium_distribution::Float64, nondimensional_end_to_end_length_per_link::Union{Float64,Vector,Matrix,Array}, )::Union{Float64,Vector,Matrix,Array} return broadcast( - (number_of_links_i, nondimensional_end_to_end_length_per_link_i) -> ccall( + ( + number_of_links_i, + nondimensional_persistance_length_i, + nondimensional_end_to_end_length_per_link_i, + ) -> ccall( ( :physics_single_chain_wlc_thermodynamics_isometric_nondimensional_equilibrium_radial_distribution, string(PROJECT_ROOT, "target/debug/libpolymers"), ), Float64, - (UInt8, Float64), + (UInt8, Float64, Float64, Float64), number_of_links_i, + nondimensional_persistance_length_i, + normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link_i, ), number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ) end @@ -593,10 +684,12 @@ function WLC( hinge_mass::Float64, persistance_length::Float64, ) + nondimensional_persistance_length = persistance_length / number_of_links / link_length normalization_nondimensional_equilibrium_distribution = integrate( nondimensional_end_to_end_length_per_link -> nondimensional_equilibrium_radial_distribution( number_of_links, + nondimensional_persistance_length, 1.0, nondimensional_end_to_end_length_per_link, ), @@ -609,18 +702,26 @@ function WLC( link_length, hinge_mass, persistance_length, + nondimensional_persistance_length, normalization_nondimensional_equilibrium_distribution, Legendre.WLC(number_of_links, link_length, hinge_mass, persistance_length), - (end_to_end_length, temperature) -> - force(number_of_links, link_length, end_to_end_length, temperature), + (end_to_end_length, temperature) -> force( + number_of_links, + link_length, + persistance_length, + end_to_end_length, + temperature, + ), (nondimensional_end_to_end_length_per_link) -> nondimensional_force( number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ), (end_to_end_length, temperature) -> helmholtz_free_energy( number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ), @@ -628,18 +729,21 @@ function WLC( number_of_links, link_length, hinge_mass, + persistance_length, end_to_end_length, temperature, ), (end_to_end_length, temperature) -> relative_helmholtz_free_energy( number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ), (end_to_end_length, temperature) -> relative_helmholtz_free_energy_per_link( number_of_links, link_length, + persistance_length, end_to_end_length, temperature, ), @@ -648,6 +752,7 @@ function WLC( number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ), @@ -656,34 +761,47 @@ function WLC( number_of_links, link_length, hinge_mass, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, temperature, ), (nondimensional_end_to_end_length_per_link) -> nondimensional_relative_helmholtz_free_energy( - number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ), (nondimensional_end_to_end_length_per_link) -> nondimensional_relative_helmholtz_free_energy_per_link( number_of_links, + nondimensional_persistance_length, nondimensional_end_to_end_length_per_link, ), - (end_to_end_length) -> - equilibrium_distribution(number_of_links, link_length, end_to_end_length), + (end_to_end_length) -> equilibrium_distribution( + number_of_links, + link_length, + persistance_length, + normalization_nondimensional_equilibrium_distribution, + end_to_end_length, + ), (nondimensional_end_to_end_length_per_link) -> nondimensional_equilibrium_distribution( number_of_links, + nondimensional_persistance_length, + normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link, ), (end_to_end_length) -> equilibrium_radial_distribution( number_of_links, link_length, + persistance_length, + normalization_nondimensional_equilibrium_distribution, end_to_end_length, ), (nondimensional_end_to_end_length_per_link) -> nondimensional_equilibrium_radial_distribution( number_of_links, + nondimensional_persistance_length, + normalization_nondimensional_equilibrium_distribution, nondimensional_end_to_end_length_per_link, ), ) diff --git a/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl b/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl index bdfcc637..15a60472 100644 --- a/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl +++ b/src/physics/single_chain/wlc/thermodynamics/isometric/test.jl @@ -1,7 +1,8 @@ module Test using Test -using Polymers.Physics.SingleChain: parameters +using Polymers.Physics: BOLTZMANN_CONSTANT +using Polymers.Physics.SingleChain: ONE, ZERO, POINTS, integrate, parameters using Polymers.Physics.SingleChain.Wlc.Thermodynamics.Isometric: WLC @testset "physics::single_chain::wlc::thermodynamics::isometric::test::base::init" begin @@ -101,4 +102,1245 @@ end end end +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::normalization::equilibrium_distribution" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + normalization = integrate( + end_to_end_length -> + 4.0 * + pi * + end_to_end_length^2 * + model.equilibrium_distribution(end_to_end_length), + ZERO, + ONE * number_of_links * link_length, + POINTS, + ) + @test abs(normalization - 1.0) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::normalization::equilibrium_radial_distribution" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + normalization = integrate( + end_to_end_length -> + model.equilibrium_radial_distribution(end_to_end_length), + ZERO, + ONE * number_of_links * link_length, + POINTS, + ) + @test abs(normalization - 1.0) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::normalization::nondimensional_equilibrium_distribution" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + normalization = integrate( + nondimensional_end_to_end_length_per_link -> + 4.0 * + pi * + nondimensional_end_to_end_length_per_link^2 * + model.nondimensional_equilibrium_distribution( + nondimensional_end_to_end_length_per_link, + ), + ZERO, + ONE, + POINTS, + ) + @test abs(normalization - 1.0) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::normalization::nondimensional_equilibrium_radial_distribution" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + normalization = integrate( + nondimensional_end_to_end_length_per_link -> + model.nondimensional_equilibrium_radial_distribution( + nondimensional_end_to_end_length_per_link, + ), + ZERO, + ONE, + POINTS, + ) + @test abs(normalization - 1.0) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::nondimensional::force" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_force = + model.nondimensional_force(nondimensional_end_to_end_length_per_link) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + force = model.force(end_to_end_length, temperature) + residual_abs = + force / BOLTZMANN_CONSTANT / temperature * link_length - nondimensional_force + residual_rel = residual_abs / nondimensional_force + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::nondimensional::helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + helmholtz_free_energy = model.helmholtz_free_energy(end_to_end_length, temperature) + residual_abs = + helmholtz_free_energy / BOLTZMANN_CONSTANT / temperature - + nondimensional_helmholtz_free_energy + residual_rel = residual_abs / nondimensional_helmholtz_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::nondimensional::helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_helmholtz_free_energy_per_link = + model.nondimensional_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + helmholtz_free_energy_per_link = + model.helmholtz_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + helmholtz_free_energy_per_link / BOLTZMANN_CONSTANT / temperature - + nondimensional_helmholtz_free_energy_per_link + residual_rel = residual_abs / nondimensional_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::nondimensional::relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_relative_helmholtz_free_energy = + model.nondimensional_relative_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_helmholtz_free_energy = + model.relative_helmholtz_free_energy(end_to_end_length, temperature) + residual_abs = + relative_helmholtz_free_energy / BOLTZMANN_CONSTANT / temperature - + nondimensional_relative_helmholtz_free_energy + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::nondimensional::relative_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_relative_helmholtz_free_energy_per_link = + model.nondimensional_relative_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_helmholtz_free_energy_per_link = + model.relative_helmholtz_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + relative_helmholtz_free_energy_per_link / BOLTZMANN_CONSTANT / temperature - + nondimensional_relative_helmholtz_free_energy_per_link + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::per_link::helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + helmholtz_free_energy = model.helmholtz_free_energy(end_to_end_length, temperature) + helmholtz_free_energy_per_link = + model.helmholtz_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + helmholtz_free_energy / number_of_links - helmholtz_free_energy_per_link + residual_rel = residual_abs / helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::per_link::relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_helmholtz_free_energy = + model.relative_helmholtz_free_energy(end_to_end_length, temperature) + relative_helmholtz_free_energy_per_link = + model.relative_helmholtz_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + relative_helmholtz_free_energy / number_of_links - + relative_helmholtz_free_energy_per_link + residual_rel = residual_abs / relative_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::per_link::nondimensional_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_helmholtz_free_energy_per_link = + model.nondimensional_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + residual_abs = + nondimensional_helmholtz_free_energy / number_of_links - + nondimensional_helmholtz_free_energy_per_link + residual_rel = residual_abs / nondimensional_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::per_link::nondimensional_relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_relative_helmholtz_free_energy = + model.nondimensional_relative_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_relative_helmholtz_free_energy_per_link = + model.nondimensional_relative_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + residual_abs = + nondimensional_relative_helmholtz_free_energy / number_of_links - + nondimensional_relative_helmholtz_free_energy_per_link + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::relative::helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + helmholtz_free_energy = model.helmholtz_free_energy(end_to_end_length, temperature) + helmholtz_free_energy_0 = + model.helmholtz_free_energy(ZERO * number_of_links * link_length, temperature) + relative_helmholtz_free_energy = + model.relative_helmholtz_free_energy(end_to_end_length, temperature) + residual_abs = + helmholtz_free_energy - helmholtz_free_energy_0 - relative_helmholtz_free_energy + residual_rel = residual_abs / relative_helmholtz_free_energy + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::relative::helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + helmholtz_free_energy_per_link = + model.helmholtz_free_energy_per_link(end_to_end_length, temperature) + helmholtz_free_energy_per_link_0 = model.helmholtz_free_energy_per_link( + ZERO * number_of_links * link_length, + temperature, + ) + relative_helmholtz_free_energy_per_link = + model.relative_helmholtz_free_energy_per_link(end_to_end_length, temperature) + residual_abs = + helmholtz_free_energy_per_link - helmholtz_free_energy_per_link_0 - + relative_helmholtz_free_energy_per_link + residual_rel = residual_abs / relative_helmholtz_free_energy_per_link + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::relative::nondimensional_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_helmholtz_free_energy_0 = + model.nondimensional_helmholtz_free_energy(ZERO, temperature) + nondimensional_relative_helmholtz_free_energy = + model.nondimensional_relative_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + ) + residual_abs = + nondimensional_helmholtz_free_energy - nondimensional_helmholtz_free_energy_0 - + nondimensional_relative_helmholtz_free_energy + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::relative::nondimensional_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_helmholtz_free_energy_per_link = + model.nondimensional_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_helmholtz_free_energy_per_link_0 = + model.nondimensional_helmholtz_free_energy_per_link(ZERO, temperature) + nondimensional_relative_helmholtz_free_energy_per_link = + model.nondimensional_relative_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + residual_abs = + nondimensional_helmholtz_free_energy_per_link - + nondimensional_helmholtz_free_energy_per_link_0 - + nondimensional_relative_helmholtz_free_energy_per_link + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy_per_link + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::zero::relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + relative_helmholtz_free_energy_0 = model.relative_helmholtz_free_energy( + ZERO * number_of_links * link_length, + temperature, + ) + @test abs(relative_helmholtz_free_energy_0) <= + ZERO * number_of_links * BOLTZMANN_CONSTANT * temperature + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::zero::relative_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + relative_helmholtz_free_energy_per_link_0 = + model.relative_helmholtz_free_energy_per_link( + ZERO * number_of_links * link_length, + temperature, + ) + @test abs(relative_helmholtz_free_energy_per_link_0) <= + ZERO * BOLTZMANN_CONSTANT * temperature + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::zero::nondimensional_relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_relative_helmholtz_free_energy_0 = + model.nondimensional_relative_helmholtz_free_energy(ZERO) + @test abs(nondimensional_relative_helmholtz_free_energy_0) <= ZERO * number_of_links + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::zero::nondimensional_relative_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_relative_helmholtz_free_energy_per_link_0 = + model.nondimensional_relative_helmholtz_free_energy_per_link(ZERO) + @test abs(nondimensional_relative_helmholtz_free_energy_per_link_0) <= ZERO + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::zero::equilibrium_radial_distribution" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + equilibrium_radial_distribution_0 = + model.equilibrium_radial_distribution(ZERO * number_of_links * link_length) + @test abs(equilibrium_radial_distribution_0) <= ZERO + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::zero::nondimensional_equilibrium_radial_distribution" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_equilibrium_radial_distribution_0 = + model.equilibrium_radial_distribution(ZERO) + @test abs(nondimensional_equilibrium_radial_distribution_0) <= ZERO + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::connection::force" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + force = model.force(end_to_end_length, temperature) + h = parameters.rel_tol * number_of_links * link_length + force_from_derivative = + ( + model.relative_helmholtz_free_energy( + end_to_end_length + 0.5 * h, + temperature, + ) - model.relative_helmholtz_free_energy( + end_to_end_length - 0.5 * h, + temperature, + ) + ) / h + residual_abs = force - force_from_derivative + residual_rel = residual_abs / force + @test abs(residual_rel) <= h + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::connection::nondimensional_force" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_force = + model.nondimensional_force(nondimensional_end_to_end_length_per_link) + h = parameters.rel_tol + nondimensional_force_from_derivative = + ( + model.nondimensional_relative_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link + 0.5 * h, + ) - model.nondimensional_relative_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link - 0.5 * h, + ) + ) / h + residual_abs = nondimensional_force - nondimensional_force_from_derivative + residual_rel = residual_abs / nondimensional_force + @test abs(residual_rel) <= h + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::connection::relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + relative_helmholtz_free_energy = + model.relative_helmholtz_free_energy(end_to_end_length, temperature) + relative_helmholtz_free_energy_from_connection = + BOLTZMANN_CONSTANT * + temperature * + log(( + model.equilibrium_distribution(ZERO * number_of_links * link_length) / + model.equilibrium_distribution(end_to_end_length) + )) + residual_abs = + relative_helmholtz_free_energy - relative_helmholtz_free_energy_from_connection + residual_rel = residual_abs / relative_helmholtz_free_energy + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::connection::nondimensional_relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + nondimensional_relative_helmholtz_free_energy = + model.nondimensional_relative_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_relative_helmholtz_free_energy_from_connection = log(( + model.nondimensional_equilibrium_distribution(ZERO) / + model.nondimensional_equilibrium_distribution( + nondimensional_end_to_end_length_per_link, + ) + )) + residual_abs = + nondimensional_relative_helmholtz_free_energy - + nondimensional_relative_helmholtz_free_energy_from_connection + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy + @test abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + force = model.force(end_to_end_length, temperature) + helmholtz_free_energy = model.helmholtz_free_energy(end_to_end_length, temperature) + helmholtz_free_energy_legendre = + model.legendre.gibbs_free_energy(end_to_end_length, temperature) + + force * end_to_end_length + residual_abs = helmholtz_free_energy - helmholtz_free_energy_legendre + residual_rel = residual_abs / helmholtz_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + end_to_end_length_per_link = nondimensional_end_to_end_length_per_link * link_length + force = model.force(end_to_end_length, temperature) + helmholtz_free_energy_per_link = + model.helmholtz_free_energy_per_link(end_to_end_length, temperature) + helmholtz_free_energy_per_link_legendre = + model.legendre.gibbs_free_energy_per_link(end_to_end_length, temperature) + + force * end_to_end_length_per_link + residual_abs = + helmholtz_free_energy_per_link - helmholtz_free_energy_per_link_legendre + residual_rel = residual_abs / helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + force = model.force(end_to_end_length, temperature) + force_0 = model.force(ZERO * number_of_links * link_length, temperature) + relative_helmholtz_free_energy = + model.relative_helmholtz_free_energy(end_to_end_length, temperature) + relative_helmholtz_free_energy_legendre = + model.legendre.relative_gibbs_free_energy(end_to_end_length, temperature) + + force * end_to_end_length - force_0 * ZERO * number_of_links * link_length + residual_abs = + relative_helmholtz_free_energy - relative_helmholtz_free_energy_legendre + residual_rel = residual_abs / relative_helmholtz_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::relative_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + end_to_end_length_per_link = nondimensional_end_to_end_length_per_link * link_length + force = model.force(end_to_end_length, temperature) + force_0 = model.force(ZERO * number_of_links * link_length, temperature) + relative_helmholtz_free_energy_per_link = + model.relative_helmholtz_free_energy_per_link(end_to_end_length, temperature) + relative_helmholtz_free_energy_per_link_legendre = + model.legendre.relative_gibbs_free_energy_per_link( + end_to_end_length, + temperature, + ) + force * end_to_end_length_per_link - force_0 * ZERO * link_length + residual_abs = + relative_helmholtz_free_energy_per_link - + relative_helmholtz_free_energy_per_link_legendre + residual_rel = residual_abs / relative_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::nondimensional_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links + nondimensional_force = + model.nondimensional_force(nondimensional_end_to_end_length_per_link) + nondimensional_helmholtz_free_energy = model.nondimensional_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_helmholtz_free_energy_legendre = + model.legendre.nondimensional_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_force * nondimensional_end_to_end_length + residual_abs = + nondimensional_helmholtz_free_energy - + nondimensional_helmholtz_free_energy_legendre + residual_rel = residual_abs / nondimensional_helmholtz_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::nondimensional_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + nondimensional_force = + model.nondimensional_force(nondimensional_end_to_end_length_per_link) + nondimensional_helmholtz_free_energy_per_link = + model.nondimensional_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_helmholtz_free_energy_per_link_legendre = + model.legendre.nondimensional_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + temperature, + ) + nondimensional_force * nondimensional_end_to_end_length_per_link + residual_abs = + nondimensional_helmholtz_free_energy_per_link - + nondimensional_helmholtz_free_energy_per_link_legendre + residual_rel = residual_abs / nondimensional_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::nondimensional_relative_helmholtz_free_energy" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + nondimensional_end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links + nondimensional_force = + model.nondimensional_force(nondimensional_end_to_end_length_per_link) + nondimensional_force_0 = model.nondimensional_force(ZERO) + nondimensional_relative_helmholtz_free_energy = + model.nondimensional_relative_helmholtz_free_energy( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_relative_helmholtz_free_energy_legendre = + model.legendre.nondimensional_relative_gibbs_free_energy( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_force * nondimensional_end_to_end_length - + nondimensional_force_0 * ZERO * number_of_links + residual_abs = + nondimensional_relative_helmholtz_free_energy - + nondimensional_relative_helmholtz_free_energy_legendre + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre::nondimensional_relative_helmholtz_free_energy_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + nondimensional_force = + model.nondimensional_force(nondimensional_end_to_end_length_per_link) + nondimensional_force_0 = model.nondimensional_force(ZERO) + nondimensional_relative_helmholtz_free_energy_per_link = + model.nondimensional_relative_helmholtz_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_relative_helmholtz_free_energy_per_link_legendre = + model.legendre.nondimensional_relative_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link, + ) + nondimensional_force * nondimensional_end_to_end_length_per_link - + nondimensional_force_0 * ZERO + residual_abs = + nondimensional_relative_helmholtz_free_energy_per_link - + nondimensional_relative_helmholtz_free_energy_per_link_legendre + residual_rel = residual_abs / nondimensional_relative_helmholtz_free_energy_per_link + @test abs(residual_abs) <= parameters.abs_tol && + abs(residual_rel) <= parameters.rel_tol + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre_connection::end_to_end_length" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + h = parameters.rel_tol * number_of_links * link_length + end_to_end_length_from_derivative = + -( + model.legendre.relative_gibbs_free_energy( + end_to_end_length + 0.5 * h, + temperature, + ) - model.legendre.relative_gibbs_free_energy( + end_to_end_length - 0.5 * h, + temperature, + ) + ) / ( + model.force(end_to_end_length + 0.5 * h, temperature) - + model.force(end_to_end_length - 0.5 * h, temperature) + ) + residual_abs = end_to_end_length - end_to_end_length_from_derivative + residual_rel = residual_abs / end_to_end_length + @test abs(residual_rel) <= h + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre_connection::end_to_end_length_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + temperature = + parameters.temperature_reference + parameters.temperature_scale * (0.5 - rand()) + end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links * link_length + end_to_end_length_per_link = nondimensional_end_to_end_length_per_link * link_length + h = parameters.rel_tol * number_of_links * link_length + end_to_end_length_per_link_from_derivative = + -( + model.legendre.relative_gibbs_free_energy_per_link( + end_to_end_length + 0.5 * h, + temperature, + ) - model.legendre.relative_gibbs_free_energy_per_link( + end_to_end_length - 0.5 * h, + temperature, + ) + ) / ( + model.force(end_to_end_length + 0.5 * h, temperature) - + model.force(end_to_end_length - 0.5 * h, temperature) + ) + residual_abs = + end_to_end_length_per_link - end_to_end_length_per_link_from_derivative + residual_rel = residual_abs / end_to_end_length_per_link + @test abs(residual_rel) <= h + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre_connection::nondimensional_end_to_end_length" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + nondimensional_end_to_end_length = + nondimensional_end_to_end_length_per_link * number_of_links + h = parameters.rel_tol + nondimensional_end_to_end_length_from_derivative = + -( + model.legendre.nondimensional_relative_gibbs_free_energy( + nondimensional_end_to_end_length_per_link + 0.5 * h, + ) - model.legendre.nondimensional_relative_gibbs_free_energy( + nondimensional_end_to_end_length_per_link - 0.5 * h, + ) + ) / ( + model.nondimensional_force( + nondimensional_end_to_end_length_per_link + 0.5 * h, + ) - model.nondimensional_force( + nondimensional_end_to_end_length_per_link - 0.5 * h, + ) + ) + residual_abs = + nondimensional_end_to_end_length - + nondimensional_end_to_end_length_from_derivative + residual_rel = residual_abs / nondimensional_end_to_end_length + @test abs(residual_rel) <= h + end +end + +@testset "physics::single_chain::wlc::thermodynamics::isometric::test::legendre_connection::nondimensional_end_to_end_length_per_link" begin + for _ = 1:parameters.number_of_loops + number_of_links = + rand(parameters.number_of_links_minimum:parameters.number_of_links_maximum) + link_length = + parameters.link_length_reference + parameters.link_length_scale * (0.5 - rand()) + hinge_mass = + parameters.hinge_mass_reference + parameters.hinge_mass_scale * (0.5 - rand()) + persistance_length = + parameters.persistance_length_reference + + parameters.persistance_length_scale * (0.5 - rand()) + model = WLC(number_of_links, link_length, hinge_mass, persistance_length) + nondimensional_end_to_end_length_per_link = + parameters.nondimensional_end_to_end_length_per_link_reference + + parameters.nondimensional_end_to_end_length_per_link_scale * (0.5 - rand()) + h = parameters.rel_tol + nondimensional_end_to_end_length_per_link_from_derivative = + -( + model.legendre.nondimensional_relative_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link + 0.5 * h, + ) - model.legendre.nondimensional_relative_gibbs_free_energy_per_link( + nondimensional_end_to_end_length_per_link - 0.5 * h, + ) + ) / ( + model.nondimensional_force( + nondimensional_end_to_end_length_per_link + 0.5 * h, + ) - model.nondimensional_force( + nondimensional_end_to_end_length_per_link - 0.5 * h, + ) + ) + residual_abs = + nondimensional_end_to_end_length_per_link - + nondimensional_end_to_end_length_per_link_from_derivative + residual_rel = residual_abs / nondimensional_end_to_end_length_per_link + @test abs(residual_rel) <= h + end +end + end diff --git a/test/runtests.jl b/test/runtests.jl index b699138a..dec114fc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,166 +1,166 @@ using Test using Polymers -# include("../src/physics/single_chain/test.jl") -# include("../src/physics/single_chain/ideal/test.jl") -# include("../src/physics/single_chain/ideal/thermodynamics/test.jl") -# include("../src/physics/single_chain/ideal/thermodynamics/isometric/test.jl") -# include("../src/physics/single_chain/ideal/thermodynamics/isotensional/test.jl") -# include("../src/physics/single_chain/fjc/test.jl") -# include("../src/physics/single_chain/fjc/thermodynamics/test.jl") -# include("../src/physics/single_chain/fjc/thermodynamics/isometric/test.jl") -# include("../src/physics/single_chain/fjc/thermodynamics/isometric/legendre/test.jl") -# include("../src/physics/single_chain/fjc/thermodynamics/isotensional/test.jl") -# include("../src/physics/single_chain/fjc/thermodynamics/isotensional/legendre/test.jl") -# include("../src/physics/single_chain/fjc/thermodynamics/modified_canonical/test.jl") -# include( -# "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/strong_potential/test.jl", -# ) -# include( -# "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/weak_potential/test.jl", -# ) -# include("../src/physics/single_chain/efjc/test.jl") -# include("../src/physics/single_chain/efjc/thermodynamics/test.jl") -# include("../src/physics/single_chain/efjc/thermodynamics/isometric/test.jl") -# include("../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/test.jl") -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -# ) -# include("../src/physics/single_chain/efjc/thermodynamics/isotensional/test.jl") -# include("../src/physics/single_chain/efjc/thermodynamics/isotensional/legendre/test.jl") -# include("../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/test.jl") -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -# ) -# include("../src/physics/single_chain/swfjc/test.jl") -# include("../src/physics/single_chain/swfjc/thermodynamics/test.jl") -# include("../src/physics/single_chain/swfjc/thermodynamics/isometric/test.jl") -# include("../src/physics/single_chain/swfjc/thermodynamics/isometric/legendre/test.jl") -# include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/test.jl") -# include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/legendre/test.jl") -# include("../src/physics/single_chain/ufjc/test.jl") -# include("../src/physics/single_chain/ufjc/lennard_jones/test.jl") -# include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.jl") -# include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/test.jl") -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -# ) -# include("../src/physics/single_chain/ufjc/log_squared/test.jl") -# include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/test.jl") -# include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/test.jl") -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -# ) -# include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/test.jl") -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -# ) -# include("../src/physics/single_chain/ufjc/morse/test.jl") -# include("../src/physics/single_chain/ufjc/morse/thermodynamics/test.jl") -# include("../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/test.jl") -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", -# ) -# include("../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/test.jl") -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/legendre/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/test.jl", -# ) -# include( -# "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", -# ) +include("../src/physics/single_chain/test.jl") +include("../src/physics/single_chain/ideal/test.jl") +include("../src/physics/single_chain/ideal/thermodynamics/test.jl") +include("../src/physics/single_chain/ideal/thermodynamics/isometric/test.jl") +include("../src/physics/single_chain/ideal/thermodynamics/isotensional/test.jl") +include("../src/physics/single_chain/fjc/test.jl") +include("../src/physics/single_chain/fjc/thermodynamics/test.jl") +include("../src/physics/single_chain/fjc/thermodynamics/isometric/test.jl") +include("../src/physics/single_chain/fjc/thermodynamics/isometric/legendre/test.jl") +include("../src/physics/single_chain/fjc/thermodynamics/isotensional/test.jl") +include("../src/physics/single_chain/fjc/thermodynamics/isotensional/legendre/test.jl") +include("../src/physics/single_chain/fjc/thermodynamics/modified_canonical/test.jl") +include( + "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/strong_potential/test.jl", +) +include( + "../src/physics/single_chain/fjc/thermodynamics/modified_canonical/asymptotic/weak_potential/test.jl", +) +include("../src/physics/single_chain/efjc/test.jl") +include("../src/physics/single_chain/efjc/thermodynamics/test.jl") +include("../src/physics/single_chain/efjc/thermodynamics/isometric/test.jl") +include("../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/test.jl") +include( + "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/alternative/legendre/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +) +include("../src/physics/single_chain/efjc/thermodynamics/isotensional/test.jl") +include("../src/physics/single_chain/efjc/thermodynamics/isotensional/legendre/test.jl") +include("../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/test.jl") +include( + "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/alternative/legendre/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/efjc/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +) +include("../src/physics/single_chain/swfjc/test.jl") +include("../src/physics/single_chain/swfjc/thermodynamics/test.jl") +include("../src/physics/single_chain/swfjc/thermodynamics/isometric/test.jl") +include("../src/physics/single_chain/swfjc/thermodynamics/isometric/legendre/test.jl") +include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/test.jl") +include("../src/physics/single_chain/swfjc/thermodynamics/isotensional/legendre/test.jl") +include("../src/physics/single_chain/ufjc/test.jl") +include("../src/physics/single_chain/ufjc/lennard_jones/test.jl") +include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/test.jl") +include("../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/test.jl") +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/ufjc/lennard_jones/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +) +include("../src/physics/single_chain/ufjc/log_squared/test.jl") +include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/test.jl") +include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/test.jl") +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +) +include("../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/test.jl") +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/ufjc/log_squared/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +) +include("../src/physics/single_chain/ufjc/morse/test.jl") +include("../src/physics/single_chain/ufjc/morse/thermodynamics/test.jl") +include("../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/test.jl") +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isometric/asymptotic/reduced/legendre/test.jl", +) +include("../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/test.jl") +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/legendre/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/test.jl", +) +include( + "../src/physics/single_chain/ufjc/morse/thermodynamics/isotensional/asymptotic/reduced/legendre/test.jl", +) include("../src/physics/single_chain/wlc/test.jl") include("../src/physics/single_chain/wlc/thermodynamics/test.jl") include("../src/physics/single_chain/wlc/thermodynamics/isometric/test.jl")