From 92d5dc5862c5bee27b5696d69333a66d7d1e0a20 Mon Sep 17 00:00:00 2001 From: mrbuche Date: Mon, 1 May 2023 15:22:19 -0600 Subject: [PATCH] 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")