@@ -14,11 +14,36 @@ use std::rc::Rc;
1414const PI36M1 : f64 = 1.0 / ( 36.0 * PI ) ;
1515const N3_CUTOFF : f64 = 1e-5 ;
1616
17+ /// Different monomer shapes for FMT.
18+ pub enum MonomerShape < ' a , N > {
19+ /// For spherical monomers, the number of components.
20+ Spherical ( usize ) ,
21+ /// For non-spherical molecules in a homosegmented approach, the
22+ /// chain length parameter $m$.
23+ NonSpherical ( & ' a Array1 < N > ) ,
24+ /// For non-spherical molecules in a heterosegmented approach,
25+ /// the geometry factors for every segment.
26+ Heterosegmented ( [ Array1 < N > ; 4 ] ) ,
27+ }
28+
1729/// Properties of (generalized) hard sphere systems.
1830pub trait FMTProperties {
1931 fn component_index ( & self ) -> Array1 < usize > ;
20- fn chain_length ( & self ) -> Array1 < f64 > ;
32+ fn monomer_shape < N : DualNum < f64 > > ( & self , temperature : N ) -> MonomerShape < N > ;
2133 fn hs_diameter < N : DualNum < f64 > > ( & self , temperature : N ) -> Array1 < N > ;
34+
35+ fn geometry_coefficients < N : DualNum < f64 > > ( & self , temperature : N ) -> [ Array1 < N > ; 4 ] {
36+ match self . monomer_shape ( temperature) {
37+ MonomerShape :: Spherical ( n) => {
38+ let m = Array1 :: ones ( n) ;
39+ [ m. clone ( ) , m. clone ( ) , m. clone ( ) , m]
40+ }
41+ MonomerShape :: NonSpherical ( m) => {
42+ [ m. to_owned ( ) , m. to_owned ( ) , m. to_owned ( ) , m. to_owned ( ) ]
43+ }
44+ MonomerShape :: Heterosegmented ( g) => g,
45+ }
46+ }
2247}
2348
2449/// Different versions of fundamental measure theory
@@ -60,8 +85,8 @@ impl<P> FMTContribution<P> {
6085impl < P : FMTProperties , N : DualNum < f64 > > FunctionalContributionDual < N > for FMTContribution < P > {
6186 fn weight_functions ( & self , temperature : N ) -> WeightFunctionInfo < N > {
6287 let r = self . properties . hs_diameter ( temperature) * 0.5 ;
63- let m = self . properties . chain_length ( ) ;
64- match ( self . version , m . len ( ) ) {
88+ let [ c0 , c1 , c2 , c3 ] = self . properties . geometry_coefficients ( temperature ) ;
89+ match ( self . version , r . len ( ) ) {
6590 ( FMTVersion :: WhiteBear | FMTVersion :: AntiSymWhiteBear , 1 ) => {
6691 WeightFunctionInfo :: new ( self . properties . component_index ( ) , false ) . extend (
6792 vec ! [
@@ -70,8 +95,9 @@ impl<P: FMTProperties, N: DualNum<f64>> FunctionalContributionDual<N> for FMTCon
7095 WeightFunctionShape :: DeltaVec ,
7196 ]
7297 . into_iter ( )
73- . map ( |s| WeightFunction {
74- prefactor : self . properties . chain_length ( ) . mapv ( |m| m. into ( ) ) ,
98+ . zip ( [ c2, c3. clone ( ) , c3] )
99+ . map ( |( s, c) | WeightFunction {
100+ prefactor : c,
75101 kernel_radius : r. clone ( ) ,
76102 shape : s,
77103 } )
@@ -83,54 +109,54 @@ impl<P: FMTProperties, N: DualNum<f64>> FunctionalContributionDual<N> for FMTCon
83109 WeightFunctionInfo :: new ( self . properties . component_index ( ) , false )
84110 . add (
85111 WeightFunction {
86- prefactor : Zip :: from ( & m )
112+ prefactor : Zip :: from ( & c0 )
87113 . and ( & r)
88- . map_collect ( |& m , & r| r. powi ( -2 ) * m / ( 4.0 * PI ) ) ,
114+ . map_collect ( |& c , & r| r. powi ( -2 ) * c / ( 4.0 * PI ) ) ,
89115 kernel_radius : r. clone ( ) ,
90116 shape : WeightFunctionShape :: Delta ,
91117 } ,
92118 true ,
93119 )
94120 . add (
95121 WeightFunction {
96- prefactor : Zip :: from ( & m )
122+ prefactor : Zip :: from ( & c1 )
97123 . and ( & r)
98- . map_collect ( |& m , & r| r. recip ( ) * m / ( 4.0 * PI ) ) ,
124+ . map_collect ( |& c , & r| r. recip ( ) * c / ( 4.0 * PI ) ) ,
99125 kernel_radius : r. clone ( ) ,
100126 shape : WeightFunctionShape :: Delta ,
101127 } ,
102128 true ,
103129 )
104130 . add (
105131 WeightFunction {
106- prefactor : m . mapv ( |m| m . into ( ) ) ,
132+ prefactor : c2 ,
107133 kernel_radius : r. clone ( ) ,
108134 shape : WeightFunctionShape :: Delta ,
109135 } ,
110136 true ,
111137 )
112138 . add (
113139 WeightFunction {
114- prefactor : m . mapv ( |m| m . into ( ) ) ,
140+ prefactor : c3 . clone ( ) ,
115141 kernel_radius : r. clone ( ) ,
116142 shape : WeightFunctionShape :: Theta ,
117143 } ,
118144 true ,
119145 )
120146 . add (
121147 WeightFunction {
122- prefactor : Zip :: from ( & m )
148+ prefactor : Zip :: from ( & c3 )
123149 . and ( & r)
124- . map_collect ( |& m , & r| r. recip ( ) * m / ( 4.0 * PI ) ) ,
150+ . map_collect ( |& c , & r| r. recip ( ) * c / ( 4.0 * PI ) ) ,
125151 kernel_radius : r. clone ( ) ,
126152 shape : WeightFunctionShape :: DeltaVec ,
127153 } ,
128154 true ,
129155 )
130156 . add (
131157 WeightFunction {
132- prefactor : m . mapv ( |m| m . into ( ) ) ,
133- kernel_radius : r. clone ( ) ,
158+ prefactor : c3 ,
159+ kernel_radius : r,
134160 shape : WeightFunctionShape :: DeltaVec ,
135161 } ,
136162 true ,
@@ -145,8 +171,9 @@ impl<P: FMTProperties, N: DualNum<f64>> FunctionalContributionDual<N> for FMTCon
145171 WeightFunctionShape :: Theta ,
146172 ]
147173 . into_iter ( )
148- . map ( |s| WeightFunction {
149- prefactor : self . properties . chain_length ( ) . mapv ( |m| m. into ( ) ) ,
174+ . zip ( self . properties . geometry_coefficients ( temperature) )
175+ . map ( |( s, c) | WeightFunction {
176+ prefactor : c,
150177 kernel_radius : r. clone ( ) ,
151178 shape : s,
152179 } )
@@ -165,7 +192,7 @@ impl<P: FMTProperties, N: DualNum<f64>> FunctionalContributionDual<N> for FMTCon
165192 let pure_component_weighted_densities = matches ! (
166193 self . version,
167194 FMTVersion :: WhiteBear | FMTVersion :: AntiSymWhiteBear
168- ) && self . properties . chain_length ( ) . len ( ) == 1 ;
195+ ) && self . properties . component_index ( ) . len ( ) == 1 ;
169196
170197 // scalar weighted densities
171198 let ( n2, n3) = if pure_component_weighted_densities {
@@ -270,8 +297,8 @@ impl FMTProperties for HardSphereProperties {
270297 Array1 :: from_shape_fn ( self . sigma . len ( ) , |i| i)
271298 }
272299
273- fn chain_length ( & self ) -> Array1 < f64 > {
274- Array :: ones ( self . sigma . len ( ) )
300+ fn monomer_shape < N > ( & self , _ : N ) -> MonomerShape < N > {
301+ MonomerShape :: Spherical ( self . sigma . len ( ) )
275302 }
276303
277304 fn hs_diameter < N : DualNum < f64 > > ( & self , _: N ) -> Array1 < N > {
0 commit comments