@@ -22,12 +22,19 @@ impl<R: Residual + Subset> State<R> {
2222 pub fn critical_point_pure (
2323 eos : & R ,
2424 initial_temperature : Option < Temperature > ,
25+ initial_density : Option < Density > ,
2526 options : SolverOptions ,
2627 ) -> FeosResult < Vec < Self > > {
2728 ( 0 ..eos. components ( ) )
2829 . map ( |i| {
2930 let pure_eos = eos. subset ( & [ i] ) ;
30- let cp = State :: critical_point ( & pure_eos, None , initial_temperature, options) ?;
31+ let cp = State :: critical_point (
32+ & pure_eos,
33+ None ,
34+ initial_temperature,
35+ initial_density,
36+ options,
37+ ) ?;
3138 let mut molefracs = DVector :: zeros ( eos. components ( ) ) ;
3239 molefracs[ i] = 1.0 ;
3340 State :: new_intensive ( eos, cp. temperature , cp. density , & molefracs)
@@ -45,15 +52,21 @@ where
4552 temperature_or_pressure : TP ,
4653 initial_temperature : Option < Temperature > ,
4754 initial_molefracs : Option < [ f64 ; 2 ] > ,
55+ initial_density : Option < Density > ,
4856 options : SolverOptions ,
4957 ) -> FeosResult < Self > {
5058 let eos_re = eos. re ( ) ;
5159 let n = N :: from_usize ( 2 ) ;
5260 let initial_molefracs = initial_molefracs. unwrap_or ( [ 0.5 ; 2 ] ) ;
5361 let initial_molefracs = OVector :: from_fn_generic ( n, U1 , |i, _| initial_molefracs[ i] ) ;
5462 if let Some ( t) = temperature_or_pressure. temperature ( ) {
55- let [ rho0, rho1] =
56- critical_point_binary_t ( & eos_re, t. re ( ) , initial_molefracs, options) ?;
63+ let [ rho0, rho1] = critical_point_binary_t (
64+ & eos_re,
65+ t. re ( ) ,
66+ initial_molefracs,
67+ initial_density,
68+ options,
69+ ) ?;
5770 let rho = implicit_derivative_binary (
5871 |rho0, rho1, & temperature| {
5972 let rho = [ rho0, rho1] ;
7487 p. re ( ) ,
7588 initial_temperature,
7689 initial_molefracs,
90+ initial_density,
7791 options,
7892 ) ?;
7993 let trho = implicit_derivative_vec :: < _ , _ , _ , _ , U3 > (
@@ -99,21 +113,24 @@ where
99113 eos : & E ,
100114 molefracs : Option < & OVector < D , N > > ,
101115 initial_temperature : Option < Temperature > ,
116+ initial_density : Option < Density > ,
102117 options : SolverOptions ,
103118 ) -> FeosResult < Self > {
104119 let eos_re = eos. re ( ) ;
105120 let molefracs = molefracs. map_or_else ( E :: pure_molefracs, |x| x. clone ( ) ) ;
106121 let x = & molefracs. map ( |x| x. re ( ) ) ;
122+ let rho_init = initial_density. map ( |r| r. into_reduced ( ) ) ;
107123 let trial_temperatures = [ 300.0 , 700.0 , 500.0 ] ;
108124 let mut t_rho = None ;
109125 if let Some ( t) = initial_temperature {
110- t_rho = Some ( critical_point_hkm ( & eos_re, x, t. into_reduced ( ) , options) ?) ;
126+ let t = t. into_reduced ( ) ;
127+ t_rho = Some ( critical_point_hkm ( & eos_re, x, t, rho_init, options) ?) ;
111128 }
112129 for & t in trial_temperatures. iter ( ) {
113130 if t_rho. is_some ( ) {
114131 break ;
115132 }
116- t_rho = critical_point_hkm ( & eos_re, x, t, options) . ok ( ) ;
133+ t_rho = critical_point_hkm ( & eos_re, x, t, rho_init , options) . ok ( ) ;
117134 }
118135 let Some ( t_rho) = t_rho else {
119136 return Err ( FeosError :: NotConverged ( String :: from ( "Critical point" ) ) ) ;
@@ -134,10 +151,12 @@ where
134151 )
135152 }
136153}
154+
137155fn critical_point_hkm < E : Residual < N > , N : Gradients > (
138156 eos : & E ,
139157 molefracs : & OVector < f64 , N > ,
140158 initial_temperature : f64 ,
159+ initial_density : Option < f64 > ,
141160 options : SolverOptions ,
142161) -> FeosResult < [ f64 ; 2 ] >
143162where
@@ -147,7 +166,7 @@ where
147166
148167 let mut t = initial_temperature;
149168 let max_density = eos. compute_max_density ( molefracs) ;
150- let mut rho = 0.3 * max_density;
169+ let mut rho = initial_density . unwrap_or ( 0.3 * max_density) ;
151170
152171 log_iter ! (
153172 verbosity,
@@ -220,6 +239,7 @@ fn critical_point_binary_t<E: Residual<N>, N: Gradients>(
220239 eos : & E ,
221240 temperature : Temperature ,
222241 initial_molefracs : OVector < f64 , N > ,
242+ initial_density : Option < Density > ,
223243 options : SolverOptions ,
224244) -> FeosResult < [ f64 ; 2 ] >
225245where
@@ -230,7 +250,8 @@ where
230250 let t = temperature. to_reduced ( ) ;
231251 let n = N :: from_usize ( 2 ) ;
232252 let max_density = eos. compute_max_density ( & initial_molefracs) ;
233- let mut rho = SVector :: from ( [ initial_molefracs[ 0 ] , initial_molefracs[ 1 ] ] ) * 0.3 * max_density;
253+ let rho_init = initial_density. map_or ( 0.3 * max_density, |r| r. into_reduced ( ) ) ;
254+ let mut rho = SVector :: from ( [ initial_molefracs[ 0 ] , initial_molefracs[ 1 ] ] ) * rho_init;
234255
235256 log_iter ! (
236257 verbosity,
@@ -302,6 +323,7 @@ fn critical_point_binary_p<E: Residual<N>, N: Gradients>(
302323 pressure : Pressure ,
303324 initial_temperature : Option < Temperature > ,
304325 initial_molefracs : OVector < f64 , N > ,
326+ initial_density : Option < Density > ,
305327 options : SolverOptions ,
306328) -> FeosResult < [ f64 ; 3 ] >
307329where
@@ -312,7 +334,8 @@ where
312334 let p = pressure. to_reduced ( ) ;
313335 let mut t = initial_temperature. map ( |t| t. to_reduced ( ) ) . unwrap_or ( 300.0 ) ;
314336 let max_density = eos. compute_max_density ( & initial_molefracs) ;
315- let mut rho = SVector :: from ( [ initial_molefracs[ 0 ] , initial_molefracs[ 1 ] ] ) * 0.3 * max_density;
337+ let rho_init = initial_density. map_or ( 0.3 * max_density, |r| r. into_reduced ( ) ) ;
338+ let mut rho = SVector :: from ( [ initial_molefracs[ 0 ] , initial_molefracs[ 1 ] ] ) * rho_init;
316339
317340 log_iter ! (
318341 verbosity,
@@ -393,7 +416,7 @@ where
393416 molefracs : Option < & OVector < f64 , N > > ,
394417 options : SolverOptions ,
395418 ) -> FeosResult < [ Self ; 2 ] > {
396- let critical_point = Self :: critical_point ( eos, molefracs, None , options) ?;
419+ let critical_point = Self :: critical_point ( eos, molefracs, None , None , options) ?;
397420 let molefracs = molefracs. map_or_else ( E :: pure_molefracs, |x| x. clone ( ) ) ;
398421 let spinodal_vapor = Self :: calculate_spinodal (
399422 eos,
0 commit comments