#[cfg(feature = "extern")]
pub mod ex;
#[cfg(feature = "python")]
pub mod py;
mod test;
pub mod asymptotic;
pub mod legendre;
use std::f64::consts::PI;
use crate::math::integrate_1d;
use crate::physics::
{
PLANCK_CONSTANT,
BOLTZMANN_CONSTANT,
single_chain::
{
ZERO,
POINTS
}
};
pub struct MORSEFJC
{
pub hinge_mass: f64,
pub link_length: f64,
pub number_of_links: u8,
pub link_stiffness: f64,
pub link_energy: f64,
pub asymptotic: self::asymptotic::MORSEFJC,
pub legendre: self::legendre::MORSEFJC
}
pub fn end_to_end_length(number_of_links: &u8, link_length: &f64, link_stiffness: &f64, link_energy: &f64, force: &f64, temperature: &f64) -> f64
{
link_length*nondimensional_end_to_end_length(number_of_links, &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(link_energy/BOLTZMANN_CONSTANT/temperature), &(force*link_length/BOLTZMANN_CONSTANT/temperature))
}
pub fn end_to_end_length_per_link(link_length: &f64, link_stiffness: &f64, link_energy: &f64, force: &f64, temperature: &f64) -> f64
{
link_length*nondimensional_end_to_end_length_per_link(&(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(link_energy/BOLTZMANN_CONSTANT/temperature), &(force*link_length/BOLTZMANN_CONSTANT/temperature))
}
pub fn nondimensional_end_to_end_length(number_of_links: &u8, nondimensional_link_stiffness: &f64, nondimensional_link_energy: &f64, nondimensional_force: &f64) -> f64
{
(*number_of_links as f64)*nondimensional_end_to_end_length_per_link(nondimensional_link_stiffness, nondimensional_link_energy, nondimensional_force)
}
pub fn nondimensional_end_to_end_length_per_link(nondimensional_link_stiffness: &f64, nondimensional_link_energy: &f64, nondimensional_force: &f64) -> f64
{
let nondimensional_morse_parameter = (nondimensional_link_stiffness/nondimensional_link_energy/2.0).sqrt();
let nondimensional_link_stretch_max = 1.0 + 2.0_f64.ln()/nondimensional_morse_parameter;
let rescaled_partition_function_integrand = |nondimensional_link_stretch: &f64|
{
let exponent_1 = nondimensional_force*nondimensional_link_stretch - nondimensional_link_energy*(1.0 - (-nondimensional_morse_parameter*(nondimensional_link_stretch - 1.0)).exp()).powi(2) + nondimensional_link_stretch.ln() - nondimensional_force.ln();
let exponent_2 = exponent_1 - 2.0*nondimensional_force*nondimensional_link_stretch;
exponent_1.exp() - exponent_2.exp()
};
let rescaled_partition_function = integrate_1d(&rescaled_partition_function_integrand, &ZERO, &nondimensional_link_stretch_max, &POINTS);
let nondimensional_end_to_end_length_per_link_integrand = |nondimensional_link_stretch: &f64|
{
let exponent_1 = nondimensional_force*nondimensional_link_stretch - nondimensional_link_energy*(1.0 - (-nondimensional_morse_parameter*(nondimensional_link_stretch - 1.0)).exp()).powi(2) + 2.0*nondimensional_link_stretch.ln() - nondimensional_force.ln();
let exponent_2 = exponent_1 - 2.0*nondimensional_force*nondimensional_link_stretch;
let exponent_3 = exponent_1 - nondimensional_link_stretch.ln() - nondimensional_force.ln();
let exponent_4 = exponent_3 - 2.0*nondimensional_force*nondimensional_link_stretch;
(exponent_1.exp() + exponent_2.exp() - exponent_3.exp() + exponent_4.exp())/rescaled_partition_function
};
integrate_1d(&nondimensional_end_to_end_length_per_link_integrand, &ZERO, &nondimensional_link_stretch_max, &POINTS)
}
pub fn gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, link_stiffness: &f64, link_energy: &f64, force: &f64, temperature: &f64) -> f64
{
BOLTZMANN_CONSTANT*temperature*nondimensional_gibbs_free_energy(number_of_links, link_length, hinge_mass, &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(link_energy/BOLTZMANN_CONSTANT/temperature), &(force*link_length/BOLTZMANN_CONSTANT/temperature), temperature)
}
pub fn gibbs_free_energy_per_link(link_length: &f64, hinge_mass: &f64, link_stiffness: &f64, link_energy: &f64, force: &f64, temperature: &f64) -> f64
{
BOLTZMANN_CONSTANT*temperature*nondimensional_gibbs_free_energy_per_link(link_length, hinge_mass, &(link_stiffness*link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(link_energy/BOLTZMANN_CONSTANT/temperature), &(force*link_length/BOLTZMANN_CONSTANT/temperature), temperature)
}
pub fn relative_gibbs_free_energy(number_of_links: &u8, link_length: &f64, link_stiffness: &f64, link_energy: &f64, force: &f64, temperature: &f64) -> f64
{
gibbs_free_energy(number_of_links, link_length, &1.0, link_stiffness, link_energy, force, temperature) - gibbs_free_energy(number_of_links, link_length, &1.0, link_stiffness, link_energy, &(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), temperature)
}
pub fn relative_gibbs_free_energy_per_link(link_length: &f64, link_stiffness: &f64, link_energy: &f64, force: &f64, temperature: &f64) -> f64
{
gibbs_free_energy_per_link(link_length, &1.0, link_stiffness, link_energy, force, temperature) - gibbs_free_energy_per_link(link_length, &1.0, link_stiffness, link_energy, &(ZERO*BOLTZMANN_CONSTANT*temperature/link_length), temperature)
}
pub fn nondimensional_gibbs_free_energy(number_of_links: &u8, link_length: &f64, hinge_mass: &f64, nondimensional_link_stiffness: &f64, nondimensional_link_energy: &f64, nondimensional_force: &f64, temperature: &f64) -> f64
{
(*number_of_links as f64)*nondimensional_gibbs_free_energy_per_link(link_length, hinge_mass, nondimensional_link_stiffness, nondimensional_link_energy, nondimensional_force, temperature)
}
pub fn nondimensional_gibbs_free_energy_per_link(link_length: &f64, hinge_mass: &f64, nondimensional_link_stiffness: &f64, nondimensional_link_energy: &f64, nondimensional_force: &f64, temperature: &f64) -> f64
{
let nondimensional_morse_parameter = (nondimensional_link_stiffness/nondimensional_link_energy/2.0).sqrt();
let nondimensional_link_stretch_max = 1.0 + 2.0_f64.ln()/nondimensional_morse_parameter;
let rescaled_partition_function_integrand = |nondimensional_link_stretch: &f64|
{
let exponent_1 = nondimensional_force*nondimensional_link_stretch - nondimensional_link_energy*(1.0 - (-nondimensional_morse_parameter*(nondimensional_link_stretch - 1.0)).exp()).powi(2) + nondimensional_link_stretch.ln() - nondimensional_force.ln();
let exponent_2 = exponent_1 - 2.0*nondimensional_force*nondimensional_link_stretch;
exponent_1.exp() - exponent_2.exp()
};
let rescaled_partition_function = integrate_1d(&rescaled_partition_function_integrand, &ZERO, &nondimensional_link_stretch_max, &POINTS);
-rescaled_partition_function.ln() - (8.0*PI.powi(2)*hinge_mass*link_length.powi(2)*BOLTZMANN_CONSTANT*temperature/PLANCK_CONSTANT.powi(2)).ln()
}
pub fn nondimensional_relative_gibbs_free_energy(number_of_links: &u8, nondimensional_link_stiffness: &f64, nondimensional_link_energy: &f64, nondimensional_force: &f64) -> f64
{
nondimensional_gibbs_free_energy(number_of_links, &1.0, &1.0, nondimensional_link_stiffness, nondimensional_link_energy, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy(number_of_links, &1.0, &1.0, nondimensional_link_stiffness, nondimensional_link_energy, &ZERO, &300.0)
}
pub fn nondimensional_relative_gibbs_free_energy_per_link(nondimensional_link_stiffness: &f64, nondimensional_link_energy: &f64, nondimensional_force: &f64) -> f64
{
nondimensional_gibbs_free_energy_per_link(&1.0, &1.0, nondimensional_link_stiffness, nondimensional_link_energy, nondimensional_force, &300.0) - nondimensional_gibbs_free_energy_per_link(&1.0, &1.0, nondimensional_link_stiffness, nondimensional_link_energy, &ZERO, &300.0)
}
impl MORSEFJC
{
pub fn init(number_of_links: u8, link_length: f64, hinge_mass: f64, link_stiffness: f64, link_energy: f64) -> Self
{
MORSEFJC
{
hinge_mass,
link_length,
number_of_links,
link_stiffness,
link_energy,
asymptotic: self::asymptotic::MORSEFJC::init(number_of_links, link_length, hinge_mass, link_stiffness, link_energy),
legendre: self::legendre::MORSEFJC::init(number_of_links, link_length, hinge_mass, link_stiffness, link_energy)
}
}
pub fn end_to_end_length(&self, force: &f64, temperature: &f64) -> f64
{
end_to_end_length(&self.number_of_links, &self.link_length, &self.link_stiffness, &self.link_energy, force, temperature)
}
pub fn end_to_end_length_per_link(&self, force: &f64, temperature: &f64) -> f64
{
end_to_end_length_per_link(&self.link_length, &self.link_stiffness, &self.link_energy, force, temperature)
}
pub fn nondimensional_end_to_end_length(&self, nondimensional_force: &f64, temperature: &f64) -> f64
{
nondimensional_end_to_end_length(&self.number_of_links, &(self.link_stiffness*self.link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(self.link_energy/BOLTZMANN_CONSTANT/temperature), nondimensional_force)
}
pub fn nondimensional_end_to_end_length_per_link(&self, nondimensional_force: &f64, temperature: &f64) -> f64
{
nondimensional_end_to_end_length_per_link(&(self.link_stiffness*self.link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(self.link_energy/BOLTZMANN_CONSTANT/temperature), nondimensional_force)
}
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.link_stiffness, &self.link_energy, force, temperature)
}
pub fn gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64
{
gibbs_free_energy_per_link(&self.link_length, &self.hinge_mass, &self.link_stiffness, &self.link_energy, force, 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.link_stiffness, &self.link_energy, force, temperature)
}
pub fn relative_gibbs_free_energy_per_link(&self, force: &f64, temperature: &f64) -> f64
{
relative_gibbs_free_energy_per_link(&self.link_length, &self.link_stiffness, &self.link_energy, force, 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.link_stiffness*self.link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(self.link_energy/BOLTZMANN_CONSTANT/temperature), nondimensional_force, temperature)
}
pub fn nondimensional_gibbs_free_energy_per_link(&self, nondimensional_force: &f64, temperature: &f64) -> f64
{
nondimensional_gibbs_free_energy_per_link(&self.link_length, &self.hinge_mass, &(self.link_stiffness*self.link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(self.link_energy/BOLTZMANN_CONSTANT/temperature), nondimensional_force, temperature)
}
pub fn nondimensional_relative_gibbs_free_energy(&self, nondimensional_force: &f64, temperature: &f64) -> f64
{
nondimensional_relative_gibbs_free_energy(&self.number_of_links, &(self.link_stiffness*self.link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(self.link_energy/BOLTZMANN_CONSTANT/temperature), nondimensional_force)
}
pub fn nondimensional_relative_gibbs_free_energy_per_link(&self, nondimensional_force: &f64, temperature: &f64) -> f64
{
nondimensional_relative_gibbs_free_energy_per_link(&(self.link_stiffness*self.link_length.powi(2)/BOLTZMANN_CONSTANT/temperature), &(self.link_energy/BOLTZMANN_CONSTANT/temperature), nondimensional_force)
}
}