MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
utilities.f90
1 module utilities
2 
3  implicit none
4 
5  PRIVATE
6  PUBLIC :: converged, restore_converged, switch, init_vars, si_dens, select_sum_rel, &
7  determine_flash_it, determine_flash_it2, new_flash, x_summation, flash_alpha, &
8  flash_sum, neutr_charge, molefrac, file_open, p_calc, dens_calc, enthalpy_etc, &
9  critical, pure_crit_point_iteration, fden_calc, only_one_term_eos_numerical, &
10  restore_previous_eos_numerical, paus, error_message
11 
12 contains
13 
14 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
15 ! subroutine converged
16 !
17 ! Once a converged solution for an equilibrium calculation is found,
18 ! this subroutine writes variables to an array "val_conv".
19 ! (= short for converged values)
20 ! The array comprises the following elements
21 ! element 0 density of third phase
22 ! element 1 density of first phase
23 ! element 2 density of second phase
24 ! element 3 temperature [K]
25 ! element 4 pressure [Pa]
26 ! element 5,..(4+NCOMP) mole-fraction of comp. i in log. from (phase 1)
27 ! element ... mole-fraction of comp. i in log. from (phase 2)
28 ! element ... mole-fraction of comp. i in log. from (phase 3)
29 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
30 
31 subroutine converged
32 
33  use basic_variables
34 
35  integer :: i, ph
36  !-----------------------------------------------------------------------------
37 
38  val_conv(0) = dense(3)
39  val_conv(1) = dense(1)
40  val_conv(2) = dense(2)
41  val_conv(3) = t
42  val_conv(4) = p
43  DO ph = 1, nphas
44  DO i = 1, ncomp
45  val_conv(4+i+(ph-1)*ncomp) = lnx(ph,i)
46  END DO
47  END DO
48 
49 end subroutine converged
50 
51 
52 
53 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
54 ! subroutine init_vars
55 !
56 ! This subroutine writes variables from an array "val_init" to the
57 ! system-variables. Those variables
58 ! include some specifications but also some starting values for a
59 ! phase equilibrium calculation. (val_init stands for 'initial value')
60 
61 ! The array comprises the following elements
62 ! element 0 density of third phase
63 ! element 1 density of first phase
64 ! element 2 density of second phase
65 ! element 3 temperature [K]
66 ! element 4 pressure [Pa]
67 ! element 5,..(5+NCOMP) mole-fraction of comp. i in log. from (phase 1)
68 ! element ... mole-fraction of comp. i in log. from (phase 2)
69 ! element ... mole-fraction of comp. i in log. from (phase 3)
70 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
71 
72 subroutine init_vars
73 
74  use basic_variables
75 
76  integer :: i, ph
77  !-----------------------------------------------------------------------------
78 
79  densta(3) = val_init(0)
80  densta(1) = val_init(1)
81  densta(2) = val_init(2)
82  t = val_init(3)
83  p = val_init(4)
84  DO ph = 1, nphas
85  DO i = 1, ncomp
86  lnx(ph,i) = val_init(4+i+(ph-1)*ncomp)
87  END DO
88  END DO
89 
90 end subroutine init_vars
91 
92 
93 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
94 ! subroutine switch
95 !
96 ! This subroutine switches the phase-index of phase 1 and phase 2.
97 ! Sometimes this is handy.
98 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
99 
100 subroutine switch
101 
102  use basic_variables
103 
104  integer :: i
105  real :: savval(nc*np+6)
106  !-----------------------------------------------------------------------------
107 
108  savval(1) = val_init(1)
109  savval(2) = val_init(2)
110  val_init(1) = savval(2)
111  val_init(2) = savval(1)
112  DO i = 1, ncomp
113  savval(i) = val_init(4+i)
114  val_init(4+i) = val_init(4+i+ncomp)
115  END DO
116  DO i = 1, ncomp
117  val_init(4+i+ncomp) = savval(i)
118  END DO
119 
120 end subroutine switch
121 
122 
123 
124 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
125 
126 subroutine restore_converged
127 
128  use basic_variables
129 
130  integer :: i, ph
131  !-----------------------------------------------------------------------------
132 
133  dense(3) = val_conv(0)
134  dense(1) = val_conv(1)
135  dense(2) = val_conv(2)
136  t = val_conv(3)
137  p = val_conv(4)
138  DO ph = 1, nphas
139  DO i = 1, ncomp
140  lnx(ph,i) = val_conv(4+i+(ph-1)*ncomp)
141  xi(ph,i) = 0.0
142  if ( lnx(ph,i) > -300.0 ) xi(ph,i) = exp( lnx(ph,i) )
143  END DO
144  END DO
145 
146 end subroutine restore_converged
147 
148 
149 
150 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
151 ! subroutine SI_DENS (density,w)
152 !
153 ! This subroutine calculates the (macroskopic) fluid-density in
154 ! units [kg/m3] from the dimensionless density (eta=zeta3).
155 ! Further, mass fractions are calculated from mole fractions.
156 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
157 
158 subroutine si_dens (density,w)
159 
160  use parameters, ONLY: pi, nav, tau
161  use basic_variables
162 
163  !-----------------------------------------------------------------------------
164  real, INTENT(OUT) :: density(np)
165  real, INTENT(OUT) :: w(np,nc)
166 
167  !-----------------------------------------------------------------------------
168  integer :: i, ph
169  real :: mm_mean, rho, z3t
170  real :: dhs(nc), d00(nc), t_p, pcon, l_st
171  !-----------------------------------------------------------------------------
172 
173 
174  DO i = 1, ncomp
175  IF (eos == 1) THEN
176  dhs(i) = parame(i,2) * ( 1.0 - 0.12 *exp( -3.0*parame(i,3)/t ) )
177  ELSE IF (eos == 0) THEN
178  d00(i) = ( 1.e30/1.e6*tau*parame(i,2)*6.0/pi/nav )**(1.0/3.0)
179  dhs(i) = d00(i) * ( 1.0 - 0.12 *exp( -3.0*parame(i,3)/t ) )
180  ELSE IF (eos == 4) THEN
181  dhs(i) = ( 0.1617/0.3107 / ( 0.689+0.311*(t/parame(i,3)/1.328)**0.3674 ) &
182  / ( pi/6.0 ) )**(1.0/3.0) * parame(i,2)
183  ELSE IF (eos == 5.OR.eos == 6) THEN
184  l_st = parame(1,25)
185  IF (ncomp /= 1) write (*,*) ' ERROR for EOS = 5'
186  t_p =((34.037352+17.733741*l_st) /(1.0+0.53237307*l_st+12.860239*l_st**2 ))**0.5
187  IF (l_st == 0.0) t_p = t_p/4.0
188  IF (eos == 5 .AND. l_st /= 0.0) t_p = t_p/4.0*parame(1,1)**2
189  t_p = t/parame(i,3)/t_p
190  pcon =0.5256+3.2088804*l_st**2 -3.1499114*l_st**2.5 +0.43049357*l_st**4
191  dhs(i) = ( pcon/(0.67793+0.32207*(t_p)**0.3674) /(pi/6.0) )**(1.0/3.0) *parame(i,2)
192  ELSE IF (eos == 8) THEN
193  dhs(i) = parame(i,2)*(1.0+0.2977*t/parame(i,3)) &
194  /(1.0+0.33163*t/parame(i,3) +1.0477e-3*(t/parame(i,3))**2 )
195  ELSE
196  write (*,*) 'define EOS in subroutine: SI_DENS'
197  stop 5
198  END IF
199  END DO
200 
201  DO ph = 1, nphas
202  mm_mean = 0.0
203  z3t = 0.0
204  DO i = 1, ncomp
205  mm_mean = mm_mean + xi(ph,i)*mm(i)
206  z3t = z3t + xi(ph,i) * parame(i,1) * dhs(i)**3
207  END DO
208  z3t = pi/6.0 * z3t
209  rho = dense(ph)/z3t
210  density(ph) = rho * mm_mean * 1.e27 /nav
211  DO i = 1, ncomp
212  w(ph,i) = xi(ph,i) * mm(i)/mm_mean
213  END DO
214  ! write (*,*) density(ph),rho,mm_mean,1.d27 /NAV
215  END DO
216 
217 end subroutine si_dens
218 
219 
220 
221 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
222 ! subroutine select_sum_rel
223 !
224 ! This subroutine determines which component of a phase "ph" is calculated
225 ! from the summation relation x_i = 1 - sum(x_j). The other components are,
226 ! by default, said to be iterated during the phase equilibrium calculation.
227 !
228 ! Note that for flash calculations not all of these mole fractions are in
229 ! fact iterated - this is raken care of in "determine_flash_it".
230 !
231 ! ph phase
232 ! excl exclude comp. n
233 ! startindex assign it(startindex) for quantities to be iterated
234 ! (further it(startindex+1) is assigned, for a ternary
235 ! mixture, etc.)
236 !
237 ! sum_index indicates the component, with the largest mole
238 ! fraction. If ph=1 and sum_index=2, we define
239 ! sum_rel(ph=1)='x12', so that this component is
240 ! calculated from the summation relation.
241 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
242 
243 subroutine select_sum_rel ( ph, excl, startindex )
244 
245  use basic_variables
246 
247  !-----------------------------------------------------------------------------
248  integer, INTENT(IN) :: ph
249  integer, INTENT(IN) :: excl
250  integer, INTENT(IN) :: startindex
251  !-----------------------------------------------------------------------------
252  integer :: i,j
253  integer :: sum_index = 0
254  real :: xmax(np)
255  ! character :: compNo*2,phasNo*2
256  !-----------------------------------------------------------------------------
257 
258  xmax(ph) = 0.0
259  DO i = 1, ncomp
260 
261  IF ( xi(ph,i) > xmax(ph) ) THEN
262  xmax(ph) = xi(ph,i)
263  sum_index = i
264 
265  IF (ph == 1 .AND. i == 1) sum_rel(1) = 'x11'
266  IF (ph == 1 .AND. i == 2) sum_rel(1) = 'x12'
267  IF (ph == 1 .AND. i == 3) sum_rel(1) = 'x13'
268  IF (ph == 1 .AND. i == 4) sum_rel(1) = 'x14'
269  IF (ph == 1 .AND. i == 5) sum_rel(1) = 'x15'
270 
271  IF (ph == 2 .AND. i == 1) sum_rel(2) = 'x21'
272  IF (ph == 2 .AND. i == 2) sum_rel(2) = 'x22'
273  IF (ph == 2 .AND. i == 3) sum_rel(2) = 'x23'
274  IF (ph == 2 .AND. i == 4) sum_rel(2) = 'x24'
275  IF (ph == 2 .AND. i == 5) sum_rel(2) = 'x25'
276 
277  IF (ph == 3 .AND. i == 1) sum_rel(3) = 'x31'
278  IF (ph == 3 .AND. i == 2) sum_rel(3) = 'x32'
279  IF (ph == 3 .AND. i == 3) sum_rel(3) = 'x33'
280  IF (ph == 3 .AND. i == 4) sum_rel(3) = 'x34'
281  IF (ph == 3 .AND. i == 5) sum_rel(3) = 'x35'
282  ! write (*,*) ph,i,xi(ph,i),sum_rel(ph)
283  END IF
284 
285  END DO
286 
287  j = 0
288  DO i = 1, ncomp
289 
290  IF ( i /= sum_index .AND. i /= excl ) THEN
291  IF (ph == 1 .AND. i == 1) it(startindex+j) = 'x11'
292  IF (ph == 1 .AND. i == 2) it(startindex+j) = 'x12'
293  IF (ph == 1 .AND. i == 3) it(startindex+j) = 'x13'
294  IF (ph == 1 .AND. i == 4) it(startindex+j) = 'x14'
295  IF (ph == 1 .AND. i == 5) it(startindex+j) = 'x15'
296 
297  IF (ph == 2 .AND. i == 1) it(startindex+j) = 'x21'
298  IF (ph == 2 .AND. i == 2) it(startindex+j) = 'x22'
299  IF (ph == 2 .AND. i == 3) it(startindex+j) = 'x23'
300  IF (ph == 2 .AND. i == 4) it(startindex+j) = 'x24'
301  IF (ph == 2 .AND. i == 5) it(startindex+j) = 'x25'
302 
303  IF (ph == 3 .AND. i == 1) it(startindex+j) = 'x31'
304  IF (ph == 3 .AND. i == 2) it(startindex+j) = 'x32'
305  IF (ph == 3 .AND. i == 3) it(startindex+j) = 'x33'
306  IF (ph == 3 .AND. i == 4) it(startindex+j) = 'x34'
307  IF (ph == 3 .AND. i == 5) it(startindex+j) = 'x35'
308  ! write (*,*) 'iter ',it(startindex+j)
309  j = j + 1
310  END IF
311 
312  END DO
313 
314 end subroutine select_sum_rel
315 
316 
317 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
318 !
319 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
320 
321 subroutine determine_flash_it
322 
323  use basic_variables
324 
325  !-----------------------------------------------------------------------------
326  integer :: i, j, ph
327  integer :: min_index = 0
328  integer :: max_index = 0
329  integer :: phase = 0
330  integer :: phase_from_flash
331  real :: d_xmax, xmin, xmax
332  !-----------------------------------------------------------------------------
333 
334  write (*,*) 'entering determine_flash_it, press return'
335  read (*,*)
336 
337  IF (nphas /= 2) WRITE (*,*) 'DETERMINE_FLASH_IT: only 2 phases!'
338  IF (nphas /= 2) stop 2
339 
340  !-----------------------------------------------------------------------------
341  ! determine component (max_index) with largest difference in xi of both phases
342  !-----------------------------------------------------------------------------
343 
344  d_xmax = 0.0
345  DO i = 1, ncomp
346  IF ( abs( xi(1,i)-xi(2,i) ) > d_xmax ) THEN
347  d_xmax = abs( xi(1,i)-xi(2,i) )
348  max_index = i
349  END IF
350  END DO
351 
352  !-----------------------------------------------------------------------------
353  ! determine the phase that is determined from component balance
354  !-----------------------------------------------------------------------------
355 
356  IF ( minval( lnx(1,1:ncomp) ) < minval( lnx(2,1:ncomp) ) ) THEN
357  !IF ( ABS(xi(1,max_index)-xif(max_index)) > ABS(xif(max_index)-xi(2,max_index)) ) THEN
358  phase_from_flash = 2
359  IF (max_index == 1) sum_rel(2) = 'fl1'
360  IF (max_index == 2) sum_rel(2) = 'fl2'
361  IF (max_index == 3) sum_rel(2) = 'fl3'
362  IF (max_index == 4) sum_rel(2) = 'fl4'
363  IF (max_index == 5) sum_rel(2) = 'fl5'
364  IF (max_index == 6) sum_rel(2) = 'fl6'
365  IF (max_index > 6) WRITE (*,*) 'DETERMINE_FLASH_IT:extend list!'
366  ELSE
367  phase_from_flash = 1
368  IF (max_index == 1) sum_rel(1) = 'fl1'
369  IF (max_index == 2) sum_rel(1) = 'fl2'
370  IF (max_index == 3) sum_rel(1) = 'fl3'
371  IF (max_index == 4) sum_rel(1) = 'fl4'
372  IF (max_index == 5) sum_rel(1) = 'fl5'
373  IF (max_index == 6) sum_rel(1) = 'fl6'
374  IF (max_index > 6) WRITE (*,*) 'DETERMINE_FLASH_IT:extend list!'
375  END IF
376 
377  DO ph = 1, nphas
378 
379  IF (ph == phase_from_flash) THEN
380 
381  !-----------------------------------------------------------------------------
382  ! find substance of lowest conc. This substance is iterated (in log)
383  !-----------------------------------------------------------------------------
384  xmin = 10.0
385  DO i = 1, ncomp
386  IF ( xi(ph,i) < xmin ) THEN
387  xmin = xi(ph,i)
388  min_index = i
389  END IF
390  END DO
391  IF (phase_from_flash == 1) it(1) = 'x1' ! define phase of it(1)
392  IF (phase_from_flash == 2) it(1) = 'x2'
393  IF (min_index == 1) it(1) = trim(it(1))//'1' ! define substance of it(1)
394  IF (min_index == 2) it(1) = trim(it(1))//'2'
395  IF (min_index == 3) it(1) = trim(it(1))//'3'
396  IF (min_index == 4) it(1) = trim(it(1))//'4'
397  IF (min_index == 5) it(1) = trim(it(1))//'5'
398  IF (min_index == 6) it(1) = trim(it(1))//'6'
399 
400  ELSE ! for the other phase ...
401 
402  !-----------------------------------------------------------------------------
403  ! find substance of highest conc. ==> calc. from summation relation
404  !-----------------------------------------------------------------------------
405  xmax=0.0
406  DO i = 1, ncomp
407  IF (xi(ph,i) > xmax) THEN
408  xmax = xi(ph,i)
409  max_index = i
410  END IF
411  END DO
412  IF (phase_from_flash == 1) phase = 2
413  IF (phase_from_flash == 1) sum_rel(2) = 'x2' ! define phase of sum_rel(...)
414  IF (phase_from_flash == 2) phase = 1
415  IF (phase_from_flash == 2) sum_rel(1) = 'x1'
416 
417  IF (max_index == 1) sum_rel(phase) = trim(sum_rel(phase))//'1' ! define substance of sum_rel(...)
418  IF (max_index == 2) sum_rel(phase) = trim(sum_rel(phase))//'2'
419  IF (max_index == 3) sum_rel(phase) = trim(sum_rel(phase))//'3'
420  IF (max_index == 4) sum_rel(phase) = trim(sum_rel(phase))//'4'
421  IF (max_index == 5) sum_rel(phase) = trim(sum_rel(phase))//'5'
422  IF (max_index == 6) sum_rel(phase) = trim(sum_rel(phase))//'6'
423 
424  j = 0
425  DO i = 1, ncomp
426  IF ( i /= max_index ) THEN
427  IF (phase == 1) it(2+j) = 'x1'
428  IF (phase == 2) it(2+j) = 'x2'
429  IF (i == 1) it(2+j) = trim(it(2+j))//'1'
430  IF (i == 2) it(2+j) = trim(it(2+j))//'2'
431  IF (i == 3) it(2+j) = trim(it(2+j))//'3'
432  IF (i == 4) it(2+j) = trim(it(2+j))//'4'
433  IF (i == 5) it(2+j) = trim(it(2+j))//'5'
434  IF (i == 6) it(2+j) = trim(it(2+j))//'6'
435  j = j + 1
436  END IF
437  END DO
438 
439  END IF
440  END DO
441 
442 end subroutine determine_flash_it
443 
444 
445 
446 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
447 !
448 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
449 
450 subroutine determine_flash_it2
451 
452  use basic_variables
453 
454  !-----------------------------------------------------------------------------
455  integer :: i, k, ph
456  real :: n_phase1, n_phase2, max_x_diff
457  !-----------------------------------------------------------------------------
458 
459  n_phase1 = 0.0
460 
461  IF ( minval( lnx(1,1:ncomp) ) < minval( lnx(2,1:ncomp) ) ) THEN
462  it(1) = 'x11'
463  it(2) = 'x12'
464  IF (ncomp >= 3) it(3) = 'x13'
465  IF (ncomp >= 4) it(4) = 'x14'
466  IF (ncomp >= 5) it(5) = 'x15'
467  sum_rel(1) = 'nfl'
468  ELSE
469  it(1) = 'x21'
470  it(2) = 'x22'
471  IF (ncomp >= 3) it(3) = 'x23'
472  IF (ncomp >= 4) it(4) = 'x24'
473  IF (ncomp >= 5) it(5) = 'x25'
474  sum_rel(2) = 'nfl'
475  ENDIF
476  max_x_diff = 0.0
477  DO i = 1, ncomp
478  IF ( abs( exp( lnx(1,i) ) - exp( lnx(2,i) ) ) > max_x_diff ) THEN
479  max_x_diff = abs( exp( lnx(1,i) ) - exp( lnx(2,i) ) )
480  n_phase1 = ( xif(i) - exp( lnx(2,i) ) ) / ( exp( lnx(1,i) ) - exp( lnx(2,i) ) )
481  n_phase2 = 1.0 - n_phase1
482  END IF
483  END DO
484  if ( n_phase1 < 1.e-12 ) n_phase1 = 1.e-12
485  if ( n_phase1 > ( 1.0 - 1.e-12 ) ) n_phase1 = 1.0 - 1.e-12
486  n_phase2 = 1.0 - n_phase1
487  lnx(1,1:ncomp) = lnx(1,1:ncomp) + log( n_phase1 ) ! these x's are treated as mole numbers
488  lnx(2,1:ncomp) = lnx(2,1:ncomp) + log( n_phase2 ) ! these x's are treated as mole numbers
489 
490  val_init(1) = dense(1)
491  val_init(2) = dense(2)
492  val_init(3) = t
493  val_init(4) = p
494  DO ph = 1, nphas
495  DO k = 1, ncomp
496  val_init(4+k+(ph-1)*ncomp) = lnx(ph,k) ! - LOG( SUM( EXP( lnx(ph,1:ncomp) ) ) )
497  ! write (*,*) ph,k, lnx(ph,k)
498  END DO
499  END DO
500 
501 end subroutine determine_flash_it2
502 
503 
504 
505 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
506 !
507 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
508 
509 subroutine new_flash (ph_it)
510 
511  use basic_variables
512 
513  !-----------------------------------------------------------------------------
514  integer, INTENT(IN) :: ph_it
515 
516  !-----------------------------------------------------------------------------
517  integer :: i, ph_cal
518  real, DIMENSION(nc) :: ni_1, ni_2
519  !-----------------------------------------------------------------------------
520 
521  ph_cal = 3 - ph_it ! for two phases only
522 
523  DO i = 1, ncomp
524  IF ( lnx(ph_it,i) < -300.0 ) THEN
525  ni_2(i) = 0.0
526  ELSE
527  ni_2(i) = exp( lnx(ph_it,i) )
528  END IF
529  END DO
530 
531  DO i = 1, ncomp
532  ni_1(i) = xif(i)-ni_2(i)
533  IF ( ni_2(i) > xif(i) .OR. sum( ni_1(1:ncomp)) <= 0.0 ) THEN
534  ni_2(i) = xif(i)
535  ni_1(i) = xif(i) * 1.e-20
536  ENDIF
537  END DO
538 
539  ! if ( SUM( ni_2(1:ncomp) ) > (1.0 - 1.E-12) ) then
540  ! ni_2(1:ncomp) = ni_2(1:ncomp) * ( 1.0 - 1.E-12 ) / SUM( ni_2(1:ncomp) )
541  ! end if
542  ! if ( SUM( ni_1(1:ncomp) ) > (1.0 - 1.E-12) ) then
543  ! ni_1(1:ncomp) = ni_1(1:ncomp) * ( 1.0 - 1.E-12 ) / SUM( ni_1(1:ncomp) )
544  ! end if
545 
546  xi(ph_it,1:ncomp) = ni_2(1:ncomp) / sum( ni_2(1:ncomp) )
547  DO i = 1, ncomp
548  IF ( xi(ph_it,i) >= 1.e-300 ) lnx(ph_it,i) = log( xi(ph_it,i) )
549  IF ( xi(ph_it,i) < 1.e-300 ) lnx(ph_it,i) = 1.e-300
550  END DO
551  xi(ph_cal,1:ncomp) = ni_1(1:ncomp) / sum( ni_1(1:ncomp) )
552  DO i = 1, ncomp
553  IF ( xi(ph_cal,i) >= 1.e-300 ) lnx(ph_cal,i) = log( xi(ph_cal,i) )
554  IF ( xi(ph_cal,i) < 1.e-300 ) lnx(ph_cal,i) = 1.e-300
555  END DO
556 
557 end subroutine new_flash
558 
559 
560 
561 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
562 ! subroutine x_summation
563 !
564 ! This subroutine solves the summation relation: xi=1-sum(xj)
565 ! The variable "sum_rel(i)" contains the information, which mole
566 ! fraction is the one to be calculated here. Consider the example
567 ! sum_rel(1)='x12'. The fist letter 'x' of this variable indicates,
568 ! that this subroutine needs to be executed and that the mole
569 ! fraction of a component has to be calculated. The second letter
570 ! of the string points to phase 1, the third letter to component 2.
571 ! If the fist letter is 'e', not 'x', then the subroutine
572 ! NEUTR_CHARGE is called. This is the case of electrolyte solutions,
573 ! neutral charges have to be enforced in all phases (see below).
574 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
575 
576 subroutine x_summation
577 
578  use basic_variables
579 
580  !-----------------------------------------------------------------------------
581  integer :: i, j, comp_i, ph_i
582  real :: sum_x
583  character (LEN=2) :: phasno
584  character (LEN=2) :: compno
585  logical :: flashcase2
586  !-----------------------------------------------------------------------------
587 
588  DO j = 1, nphas
589  IF (sum_rel(j)(1:3) == 'nfl') THEN
590  CALL new_flash (j)
591  RETURN
592  END IF
593  END DO
594 
595 
596 
597  flashcase2 = .false.
598 
599  DO j = 1, nphas
600 
601  IF (sum_rel(j)(1:1) == 'x') THEN
602 
603  phasno = sum_rel(j)(2:2)
604  READ (phasno,*) ph_i
605  compno = sum_rel(j)(3:3)
606  READ (compno,*) comp_i
607  IF ( sum_rel(nphas+j)(1:1) == 'e' ) CALL neutr_charge(nphas+j)
608 
609  sum_x = 0.0
610  DO i = 1, ncomp
611  IF ( i /= comp_i ) sum_x = sum_x + xi(ph_i,i)
612  END DO
613  xi(ph_i,comp_i) = 1.0 - sum_x
614  IF ( xi(ph_i,comp_i ) < 0.0 ) xi(ph_i,comp_i) = 0.0
615  IF ( xi(ph_i,comp_i ) /= 0.0 ) THEN
616  lnx(ph_i,comp_i) = log( xi(ph_i,comp_i) )
617  ELSE
618  lnx(ph_i,comp_i) = -100000.0
619  END IF
620  ! write (*,*) 'sum_x',ph_i,comp_i,lnx(ph_i,comp_i),xi(ph_i,comp_i)
621 
622  ELSE IF ( sum_rel(j)(1:2) == 'fl' ) THEN
623 
624  flashcase2 = .true.
625  ! ------------------------------------------------------------------
626  ! This case is true when all molefractions of one phase are
627  ! determined from a component balance. What is needed to
628  ! calculate all molefractions of that phase are all mole-
629  ! fractions of the other phase (nphas=2, so far) and the
630  ! phase fraction alpha.
631  ! Alpha is calculated (in FLASH_ALPHA) from the mole fraction
632  ! of component {sum_rel(j)(3:3)}. IF sum_rel(2)='fl3', then
633  ! the alpha is determined from the molefraction of comp. 3 and
634  ! the molefraction of phase 2 is then completely determined ELSE
635  ! ------------------------------------------------------------------
636 
637  ELSE
638  WRITE (*,*) 'summation relation not defined'
639  stop 3
640  END IF
641 
642  END DO
643 
644  IF ( it(1) == 'fls' ) CALL flash_sum
645  IF ( flashcase2 ) CALL flash_alpha
646 
647 end subroutine x_summation
648 
649 
650 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
651 ! subroutine flash_alpha
652 !
653 ! This subroutine calculates all molefractions of one phase
654 ! from a component balance. What is needed for this calculation
655 ! are all molefractions of the other phase (nphas=2, so far)
656 ! and the phase fraction alpha.
657 ! Alpha is calculated from the mole fraction
658 ! of component {sum_rel(j)(3:3)}. If for example sum_rel(2)='fl3',
659 ! then the alpha is determined from the molefraction of comp. 3 and
660 ! all molefractions of one phase are calculated using that alpha-value.
661 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
662 
663 subroutine flash_alpha
664 
665  use basic_variables
666 
667  !-----------------------------------------------------------------------------
668  integer :: i, j, comp_i, phase1, phase2
669  character (LEN=2) :: compno
670  !-----------------------------------------------------------------------------
671 
672 
673  !-----------------------------------------------------------------------------
674  ! first calculate the phase fraction alpha from a known composition
675  ! of component sum_rel(j)(3:3).
676  !-----------------------------------------------------------------------------
677 
678  DO j = 1, nphas
679  IF ( sum_rel(j)(1:2) == 'fl' ) THEN
680  compno = sum_rel(j)(3:3)
681  READ (compno,*) comp_i
682  IF ( (xi(1,comp_i)-xi(2,comp_i)) /= 0.0 ) THEN
683  alpha = (xif(comp_i)-xi(2,comp_i)) / (xi(1,comp_i)-xi(2,comp_i))
684  write (*,*) 'flsh',(xif(comp_i)-xi(2,comp_i)),(xi(1,comp_i)-xi(2,comp_i))
685  ELSE
686  alpha = 0.5
687  WRITE (*,*) 'FLASH_ALPHA:error in calc. of phase fraction',comp_i
688  END IF
689  ! IF (alpha <= 0.0 .OR. alpha >= 1.0) WRITE(*,*) 'FLASH_ALPHA: error',alpha
690  IF (alpha > 1.0) alpha = 1.0
691  IF (alpha < 0.0) alpha = 0.0
692  END IF
693  END DO
694 
695  !-----------------------------------------------------------------------------
696  ! determine which phase is fully determined by iterated molefractions (+ summation relation)
697  !-----------------------------------------------------------------------------
698  phase1 = 0
699  phase2 = 0
700  DO i = 1, ncomp
701  IF ( it(i)(2:2) == '1' ) phase1 = phase1 + 1
702  IF ( it(i)(2:2) == '2' ) phase2 = phase2 + 1
703  END DO
704  DO i = 1, ncomp
705  IF ( sum_rel(i)(2:2) == '1' ) phase1 = phase1 + 1
706  IF ( sum_rel(i)(2:2) == '2' ) phase2 = phase2 + 1
707  END DO
708 
709 
710  IF ( phase1 == ncomp ) THEN
711  ! --------------------------------------------------------------------
712  ! phase 1 is defined by iterated molefractions + summation relation
713  ! phase 2 is determined from componennt balance (using alpha)
714  ! --------------------------------------------------------------------
715  IF ( alpha == 1.0 ) alpha = 1.0 - 1.0e-10
716  DO i = 1, ncomp
717  xi(2,i) = ( xif(i) - alpha*xi(1,i) ) / (1.0-alpha)
718  IF ( xi(2,i) < 0.0 ) xi(2,i) = 0.0
719  IF ( xi(2,i) > 1.0 ) xi(2,i) = 1.0
720  IF ( xi(2,i) /= 0.0 ) THEN
721  lnx(2,i) = log( xi(2,i) )
722  ELSE
723  lnx(2,i) = -100000.0
724  END IF
725  write (*,*) 'fl_cal ph=2',i,lnx(2,i),xi(2,i)
726  END DO
727  ELSE IF ( phase2 == ncomp ) THEN
728  ! --------------------------------------------------------------------
729  ! phase 2 is defined by iterated molefractions + summation relation
730  ! phase 1 is determined from componennt balance (using alpha)
731  ! --------------------------------------------------------------------
732  DO i = 1, ncomp
733  xi(1,i) = ( xif(i) - (1.0-alpha)*xi(2,i) ) /alpha
734  IF ( xi(1,i) < 0.0 ) xi(1,i) = 0.0
735  IF ( xi(1,i) > 1.0 ) xi(1,i) = 1.0
736  IF ( xi(1,i) /= 0.0 ) THEN
737  lnx(1,i) = log( xi(1,i) )
738  ELSE
739  lnx(1,i) = -100000.0
740  END IF
741  write (*,*) 'fl_cal ph=1',i,lnx(1,i),xi(1,i),alpha
742  END DO
743  ELSE
744  WRITE (*,*) ' FLASH_ALPHA: undefined flash-case'
745  stop 2
746  END IF
747 
748 end subroutine flash_alpha
749 
750 
751 
752 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
753 !
754 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
755 
756 subroutine flash_sum
757 
758  use basic_variables
759 
760  integer :: i, j, ph_i, phase1, phase2
761  !-----------------------------------------------------------------------------
762 
763  phase1=0
764  phase2=0
765  DO j = 1, ncomp
766  IF (it(j)(2:2) == '1') phase1=phase1+1
767  IF (it(j)(2:2) == '2') phase2=phase2+1
768  END DO
769 
770  IF (phase1 == ncomp-1) THEN
771  ph_i = 1
772  ELSE IF (phase2 == ncomp-1) THEN
773  ph_i = 2
774  ELSE
775  WRITE (*,*) ' FLASH_SUM: undefined flash-case'
776  stop
777  END IF
778 
779 
780 
781  IF (ph_i == 1) THEN
782  DO i = 1, ncomp
783  IF (alpha > dmin1(1.0,xif(i)/xi(1,i), &
784  (xif(i)-1.0)/(xi(1,i)-1.0),alpha)) THEN
785  WRITE (*,*) ' FLASH_SUM: exeeded 1st alpha-bound'
786  alpha=dmin1(1.0,xif(i)/xi(1,i),(xif(i)-1.0)/(xi(1,i)-1.0))
787  END IF
788  END DO
789  DO i = 1, ncomp
790  xi(2,i) = ( xif(i) - alpha*xi(1,i) ) / (1.0-alpha)
791  IF (xi(2,i) > 0.0) THEN
792  lnx(2,i) = log(xi(2,i))
793  ELSE
794  xi(2,i) = 0.0
795  lnx(2,i) = -100000.0
796  END IF
797  END DO
798  ELSE IF (ph_i == 2) THEN
799  DO i = 1, ncomp
800  IF (alpha > dmax1(0.0,(xif(i)-xi(2,i))/(1.0-xi(2,i)), &
801  1.0-xif(i)/xi(2,i),alpha)) THEN
802  WRITE (*,*) ' FLASH_SUM: exeeded 2nd alpha-bound'
803  WRITE (*,*) 0.0,(xif(i)-xi(2,i))/(1.0-xi(2,i)), 1.0-xif(i)/xi(2,i)
804  alpha=dmax1(0.0,(xif(i)-xi(2,i))/(1.0-xi(2,i)), 1.0-xif(i)/xi(2,i))
805  END IF
806  END DO
807  DO i = 1, ncomp
808  xi(1,i) = ( xif(i) - (1.0-alpha)*xi(2,i) ) / alpha
809  ! write (*,*) 'x1,i',xi(1,i),xi(2,i),alpha
810  IF (xi(1,i) > 0.0) THEN
811  lnx(1,i) = log(xi(1,i))
812  ELSE
813  xi(1,i) = 0.0
814  lnx(1,i) = -100000.0
815  END IF
816  END DO
817  END IF
818 
819 end subroutine flash_sum
820 
821 
822 
823 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
824 ! subroutine neutr_charge
825 !
826 ! This subroutine is called for electrolye solutions, where a
827 ! neutral overall-charge has to be enforced in all phases. The basic
828 ! philosophy is similar to the above described routine X_SUMMATION.
829 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
830 
831 subroutine neutr_charge(i)
832 
833  use basic_variables
834 
835  !-----------------------------------------------------------------------------
836  integer, INTENT(IN) :: i
837 
838  !-----------------------------------------------------------------------------
839  integer :: comp_e, ph_e
840  real :: sum_c
841  character (LEN=2) :: phasno
842  character (LEN=2) :: compno
843  !-----------------------------------------------------------------------------
844 
845  phasno = sum_rel(i)(2:2)
846  READ (phasno,*) ph_e
847  compno = sum_rel(i)(3:3)
848  READ (compno,*) comp_e
849 
850  sum_c = 0.0
851  write (*,*) 'there must be an error in neutr_charge'
852  stop
853  ! there is an error in the following passage. The index i is an
854  ! argument to this subroutine - I guess it is INTENT(IN), so the
855  ! index in the following loop can not be i.
856  !
857  ! I have commented the loop until I check the code.
858  !DO i = 1, ncomp
859  ! IF ( comp_e /= i .AND. parame(i,10) /= 0.0) &
860  ! sum_c = sum_c + xi(ph_e,i)*parame(i,10)
861  !END DO
862 
863  xi(ph_e,comp_e) = - sum_c
864  IF (xi(ph_e,comp_e) < 0.0) xi(ph_e,comp_e)=0.0
865  IF (xi(ph_e,comp_e) /= 0.0) THEN
866  lnx(ph_e,comp_e) = log(xi(ph_e,comp_e))
867  ELSE
868  lnx(ph_e,comp_e) = -100000.0
869  END IF
870 
871  ! xi(2,1) = xi(2,2)
872  ! IF (xi(2,1).NE.0.0) lnx(2,1) = LOG(xi(2,1))
873 
874 end subroutine neutr_charge
875 
876 
877 
878 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
879 ! subroutine molefrac (w,phas1,phas2)
880 !
881 ! This subroutine calculates mole fractions from mass fractions.
882 ! The calculation is performed for phase 1 if phas1=1 and for
883 ! phase 2 if phas2=1.
884 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
885 
886 subroutine molefrac ( w, phas1, phas2 )
887 
888  use basic_variables
889 
890  !-----------------------------------------------------------------------------
891  real, INTENT(IN) :: w(np,nc)
892  integer, INTENT(IN) :: phas1
893  integer, INTENT(IN) :: phas2
894 
895  !-----------------------------------------------------------------------------
896  integer :: i,ph
897  real :: mm_denom
898  !-----------------------------------------------------------------------------
899 
900 
901  DO ph = 1, nphas
902  IF ((ph == 1.AND.phas1 == 1).OR.(ph == 2.AND.phas2 == 1)) THEN
903  mm_denom = 0.0
904  DO i = 1, ncomp
905  mm_denom = mm_denom + w(ph,i)/mm(i)
906  END DO
907  IF (mm_denom > 0.0) THEN
908  DO i = 1, ncomp
909  xi(ph,i)=w(ph,i)/mm(i)/mm_denom
910  END DO
911  END IF
912  END IF
913  END DO
914 
915 end subroutine molefrac
916 
917 
918 
919 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
920 ! subroutine file_open
921 !
922 ! This subroutine opens files for reading. Beforehand, it checks
923 ! whether this file is available.
924 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
925 
926 subroutine file_open(filename,file_number)
927 
928  !-----------------------------------------------------------------------------
929  character (LEN=*) :: filename
930  integer :: file_number
931  logical :: filefound
932  !-----------------------------------------------------------------------------
933 
934  INQUIRE (file=filename, exist = filefound)
935  IF (filefound) THEN
936  OPEN (file_number, file = filename)
937  ELSE
938  write (*,*) ' Solubility Code: FOLLOWING FILE CAN NOT BE OPENED', filename
939  stop 6
940  END IF
941 
942 end subroutine file_open
943 
944 
945 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
946 ! subroutine p_calc (pges_transfer, zges)
947 !
948 ! This subroutine serves as an iterface to the EOS-routines. The
949 ! system pressure corresponding to given (desity,T,xi) is calculated.
950 ! (Note: the more common interface is subroutine FUGACITY. This
951 ! routine is only used for one-phase systems, e.g. calculation of
952 ! virial coefficients)
953 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
954 
955 subroutine p_calc (pges_transfer, zges)
956 
957  use basic_variables
958  use eos_variables
959 
960  !-----------------------------------------------------------------------------
961  real, INTENT(IN OUT) :: pges_transfer
962  real, INTENT(OUT) :: zges
963  !-----------------------------------------------------------------------------
964 
965  IF (nphas /= 1 ) THEN
966  write (*,*) 'P_CALC: can only be called for single phases'
967  stop 5
968  ENDIF
969 
970  IF (eos < 2) THEN
971 
972  phas = 1
973  eta = dense(1)
974  x(1:ncomp) = xi(1,1:ncomp)
975 
976  CALL perturbation_parameter
977  CALL p_eos_interface
978 
979  pges_transfer = pges
980  rho = eta / z3t
981  zges = (pges * 1.e-30) / ( kbol * t * rho )
982 
983  ELSE
984  write (*,*) ' subroutine P_CALC not available for cubic EOS'
985  stop 6
986  END IF
987 
988 end subroutine p_calc
989 
990 
991 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
992 ! subroutine dens_calc
993 !
994 ! This subroutine serves as an interface to the EOS-routines. The
995 ! densities corresponding to given (P,T,xi) are calculated.
996 ! (Note: the more common interface is subroutine FUGACITY.
997 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
998 
999 subroutine dens_calc ( rho_phas )
1000 
1001  use basic_variables
1002  use eos_variables
1003 
1004  !-----------------------------------------------------------------------------
1005  real, INTENT(OUT) :: rho_phas(np)
1006 
1007  integer :: ph
1008  !-----------------------------------------------------------------------------
1009 
1010 
1011  DO ph = 1, nphas
1012 
1013  IF (eos < 2) THEN
1014 
1015  phas = ph
1016  eta = densta(ph)
1017  eta_start = densta(ph)
1018  x(1:ncomp) = xi(ph,1:ncomp)
1019 
1020  CALL perturbation_parameter
1021  CALL density_iteration
1022 
1023  dense(ph)= eta
1024  rho_phas(ph) = eta/z3t
1025 
1026  ELSE
1027  write (*,*) ' subroutine DENS_CALC not available for cubic EOS'
1028  stop 6
1029  END IF
1030 
1031  END DO
1032 
1033 end subroutine dens_calc
1034 
1035 
1036 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1037 ! subroutine enthalpy_etc
1038 !
1039 ! This subroutine serves as an interface to the EOS-routines. The
1040 ! residual enthalpy h_res, residual entropy s_res, residual Gibbs
1041 ! enthalpy g_res, and residual heat capacity at constant pressure
1042 ! (cp_res) corresponding to converged conditions are calculated.
1043 ! The conditions in (T,P,xi,rho) need to be converged equilibrium
1044 ! conditions !!
1045 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1046 
1047 subroutine enthalpy_etc
1048 
1049  use basic_variables
1050  use eos_variables
1051 
1052  integer :: ph
1053  !-----------------------------------------------------------------------------
1054 
1055  IF ( eos <= 1 ) THEN
1056 
1057  DO ph = 1, nphas
1058 
1059  phas = ph
1060  eta = dense(ph)
1061  ! eta_start = dense(ph)
1062  x(1:ncomp) = xi(ph,1:ncomp)
1063 
1064  CALL h_eos_interface
1065  enthal(ph) = h_res
1066  entrop(ph) = s_res
1067  ! gibbs(ph) = h_res - t * s_res ! already defined in eos.f90 (including ideal gas)
1068  cpres(ph) = cp_res
1069  speed_of_sound(ph) = speed_sound
1070 
1071  END DO
1072  IF (nphas == 2) h_lv = enthal(2)-enthal(1)
1073 
1074  ENDIF
1075 
1076 end subroutine enthalpy_etc
1077 
1078 
1079 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1080 ! subroutine CRITICAL
1081 !
1082 ! This subroutine serves as an interface for the calculation of
1083 ! a pure component's critical point.
1084 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1085 
1086 subroutine critical ( tc, pc, rhoc )
1087 
1088  use basic_variables
1089  use eos_variables
1090 
1091  !-----------------------------------------------------------------------------
1092  real, INTENT(IN OUT) :: tc
1093  real, INTENT(IN OUT) :: pc
1094  real, INTENT(OUT) :: rhoc
1095 
1096  !-----------------------------------------------------------------------------
1097  integer :: phassav
1098  real :: density(np), w(np,nc)
1099  !-----------------------------------------------------------------------------
1100 
1101  phassav= nphas
1102  nphas = 1
1103  xi(1,1) = 1.0 ! only for pure components
1104 
1105 
1106  IF (eos < 2.AND.ncomp == 1) THEN
1107 
1108  t = tc
1109  p = pc
1110  phas = 1
1111  eta = 0.2
1112  eta_start = 0.2
1113  x(1:ncomp) = xi(nphas,1:ncomp)
1114 
1115  CALL perturbation_parameter
1116  CALL pure_crit_point_iteration
1117  dense(1)= eta
1118  CALL si_dens (density,w)
1119  rhoc = density(1)
1120  tc = t
1121  pc = p
1122 
1123  ELSE
1124  write (*,*) ' PURE_CRIT_POINT_ITERATION not available for cubic EOS'
1125  write (*,*) ' and not for mixtures'
1126  stop 5
1127  END IF
1128 
1129  nphas = phassav
1130 
1131 end subroutine critical
1132 
1133 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1134 ! subroutine PURE_CRIT_POINT_ITERATION
1135 !
1136 ! This subroutine determines the critical point of a pure substance.
1137 ! The density and temperature of the pure component is iterated
1138 ! until the derivative of (dP/d_rho) and the second derivative
1139 ! (dP2/d2_rho) are zero.
1140 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1141 
1142 subroutine pure_crit_point_iteration
1143 
1144  use basic_variables, ONLY: num
1145  use eos_variables
1146 
1147  !-----------------------------------------------------------------------------
1148  integer :: count, count_t, max_eta_count
1149  real :: tdelt, pdz1, pdz2, t_tol, eta_tol, zc, r_damp, t_damp, eta_l1
1150  !-----------------------------------------------------------------------------
1151 
1152  r_damp = 1.0
1153  IF (num == 2) r_damp = 0.15
1154  tdelt = 0.1
1155  t_tol = 0.005
1156 
1157  eta_tol= 0.2
1158  IF (num == 1) eta_tol = 2.0
1159  IF (num == 2) eta_tol = 0.5
1160 
1161  count_t = 0
1162  max_eta_count = 200
1163  t = 2.0 * t ! prefer a larger starting value for t over a too low value.
1164  pgesdz = t_tol + 1.0
1165 
1166  DO WHILE (abs(pgesdz) > t_tol .AND. count_t < 30)
1167  t = t - tdelt
1168  count = 0
1169  count_t =count_t + 1
1170  t_damp = 1.0
1171  pgesd2 = eta_tol + 1.0
1172 
1173  DO WHILE ( abs(pgesd2) > eta_tol .AND. count < max_eta_count )
1174  count =count + 1
1175  CALL perturbation_parameter
1176  CALL p_eos_interface
1177  eta = eta - r_damp*pgesd2/pgesd3
1178  IF (eta < 0.0) eta=0.001
1179  IF (eta > 0.7) eta=0.5
1180  ! write(*,'(a,i4,4(E16.7))') 'c_1',count,eta,pges,pgesd2,pgesd3
1181  eta_l1 = eta
1182  END DO
1183  pdz1 = pgesdz
1184 
1185 
1186 
1187  t = t + tdelt
1188  count = 0
1189  pgesd2 = eta_tol + 1.0
1190 
1191  DO WHILE ( abs(pgesd2) > eta_tol .AND. count < max_eta_count )
1192  count =count +1
1193  CALL perturbation_parameter
1194  CALL p_eos_interface
1195  eta = eta - r_damp*pgesd2/pgesd3
1196  IF (eta < 0.0) eta = 0.001
1197  IF (eta > 0.7) eta = 0.5
1198  END DO
1199  pdz2 = pgesdz
1200 
1201  IF ( abs(pdz2 / ( (pdz2-pdz1)/tdelt ))/t >= 0.05 ) t_damp = 0.5
1202  t = t - t_damp * pdz2 / ( (pdz2-pdz1)/tdelt )
1203 
1204  IF (.NOT.( t > 0.0 )) t = 300.0
1205 
1206  END DO
1207 
1208  IF (abs(pgesdz) > t_tol) write (*,*) 'PURE_CRIT_POINT_ITERATION: T-iteration not converged'
1209  IF (abs(pgesd2) > eta_tol) write (*,*) 'PURE_CRIT_POINT: density-iteration not converged',pgesd2
1210 
1211  p = pges
1212  rho= eta/z3t
1213  zc = (p * 1.e-30)/(kbol*t*rho)
1214 
1215 end subroutine pure_crit_point_iteration
1216 
1217 
1218 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1219 !
1220 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1221 
1222 subroutine fden_calc (fden, rhoi)
1223 
1224  use basic_variables
1225  use eos_variables
1226 
1227  !-----------------------------------------------------------------------------
1228  real, INTENT(OUT) :: fden
1229  real, INTENT(IN OUT) :: rhoi(nc)
1230  !-----------------------------------------------------------------------------
1231  real :: rhot, fden_id
1232  !-----------------------------------------------------------------------------
1233 
1234 
1235  IF (eos < 2) THEN
1236 
1237  rhot = sum( rhoi(1:ncomp) )
1238  x(1:ncomp) = rhoi(1:ncomp) / rhot
1239 
1240  CALL perturbation_parameter
1241  eta = rhot * z3t
1242  eta_start = eta
1243 
1244  call f_eos_interface
1245 
1246  fden_id = sum( rhoi(1:ncomp) * ( log( rhoi(1:ncomp) ) - 1.0 ) )
1247 
1248  fden = fres * rhot + fden_id
1249 
1250  ELSE
1251  write (*,*) ' subroutine FDEN_CALC not available for cubic EOS'
1252  stop 5
1253  END IF
1254 
1255 end subroutine fden_calc
1256 
1257 
1258 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1259 !
1260 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1261 
1262 subroutine only_one_term_eos_numerical ( only_term, type_of_term )
1263 
1265 
1266  character (LEN=9) :: only_term, type_of_term
1267  !-----------------------------------------------------------------------------
1268 
1269  save_eos_terms(1) = ideal_gas
1270  save_eos_terms(2) = hard_sphere
1271  save_eos_terms(3) = chain_term
1272  save_eos_terms(4) = disp_term
1273  save_eos_terms(5) = hb_term
1274  save_eos_terms(6) = lc_term
1275  save_eos_terms(7) = branch_term
1276  save_eos_terms(8) = ii_term
1277  save_eos_terms(9) = id_term
1278  save_eos_terms(10)= dd_term
1279  save_eos_terms(11)= qq_term
1280  save_eos_terms(12)= dq_term
1281 
1282  ideal_gas = 'no'
1283  hard_sphere = 'no'
1284  chain_term = 'no'
1285  disp_term = 'no'
1286  hb_term = 'no'
1287  lc_term = 'no'
1288  branch_term = 'no'
1289  ii_term = 'no'
1290  id_term = 'no'
1291  dd_term = 'no'
1292  qq_term = 'no'
1293  dq_term = 'no'
1294 
1295  IF ( only_term == 'ideal_gas' ) ideal_gas = trim( adjustl( type_of_term ) )
1296  IF ( only_term == 'hard_sphere' ) hard_sphere = trim( adjustl( type_of_term ) )
1297  IF ( only_term == 'chain_term' ) chain_term = trim( adjustl( type_of_term ) )
1298  IF ( only_term == 'disp_term' ) disp_term = trim( adjustl( type_of_term ) )
1299  IF ( only_term == 'hb_term' ) hb_term = trim( adjustl( type_of_term ) )
1300  IF ( only_term == 'LC_term' ) lc_term = trim( adjustl( type_of_term ) )
1301  IF ( only_term == 'branch_term' ) branch_term = trim( adjustl( type_of_term ) )
1302  IF ( only_term == 'II_term' ) ii_term = trim( adjustl( type_of_term ) )
1303  IF ( only_term == 'ID_term' ) id_term = trim( adjustl( type_of_term ) )
1304  IF ( only_term == 'dd_term' ) dd_term = trim( adjustl( type_of_term ) )
1305  IF ( only_term == 'qq_term' ) qq_term = trim( adjustl( type_of_term ) )
1306  IF ( only_term == 'dq_term' ) dq_term = trim( adjustl( type_of_term ) )
1307 
1308 end subroutine only_one_term_eos_numerical
1309 
1310 
1311 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1312 !
1313 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1314 
1315 subroutine restore_previous_eos_numerical
1316 
1318 
1319  !-----------------------------------------------------------------------------
1320  ideal_gas = trim( adjustl( save_eos_terms(1) ) )
1321  hard_sphere = trim( adjustl( save_eos_terms(2) ) )
1322  chain_term = trim( adjustl( save_eos_terms(3) ) )
1323  disp_term = trim( adjustl( save_eos_terms(4) ) )
1324  hb_term = trim( adjustl( save_eos_terms(5) ) )
1325  lc_term = trim( adjustl( save_eos_terms(6) ) )
1326  branch_term = trim( adjustl( save_eos_terms(7) ) )
1327  ii_term = trim( adjustl( save_eos_terms(8) ) )
1328  id_term = trim( adjustl( save_eos_terms(9) ) )
1329  dd_term = trim( adjustl( save_eos_terms(10) ) )
1330  qq_term = trim( adjustl( save_eos_terms(11) ) )
1331  dq_term = trim( adjustl( save_eos_terms(12) ) )
1332 
1333 end subroutine restore_previous_eos_numerical
1334 
1335 
1336 
1337 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1338 !
1339 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1340 
1341 subroutine paus ( message_to_screen )
1342 
1343  character (LEN=*), optional, intent(in) :: message_to_screen
1344  !-----------------------------------------------------------------------------
1345 
1346  if ( present( message_to_screen ) ) then
1347  write (*,*) 'MESSAGE: ',message_to_screen
1348  else
1349  write (*,*) 'PAUSE: press any key to continue'
1350  end if
1351 
1352  read (*,*)
1353 
1354 end subroutine paus
1355 
1356 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1357 !
1358 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
1359 
1360 subroutine error_message ( message_to_screen )
1361 
1362  implicit none
1363  character (LEN=*) :: message_to_screen
1364 
1365  write (*,*) message_to_screen
1366  stop 6
1367 
1368 end subroutine error_message
1369 
1370 end module utilities
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains constant...
Definition: modules.f90:6
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
Definition: modules.f90:120
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
Definition: modules.f90:29
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
Definition: modules.f90:220