MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
mod_DFT_CHAIN.F90
Go to the documentation of this file.
1 
4 
5 
6 Module mod_dft_chain
7 
8 Implicit None
9 private
10 
11 
12 public :: chain_aux
13 public :: chain_dfdrho
14 
15 
16  contains
17 
18 
19 
20 Subroutine chain_aux(rhop,rhobar,lambda,user)
21 
22 Use basic_variables, Only: ncomp
23 Use eos_variables, Only: dhs,rho
24 Use mod_dft, Only: zp,dzp,fa
25 
26 
27 !PETSc module
29 
30 #include <finclude/petscsys.h>
31 
32 !passed
33 type(userctx) :: user
34 petscscalar :: rhop(ncomp,user%gxs:user%gxe)
35 REAL,INTENT(OUT) :: rhobar(user%gxs:user%gxe,ncomp)
36 REAL,INTENT(OUT) :: lambda(user%gxs:user%gxe,ncomp)
37 
38 !local
39 INTEGER :: i,j,k
40 REAL :: dhsk
41 INTEGER :: fak,n
42 REAL :: zz,dz,xlo,xhi,integral_lamb,integral_rb
43 INTEGER, parameter :: nmax = 800
44 REAL,dimension(NMAX) :: x_int, lamb_int, rb_int
45 REAL,dimension(NMAX) :: y2_lamb, y2_rb
46 REAL :: rhopjk,rhopjp1k
47 
48 
49 !fak = maxval(fa(1:ncomp))
50 
51 Do k = 1,ncomp
52  dhsk = dhs(k)
53  fak = fa(k) + 1
54 
55  Do i = user%xs-fak,user%xe+fak !lambda und rhobar werden bis i+-sig gebraucht -> Schleife bis +- fa
56  n = 1 !this is the index of the arrays that will be passed to the spline integration routines
57  x_int = 0.0
58  lamb_int = 0.0
59  rb_int = 0.0
60 
61  Do j = i-fak,i+fak !um lambda bei i zu berechnen, muss bis +- sig um i integriert werden -> Schleife bis +- fa
62  rhopjk = rhop(k,j)
63  rhopjp1k = rhop(k,j+1)
64 
65 
66  If( ( zp(i)-zp(j+1) ) < dhsk .and. ( zp(i) - zp(j) ) >= dhsk ) Then !the position of j+1 is already within i-d while j is still outside this range in this case, the integration steplength (dz) is just the distance, which j+1 overlaps with i-d and what is integrated is the interpolated value of the integrand
67 
68  If(n/= 1) Then
69  write(*,*) 'Surface Tension Code: n /=1 in Chain_aux' !here always n=1!
70  stop 5
71  End If
72 
73  zz = zp(j) - zp(i) !distance between grid points j and i
74  dz = zp(j+1) - (zp(i) - dhsk) !the part of the intervall between zp(j) and zp(j+1) which is already within i-d
75  !if(dz < epsilon(dz)) dz = epsilon(dz) !bei unguenstiger Kombination von sig und ngrid kann dz unter Machinengenauigkeit epsilon liegen, dann ist x(2) = x(1) + dz = x(1) -> das fuehrt zu Abbruch in Spline Interpolation
76  x_int(n) = 0.0 !array containing x-values for spline integration
77 
78  lamb_int(n) = rhopjk + (rhopjp1k - rhopjk)/dzp * (dzp-dz) !lineare interpolation analog zum FMT Teil
79  rb_int(n) = 0.0 !erklärung analog wie bei n3_int in FMT Teil
80 
81 
82  Else If (zp(j) > (zp(i)-dhsk) .and. zp(j) <= (zp(i)+dhsk)) Then !grid point j within i+-d
83 
84  n = n + 1
85  x_int(n) = x_int(n-1) + dz !first time in this If condition, dz is stil the old value from above!
86  zz = zp(j) - zp(i)
87  dz = dzp
88  lamb_int(n) = rhopjk
89  rb_int(n) = rhopjk * ( dhsk**2 - zz**2 )
90 
91  If (zp(j) < (zp(i)+dhsk) .and. zp(j+1) >= (zp(i)+dhsk) ) Then !zp(j) is still within zp(i)+d but zp(j+1) is already outside zp(i)+d
92 
93  dz = zp(i) + dhsk - zp(j)
94  !If(dz <= epsilon(dz)) exit !wie oben, kann auch hier bei ungluecklicher Wahl von sig und ngrid dz < eps werden und somit x(n) = x(n-1) -> Abbruch in Spline interpolation. Dann einfach ngrid aendern!
95  zz = zp(j) - zp(i)
96  n = n + 1
97  x_int(n) = x_int(n-1) + dz
98  rb_int(n) = 0.0
99  lamb_int(n) = rhopjk + (rhopjp1k - rhopjk)/dzp * dz
100 ! If(x_int(n) == x_int(n-1)) Then
101 ! n = n - 1
102 ! exit
103 ! End If
104 
105  End If
106  End If
107  End Do
108 
109 
110 
111  !spline integration
112  xlo = x_int(1)
113  xhi = x_int(n)
114 
115  If(n > nmax) Then
116  write(*,*)'Surface Tension Code: Increase NMAX in Chain_aux (also in AD Routine!!)'
117  stop 5
118  End If
119 
120  call spline ( x_int, lamb_int, n, 1.e30, 1.e30, y2_lamb )
121  call spline ( x_int, rb_int, n, 1.e30, 1.e30, y2_rb )
122 
123  call splint_integral ( x_int, lamb_int, y2_lamb, n, xlo, xhi, integral_lamb )
124  call splint_integral ( x_int, rb_int, y2_rb, n, xlo, xhi, integral_rb )
125  lambda(i,k) = 0.5 * integral_lamb / dhsk
126  rhobar(i,k) = 0.75 * integral_rb / dhsk**3
127 
128  If(lambda(i,k) < epsilon(dz) ) lambda(i,k) = epsilon(dz)
129  !If ( lambda(i,k) < 0.5*xx(k)*rho ) write (*,*) 'warning: lambda too low',i,lambda(i,k)
130  !If ( k == 1 .AND. lambda(i,k) < 0.5*rhob(2,k) ) lambda(i,k) = 0.5*rhob(2,k)
131 
132 
133  End Do
134 
135 End Do
136 
137 
138 End Subroutine chain_aux
139 
140 
141 
142 
143 
144 
145 
146 
147 Subroutine chain_dfdrho(i,rhop,lambda,rhobar,dF_drho_CHAIN,f_ch,user)
148 
149 Use basic_variables, Only: ncomp,parame
150 Use eos_variables, Only: dhs
151 Use mod_dft, Only: zp,dzp,fa
152 
153 !PETSc module
154 Use petscmanagement
155 
156 #include <finclude/petscsys.h>
157 
158 !passed
159 INTEGER, INTENT(IN) :: i !the grid point to calculate dFdrho at
160 type(userctx) :: user
161 petscscalar :: rhop(ncomp,user%gxs:user%gxe)
162 REAL,INTENT(IN) :: rhobar(user%gxs:user%gxe,ncomp)
163 REAL,INTENT(IN) :: lambda(user%gxs:user%gxe,ncomp)
164 REAL,INTENT(OUT) :: df_drho_chain(user%xs:user%xe,ncomp)
165 REAL, INTENT(OUT) :: f_ch
166 
167 
168 !local
169 INTEGER :: j,k,n
170 REAL :: dhsk
171 INTEGER :: fak
172 REAL :: rhopjk,rhopjp1k,logrho,xlo,xhi
173 REAL :: ycorr(ncomp),dlny(ncomp,ncomp)
174 INTEGER, parameter :: nmax = 800
175 REAL,dimension(NMAX) :: x_int, int_1,int_2 !Fehlerwarnung falls 800 ueberschritten einbauen
176 REAL,dimension(NMAX) :: y2_1, y2_2
177 REAL :: dz,zz,integral_1,integral_2
178 REAL :: lamy
179 
180 
181  call cavity_mix(rhobar(i,1:ncomp),ycorr,dlny)
182 
183  f_ch = 0.0
184 
185  Do k = 1,ncomp
186  fak = fa(k)
187  dhsk = dhs(k)
188  n = 1
189  x_int = 0.0
190  int_1 = 0.0
191  int_2 = 0.0
192 
193 
194  Do j = i-fak,i+fak !es muss bis +- sig um i integriert werden
195  rhopjk = rhop(k,j)
196  rhopjp1k = rhop(k,j+1)
197 
198  If( ( zp(i)-zp(j+1) ) < dhsk .and. ( zp(i) - zp(j) ) >= dhsk ) Then !the position of j+1 is already within i-d while j is still outside this range in this case, the integration steplength (dz) is just the distance, which j+1 overlaps with i-d and what is integrated is the interpolated value of the integrand
199 
200  If(n/= 1) Then
201  write(*,*) 'Surface Tension Code: n /=1 in Chain_dFdrho' !here always n=1!
202  stop 5
203  End If
204 
205  zz = zp(j) - zp(i) !distance between grid points j and i
206  dz = zp(j+1) - (zp(i) - dhsk) !the part of the intervall between zp(j) and zp(j+1) which is already within i-d
207  !if(dz < epsilon(dz)) dz = epsilon(dz) !bei unguenstiger Kombination von sig und ngrid kann dz unter Machinengenauigkeit epsilon liegen, dann ist x(2) = x(1) + dz = x(1) -> das fuehrt zu Abbruch in Spline Interpolation
208  x_int(n) = 0.0 !array containing x-values for spline integration
209  int_1(n) = 0.0 !erklärung analog wie bei n3_int in FMT Teil
210  int_2(n) = rhopjk*lambda(j,k) + (rhopjp1k*lambda(j+1,k) - rhopjk*lambda(j,k) )/dzp * (dzp-dz) !lineare interpolation analog zum FMT Teil
211 
212  Else If (zp(j) > (zp(i)-dhsk) .and. zp(j) <= (zp(i)+dhsk)) Then !grid point j within i+-d
213 
214  n = n + 1
215  x_int(n) = x_int(n-1) + dz !first time in this If condition, dz is stil the old value from above!
216  zz = zp(j) - zp(i)
217  dz = dzp
218  int_1(n) = sum( ( parame(1:ncomp,1)-1.0 ) * rhop(1:ncomp,j)*dlny(1:ncomp,k) ) &
219  * 0.75/dhsk**3 * (dhsk**2-zz**2)
220  int_2(n) = rhopjk / lambda(j,k)
221 
222  If (zp(j) < (zp(i)+dhsk) .and. zp(j+1) >= (zp(i)+dhsk) ) Then !zp(j) is still within zp(i)+d but zp(j+1) is already outside zp(i)+d
223 
224  dz = zp(i) + dhsk - zp(j)
225  !If(dz <= epsilon(dz)) exit !wie oben, kann auch hier bei ungluecklicher Wahl von sig und ngrid dz < eps werden und somit x(n) = x(n-1) -> Abbruch in Spline interpolation. Dann einfach ngrid aendern!
226  zz = zp(j) - zp(i)
227  n = n + 1
228  x_int(n) = x_int(n-1) + dz
229  int_1(n) = 0.0
230  int_2(n) = rhopjk*lambda(j,k) + (rhopjp1k*lambda(j+1,k) - rhopjk*lambda(j,k) )/dzp * dz
231 
232 ! If(x_int(n) == x_int(n-1)) Then
233 ! n = n - 1
234 ! exit
235 ! End If
236 
237  End If
238  End If
239  End Do
240 
241  !Spline Integration
242  xlo = x_int(1)
243  xhi = x_int(n)
244 
245  If(n > nmax) Then
246  write(*,*)'Surface Tension Code: Increase NMAX in Chain_dFdrho (also in AD Routine!!)'
247  stop 5
248  End If
249 
250  CALL spline ( x_int, int_1, n, 1.e30, 1.e30, y2_1 )
251  CALL splint_integral( x_int, int_1, y2_1, n, xlo, xhi, integral_1 )
252  CALL spline ( x_int, int_2, n, 1.e30, 1.e30, y2_2 )
253  CALL splint_integral( x_int, int_2, y2_2, n, xlo, xhi, integral_2 )
254 
255  If(rhop(k,i) < epsilon(dz)) rhop = epsilon(dz)
256 
257  df_drho_chain(i,k) = (parame(k,1) - 1.0)*log(rhop(k,i)) &
258  - (parame(k,1) - 1.0) * ( log(ycorr(k)*lambda(i,k))-1.0 + 0.5*integral_2/dhsk ) - integral_1
259 
260 
261  f_ch = f_ch + ( parame(k,1) - 1.0 ) * rhop(k,i) * ( log(rhop(k,i)) - 1.0 ) &
262  - ( parame(k,1) - 1.0 ) * rhop(k,i) * ( log(ycorr(k)*lambda(i,k)) - 1.0 )
263 
264 
265 
266 
267 
268 End Do
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 End Subroutine chain_dfdrho
282 
283 
284 
285 
286 
287 
288 
289 
290 
291 
292 
293 
294 
295 
296 
297 
298 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
299 !
300 !WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
301 !
302  SUBROUTINE cavity_mix ( rhoi, ycorr, dlnydr )
303 !
304  USE parameters, ONLY: pi
305  USE basic_variables, ONLY: ncomp,parame
306  USE eos_variables, Only: dhs
307  IMPLICIT NONE
308 !
309 ! ----------------------------------------------------------------------
310  REAL, INTENT(IN) :: rhoi(ncomp)
311  REAL, INTENT(OUT) :: ycorr(ncomp)
312  REAL, INTENT(OUT) :: dlnydr(ncomp,ncomp) ! this is: d( ln( yij ) ) / d( rho(k) ) used with i=j
313 !
314 ! ----------------------------------------------------------------------
315  INTEGER :: i, j, k
316  REAL :: z0, z1, z2, z3, zms, z1_rk, z2_rk, z3_rk
317  REAL, DIMENSION(ncomp,ncomp) :: dij_ab, gij, gij_rk
318 ! ----------------------------------------------------------------------
319 
320  z0 = pi / 6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) )
321  z1 = pi / 6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp) )
322  z2 = pi / 6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**2 )
323  z3 = pi / 6.0 * sum( rhoi(1:ncomp) * parame(1:ncomp,1) * dhs(1:ncomp)**3 )
324 
325  zms = 1.0 - z3
326 
327  DO i = 1,ncomp
328  DO j=1,ncomp
329  dij_ab(i,j)=dhs(i)*dhs(j)/(dhs(i)+dhs(j))
330  ENDDO
331  END DO
332 
333  DO k = 1, ncomp
334  DO i = 1, ncomp
335  z1_rk = pi/6.0 * parame(k,1) * dhs(k)
336  z2_rk = pi/6.0 * parame(k,1) * dhs(k)*dhs(k)
337  z3_rk = pi/6.0 * parame(k,1) * dhs(k)**3
338  !DO j = 1, ncomp
339  j = i
340  gij(i,j) = 1.0/zms + 3.0*dij_ab(i,j)*z2/zms/zms &
341  + 2.0*(dij_ab(i,j)*z2)**2 /zms**3
342  !dgijdz(i,j)= 1.0/zms/zms + 3.0*dij_ab(i,j)*z2*(1.0+z3)/z3/zms**3 &
343  ! + (dij_ab(i,j)*z2/zms/zms)**2 *(4.0+2.0*z3)/z3
344  gij_rk(i,j) = z3_rk/zms/zms &
345  + 3.0*dij_ab(i,j)*(z2_rk+2.0*z2*z3_rk/zms)/zms/zms &
346  + dij_ab(i,j)**2 *z2/zms**3 *(4.0*z2_rk+6.0*z2*z3_rk/zms)
347  !END DO
348 
349  ycorr(i) = gij(i,i)
350  dlnydr(i,k) = gij_rk(i,i) / gij(i,i)
351 
352  END DO
353  END DO
354 
355 END SUBROUTINE cavity_mix
356 
357 
358 
359 
360 
361 
362 
363 
364 
365 
366 End Module mod_DFT_CHAIN
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW This module contains constant...
Definition: modules.f90:6
double lambda
Latent heat of blowing agent, J/kg.
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