use crate::math::assert::Assert;
use crate::{
EPSILON,
math::{Scalar, assert::AssertionError},
physics::molecular::single_chain::{Ensemble, ExtensibleFreelyJointedChain, Thermodynamics},
units::{BOLTZMANN_CONSTANT, ROOM_TEMPERATURE},
};
const NUM: usize = 333;
#[test]
fn monte_carlo() {
use crate::physics::molecular::single_chain::MonteCarloExtensible;
let link_length = 1.0;
let model = ExtensibleFreelyJointedChain {
link_length,
link_stiffness: 5.0 * BOLTZMANN_CONSTANT.value() * ROOM_TEMPERATURE.value()
/ (link_length * link_length),
number_of_links: 5,
ensemble: Ensemble::Isometric(ROOM_TEMPERATURE.value()),
};
let (gamma, g) =
MonteCarloExtensible::nondimensional_radial_distribution(&model, 0.0, 333, 10_000, 1, 3.0);
gamma
.into_iter()
.zip(g)
.for_each(|(gamma_i, g_i)| println!("[{gamma_i}, {g_i}],"))
}
#[test]
fn finite_difference() -> Result<(), AssertionError> {
const NONDIMENSIONAL_LINK_STIFFNESS: Scalar = 1e3;
const NONDIMENSIONAL_STRETCH: Scalar = 0.6;
let link_stiffness =
NONDIMENSIONAL_LINK_STIFFNESS * BOLTZMANN_CONSTANT.value() * ROOM_TEMPERATURE.value();
[Ensemble::Isotensional(ROOM_TEMPERATURE.value())]
.into_iter()
.try_for_each(|ensemble| {
(3..16).into_iter().try_for_each(|number_of_links| {
let model = ExtensibleFreelyJointedChain {
link_length: 1.0,
link_stiffness,
number_of_links,
ensemble,
};
(10..NUM)
.map(|k| {
k as Scalar / NUM as Scalar
* NONDIMENSIONAL_STRETCH
* NONDIMENSIONAL_LINK_STIFFNESS
})
.into_iter()
.try_for_each(|mut nondimensional_force| {
nondimensional_force += 0.5 * EPSILON;
let mut finite_difference_3 = -model
.nondimensional_gibbs_free_energy_per_link(nondimensional_force)?;
nondimensional_force -= EPSILON;
finite_difference_3 -= -model
.nondimensional_gibbs_free_energy_per_link(nondimensional_force)?;
nondimensional_force += 0.5 * EPSILON;
let nondimensional_extension =
model.nondimensional_extension(nondimensional_force)?;
Assert::default().eq_within_fd_tol(
nondimensional_extension,
&(finite_difference_3 / EPSILON),
)
})
})
})
}