MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
crit_point_mixtures.F90
1 
3 
4 
5 SUBROUTINE crit_point_mix(tc,user)
6 
7 !PETSc module
9 
10 !VLE and DFT modules
12 
13 IMPLICIT NONE
14 
15 #include <finclude/petscsys.h>
16 
17 type(userctx) user
18 REAL :: tc
19 !local
20 REAL :: tc_l, tc_v, xi_save(np,nc),p_save
21 petscerrorcode ierr
22 
23 
24 !!J:save value of pressure because it is changed during the calculation
25 p_save = p
26 
27 ! ---------------------------------------------------------------------
28  ! determine the critical temp. to xi of liquid and to xi of vapor
29  ! ---------------------------------------------------------------------
30 
31 
32  xi_save(:,:) = xi(:,:)
33  dense(1) = 0.15
34 
35  !call MPI_Barrier(PETSC_COMM_WORLD,ierr)
36 
37  !only proc 0 reads in the estimate and then sends it to all other procs using MPI_Bcast
38 ! IF(user%rank == 0) THEN
39 ! WRITE (*,*) 'provide an estimate of the crit. Temp. of the mixture'
40 ! READ (*,*) t
41 ! END IF
42 
43  t = 1.2 * t !initial estimate of critical temperature
44 
45  CALL mpi_bcast(t,1,mpi_double_precision,0,petsc_comm_world,ierr)
46 
47  xif(1:ncomp) = xi_save(1,1:ncomp)
48  CALL heidemann_khalil
49  tc_l = t
50 ! IF(user%rank == 0) THEN
51 ! WRITE (*,*) 'critical temperature to xi_liquid',tc_L
52 ! END IF
53 
54  xif(1:ncomp) = xi_save(2,1:ncomp)
55  ! dense(1) = 0.15
56  ! WRITE (*,*) 'provide an estimate of the crit. Temp. of the mixture'
57  ! READ (*,*) t
58  CALL heidemann_khalil
59  tc_v = t
60 ! IF(user%rank == 0) THEN
61 ! WRITE (*,*) 'critical temperature to xi_vapor ',tc_V
62 ! END IF
63 
64  ! tc_L = 600.0
65  ! WRITE (*,*) 'I have tentitativly set tc=700 '
66  ! pause
67 
68 
69  !tc = ( tc_L + tc_V ) / 2.0
70  tc = tc_l
71  xi(:,:) = xi_save(:,:)
72  densta(1:nphas) = val_conv(1:nphas)
73  dense(1:nphas) = val_conv(1:nphas)
74  t = val_conv(3)
75  IF(user%rank == 0) THEN
76  WRITE (*,*) 'estimate of critical temperature:',tc,'K'
77  WRITE (*,*) ' '
78  END IF
79 
80 !!J: set pressure to its regular value
81 p = p_save
82 
83 
84 END SUBROUTINE crit_point_mix
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
95 ! SUBROUTINE Heidemann_Khalil
96 !
97 ! This subroutine ....
98 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
99 !
100  SUBROUTINE heidemann_khalil
101 !
102  USE parameters, ONLY: pi
103  USE basic_variables
104  USE module_heidemann_khalil
105  USE solve_nonlin
106  IMPLICIT NONE
107 !
108 ! ----------------------------------------------------------------------
109  INTERFACE
110  SUBROUTINE heidemann_khalil_obj ( iter_no, y, residu, dummy )
111  INTEGER, INTENT(IN) :: iter_no
112  REAL, INTENT(IN) :: y(iter_no)
113  REAL, INTENT(OUT) :: residu(iter_no)
114  INTEGER, INTENT(IN OUT) :: dummy
115  END SUBROUTINE heidemann_khalil_obj
116  END INTERFACE
117 !
118  INTEGER :: info
119  REAL, ALLOCATABLE :: y(:),diag(:),residu(:)
120 
121  INTEGER :: i, count, nphas_save
122  REAL :: error0, error1, dense0, dfdx, delta_rho
123  CHARACTER (LEN=2) :: ensemble_save
124 ! ----------------------------------------------------------------------
125 
126  ensemble_save = ensemble_flag
127  ensemble_flag = 'tv'
128 
129  nphas_save = nphas
130  nphas = 1
131 
132  ! xiF(2) = 0.5 * ( 0.71928411 + 0.72025642 )
133  ! xiF(1) = 1.0 - xiF(2)
134  ! dense(1) = 0.5 * ( 0.159315 + 0.158817 ) + 0.02
135  ! t = 500.0
136 
137  dense0 = dense(1)
138 
139  info = 1
140  n_unkw = ncomp + 1
141  acc_a = 5.e-8
142  step_a = 1.e-8
143 
144 
145  ALLOCATE( y(n_unkw), diag(n_unkw), residu(n_unkw) )
146  DO i = 1,ncomp
147  y(i) = 1.0 / sqrt( REAL( ncomp ) )
148  END DO
149  y(ncomp+1) = t
150  count = 0
151  error0 = 1.0
152 
153  DO WHILE ( abs( error0) > 0.001 .AND. count < 20 )
154  count = count + 1
155 
156  dense(1) = dense0 + 0.0001
157  CALL hbrd (heidemann_khalil_obj, n_unkw, y, residu, step_a, acc_a, info, diag)
158  error1 = error_condition2
159  IF (sum( abs( residu(1:n_unkw) ) ) > 1.e-5) write (*,*) 'caution: error 1st inner loop', sum( abs( residu(1:n_unkw) ) )
160 
161  dense(1) = dense0
162  CALL hbrd (heidemann_khalil_obj, n_unkw, y, residu, step_a, acc_a, info, diag)
163  IF (sum( abs( residu(1:n_unkw) ) ) > 1.e-5) write (*,*) 'caution: error 2nd inner loop', sum( abs( residu(1:n_unkw) ) )
164  error0 = error_condition2
165 
166  ! write (*,'(a,4G18.10)') ' t, p, eta error', t, p, dense(1), error0
167  ! pause
168  dfdx = ( error1 - error0 ) / 0.0001
169  delta_rho = min( error0 / dfdx, 0.02)
170  delta_rho = max( delta_rho, -0.02)
171  dense0 = dense0 - delta_rho
172  dense(1) = dense0
173 
174  END DO
175 
176  !tc = t
177  !pc = p
178 
179  DEALLOCATE( y, diag, residu )
180 
181  ensemble_flag = ensemble_save
182  nphas = nphas_save
183  IF ( abs( error_condition2 ) > 1.e-1 ) write (*,*) 'caution: error outer loop', abs( error_condition2 )
184 
185 END SUBROUTINE heidemann_khalil
186 
187 
188 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
189 ! SUBROUTINE Heidemann_Khalil
190 !
191 ! This subroutine ....
192 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
193 !
194  SUBROUTINE heidemann_khalil_obj ( iter_no, y, residu, dummy )
195 !
196  USE parameters, ONLY: pi
197  USE basic_variables
198  USE module_heidemann_khalil
199  IMPLICIT NONE
200 !
201 ! ----------------------------------------------------------------------
202  INTEGER, INTENT(IN) :: iter_no
203  REAL, INTENT(IN) :: y(iter_no)
204  REAL, INTENT(OUT) :: residu(iter_no)
205  INTEGER, INTENT(IN OUT) :: dummy
206 !
207 ! ----------------------------------------------------------------------
208  INTEGER :: i, j, k
209  REAL, DIMENSION(nc) :: dn
210  REAL, DIMENSION(nc) :: dhs, rhoi00, rhoi0
211  REAL :: rho, d_rho
212  ! REAL :: lnphi(np,nc)
213  REAL :: qij(nc,nc), qij0(nc,nc), qijk(nc,nc,nc)
214  ! CHARACTER (LEN=3) :: char_len
215 ! ----------------------------------------------------------------------
216 
217  dn(1:ncomp) = y(1:ncomp)
218  t = y(ncomp+1)
219  !dense(1) = y(ncomp+2)
220 
221  dhs(1:ncomp) = parame(1:ncomp,2) * ( 1.0 - 0.12 *exp( -3.0*parame(1:ncomp,3)/t ) )
222  rho = dense(1) / sum( pi/6.0*xif(1:ncomp)*parame(1:ncomp,1)* dhs(1:ncomp)**3 )
223  rhoi00(1:ncomp) = xif(1:ncomp)*rho
224 
225  d_rho = 0.000001
226 
227  DO k = 1, ncomp
228 
229  rhoi0(1:ncomp) = rhoi00(1:ncomp)
230  rhoi0(k) = rhoi00(k) + d_rho
231  CALL qij_matrix ( rhoi0, dhs, d_rho, qij )
232  qij0(:,:) = qij(:,:)
233 
234  rhoi0(1:ncomp) = rhoi00(1:ncomp)
235  CALL qij_matrix ( rhoi0, dhs, d_rho, qij )
236 
237  DO i = 1, ncomp
238  DO j = 1, ncomp
239  qijk(i,j,k) = ( qij0(i,j) - qij(i,j) ) / d_rho
240  ! write(*,*) i,j,k,qijk(i,j,k)
241  END DO
242  END DO
243 
244  END DO
245 
246  ! write (*,'(a,4G18.10)') 'det',qij(2,2)*qij(1,1) - qij(2,1)*qij(1,2)
247  ! write (*,'(a,3G18.10)') ' t,p,eta ', t, p, dense(1)
248  DO j = 1, ncomp
249  residu(j) = sum( qij(1:ncomp,j)*dn(1:ncomp) )
250  END DO
251  residu(ncomp+1) = 1.0 - sum( dn(1:ncomp)*dn(1:ncomp) )
252 
253  error_condition2 = 0.0
254  DO k = 1, ncomp
255  DO i = 1, ncomp
256  DO j = 1, ncomp
257  error_condition2 = error_condition2 + qijk(i,j,k) * dn(i) * dn(j) * dn(k)
258  END DO
259  END DO
260  END DO
261  error_condition2 = error_condition2 * 1.e-4 ! the values are scaled down to prevent numerical dominance of this error
262  !residu(ncomp+2) = error_condition2
263 
264  !write (char_len,'(I3)') ncomp+2
265  !write (*,'(a,'//char_len//'G18.10)') ' error',residu(1:ncomp+1)
266  !write (*,*) ' '
267  !pause
268 
269 END SUBROUTINE heidemann_khalil_obj
270 
271 
272 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
273 ! SUBROUTINE Heidemann_Khalil
274 !
275 ! This subroutine calculates the spinodal for a binary mixture to given
276 ! T, p and for a given starting value of the density vector rhoi
277 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
278 !
279  SUBROUTINE binary_tp_spinodal ( rhoi, p_sp )
280 !
281  USE parameters, ONLY: pi
282  USE basic_variables
283  USE module_heidemann_khalil
284  USE solve_nonlin
285  IMPLICIT NONE
286 !
287 ! ----------------------------------------------------------------------
288  INTERFACE
289  SUBROUTINE binary_spinodal_obj ( iter_no, y, residu, dummy )
290  INTEGER, INTENT(IN) :: iter_no
291  REAL, INTENT(IN) :: y(iter_no)
292  REAL, INTENT(OUT) :: residu(iter_no)
293  INTEGER, INTENT(IN OUT) :: dummy
294  END SUBROUTINE binary_spinodal_obj
295  END INTERFACE
296 
297  REAL, dimension(nc) :: rhoi
298  REAL :: p_sp
299 ! ----------------------------------------------------------------------
300 
301  INTEGER :: info
302  REAL, ALLOCATABLE :: y(:), diag(:), residu(:)
303 
304  INTEGER :: i, nphas_save
305  CHARACTER (LEN=2) :: ensemble_save
306 ! ----------------------------------------------------------------------
307 
308  ensemble_save = ensemble_flag
309  ensemble_flag = 'tv'
310 
311  nphas_save = nphas
312  nphas = 1
313 
314  info = 1
315  n_unkw = ncomp + 2
316  acc_a = 5.e-8
317  step_a = 1.e-8
318 
319 
320  ALLOCATE( y(n_unkw), diag(n_unkw), residu(n_unkw) )
321  DO i = 1, ncomp
322  y(i) = 1.0 / sqrt( REAL( ncomp ) )
323  END DO
324  DO i = 1, ncomp
325  y( ncomp + i ) = rhoi( i )
326  END DO
327 
328  CALL hbrd (binary_spinodal_obj, n_unkw, y, residu, step_a, acc_a, info, diag)
329 
330  DO i = 1, ncomp
331  rhoi( i ) = y( ncomp + i )
332  END DO
333  write (*,*) 'info',info
334  write (*,*) 'rhoi',rhoi(1:ncomp)
335  !write (*,*) 'eta',PI / 6.0 * sum( rhoi(1:ncomp)*mseg(1:ncomp)*dhs(1:ncomp)**3 )
336  write (*,*) 'x',rhoi(1:ncomp) / sum( rhoi(1:ncomp) )
337 
338  DEALLOCATE( y, diag, residu )
339 
340  ensemble_flag = ensemble_save
341  nphas = nphas_save
342 
343 END SUBROUTINE binary_tp_spinodal
344 
345 
346 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
347 ! SUBROUTINE Heidemann_Khalil
348 !
349 ! This subroutine ....
350 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
351 !
352  SUBROUTINE binary_spinodal_obj ( iter_no, y, residu, dummy )
353 !
354  USE parameters, ONLY: pi
355  USE basic_variables
356  USE module_heidemann_khalil
357  IMPLICIT NONE
358 !
359 ! ----------------------------------------------------------------------
360  INTEGER, INTENT(IN) :: iter_no
361  REAL, INTENT(IN) :: y(iter_no)
362  REAL, INTENT(OUT) :: residu(iter_no)
363  INTEGER, INTENT(IN OUT) :: dummy
364 !
365 ! ----------------------------------------------------------------------
366  INTEGER :: j, k
367  REAL :: p_calculated, zges, p_sp
368  REAL :: d_rho
369  REAL, DIMENSION(nc) :: dn
370  REAL, DIMENSION(nc) :: dhs, rhoi
371  REAL, DIMENSION(nc,nc) :: qij
372 ! ----------------------------------------------------------------------
373 
374  dn(1:ncomp) = y(1:ncomp)
375  rhoi(1:ncomp) = y( (ncomp+1) : (ncomp+ncomp) )
376  dhs(1:ncomp) = parame(1:ncomp,2) * ( 1.0 - 0.12 *exp( -3.0*parame(1:ncomp,3)/t ) ) ! is this calc. needed?
377 
378  call p_calc ( p_calculated, zges )
379 
380  d_rho = 0.000001
381 
382  DO k = 1, ncomp
383 
384  CALL qij_matrix ( rhoi, dhs, d_rho, qij )
385 
386  END DO
387 
388  !write (*,'(a,4G18.10)') 'det',qij(2,2)*qij(1,1) - qij(2,1)*qij(1,2)
389  write (*,'(a,3G18.10)') ' t,p,eta ', t, p, dense(1)
390  DO j = 1, ncomp
391  residu(j) = sum( qij(1:ncomp,j)*dn(1:ncomp) )
392  END DO
393  residu(ncomp+1) = 1.0 - sum( dn(1:ncomp)*dn(1:ncomp) )
394  write (*,*) 'p_sp has to be handed over to the obj fct properly!'
395  write (*,*) 'Can I simply set p = p_sp? In other words is p altered during the calculation?'
396  stop 5
397  residu(ncomp+2) = p_sp - p_calculated
398 
399  write (*,'(a,4G18.10)') ' error',residu(1:4)
400  write (*,*) ' '
401  pause
402 
403 END SUBROUTINE binary_spinodal_obj
404 
405 
406 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
407 ! SUBROUTINE Heidemann_Khalil
408 !
409 ! This subroutine ....
410 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
411 !
412  SUBROUTINE qij_matrix ( rhoi0, dhs, d_rho, qij )
413 !
414  USE parameters, ONLY: pi, kbol
415  USE basic_variables
416  USE eos_variables, ONLY: pges
417  IMPLICIT NONE
418 !
419 ! ----------------------------------------------------------------------
420  REAL, DIMENSION(nc), INTENT(IN) :: rhoi0
421  REAL, DIMENSION(nc), INTENT(IN) :: dhs
422  REAL, INTENT(IN) :: d_rho
423  REAL, DIMENSION(nc,nc), INTENT(OUT) :: qij
424 !
425 ! ----------------------------------------------------------------------
426  INTEGER :: i
427  REAL, DIMENSION(nc) :: rhoi, lnf0, lnf1, lnf2
428  REAL :: lnphi(np,nc), zges
429 ! ----------------------------------------------------------------------
430 
431 
432  DO i = 1, ncomp
433  rhoi(1:ncomp) = rhoi0(1:ncomp)
434  rhoi(i) = rhoi0(i) + d_rho
435  dense(1) = sum( pi/6.0*rhoi(1:ncomp)*parame(1:ncomp,1)* dhs(1:ncomp)**3 )
436  densta(1) = dense(1)
437  xi(1,1:ncomp) = rhoi(1:ncomp) / sum( rhoi(1:ncomp) )
438  CALL fugacity ( lnphi )
439  p = pges
440  zges = (pges * 1.d-30) / ( kbol*t*sum(rhoi(1:ncomp)) )
441  lnf1(1:ncomp) = lnphi(1,1:ncomp) + log( rhoi(1:ncomp) )
442 
443  IF (rhoi0(i) - d_rho > 0.0 ) THEN
444  rhoi(1:ncomp) = rhoi0(1:ncomp)
445  rhoi(i) = rhoi0(i) - d_rho
446  dense(1) = sum( pi/6.0*rhoi(1:ncomp)*parame(1:ncomp,1)* dhs(1:ncomp)**3 )
447  densta(1) = dense(1)
448  xi(1,1:ncomp) = rhoi(1:ncomp) / sum( rhoi(1:ncomp) )
449  CALL fugacity ( lnphi )
450  p = pges
451  zges = (pges * 1.d-30) / ( kbol*t*sum(rhoi(1:ncomp)) )
452  lnf2(1:ncomp) = lnphi(1,1:ncomp) + log( rhoi(1:ncomp) )
453  END IF
454 
455  rhoi(1:ncomp) = rhoi0(1:ncomp)
456  dense(1) = sum( pi/6.0*rhoi(1:ncomp)*parame(1:ncomp,1)* dhs(1:ncomp)**3 )
457  densta(1) = dense(1)
458  xi(1,1:ncomp) = rhoi(1:ncomp) / sum( rhoi(1:ncomp) )
459  CALL fugacity ( lnphi )
460  p = pges
461  zges = (pges * 1.d-30) / ( kbol*t*sum(rhoi(1:ncomp)) )
462  lnf0(1:ncomp) = lnphi(1,1:ncomp) + log( rhoi(1:ncomp) )
463 
464  IF (rhoi0(i) - d_rho > 0.0 ) THEN
465  qij(i,1:ncomp) = ( lnf1(1:ncomp) - lnf2(1:ncomp) ) / (2.0*d_rho) ! qij = d(F/V) / (d_rho_i*d_rho_j)
466  ELSE
467  qij(i,1:ncomp) = ( lnf1(1:ncomp) - lnf0(1:ncomp) ) / d_rho ! qij = d(F/V) / (d_rho_i*d_rho_j)
468  END IF
469  ! write (*,*) i,1,qij(i,1)
470  ! write (*,*) i,2,qij(i,2)
471  END DO
472 
473 END SUBROUTINE qij_matrix
474 
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains constant...
Definition: modules.f90:6
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
Definition: modules.f90:120
In this module, the application context is defined.
Definition: mod_PETSc.F90:7
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains paramete...
Definition: modules.f90:29