21 real,
dimension(nc),
public :: rhoi_trial
23 logical :: first_call = .true.
24 logical,
public :: generate_starting_val
25 logical,
public :: flashcase
27 real,
dimension(nc) :: rhoi_best
31 PUBLIC ::
start_var, start_var_fixed_composition, phase_stability, vle_min, &
32 tangent_plane_line_search, rachford_rice, occupy_val_init, &
33 scan_compositions, bubble_point_rachford_rice, stability_hessian
70 integer,
intent(in out) :: converg
73 logical :: renormalize
80 generate_starting_val = .true.
84 if ( first_call .AND. xif(1) == 0.0 )
call read_mode_staring_value ( scan_index, outp )
87 if (num == 2) renormalize = .true.
90 if ( xif(1) /= 0.0 )
then 94 call start_var_fixed_composition ( converg )
100 if ( ncomp > 2 )
then 101 write (*,*)
'Solubility Code: SR starting_value requires a defined feed composition for all but binary mixtures' 105 if ( scan_index == 2 )
then 107 xif( 1:ncomp ) = xi( 1, 1:ncomp )
108 call start_var_fixed_composition ( converg )
110 call scan_compositions ( converg )
117 IF (renormalize) num = 2
118 generate_starting_val = .false.
135 subroutine scan_compositions ( converg )
142 integer,
intent(in out) :: converg
145 integer :: i, i_conv, steps
146 integer :: converg_overall
149 real :: xiF_in_between_x
150 real,
dimension( 4, 0:nc*np+6 ) :: val_save
151 logical :: different_equilibrium_as_previous
152 real :: density(np),w(np,nc)
158 if ( ncomp > 2 )
write (*,*)
'SR scan_compositions only suited for binary systems' 159 if ( ncomp > 2 ) stop 5
163 xif(1) =
REAL(i) /
REAL(steps)
164 if ( xif(1) <= 1.e-30 ) xif(1) = 1.e-30
165 if ( xif(1) >= (1.0 - 1.e-12) ) xif(1) = 1.0 - 1.e-12
166 xif(2) = 1.0 - xif(1)
168 if ( xif(1) > x1_right )
then 170 if ( outp >= 1 )
write (*,
'(a,G19.11)')
' scan x, with x(1)=',xif(1)
172 call start_var_fixed_composition ( converg )
174 xif_in_between_x = ( exp(val_init(5)) - xif(1) ) / (xif(1) - exp(val_init(7)) )
176 if ( converg == 1 .AND. xif_in_between_x > 0.0 )
then 178 different_equilibrium_as_previous = .true.
179 if ( converg_overall > 0 )
then 180 diff_para = abs( exp(val_save(converg_overall,5))-exp(val_init(5)) ) &
181 + abs( exp(val_save(converg_overall,7))-exp(val_init(7)) )
182 if ( diff_para < 1.e-5 ) different_equilibrium_as_previous = .false.
185 if ( different_equilibrium_as_previous )
then 186 converg_overall = converg_overall + 1
187 val_save( converg_overall, : ) = val_init(:)
188 x1_right = max( xi(1,1), xi(2,1) )
189 if ( outp >= 1 )
write (*,
'(a,2i4,5G19.11)')
' found equil.',i,converg_overall, &
190 exp(val_init(5) ),xif(1),exp(val_init(7) ),val_init(1:2)
191 if ( outp >= 1 )
write (*,*)
' ' 201 if ( converg_overall > 0) converg = 1
203 if ( outp >= 1 .OR. converg_overall > 1 )
then 204 if ( converg_overall >= 1)
write (*,*)
' ' 205 if ( converg_overall >= 1)
write (*,*)
'=================================' 206 if ( converg_overall == 1)
write (*,*)
'phase equilibrium:' 207 if ( converg_overall == 2)
write (*,*)
'two phase equilibria found:' 208 if ( converg_overall >= 1)
write (*,*)
'=================================' 209 do i_conv = 1, converg_overall
210 dense(1:2) = val_save( i_conv, 1:2 )
211 lnx(1,1:2) = val_save( i_conv, 5:6 )
212 lnx(2,1:2) = val_save( i_conv, 7:8 )
213 xi(1,1:2) = exp( lnx(1,1:2) )
214 xi(2,1:2) = exp( lnx(2,1:2) )
215 call si_dens ( density, w )
217 if ( converg_overall > 1)
write (*,*)
'EQUILIBRIUM', i_conv
218 if ( converg_overall > 1)
write (*,*)
'---------------------------------------------' 219 write(*,
'(t20,a,f7.2,a,f10.5,a)')
'T =',t-u_out_t,
' P =',p/u_out_p
220 write (*,
'(t26,a)')
'PHASE I PHASE II ' 221 write (*,
'(a,t20,F13.4,t39,F13.4)')
' Density ',density(1),density(2)
222 write (*,
'(x,a,t20,a3,E14.6,t42,E14.6)') compna(1),
'x =',exp( lnx(1:2,1) )
223 write (*,
'(x,a,t20,a3,E14.6,t42,E14.6)') compna(2),
'x =',exp( lnx(1:2,2) )
224 write (*,
'(x,a,t20,a3,E14.6,t42,E14.6)') compna(1),
'w =',w(1:2,1)
225 write (*,
'(x,a,t20,a3,E14.6,t42,E14.6)') compna(2),
'w =',w(1:2,2)
229 val_init( : ) = val_save( 1, : )
230 if ( converg_overall > 1)
then 232 write (*,*)
'choose a phase equilibrium' 233 write (*,*)
'---------------------------------------------' 235 val_init( : ) = val_save( i_conv, : )
238 end subroutine scan_compositions
251 subroutine calculate_equilibrium_feed ( rhoi1, rhoi2, converg )
259 integer,
intent(in out) :: converg
260 real,
dimension(nc),
intent(in out) :: rhoi1
261 real,
dimension(nc),
intent(in out) :: rhoi2
264 integer :: promising_min
266 real,
dimension(np,nc) :: rho_enter
269 rho_enter(1,1:ncomp) = rhoi1(1:ncomp)
270 rho_enter(2,1:ncomp) = rhoi2(1:ncomp)
272 xi(1,1:ncomp) = rhoi1(1:ncomp) / sum(rhoi1(1:ncomp))
273 xi(2,1:ncomp) = rhoi2(1:ncomp) / sum(rhoi2(1:ncomp))
274 dense(1) = pi/6.0 * sum( rhoi1(1:ncomp) * mseg(1:ncomp) * dhs(1:ncomp)**3 )
275 dense(2) = pi/6.0 * sum( rhoi2(1:ncomp) * mseg(1:ncomp) * dhs(1:ncomp)**3 )
277 CALL rachford_rice ( converg, rhoi1, rhoi2 )
279 if ( converg == 0 )
then 281 rhoi1(1:ncomp) = rho_enter(1,1:ncomp)
282 rhoi2(1:ncomp) = rho_enter(2,1:ncomp)
283 call tangent_plane_line_search ( rhoi1, rhoi2, phi_2_start, promising_min )
285 if ( promising_min == 1 .AND. maxval( abs( xi(1,1:ncomp) - xi(2,1:ncomp) ) ) > 0.0001 )
then 287 call tangent_plane_2 ( phi_2_start, rhoi1, rhoi2 )
288 xi( 1, 1:ncomp ) = rhoi1( 1:ncomp ) / sum( rhoi1( 1:ncomp ) )
289 xi( 2, 1:ncomp ) = rhoi2( 1:ncomp ) / sum( rhoi2( 1:ncomp ) )
290 if ( maxval( abs( xi( 1, 1:ncomp ) - xi( 2, 1:ncomp ) ) ) > 0.0001 )
then 292 CALL occupy_val_init ( rhoi1, rhoi2 )
293 if ( .NOT. flashcase )
then 294 CALL select_sum_rel (1,0,1)
295 CALL select_sum_rel (2,0,2)
297 CALL determine_flash_it2
300 CALL objective_ctrl ( converg )
302 if ( converg == 1 ) val_init = val_conv
310 CALL occupy_val_init ( rhoi1, rhoi2 )
315 if ( outp >= 2 )
write (*,*)
' ' 316 if ( outp >= 2 )
write (*,*)
'leaving calculate_equilibrium_feed: convergence=',converg
318 end subroutine calculate_equilibrium_feed
334 subroutine start_var_fixed_composition ( converg )
342 integer,
intent(in out) :: converg
346 real,
dimension(np,nc) :: lnphi
347 real,
dimension(nc) :: rhoi_feed
348 real,
dimension(nc) :: rhoi1, rhoi2
349 real,
dimension(nc) :: rhoi_trial
354 if ( sum( xif(1:ncomp) ) /= 1.0 )
write (*,*)
'Solubility Code: feed composition /= 1.0', sum( xif(1:ncomp) )
355 if ( sum( xif(1:ncomp) ) /= 1.0 ) stop 5
357 xi(1,1:ncomp) = xif(1:ncomp)
358 xi(2,1:ncomp) = xif(1:ncomp)
368 CALL rachford_rice ( converg, rhoi1, rhoi2 )
377 if ( converg /= 1 )
then 384 if ( outp >= 2 )
write (*,*)
' ' 385 if ( outp >= 2 )
write (*,*)
'--------------------------------------------------------' 386 if ( outp >= 1 )
write (*,*)
'do phase stability analysis' 387 if ( outp >= 2 )
write (*,*)
'--------------------------------------------------------' 388 if ( outp >= 2 )
write (*,*)
' ' 392 xi( 1, 1:ncomp ) = xif( 1:ncomp )
393 xi( 2, 1:ncomp ) = xif( 1:ncomp )
394 CALL fugacity (lnphi)
399 my_f( 1:ncomp ) = my_cal(1,1:ncomp)
400 rhoi_feed( 1:ncomp ) = rhoi_cal( 1, 1:ncomp )
404 CALL phase_stability ( rhoi_feed, eta_trial, ph_split, rhoi_trial )
405 rhoi1( 1:ncomp ) = rhoi_feed( 1:ncomp )
406 rhoi2( 1:ncomp ) = rhoi_trial( 1:ncomp )
407 if ( outp > 0 )
write (*,*)
'phase split =', ph_split
408 if ( ph_split == 0 .AND. outp > 0 )
write (*,*)
'no phase split detected, stable phase is likely' 409 if ( ph_split == 2 .AND. outp > 0 )
write (*,*)
'condition could be close to critical point' 411 if ( ph_split >= 1 )
then 417 call calculate_equilibrium_feed ( rhoi1, rhoi2, converg )
419 if ( converg == 1 .AND. outp > 0 )
write (*,*)
'end of starting value - solution found' 423 if ( converg == 0 )
then 461 if ( outp >= 2 )
write (*,*)
' now test phase stability' 462 if ( outp >= 2 )
write (*,*)
' ' 464 my_f( 1:ncomp ) = my_cal(1,1:ncomp)
466 rhoi_feed( 1:ncomp ) = rhoi1( 1:ncomp )
467 if ( dense(2) > dense(1) ) rhoi_feed( 1:ncomp ) = rhoi2( 1:ncomp )
469 CALL phase_stability ( rhoi_feed, eta_trial, ph_split, rhoi_trial )
470 if ( outp > 0 )
write (*,*)
'result of stability-test for L-phase, ph_split =', ph_split
472 if ( ph_split /= 1 )
then 477 if ( outp >= 2 )
write (*,*)
'the calculated VLE is stable' 478 CALL occupy_val_init ( rhoi1, rhoi2 )
489 if ( outp >= 2 )
write (*,*)
'========================================================' 490 if ( outp > 0 )
write (*,*)
' converged VLE (or LLE) not stable: searching (other) LLE' 491 if ( outp >= 2 )
write (*,*)
'========================================================' 492 if ( outp >= 2 )
write (*,*)
' ' 497 call occupy_val_init ( rhoi1, rhoi2 )
499 rhoi1( 1:ncomp ) = rhoi_feed( 1:ncomp )
500 rhoi2( 1:ncomp ) = rhoi_trial( 1:ncomp )
502 phi_1 = ( xif(1) - rhoi2(1)/sum(rhoi2(1:ncomp)) ) &
503 / ( rhoi1(1)/sum(rhoi1(1:ncomp)) - rhoi2(1)/sum(rhoi2(1:ncomp)) )
505 if ( outp > 0 )
write (*,*)
'initial phase fraction', phi_1, kij(1,2)
509 call calculate_equilibrium_feed ( rhoi1, rhoi2, converg )
511 if ( converg == 1 )
then 512 phi_1 = ( xif(1) - xi(2,1) ) / ( xi(1,1) - xi(2,1) )
513 fmin = phi_1 * gibbs(1) + ( 1.0 - phi_1 ) * gibbs(2)
514 if ( outp >= 2 )
write (*,*)
' ' 515 if ( outp >= 2 )
write (*,*)
'--------------------------------------------------------' 516 if ( outp > 0 )
write (*,*)
'first phase equilibrium trial converged ',fmin
517 if ( outp >= 2 )
write (*,*)
'--------------------------------------------------------' 518 if ( outp >= 2 )
write (*,*)
' ' 520 if ( outp >= 2 )
write (*,*)
'search for additional phase split gave no solution' 555 if ( converg == 0 )
then 567 if ( outp > 0 )
write (*,*)
' ' 569 end subroutine start_var_fixed_composition
581 subroutine tangent_plane_line_search ( rhoi1, rhoi2, phi_2_opt, promising_min )
588 real,
dimension(nc),
intent(in out) :: rhoi1
589 real,
dimension(nc),
intent(in out) :: rhoi2
590 real,
intent(out) :: phi_2_opt
591 integer,
intent(out) :: promising_min
594 integer :: n, i, steps
596 real :: phi_2, phi_2_min, phi_2_max, fmin_scan
597 real,
allocatable :: optpara(:)
604 ALLOCATE( optpara(n) )
606 xi( 1, 1:ncomp ) = rhoi1( 1:ncomp ) / sum( rhoi1( 1:ncomp ) )
607 xi( 2, 1:ncomp ) = rhoi2( 1:ncomp ) / sum( rhoi2( 1:ncomp ) )
608 lnx( 1, 1:ncomp ) = log( xi( 1, 1:ncomp ) )
609 lnx( 2, 1:ncomp ) = log( xi( 2, 1:ncomp ) )
611 densta(1) = pi / 6.0 * sum( rhoi1( 1:ncomp ) * mseg( 1:ncomp ) * dhs( 1:ncomp )**3 )
612 densta(2) = pi / 6.0 * sum( rhoi2( 1:ncomp ) * mseg( 1:ncomp ) * dhs( 1:ncomp )**3 )
618 phi_2_max = min( phi_2_max, xif(i) / xi(2,i) )
626 phi_2 = phi_2_min + ( phi_2_max - phi_2_min ) *
real(i) /
real(steps)
627 if ( phi_2 < 1.e-6 ) phi_2 = 1.e-6
628 if ( phi_2 > (1.0 - 1.e-6) ) phi_2 = 1.0 - 1.e-6
630 optpara( 1:ncomp ) = log( xi( 2, 1:ncomp ) * phi_2 )
632 call tangent_value ( fmin, optpara, n )
634 if ( fmin < fmin_scan )
then 637 rhoi1( 1:ncomp ) = rhoi_cal( 1, 1:ncomp )
638 rhoi2( 1:ncomp ) = rhoi_cal( 2, 1:ncomp )
639 if ( i > 0 ) promising_min = 1
644 DEALLOCATE( optpara )
646 xi( 1, 1:ncomp ) = rhoi1( 1:ncomp ) / sum( rhoi1( 1:ncomp ) )
647 xi( 2, 1:ncomp ) = rhoi2( 1:ncomp ) / sum( rhoi2( 1:ncomp ) )
649 if ( outp >= 1 )
write (*,*)
'finished line search' 650 if ( outp >= 2 )
write (*,*)
' ' 652 end subroutine tangent_plane_line_search
660 subroutine tangent_value ( fmin, optpara, n )
666 integer,
intent(IN) :: n
667 real,
intent(IN) :: optpara(:)
668 real,
intent(IN OUT) :: fmin
673 real :: ph_1_frac, punish
674 real,
dimension(nc) :: ni_1, ni_2
680 if ( maxval( optpara(1:n) ) > 5.0 )
then 681 fmin = 1.e8 * maxval( optpara(1:n) )
684 if ( maxval( optpara(1:n) ) < -100.0 )
then 689 if ( optpara(i) /= optpara(i) )
then 700 if ( optpara(i) < -100.0 )
then 703 ni_2(i) = exp( optpara(i) )
709 ni_1(i) = xif(i) - ni_2(i)
710 if ( ni_2(i) > xif(i) )
then 711 punish = punish - 1.e8*ni_1(i) + 0.1
713 ni_1(i) = xif(i) * 1.e-50
715 if ( ni_1(i) <= 0.0 ) ni_1(i) = xif(i) * 1.e-50
723 xi(2,1:ncomp) = ni_2(1:ncomp) / sum( ni_2(1:ncomp) )
724 lnx(2,1:ncomp) = optpara(1:ncomp) - log( sum( ni_2(1:ncomp) ) )
726 ph_1_frac = sum( ni_1(1:ncomp) )
727 xi( 1, 1:ncomp ) = ni_1( 1:ncomp ) / ph_1_frac
728 lnx( 1, 1:ncomp ) = log( ni_1( 1:ncomp ) ) - log( ph_1_frac )
736 CALL fugacity (lnphi)
738 fmin = gibbs(1) * ph_1_frac + gibbs(2) * ( 1.0 - ph_1_frac ) + punish
740 fmin = fmin - sum( xif(1:ncomp)*my_f( 1:ncomp ))
741 if ( outp >= 2 )
write (*,
'(a,4G18.8)')
'TP',fmin, ni_1(1:ncomp)
746 end subroutine tangent_value
754 subroutine tangent_grad ( g, optpara, n )
761 integer,
intent(IN) :: n
762 real,
intent(IN) :: optpara(:)
763 real,
intent(in out) :: g(:)
767 real :: lnphi(np,nc), ph_1_frac
768 real,
dimension(nc) :: ni_1, ni_2
775 if ( maxval( optpara(1:n) ) < -100.0 )
then 780 if ( optpara(i) /= optpara(i) .OR. optpara(i) > 5.0 )
then 791 if ( optpara(i) < -300.0 )
then 794 ni_2(i) = exp( optpara(i) )
799 ni_1(i) = xif(i) - ni_2(i)
800 if ( ni_2(i) > xif(i) )
then 803 ni_1(i) = xif(i) * 1.e-100
811 xi(2,1:ncomp) = ni_2(1:ncomp) / sum( ni_2(1:ncomp) )
812 lnx(2,1:ncomp) = optpara(1:ncomp) - log( sum( ni_2(1:ncomp) ) )
814 ph_1_frac = sum( ni_1(1:ncomp) )
815 xi( 1, 1:ncomp ) = ni_1( 1:ncomp ) / ph_1_frac
816 lnx( 1, 1:ncomp ) = log( ni_1( 1:ncomp ) ) - log( ph_1_frac )
822 CALL fugacity (lnphi)
830 g( 1:ncomp ) = - ( lnphi(1,1:ncomp) + log( xi(1,1:ncomp) ) ) &
831 + ( lnphi(2,1:ncomp) + log( xi(2,1:ncomp) ) )
832 g( 1:ncomp ) = g( 1:ncomp ) * exp( optpara(1:ncomp) )
836 end subroutine tangent_grad
842 subroutine tangent_hessian (hessian, gtrans, optpara, n)
847 integer,
intent(IN) :: n
848 real,
intent(IN) :: optpara(:)
849 real,
intent(IN OUT) :: gtrans(:)
850 real,
intent(IN OUT) :: hessian(:,:)
855 real :: optpara_mod(n), g(n), gi(n,n), gi_left(n,n)
861 optpara_mod = optpara
865 optpara_mod = optpara
866 optpara_mod(i) = optpara(i)*(1.0+delta)
868 call tangent_grad (g, optpara_mod, n)
871 optpara_mod(i) = optpara(i)*(1.0-delta)
873 call tangent_grad (g, optpara_mod, n)
874 gi_left(i,1:n) = g(1:n)
878 call tangent_grad (g, optpara, n)
884 hessian(i,j) = ( gi(i,j) - gi_left(i,j) ) / ( 2.0*optpara(i)*delta )
895 end subroutine tangent_hessian
908 subroutine tangent_plane_2 ( phi_2_start, rhoi1, rhoi2 )
915 real,
intent(in) :: phi_2_start
916 real,
dimension(nc),
intent(out) :: rhoi1
917 real,
dimension(nc),
intent(out) :: rhoi2
921 integer :: small_i, min_ph, other_ph
923 real,
allocatable :: optpara(:)
924 integer :: STATUS, iter, nfunc, ngrad
926 real,
allocatable :: d(:), g(:), xtemp(:), gtemp(:)
931 ALLOCATE( optpara(n) )
937 lnx( 1, 1:ncomp ) = log( xi( 1, 1:ncomp ) )
938 lnx( 2, 1:ncomp ) = log( xi( 2, 1:ncomp ) )
940 optpara( 1:ncomp ) = log( xi( 2, 1:ncomp ) * phi_2_start )
945 CALL cg_descent ( 1.e-6, optpara, n, tangent_value, tangent_grad, status, &
946 gnorm, fmin, iter, nfunc, ngrad, d, g, xtemp, gtemp )
955 if ( minval( lnx( 1, 1:ncomp ) ) < minval( lnx( 2, 1:ncomp ) ) )
then 962 small_i = minloc( lnx(min_ph,1:ncomp), 1 )
964 if ( minval( lnx(min_ph,1:ncomp) ) < -20.0 )
then 965 CALL fugacity ( lnphi )
966 lnx(min_ph,small_i) = lnx(other_ph,small_i)+lnphi(other_ph,small_i) - lnphi(min_ph,small_i)
967 xi(min_ph,1:ncomp) = exp( lnx(min_ph,1:ncomp) ) / sum( exp( lnx(min_ph,1:ncomp) ) )
968 call fugacity ( lnphi )
971 rhoi1( 1:ncomp ) = rhoi_cal( 1, 1:ncomp )
972 rhoi2( 1:ncomp ) = rhoi_cal( 2, 1:ncomp )
974 DEALLOCATE( optpara, d, g, xtemp, gtemp )
977 end subroutine tangent_plane_2
986 subroutine tangent_plane ( phi_2_start, rhoi1, rhoi2 )
992 real,
intent(in) :: phi_2_start
993 real,
dimension(nc),
intent(out) :: rhoi1
994 real,
dimension(nc),
intent(out) :: rhoi2
998 integer :: small_i, min_ph, other_ph
1000 real :: fmin , t0, h0, MACHEP
1001 real :: lnphi(np,nc)
1002 real,
allocatable :: optpara(:)
1011 ALLOCATE( optpara(n) )
1013 lnx( 1, 1:ncomp ) = log( xi( 1, 1:ncomp ) )
1014 lnx( 2, 1:ncomp ) = log( xi( 2, 1:ncomp ) )
1016 optpara( 1:ncomp ) = log( xi( 2, 1:ncomp ) * phi_2_start )
1019 call praxis( t0, machep, h0, n, prin, optpara, tangent_value, fmin )
1023 call tangent_value( fmin, optpara, n )
1032 if ( minval( lnx( 1, 1:ncomp ) ) < minval( lnx( 2, 1:ncomp ) ) )
then 1039 small_i = minloc( lnx(min_ph,1:ncomp), 1 )
1041 if ( minval( lnx(min_ph,1:ncomp) ) < -20.0 )
then 1042 CALL fugacity ( lnphi )
1043 lnx(min_ph,small_i) = lnx(other_ph,small_i)+lnphi(other_ph,small_i) - lnphi(min_ph,small_i)
1044 optpara(small_i) = lnx(2,small_i) + log( sum( exp( optpara(1:ncomp) ) ) )
1052 rhoi1( 1:ncomp ) = rhoi_cal( 1, 1:ncomp )
1053 rhoi2( 1:ncomp ) = rhoi_cal( 2, 1:ncomp )
1055 DEALLOCATE( optpara )
1057 end subroutine tangent_plane
1065 subroutine helmholtz_flash_grads ( n, x_in, f_tpd, grad, hessian, diagonal )
1068 use basic_variables, only: np, nc, ncomp, t, p, xi, xif, densta, my_cal, parame
1070 use utilities
, only: fden_calc
1074 integer,
intent(in) :: n
1075 real,
dimension(n),
intent(in) :: x_in
1076 real,
intent(out) :: f_tpd
1077 real,
dimension(n),
intent(out) :: grad
1078 real,
dimension(n,n),
intent(out) :: hessian
1079 real,
dimension(n,n),
intent(out) :: diagonal
1085 real,
dimension(ncomp) :: w
1086 real,
dimension(ncomp) :: rhoi1, rhoi2
1088 real,
dimension(ncomp) :: my1, my2
1089 real :: lnphi(np,nc)
1090 real :: df_phi, df_V
1091 real,
dimension(ncomp) :: df_wi
1092 real,
allocatable,
dimension(:,:) :: A1_rr, Aig1_rr, A2_rr, Aig2_rr
1093 real,
dimension(ncomp,ncomp) :: df_wi_wj
1094 real,
dimension(ncomp) :: df_wi_V, df_wi_phi
1095 real :: df_phi_phi, df_phi_V, df_V_V
1096 real,
dimension(2) :: sum_f_rhoi_rhoj_w_w, sum_f_rhoi_rhoj_w_r, sum_f_rhoi_rhoj_r_r
1099 w(1:ncomp) = x_in(1:ncomp)
1107 rhoi1(i) = xif(i) / v + ( phi - 0.5 ) * w(i)
1108 rhoi2(i) = xif(i) / v + ( phi + 0.5 ) * w(i)
1109 if ( rhoi1(i) < 0.0 ) rhoi1(i) = 0.0
1110 if ( rhoi2(i) < 0.0 ) rhoi2(i) = 0.0
1113 call fden_calc (f1, rhoi1)
1114 call fden_calc (f2, rhoi2)
1116 densta(1) = pi / 6.0 * sum( rhoi1(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**3 )
1117 densta(2) = pi / 6.0 * sum( rhoi2(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**3 )
1118 xi(1,1:ncomp) = rhoi1(1:ncomp) / sum( rhoi1(1:ncomp) )
1119 xi(2,1:ncomp) = rhoi2(1:ncomp) / sum( rhoi2(1:ncomp) )
1120 call fugacity ( lnphi )
1122 my1( 1:ncomp ) = my_cal(1,1:ncomp)
1123 my2( 1:ncomp ) = my_cal(2,1:ncomp)
1126 f_tpd = v * ( ( 0.5 + phi ) * f1 + ( 0.5 - phi ) * f2 + p / ( kbol*1.e30 * t ) )
1129 df_phi = v * ( f1 -f2 + ( 0.5 + phi )*sum( my1(1:ncomp)*w(1:ncomp) ) &
1130 + ( 0.5 - phi )*sum( my2(1:ncomp)*w(1:ncomp) ) )
1131 df_v = ( f_tpd - ( 0.5 + phi )*sum( my1(1:ncomp)*xif(1:ncomp) ) &
1132 - ( 0.5 - phi )*sum( my2(1:ncomp)*xif(1:ncomp) ) ) / v
1134 df_wi(i) = v * ( phi*phi - 0.25 ) * ( my1(i) - my2(i) )
1137 grad(1:ncomp) = df_wi(1:ncomp)
1138 grad(ncomp+1) = df_phi
1139 grad(ncomp+2) = df_v
1141 allocate( a1_rr( ncomp, ncomp ), aig1_rr( ncomp, ncomp ) )
1142 allocate( a2_rr( ncomp, ncomp ), aig2_rr( ncomp, ncomp ) )
1144 call dda_drhoi_drhoj_eos ( ncomp, rhoi1, a1_rr, aig1_rr )
1145 a1_rr(:,:) = a1_rr(:,:) + aig1_rr(:,:)
1147 sum_f_rhoi_rhoj_w_w(1) = 0.0
1148 sum_f_rhoi_rhoj_w_r(1) = 0.0
1149 sum_f_rhoi_rhoj_r_r(1) = 0.0
1152 sum_f_rhoi_rhoj_w_w(1) = sum_f_rhoi_rhoj_w_w(1) + a1_rr(i,j)*w(i)*w(j)
1153 sum_f_rhoi_rhoj_w_r(1) = sum_f_rhoi_rhoj_w_r(1) + a1_rr(i,j)*w(i)*xif(j)
1154 sum_f_rhoi_rhoj_r_r(1) = sum_f_rhoi_rhoj_r_r(1) + a1_rr(i,j)*xif(i)*xif(j)
1158 call dda_drhoi_drhoj_eos ( ncomp, rhoi2, a2_rr, aig2_rr )
1159 a2_rr(:,:) = a2_rr(:,:) + aig2_rr(:,:)
1162 sum_f_rhoi_rhoj_w_w(2) = 0.0
1163 sum_f_rhoi_rhoj_w_r(2) = 0.0
1164 sum_f_rhoi_rhoj_r_r(2) = 0.0
1167 sum_f_rhoi_rhoj_w_w(2) = sum_f_rhoi_rhoj_w_w(2) + a2_rr(i,j)*w(i)*w(j)
1168 sum_f_rhoi_rhoj_w_r(2) = sum_f_rhoi_rhoj_w_r(2) + a2_rr(i,j)*w(i)*xif(j)
1169 sum_f_rhoi_rhoj_r_r(2) = sum_f_rhoi_rhoj_r_r(2) + a2_rr(i,j)*xif(i)*xif(j)
1176 df_wi_wj(i,j) = v * (phi*phi - 0.25 ) * ( (phi-0.5) * a1_rr(i,j) - (phi+0.5) * a2_rr(i,j) )
1181 df_wi_phi(i) = v * ( 2.0*phi*( my1(i)-my2(i) ) &
1182 + (phi*phi-0.25)*sum( w(1:ncomp)*(a1_rr(i,1:ncomp)-a2_rr(i,1:ncomp)) ) )
1183 df_wi_v(i) = ( df_wi(i) - (phi*phi-0.25)*sum( xif(1:ncomp)*(a1_rr(i,1:ncomp)-a2_rr(i,1:ncomp)) ) ) / v
1186 df_phi_phi = v * ( 2.0*sum( ( my1(1:ncomp)-my2(1:ncomp))*w(1:ncomp) ) &
1187 + ( 0.5 + phi ) * sum_f_rhoi_rhoj_w_w(1) &
1188 + ( 0.5 - phi ) * sum_f_rhoi_rhoj_w_w(2) )
1189 df_phi_v = ( df_phi - sum( ( my1(1:ncomp)-my2(1:ncomp))*xif(1:ncomp) ) &
1190 - ( 0.5 + phi ) * sum_f_rhoi_rhoj_w_r(1) &
1191 - ( 0.5 - phi ) * sum_f_rhoi_rhoj_w_r(2) ) / v
1192 df_v_v = ( (0.5+phi) * sum_f_rhoi_rhoj_r_r(1) + (0.5-phi) * sum_f_rhoi_rhoj_r_r(2) ) / v**3
1196 hessian(i,j) = df_wi_wj(i,j)
1198 hessian(i,ncomp+1) = df_wi_phi(i)
1199 hessian(i,ncomp+2) = df_wi_v(i)
1200 hessian(ncomp+1,i) = df_wi_phi(i)
1201 hessian(ncomp+2,i) = df_wi_v(i)
1203 hessian(ncomp+1,ncomp+1) = df_phi_phi
1204 hessian(ncomp+1,ncomp+2) = df_phi_v
1205 hessian(ncomp+2,ncomp+1) = df_phi_v
1206 hessian(ncomp+2,ncomp+2) = df_v_v
1209 diagonal(i,i) = v * (phi*phi - 0.25 ) * ( (phi-0.5)/rhoi1(i) - (phi+0.5)/rhoi2(i) )
1211 diagonal(ncomp+1,ncomp+1) = v * ( 2.0*sum( ( log( rhoi1(1:ncomp) )- log(rhoi2(1:ncomp)) )*w(1:ncomp) ) &
1212 + (0.5+phi) * sum(w(1:ncomp)*w(1:ncomp)/rhoi1(1:ncomp)) &
1213 + (0.5-phi) * sum(w(1:ncomp)*w(1:ncomp)/rhoi2(1:ncomp)) )
1214 diagonal(ncomp+2,ncomp+2) = ( (0.5+phi) * sum(xif(1:ncomp)*xif(1:ncomp)/rhoi1(1:ncomp)) &
1215 + (0.5-phi) * sum(xif(1:ncomp)*xif(1:ncomp)/rhoi2(1:ncomp)) ) / v**3
1222 deallocate( a1_rr, aig1_rr, a2_rr, aig2_rr )
1224 end subroutine helmholtz_flash_grads
1243 subroutine phase_stability ( rhoi_feed, eta_trial, ph_split, rhoi_trial )
1253 real,
dimension(nc),
intent(IN) :: rhoi_feed
1254 real,
intent(IN) :: eta_trial
1255 integer,
intent(OUT) :: ph_split
1256 real,
dimension(nc),
intent(OUT) :: rhoi_trial
1261 real,
allocatable :: optpara(:)
1264 integer :: i_trial_composition
1266 real :: delta_rhoi(nc)
1267 real :: w(np,nc), mean_mass
1268 integer :: ph_split_i( 2*ncomp+1 )
1269 real :: fmin_vec( 2*ncomp+1 )
1270 real :: rhoi2_vec(2*ncomp+1, 1:ncomp)
1271 character (LEN=2) :: ensemble_flag_save
1273 integer :: STATUS, iter, nfunc, ngrad
1275 real,
allocatable :: d(:), g(:), xtemp(:), gtemp(:)
1280 ensemble_flag_save = ensemble_flag
1281 ensemble_flag =
'tv' 1284 ALLOCATE( optpara(n) )
1287 ALLOCATE( xtemp(n) )
1288 ALLOCATE( gtemp(n) )
1291 if ( outp >= 2 )
then 1292 write (*,
'(a)')
' reference x_i, tested for stability:' 1293 write (*,
'(a,4G21.12)')
' x_i feed:', rhoi_feed(1:ncomp) / sum( rhoi_feed(1:ncomp) )
1298 do i_trial_composition = 0, (ncomp + ncomp)
1303 if ( i_trial_composition == 0 ) w(2,1:ncomp) = 1.0 /
REAL(ncomp)
1304 if ( i_trial_composition >= 1 .AND. i_trial_composition <= ncomp )
then 1305 w( 2, 1:ncomp ) = 1.0 /
REAL( ncomp-1 ) * 0.05
1306 w( 2, i_trial_composition ) = 0.95
1307 else if ( i_trial_composition >= ncomp+1 )
then 1308 w( 2, 1:ncomp ) = 1.0 /
REAL( ncomp-1 ) * 0.00001
1309 w( 2, i_trial_composition - ncomp ) = 0.99999
1312 mean_mass = 1.0 / sum( w(2,1:ncomp)/mm(1:ncomp) )
1313 xi(2,1:ncomp) = w(2,1:ncomp)/mm(1:ncomp) * mean_mass
1314 if ( outp >= 2 )
write (*,
'(a,4G20.12)')
' trial phase x ---- ', xi(2,1:ncomp)
1320 rhoi(i) = xi(2,i)*eta_trial/sum( pi/6.0*xi(2,1:ncomp)*mseg(1:ncomp)*dhs(1:ncomp)**3 )
1321 optpara(i) = log( rhoi(i) )
1330 CALL newton_opt_2d ( f_stability, optpara, n, 1.e-8, 1.e-8, gtemp, fmin )
1333 if ( optpara(i) > -50.0 )
then 1334 rhoi_best(i) = exp( optpara(i) )
1336 rhoi_best(i) = 1.e-50
1341 CALL cg_descent ( 1.e-5, optpara, n, f_stability, stability_grad, status, &
1342 gnorm, fmin, iter, nfunc, ngrad, d, g, xtemp, gtemp)
1350 delta_rhoi( 1:n ) = abs( 1.0 - rhoi_best(1:n) / rhoi_feed(1:n) )
1352 rhoi2_vec( i_trial_composition + 1, 1:ncomp ) = rhoi_best(1:ncomp)
1353 fmin_vec( i_trial_composition + 1 ) = 1.e8
1355 ph_split_i( i_trial_composition + 1 ) = 0
1356 if ( fmin < 1.e-3 .AND. maxval( delta_rhoi(1:n) ) > 0.1 )
then 1357 ph_split_i( i_trial_composition + 1 ) = 2
1358 fmin_vec( i_trial_composition + 1 ) = fmin
1361 if (fmin < -1.e-8 .AND. maxval( delta_rhoi(1:n) ) > 0.001 )
then 1362 ph_split_i( i_trial_composition + 1 ) = 1
1363 fmin_vec( i_trial_composition + 1 ) = fmin
1370 if ( outp >= 2 )
then 1371 write (*,
'(a, 5G20.12)')
' eta, xi_trialphase ',pi/6.0 &
1372 * sum( rhoi_best(1:ncomp) * mseg(1:ncomp) * dhs(1:ncomp)**3 ), &
1373 rhoi_best(1:ncomp) / sum( rhoi_best(1:ncomp) )
1374 write (*,
'(a,G20.12,i4,G20.12,i3)')
' trial-result: fmin, N, d(x), ph-split:', &
1375 fmin, i_trial_composition, maxval( delta_rhoi( 1:n ) ), &
1376 ph_split_i( i_trial_composition+1 )
1386 i_trial_composition = minloc( fmin_vec( 1: (ncomp+ncomp)+1 ), 1 )
1387 rhoi_trial( 1:ncomp ) = rhoi2_vec( i_trial_composition, 1:ncomp )
1388 ph_split = ph_split_i( i_trial_composition )
1390 if ( outp >= 2 )
write (*,*)
'selected trial-result',i_trial_composition,fmin_vec( i_trial_composition )
1392 DEALLOCATE( optpara )
1393 DEALLOCATE( d, g, xtemp, gtemp )
1394 ensemble_flag = ensemble_flag_save
1396 end subroutine phase_stability
1404 subroutine f_stability ( f_tpd, optpara, n )
1409 use utilities
, only: fden_calc
1413 integer,
intent(in) :: n
1414 real,
intent(in) :: optpara(:)
1415 real,
intent(in out) :: f_tpd
1419 real :: rhoi(nc),gradterm
1427 if ( maxval( optpara(1:n) ) > 2.0 )
then 1428 f_tpd = 100.0 * maxval( optpara(1:n) )
1432 if ( optpara(i) /= optpara(i) )
then 1437 if ( maxval( optpara(1:n) ) < -50.0 )
then 1438 f_tpd = - 100.0 * sum( optpara(1:n) )
1449 if ( optpara(i) > -50.0 )
then 1450 rhoi(i) = exp( optpara(i) )
1461 dens = pi/6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**3 )
1467 if (dens > 0.65)
then 1468 punish = punish + (dens-0.65)*1000.0
1469 rhoi(1:n) = rhoi(1:n)*0.65/dens
1476 call fden_calc (fden, rhoi)
1478 gradterm = sum( my_f(1:n) * rhoi(1:n) )
1480 f_tpd = fden + (p * 1.e-30) / (kbol*t) - gradterm + punish
1481 f_tpd = f_tpd * 1000.0
1484 if ( f_tpd < fmin_best )
then 1486 rhoi_best(1:n) = rhoi(1:n)
1489 end subroutine f_stability
1497 subroutine stability_grad (g, optpara, n)
1503 integer,
intent(in) :: n
1504 real,
intent(in) :: optpara(:)
1505 real,
intent(in out) :: g(:)
1509 integer :: nphas_save
1511 real :: lnphi(np,nc)
1522 if ( optpara(i) /= optpara(i) .OR. optpara(i) > 5.0 )
then 1528 if ( maxval( optpara(1:n) ) < -50.0 )
then 1539 if ( optpara(i) > -50.0 )
then 1540 rhoi(i) = exp( optpara(i) )
1548 densta(1) = pi/6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**3 )
1554 if (densta(1) > 0.65)
then 1555 rhoi(1:n) = rhoi(1:n) * 0.65 / densta(1)
1556 densta(1) = pi/6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**3 )
1559 xi(1,1:ncomp) = rhoi(1:ncomp) / sum( rhoi(1:ncomp) )
1565 call fugacity (lnphi)
1567 g( 1:n ) = lnphi( 1, 1:n ) + log( rhoi( 1:n ) ) - my_f( 1:n )
1568 g( 1:n ) = g( 1:n ) * rhoi( 1:n ) * 1000.0
1573 end subroutine stability_grad
1582 subroutine stability_hessian (hessian, gtrans, fmin, optpara, n)
1587 integer,
intent(IN) :: n
1588 real,
intent(IN) :: optpara(:)
1589 real,
intent(IN OUT) :: fmin
1590 real,
intent(IN OUT) :: gtrans(:)
1591 real,
intent(IN OUT) :: hessian(:,:)
1596 real :: optpara_mod(n), g(n), gi_right(n,n), gi_left(n,n)
1597 real,
allocatable,
dimension(:,:) :: A_rr, Aig_rr
1603 optpara_mod = optpara
1607 optpara_mod = optpara
1608 optpara_mod(i) = optpara(i)*(1.0+delta)
1610 call stability_grad (g, optpara_mod, n)
1611 gi_right(i,1:n) = g(1:n)
1613 optpara_mod(i) = optpara(i)*(1.0-delta)
1615 call stability_grad (g, optpara_mod, n)
1616 gi_left(i,1:n) = g(1:n)
1620 call stability_grad (g, optpara, n)
1625 hessian(i,j) = ( gi_right(i,j) - gi_left(i,j) ) / ( 2.0*optpara(i)*delta )
1627 write (*,*) i,j,hessian(i,j)
1634 call f_stability (fmin, optpara, n)
1636 allocate( a_rr(ncomp,ncomp), aig_rr(ncomp,ncomp) )
1637 call dda_drhoi_drhoj_eos ( ncomp, exp( optpara(:) ), a_rr, aig_rr )
1640 hessian(i,j) = a_rr(i,j)
1641 if (i==j) hessian(i,j) = hessian(i,j) + 1.0 / exp( optpara(i) )
1643 if (i/=j) hessian(i,j) = hessian(i,j)*exp( optpara(i) )*exp( optpara(j) )*1000.0
1644 if (i==j) hessian(i,j) = hessian(i,j)*exp( optpara(i) )*exp( optpara(j) )*1000.0 + g(i)
1645 if (i/=j)
write (*,*) i,j,hessian(i,j)
1646 if (i==j)
write (*,*) i,j,hessian(i,j)
1649 deallocate( a_rr, aig_rr )
1652 end subroutine stability_hessian
1668 integer,
parameter :: steps = 40
1669 logical :: lle_check
1670 integer :: i, j, k, phasen(0:steps)
1671 real :: lnphi(np,nc)
1672 real,
dimension(0:steps) :: vlemin, llemin, xval, start_xv, start_xl
1673 real :: x_sav,dg_dx2
1691 xi(1,1) = 1.0 -
REAL(i) /
REAL(steps)
1692 if ( xi(1,1) <= 1.e-50 ) xi(1,1) = 1.e-50
1694 lnx(1,1) = log(xi(1,1))
1695 lnx(2,1) = log(xi(2,1))
1698 CALL fugacity ( lnphi )
1701 llemin(i)= gibbs(1) * rgas * t
1703 if ( abs(1.0-dense(1)/dense(2)) > 0.0001 )
then 1704 vlemin(i) = ( gibbs(1) - gibbs(2) ) * rgas * t
1710 if (i > 0 .AND. phasen(i) == 2)
then 1712 if ( phasen(i-1) == 2 .AND. abs( vlemin(i) + vlemin(i-1) ) < &
1713 abs( vlemin(i) ) + abs( vlemin(i-1) ) )
then 1715 start_xv(j) = xval(i-1) + (xval(i)-xval(i-1)) &
1716 * abs( vlemin(i-1) ) / abs( vlemin(i) - vlemin(i-1) )
1725 dg_dx2 = (-llemin(i-2) + 16.0*llemin(i-1) - 30.0*llemin(i) &
1726 + 16.0*llemin(i+1) - llemin(i+2)) / ( 12.0 * ((xval(i)-xval(i-1))**2) )
1727 if ( dg_dx2 < 0.0 )
then 1729 start_xl(k) = xval(i)
1734 if ( start_xl(1) == 0.0 .AND. start_xv(1) /= 0.0 )
then 1735 xi(1,1) = start_xv(1)
1736 xi(1,2) = 1.0 - xi(1,1)
1738 if ( outp >= 1)
write (*,*)
'VLE is likely', xi(1,1),xi(1,2)
1739 else if ( start_xl(1) /= 0.0 .AND. start_xv(1) == 0.0 )
then 1740 xi(1,1) = start_xl(1)
1741 xi(1,2) = 1.0 - xi(1,1)
1742 if ( outp >= 1)
write (*,*)
'LLE is likely', xi(1,1),xi(1,2)
1744 else if ( start_xl(1) /= 0.0 .AND. start_xv(1) /= 0.0 )
then 1745 xi(1,1) = start_xv(1)
1746 xi(1,2) = 1.0 - xi(1,1)
1747 if ( outp >= 1)
write(*,*)
'starting with VLE and check for LLE' 1751 xi(1,2) = 1.0 - xi(1,1)
1756 end subroutine vle_min
1773 subroutine rachford_rice ( converg, rhoi1, rhoi2 )
1776 use optimizer_2d
, only: newton_opt_analytic
1780 integer,
intent(in out) :: converg
1781 real,
dimension(nc),
intent(out) :: rhoi1
1782 real,
dimension(nc),
intent(out) :: rhoi2
1786 integer :: nr_inside_steps, nr_outside_steps
1787 real,
parameter :: tol_out = 1.e-11
1788 real,
parameter :: tol_in = 1.e-13
1789 real :: ph_frac, ph_frac0
1790 real :: lnphi(np,nc), Ki(nc)
1791 real :: f1, d_ph, dfdph
1792 real :: error1, error2 = 0.0
1793 real :: xi_compare(2,nc)
1794 logical :: comp_balance_violation = .false.
1797 real,
allocatable,
dimension(:) :: w
1798 real,
allocatable,
dimension(:) :: x_in, grad
1799 real,
allocatable,
dimension(:,:) :: hessian
1800 real :: phi, V1, V2, V, phi_00, f_tpd
1806 nr_outside_steps = 80
1807 nr_inside_steps = 10
1809 xi_compare(1:2,:) = xi(1:2,:)
1811 ensemble_flag =
'tp' 1812 densta(1) = dense(1)
1813 densta(2) = dense(2)
1817 if ( outp >= 2 )
write (*,
'(a,4G20.12)')
'RR, N_out, N_inner, xi(1,1), xiF(1), xi(2,1), ph_frac, error1' 1824 error1 = tol_out + 1.0
1825 do while ( error1 > tol_out .AND. k1 < nr_outside_steps )
1833 CALL fugacity ( lnphi )
1835 ki(1:ncomp) = exp( lnphi(1,1:ncomp) - lnphi(2,1:ncomp) )
1836 write (*,*)
'dense',dense(1),dense(2)
1838 if ( abs(1.0-dense(1)/dense(2)) < 1.e-6 .AND. sum(abs(ki(1:ncomp)-1.0)) < 1.e-8 )
exit 1842 do while ( error2 > tol_in .AND. k2 < nr_inside_steps )
1851 f1 = sum( xif(1:ncomp)*(ki(1:ncomp)-1.0) / ( 1.0 + (ki(1:ncomp)-1.0)*ph_frac ) )
1853 dfdph = - sum( xif(1:ncomp) / ( 1.0/(ki(1:ncomp)-1.0) + ph_frac )**2 )
1854 if ( dfdph == 0.0 ) dfdph = 0.0000001
1856 ph_frac = ph_frac0 - f1 / dfdph
1858 error2 = abs( ph_frac - ph_frac0 )
1859 if ( outp >= 3 )
write (*,
'(a,3G20.8)')
'phase_fraction, error', ph_frac, ph_frac0, error2
1866 comp_balance_violation = .false.
1867 if ( ph_frac > 1.0 ) comp_balance_violation = .true.
1868 if ( ph_frac < 0.0 ) comp_balance_violation = .true.
1869 if ( ph_frac > 1.0 ) ph_frac = 0.9999999
1870 if ( ph_frac < 0.0 ) ph_frac = 0.0000001
1876 xi(1,1:ncomp) = xif(1:ncomp) / ( 1.0 + ph_frac *( ki(1:ncomp)-1.0 ) )
1877 xi(2,1:ncomp) = ki(1:ncomp)* xif(1:ncomp) / ( 1.0 + ph_frac *( ki(1:ncomp)-1.0 ) )
1879 if ( sum( xi(2,1:ncomp) ) < 0.2 ) xi(2,1:ncomp) = xi(2,1:ncomp) / sum( xi(2,1:ncomp) )
1880 if ( sum( xi(1,1:ncomp) ) < 0.2 ) xi(1,1:ncomp) = xi(1,1:ncomp) / sum( xi(1,1:ncomp) )
1882 error1 = sum( abs( xi_compare(1,1:ncomp) - xi(1,1:ncomp) ) ) &
1883 + sum( abs( xi_compare(2,1:ncomp) - xi(2,1:ncomp) ) )
1884 xi_compare(1:2,:) = xi(1:2,:)
1886 if ( outp >= 2 )
write (*,
'(a,2i5,5G20.12)')
'RR',k1,k2,xi(1,1), xif(1),xi(2,1), ph_frac, error1
1888 if ( k1 == 100 .AND. outp > 0 )
write (*,*)
'Rachford-Rice: outside loop slow convergence' 1897 if ( error1 < tol_out .AND. error2 < tol_in .AND. .NOT. comp_balance_violation )
then 1899 rhoi1( 1:ncomp ) = rhoi_cal( 1, 1:ncomp )
1900 rhoi2( 1:ncomp ) = rhoi_cal( 2, 1:ncomp )
1902 if ( outp >= 2 )
write (*,*)
' ' 1903 if ( outp >= 2 )
write (*,*)
'========================================================' 1904 if ( outp >= 1 )
write (*,*)
'Rachford-Rice converged' 1905 if ( outp >= 2 )
write (*,*)
'========================================================' 1906 if ( outp >= 2 )
write (*,*)
' x p1 = ',rhoi1( 1:ncomp ) / sum( rhoi1( 1:ncomp ) )
1907 if ( outp >= 2 )
write (*,*)
' x p2 = ',rhoi2( 1:ncomp ) / sum( rhoi2( 1:ncomp ) )
1908 if ( outp >= 2 )
write (*,*)
'eta 1,2 = ',dense(1), dense(2)
1909 if ( outp >= 2 )
write (*,*)
' ' 1920 if ( converg /= 1 .AND. error1 < 1.e-4 )
then 1922 if( outp >= 1)
write (*,*)
'Rachf.-R.: not converged' 1925 ensemble_flag =
'tv' 1926 allocate ( w(ncomp), x_in(ncomp+2), grad(ncomp+2), hessian(ncomp+2,ncomp+2) )
1927 rhoi1(1:ncomp) = rhoi_cal(1,1:ncomp)
1928 rhoi2(1:ncomp) = rhoi_cal(2,1:ncomp)
1929 w(1:ncomp) = rhoi2(1:ncomp) - rhoi1(1:ncomp)
1930 v1 = (1.0-phi_00) * sum( xif(1:ncomp) ) / sum( rhoi1(1:ncomp) )
1931 v2 = phi_00 * sum( xif(1:ncomp) ) / sum( rhoi2(1:ncomp) )
1932 write (*,*)
'phi_00, xiF(1:ncomp)', phi_00, xif(1:ncomp)
1933 write (*,*)
'V1, V2', v1, v2
1934 write (*,*)
'check:',1, (1.0-ph_frac)*xi(1,1) + ph_frac*xi(2,1), xif(1)
1935 write (*,*)
'check:',2, (1.0-ph_frac)*xi(1,2) + ph_frac*xi(2,2), xif(2)
1937 phi = 0.5 * ( v1 - v2 ) / v
1938 x_in(1:ncomp) = w(1:ncomp)
1941 call newton_opt_analytic ( helmholtz_flash_grads, (ncomp+2), x_in, 1.e-7, 1.e-12, grad, f_tpd, converg )
1943 w(1:ncomp) = x_in(1:ncomp)
1947 rhoi1(i) = xif(i) / v + ( phi - 0.5 ) * w(i)
1948 rhoi2(i) = xif(i) / v + ( phi + 0.5 ) * w(i)
1949 if ( rhoi1(i) < 0.0 ) rhoi1(i) = 0.0
1950 if ( rhoi2(i) < 0.0 ) rhoi2(i) = 0.0
1953 if ( maxval(abs(grad(:))) < 1.e-7 )
then 1956 if ( outp >= 2 )
write (*,*)
' ' 1957 if ( outp >= 2 )
write (*,*)
'========================================================' 1958 if ( outp >= 1 )
write (*,*)
'Newton iteration (subsequent to Rachford-Rice) converged' 1959 if ( outp >= 2 )
write (*,*)
'========================================================' 1960 if ( outp >= 2 )
write (*,*)
' x p1 = ',rhoi1( 1:ncomp ) / sum( rhoi1( 1:ncomp ) )
1961 if ( outp >= 2 )
write (*,*)
' x p2 = ',rhoi2( 1:ncomp ) / sum( rhoi2( 1:ncomp ) )
1962 if ( outp >= 2 )
write (*,*)
'eta 1,2 = ',dense(1), dense(2)
1963 if ( outp >= 2 )
write (*,*)
' ' 1964 alpha = v * ( 0.5 - phi )*sum( rhoi2(1:ncomp) )
1968 deallocate( w, x_in, grad, hessian )
1973 end subroutine rachford_rice
1996 subroutine bubble_point_rachford_rice ( iterate_t, converg, rhoi1, rhoi2 )
2002 integer,
intent(in) :: iterate_t
2003 integer,
intent(in out) :: converg
2004 real,
dimension(nc),
intent(out) :: rhoi1
2005 real,
dimension(nc),
intent(out) :: rhoi2
2009 integer :: nr_inside_steps, nr_outside_steps
2010 real,
parameter :: tol_out = 1.e-11
2011 real,
parameter :: tol_in_p = 1.e-10
2012 real,
parameter :: tol_in_t = 1.e-8
2014 real :: p0, t0, dp, dt, deltap
2015 real :: p_sav, t_sav
2016 real :: damping, acceleration
2017 real :: lnphi(np,nc), Ki(nc)
2018 real :: f0, f1, dfdp
2019 real :: error1, error2 = 0.0
2020 real :: xi_compare(nc)
2030 nr_outside_steps = 1000
2031 nr_inside_steps = 10
2032 if ( iterate_t == 1 ) tol_in = tol_in_t
2033 if ( iterate_t == 0 ) tol_in = tol_in_p
2036 xi_compare(:) = xi(2,:)
2038 ensemble_flag =
'tp' 2039 densta(1) = dense(1)
2040 densta(2) = dense(2)
2044 if ( outp >= 2 )
write (*,
'(a,4G20.12)')
'bbp-RR, N_out, N_inner, xi(1,1), xi(2,1), p, t, error1' 2051 error1 = tol_out + 1.0
2052 do while ( error1 > tol_out .AND. k1 < nr_outside_steps )
2061 error2 = tol_in + 1.0
2062 do while ( error2 > tol_in .AND. k2 < nr_inside_steps )
2072 if ( iterate_t == 1 )
then 2078 CALL fugacity ( lnphi )
2080 if ( abs(1.0-dense(1)/dense(2)) < 1.e-6 .AND. sum(abs(ki(1:ncomp)-1.0)) < 1.e-8 )
exit 2081 ki(1:ncomp) = exp( lnphi(1,1:ncomp) - lnphi(2,1:ncomp) )
2082 f0 = sum( xi(1,1:ncomp) * ki(1:ncomp) ) - 1.0
2086 CALL fugacity ( lnphi )
2088 ki(1:ncomp) = exp( lnphi(1,1:ncomp) - lnphi(2,1:ncomp) )
2089 f1 = sum( xi(1,1:ncomp) * ki(1:ncomp) ) - 1.0
2091 if ( iterate_t == 1 )
then 2093 dfdp = ( f1 - f0 ) / dt
2094 if ( dfdp == 0.0 ) dfdp = 0.0000001
2100 error2 = abs( t - t0 )
2101 if ( outp >= 3 )
write (*,
'(a,3G20.12)')
'inner loop error', t, t0, error2
2102 if ( error2 > 2.0 .OR. t < 0.0 ) sr_exit = .true.
2103 if ( error2 > 2.0 .OR. t < 0.0 )
exit 2107 dfdp = ( f1 - f0 ) / ( log(p0) - log(p0 - dp) )
2108 if ( dfdp == 0.0 ) dfdp = 0.0000001
2113 if ( deltap > 2.0 ) deltap = 2.0
2114 if ( deltap < -2.0 ) deltap = -2.0
2115 p = log( p0) - deltap
2121 if ( abs( p / p0 - 1.0 ) > 0.3 ) p = damping * p + ( 1.0 - damping ) * p0
2124 error2 = abs( p / p0 - 1.0 )
2126 if ( outp >= 3 )
write (*,
'(a,3G20.12)')
'inner loop error', p, p0, error2
2127 if ( error2 > 10.0 ) sr_exit = .true.
2128 if ( error2 > 10.0 )
exit 2139 xi(2,1:ncomp) = ki(1:ncomp)* xi(1,1:ncomp) / sum( xi(1,1:ncomp) * ki(1:ncomp) )
2140 xi(2,1:ncomp) = max( xi(2,1:ncomp), 1.e-50 )
2142 if ( sum( xi(2,1:ncomp) ) < 0.4 ) xi(2,1:ncomp) = xi(2,1:ncomp) / sum( xi(2,1:ncomp) )
2144 error1 = sum( abs( xi_compare(1:ncomp) - xi(2,1:ncomp) ) )
2146 if ( k1 > 100 )
then 2147 acceleration =
real(k1) / 100.0 + 1.0
2148 if ( k1 > 900 ) acceleration = acceleration * 2.0
2149 xi(2,1:ncomp) = xi(2,1:ncomp) + acceleration * ( xi(2,1:ncomp) - xi_compare(1:ncomp) )
2150 xi(2,1:ncomp) = max( xi(2,1:ncomp), 1.e-50 )
2152 xi(2,1:ncomp) = xi(2,1:ncomp) / sum( xi(2,1:ncomp) )
2155 xi_compare(:) = xi(2,:)
2157 if ( error2 > tol_in ) error1 = error1 + tol_out
2159 if ( k1 >= 500 ) error1 = error1 / 10.0
2160 if ( k1 >= 1000 ) error1 = error1 / 100.0
2162 if ( outp >= 2 )
write (*,
'(a,2i5,5G18.10)')
'bbp-RR',k1,k2,xi(1,1), xi(2,1), p, t, error1
2164 if ( k1 == 100 .AND. outp > 0 )
write (*,*)
'bbp-Rachford-Rice: outside loop slow convergence' 2173 if ( error1 < tol_out .AND. error2 < tol_in )
then 2175 rhoi1( 1:ncomp ) = rhoi_cal( 1, 1:ncomp )
2176 rhoi2( 1:ncomp ) = rhoi_cal( 2, 1:ncomp )
2178 if ( outp >= 2 )
write (*,*)
' ' 2179 if ( outp >= 2 )
write (*,*)
'========================================================' 2180 if ( outp >= 1 )
write (*,*)
'bubble point Rachford-Rice converged' 2181 if ( outp >= 2 )
write (*,*)
'========================================================' 2182 if ( outp >= 2 )
write (*,*)
' x p1 = ',rhoi1( 1:ncomp ) / sum( rhoi1( 1:ncomp ) )
2183 if ( outp >= 2 )
write (*,*)
' x p2 = ',rhoi2( 1:ncomp ) / sum( rhoi2( 1:ncomp ) )
2184 if ( outp >= 2 )
write (*,*)
'eta 1,2 = ',dense(1), dense(2)
2185 if ( outp >= 2 )
write (*,*)
' ' 2191 if ( outp >= 1)
write (*,*)
'bbp-Rachf.-R.: not converged' 2195 end subroutine bubble_point_rachford_rice
2213 subroutine t_x_rachford_rice ( x12, converg, rhoi1, rhoi2 )
2219 real,
intent(in) :: x12
2220 integer,
intent(in out) :: converg
2221 real,
dimension(nc),
intent(out) :: rhoi1
2222 real,
dimension(nc),
intent(out) :: rhoi2
2236 do while ( abs( f ) > 1.e-6 .AND. count < 10 )
2241 p = p0 * ( 1.0 + delta )
2242 call rachford_rice ( converg, rhoi1, rhoi2 )
2246 call rachford_rice ( converg, rhoi1, rhoi2 )
2249 dfdx = ( fr - f ) / ( p0 * delta )
2256 end subroutine t_x_rachford_rice
2264 subroutine occupy_val_init ( rhoi1, rhoi2 )
2271 real,
dimension(nc),
intent(in) :: rhoi1
2272 real,
dimension(nc),
intent(in) :: rhoi2
2278 dense(1) = pi/6.0 * sum( rhoi1(1:ncomp) * mseg(1:ncomp) * dhs(1:ncomp)**3 )
2279 dense(2) = pi/6.0 * sum( rhoi2(1:ncomp) * mseg(1:ncomp) * dhs(1:ncomp)**3 )
2281 xi( 1, 1:ncomp ) = rhoi1( 1:ncomp ) / sum( rhoi1(1:ncomp) )
2282 xi( 2, 1:ncomp ) = rhoi2( 1:ncomp ) / sum( rhoi2(1:ncomp) )
2283 lnx( 1, 1:ncomp ) = log( xi( 1, 1:ncomp ) )
2284 lnx( 2, 1:ncomp ) = log( xi( 2, 1:ncomp ) )
2286 val_init(1) = dense(1)
2287 val_init(2) = dense(2)
2292 val_init(4+i+(ph-1)*ncomp) = lnx( ph, i )
2296 end subroutine occupy_val_init
2304 subroutine read_mode_staring_value ( scan_index, outp )
2306 use utilities
, only: file_open
2310 integer,
intent(out) :: scan_index
2311 integer,
intent(in out) :: outp
2314 character (LEN=50) :: textstring
2315 character (LEN=50) :: start_value_file
2318 first_call = .false.
2319 start_value_file =
'./input_file/starting_value_default.inp' 2320 call file_open ( start_value_file, 84 )
2321 read (84,*) textstring
2322 read (84,*) scan_index, outp
2324 if ( outp == 3 )
then 2325 if ( scan_index == 1 ) outp = 0
2326 if ( scan_index == 2 ) outp = 1
2328 if ( outp >= 1 )
write (*,*)
'level of info given to terminal:',outp
2329 write (*,*)
'calculation option composition-scan:',scan_index
2331 end subroutine read_mode_staring_value
2339 subroutine output_rho_info ( rhoi )
2343 real,
dimension(nc),
intent(IN) :: rhoi
2347 dens = pi/6.0 * sum( rhoi(1:ncomp) * mseg(1:ncomp) * dhs(1:ncomp)**3 )
2349 write (*,*)
' eta = ', dens
2350 write (*,*)
' x = ', rhoi( 1:ncomp ) / sum( rhoi(1:ncomp) )
2352 end subroutine output_rho_info
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains constant...
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW Module STARTING_VALUES This m...
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
subroutine, public start_var(converg)
subroutine start_var