MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
mod_DFT_FMT.F90
Go to the documentation of this file.
1 
4 
5 
6 
7 
8 Module mod_dft_fmt
9 
10 Implicit None
11 
12 Private
13 
14 Public :: fmt_weighted_densities
15 Public :: fmt_dfdrho
16 
17  Contains
18 
19 
20 
21 
22 
23 Subroutine fmt_weighted_densities(rhop,n0,n1,n2,n3,nv1,nv2,phi_dn0,phi_dn1,phi_dn2,phi_dn3,phi_dnv1,phi_dnv2,user)
24 
25 Use parameters, ONLY: pi
26 Use basic_variables, Only: ncomp,parame
27 Use eos_variables, Only: dhs
28 Use mod_dft, Only: zp,dzp,fa
29 
30 !PETSc module
32 
33 #include <finclude/petscsys.h>
34 
35 !passed
36 type(userctx) :: user
37 petscscalar :: rhop(ncomp,user%gxs:user%gxe)
38 REAL,dimension(user%gxs:user%gxe),Intent(OUT) :: n0,n1,n2,n3,nv1,nv2 !ngp muss groesser als fa+fa/2 sein!!
39 REAL,dimension(user%gxs:user%gxe),Intent(OUT) :: phi_dn0,phi_dn1,phi_dn2,phi_dn3,phi_dnv1,phi_dnv2
40 
41 !local
42 Integer :: k,i,j
43 Integer :: fa2
44 REAL :: dz,d2,zz
45 INTEGER :: n
46 INTEGER, parameter :: nmax = 800
47 REAL,dimension(NMAX) :: x_int,n2_int,n3_int,nv2_int !Fehlerwarnung falls 200 ueberschritten einbauen
48 REAL,dimension(NMAX) :: y2_n2, y2_n3,y2_nv2
49 REAL :: int_n2,int_n3,int_nv2,xhi,xlo
50 REAL :: zms,zms2,zms3,logzms
51 REAL :: nn0,nn1,nn2,nn3,nnv1,nnv2
52 REAL :: rhopjk, rhopjp1k
53 
54 
55  n0 = 0.0
56  n1 = 0.0
57  n2 = 0.0
58  n3 = 0.0
59  nv1 = 0.0
60  nv2 = 0.0
61 
62  fa2 = maxval(fa(1:ncomp) + 5) / 2
63 
64 Do k=1,ncomp
65  !fa2 = (fa(k) + 5) / 2 !grid points in sig/2
66  d2 = dhs(k) / 2.0 !half of dhs [A]
67 
68 
69  Do i=user%xs-fa2,user%xe+fa2 !to evaluate dF/drho at any point, the derivatives dphi/dn have to be evaluated at +-d/2 around this point
70  n = 1 !this is the index of the arrays that will be passed to the spline integration routines
71  x_int = 0.0
72  n2_int = 0.0
73  n3_int = 0.0
74  nv2_int = 0.0
75 
76  Do j=i-fa2,i+fa2 !to evaluate dphi/dn at a given point, the weighted densities are needed at +-d/2 around this point
77 
78  rhopjk = rhop(k,j) * parame(k,1)
79  rhopjp1k = rhop(k,j+1) * parame(k,1)
80 
81  If( ( zp(i)-zp(j+1) ) < d2 .and. ( zp(i) - zp(j) ) >= d2 ) Then !the position of j+1 is already within i-d/2 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/2 and what is integrated is the interpolated value of the integrand
82 
83  If(n/= 1) Then
84  write(*,*)'Surface Tension Code: n /=1 in FMT_Weighted_Densities' !here always n=1!
85  call exit
86  End If
87 
88  zz = zp(j) - zp(i) !distance between grid points j and i
89  dz = zp(j+1) - (zp(i) - d2) !the part of the intervall between zp(j) and zp(j+1) which is already within i-d/2
90  !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
91  x_int(n) = 0.0 !array containing x-values for spline integration
92  n2_int(n) = rhopjk + (rhopjp1k-rhopjk) / (dzp) * (dzp-dz) !integrand f�r n2 (=rhop) linear interpoliert f�r den Punk zp(i)-d/2
93  n3_int(n) = 0.0 !integrand f�r n3: rhop*(d2**2 - z'**2), da hier gerade z' = d2 -> integrand wird hier = 0!!
94  nv2_int(n) = rhopjk*zz +(rhopjp1k*(zp(j+1)-zp(i))-rhopjk*zz)/(dzp)*(dzp-dz) !analog
95 
96 
97  Else If (zp(j) > (zp(i)-d2) .and. zp(j) <= (zp(i)+d2)) Then !grid point j within i+-d2
98 
99  n = n + 1
100  x_int(n) = x_int(n-1) + dz !first time in this If condition, dz is stil the old value from above!
101  zz = zp(j) - zp(i)
102  dz = dzp
103  n2_int(n) = rhopjk
104  n3_int(n) = rhopjk * (d2**2 - zz**2)
105  nv2_int(n) = rhopjk * zz
106 
107  If (zp(j) < (zp(i)+d2) .and. zp(j+1) >= (zp(i)+d2) ) Then !zp(j) is still within zp(i)+d2 but zp(j+1) is already outside zp(i)+d2
108 
109  dz = zp(i) + d2 - zp(j)
110  !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!
111  zz = zp(j) - zp(i)
112  n = n + 1
113  x_int(n) = x_int(n-1) + dz
114 ! If(x_int(n) == x_int(n-1)) Then
115 ! n = n - 1
116 ! exit
117 ! End If
118  n2_int(n) = rhopjk + (rhopjp1k-rhopjk) / (dzp) * dz
119  n3_int(n) = 0.0 !Begr�ndung wie oben
120  nv2_int(n) = rhopjk*zz + (rhopjp1k*(zp(j+1)-zp(i)) - rhopjk*zz) / (dzp) * dz
121 
122  End If
123 
124  End If
125 
126 
127  End Do
128 
129  !spline integration
130  xlo = x_int(1)
131  xhi = x_int(n)
132 
133  If(n > nmax) Then
134  write(*,*) 'Increase NMAX in FMT_Weighted_Densities (also in AD Routine!!)'
135  call exit
136  End If
137 
138  call spline ( x_int, n2_int, n, 1.e30, 1.e30, y2_n2 )
139  call spline ( x_int, n3_int, n, 1.e30, 1.e30, y2_n3 )
140  call spline ( x_int, nv2_int, n, 1.e30, 1.e30, y2_nv2 )
141 
142  call splint_integral ( x_int, n2_int, y2_n2, n, xlo, xhi, int_n2 )
143  call splint_integral ( x_int, n3_int, y2_n3, n, xlo, xhi, int_n3 )
144  call splint_integral ( x_int, nv2_int, y2_nv2, n, xlo, xhi, int_nv2 )
145 
146  !weighted densities
147  n2(i) = n2(i) + pi * dhs(k) * int_n2
148  n1(i) = n1(i) + 0.5 * int_n2
149  n0(i) = n0(i) + int_n2/dhs(k)
150  n3(i) = n3(i) + pi * int_n3
151  nv2(i) = nv2(i) -2.0 * pi * int_nv2
152  nv1(i) = nv1(i) -int_nv2 / dhs(k)
153 
154 ! If(i < 5) Then
155 ! write(*,*)'i dens',i,nv2(i),n1(i),n0(i)
156 ! write(*,*)'i dens',i,n3(i),nv1(i),nv2(i)
157 ! end if
158 !
159 ! If(i > 95) then
160 ! write(*,*)'i dens',i,nv2(i),n1(i),n0(i)
161 ! write(*,*)'i dens',i,n3(i),nv1(i),nv2(i)
162 ! End If
163 !
164  End Do
165 
166  ! pause
167 
168 End Do
169 
170 
171 !derivatives of FMT helmholtz energy density w.r.t. weighted densities
172 Do i=user%xs-maxval((fa(1:ncomp)+1)/2),user%xe+maxval((fa(1:ncomp)+1)/2)
173  !weils k�rzer ist
174  nn0 = n0(i)
175  nn1 = n1(i)
176  nn2 = n2(i)
177  nn3 = n3(i)
178  nnv1 = nv1(i)
179  nnv2 = nv2(i)
180 
181  zms = 1.0 - nn3
182  zms2 = zms*zms
183  zms3 = zms2*zms
184  logzms = log(zms)
185  if(isnan(logzms)) Then
186  write(*,*)'Surface Tension Code: zms < 0, log(zms) undefined FMT_Weighted_Densities'
187  call exit
188  End If
189  phi_dn0(i) = -logzms
190  phi_dn1(i) = nn2/zms
191  phi_dn2(i) = nn1/zms + 3.0*(nn2*nn2-nnv2*nnv2) * (nn3+zms2*logzms) / (36.0*pi*nn3*nn3*zms2)
192 
193  phi_dn3(i) = nn0/zms + (nn1*nn2-nnv1*nnv2)/zms2 - (nn2**3-3.0*nn2*nnv2*nnv2) * (nn3*(nn3**2-5.0*nn3+2.0)+2.0*zms3*logzms) &
194  / (36.0*pi*nn3**3*zms3)
195 
196  phi_dnv1(i) = -nnv2/zms
197 
198  phi_dnv2(i) = -nnv1/zms - 6.0*nn2*nnv2*(nn3+zms2*logzms)/(36.0*pi*nn3**2*zms2)
199 
200 End Do
201 
202 End Subroutine fmt_weighted_densities
203 
204 
205 
206 
207 
208 
209 
210 Subroutine fmt_dfdrho(i,fa,user,phi_dn0,phi_dn1,phi_dn2,phi_dn3,phi_dnv1,phi_dnv2,dF_drho_FMT)
211 
212 Use basic_variables, Only: ncomp,parame
213 Use eos_variables, Only: dhs
214 Use mod_dft, Only: zp,dzp
215 Use parameters, ONLY: pi
216 
217 !PETSc module
218 Use petscmanagement
219 
220 !passed
221 INTEGER, INTENT(IN) :: i !the grid point at which to calculate dFdrho
222 INTEGER, INTENT(IN) :: fa(ncomp)
223 type(userctx) :: user
224 REAL,dimension(user%gxs:user%gxe),INTENT(IN) :: phi_dn0,phi_dn1,phi_dn2,phi_dn3,phi_dnv1,phi_dnv2
225 REAL,dimension(user%xs:user%xe,ncomp), INTENT(OUT) :: df_drho_fmt
226 
227 
228 !local
229 INTEGER :: j,k,n
230 INTEGER :: fa2
231 REAL :: dz,d2,zz, zz_jp1
232 INTEGER, parameter :: nmax = 800
233 REAL,dimension(NMAX) :: x_int,y_int,y0_int,y1_int,y2_int,y3_int,yv1_int,yv2_int,y2
234 REAL :: xhi,xlo,integral,int0,int1,int2,int3,intv1,intv2
235 REAL :: at_j, at_jp1
236 
237 
238 !Das Integral (Gleichung A1 in Gross DFT 2009) wird hier in einem Schlag berechnet!
239 !Falls die einzelnen Terme einzeln integriert werden sollen, einfach die auskommentierte Version verwenden
240 
241 Do k=1,ncomp !das einzige, das hier von k abhaengt, sind fa und dhs!! die Ableitungen phi_dn... sind nicht Komponentenspez, da die
242  !gewichteten Dichten ja uch nicht mehr Komponentenspez sind (n_i = sum n_i(k))
243 
244  n = 1
245  fa2 = ( fa(k) + 5 ) / 2 !number of grid points within dhs/2
246  d2 = dhs(k)/2.0
247 
248  Do j = i-fa2,i+fa2
249 
250  If( ( zp(i)-zp(j+1) ) < d2 .and. ( zp(i) - zp(j) ) >= d2 ) Then !the position of j+1 is already within i-d/2 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/2 and what is integrated is the interpolated value of the integrand
251  x_int(n) = 0.0
252  If(n/=1) Then
253  write(*,*) 'Surface Tension Code: error in FMT_dFdrho, n should be 1 here!'
254  call exit
255  End If
256  dz = zp(j+1) - (zp(i) - d2)
257  zz = zp(j) - zp(i)
258  zz_jp1 = zp(j+1) - zp(i)
259  at_j = phi_dn0(j)/dhs(k) + 0.5*phi_dn1(j) + pi*dhs(k)*phi_dn2(j) &
260  + pi*phi_dn3(j)*(d2**2 - zz**2) + phi_dnv1(j)*zz/dhs(k) + 2.0*pi*phi_dnv2(j)*zz
261 
262  at_jp1 = phi_dn0(j+1)/dhs(k) + 0.5*phi_dn1(j+1) + pi*dhs(k)*phi_dn2(j+1) &
263  + pi*phi_dn3(j+1)*(d2**2 - zz_jp1**2) + phi_dnv1(j+1)*zz_jp1/dhs(k) + 2.0*pi*phi_dnv2(j+1)*zz_jp1
264 
265  y_int(n) = at_j + (at_jp1-at_j)/dzp * (dzp-dz) !lineare interpolation genau, wie in FMT_Weighted_Densities
266 ! y0_int(n) = phi_dn0(j) + (phi_dn0(j+1) -phi_dn0(j))/dzp * (dzp-dz)
267 ! y1_int(n) = phi_dn1(j) + (phi_dn1(j+1) -phi_dn1(j))/dzp * (dzp-dz)
268 ! y2_int(n) = phi_dn2(j) + (phi_dn2(j+1) -phi_dn2(j))/dzp * (dzp-dz)
269 ! y3_int(n) = phi_dn3(j)*(d2**2-zz**2) + (phi_dn3(j+1)*(d2**2-zz_jp1**2) - phi_dn3(j)*(d2**2-zz**2) )/dzp * (dzp-dz)
270 ! yv1_int(n) = phi_dnv1(j)*zz + (phi_dnv1(j+1)*zz_jp1 - phi_dnv1(j)*zz)/dzp * (dzp-dz)
271 ! yv2_int(n) = phi_dnv2(j)*zz + (phi_dnv2(j+1)*zz_jp1 - phi_dnv2(j)*zz)/dzp * (dzp-dz)
272 !
273 
274  Else If (zp(j) > (zp(i)-d2) .and. zp(j) <= (zp(i)+d2)) Then !grid points j and j+1 are completely within i+-d2
275 
276  n = n + 1
277  zz = zp(j) - zp(i)
278  x_int(n) = x_int(n-1) + dz
279 
280 
281  y_int(n) = phi_dn0(j)/dhs(k) + 0.5*phi_dn1(j) + pi*dhs(k)*phi_dn2(j) &
282  + pi*phi_dn3(j)*(d2**2 - zz**2) + phi_dnv1(j)*zz/dhs(k) + 2.0*pi*phi_dnv2(j)*zz
283 
284 
285 ! y0_int(n) = phi_dn0(j)
286 ! y1_int(n) = phi_dn1(j)
287 ! y2_int(n) = phi_dn2(j)
288 ! y3_int(n) = phi_dn3(j)*(d2**2-zz**2)
289 ! yv1_int(n) = phi_dnv1(j)*zz
290 ! yv2_int(n) = phi_dnv2(j)*zz
291 !
292 
293  dz = dzp
294 
295  If (zp(j) < (zp(i)+d2) .and. zp(j+1) > (zp(i)+d2) ) Then !zp(j) is still within zp(i)+d2 but zp(j+1) is already out side zp(i)+d2
296 
297  n = n + 1
298  zz = zp(j) - zp(i)
299  zz_jp1 = zp(j+1) - zp(i)
300  dz = zp(i) + d2 - zp(j)
301  x_int(n) = x_int(n-1) + dz
302  at_j = phi_dn0(j)/dhs(k) + 0.5*phi_dn1(j) + pi*dhs(k)*phi_dn2(j) &
303  + pi*phi_dn3(j)*(d2**2 - zz**2) + phi_dnv1(j)*zz/dhs(k) + 2.0*pi*phi_dnv2(j)*zz
304  at_jp1 = phi_dn0(j+1)/dhs(k) + 0.5*phi_dn1(j+1) + pi*dhs(k)*phi_dn2(j+1) &
305  + pi*phi_dn3(j+1)*(d2**2 - zz_jp1**2) + phi_dnv1(j+1)*zz_jp1/dhs(k) + 2.0*pi*phi_dnv2(j+1)*zz_jp1
306  y_int(n) = at_j + (at_jp1-at_j)/dzp * dz
307 
308 
309 ! y0_int(n) = phi_dn0(j) + (phi_dn0(j+1) - phi_dn0(j))/dzp * dz
310 ! y1_int(n) = phi_dn1(j) + (phi_dn1(j+1) - phi_dn1(j))/dzp * dz
311 ! y2_int(n) = phi_dn2(j) + (phi_dn2(j+1) - phi_dn2(j))/dzp * dz
312 ! y3_int(n) = phi_dn3(j)*(d2**2 - zz**2) + (phi_dn3(j+1)*(d2**2 - zz_jp1**2) - phi_dn3(j)*(d2**2 - zz**2))/dzp * dz
313 ! yv1_int(n) = phi_dnv1(j)*zz + (phi_dnv1(j+1)*zz_jp1 - phi_dnv1(j)*zz)/dzp * dz
314 ! yv2_int(n) = phi_dnv2(j)*zz + (phi_dnv2(j+1)*zz_jp1 - phi_dnv2(j)*zz)/dzp * dz
315 !
316 
317 
318  End If
319 
320  End If
321 
322 
323  End Do
324 
325  !spline integration
326  xlo = x_int(1)
327  xhi = x_int(n)
328 
329  If(n > nmax) Then
330  write(*,*)'Surface Tension code: Increase NMAX in FMT_dFdrho (also in AD Routine!!)'
331  call exit
332  End If
333 
334  call spline(x_int,y_int,n,1.e30,1.e30,y2)
335  call splint_integral(x_int,y_int,y2,n,xlo,xhi,integral)
336 
337 ! call spline ( x_int, y0_int, n, 1.E30, 1.E30, y2 )
338 ! call splint_integral ( x_int, y0_int, y2, n, xlo, xhi, int0 )
339 ! call spline ( x_int, y1_int, n, 1.E30, 1.E30, y2 )
340 ! call splint_integral ( x_int, y1_int, y2, n, xlo, xhi, int1 )
341 ! call spline ( x_int, y2_int, n, 1.E30, 1.E30, y2 )
342 ! call splint_integral ( x_int, y2_int, y2, n, xlo, xhi, int2 )
343 ! call spline ( x_int, y3_int, n, 1.E30, 1.E30, y2 )
344 ! call splint_integral ( x_int, y3_int, y2, n, xlo, xhi, int3 )
345 ! call spline ( x_int, yv1_int, n, 1.E30, 1.E30, y2 )
346 ! call splint_integral ( x_int, yv1_int, y2, n, xlo, xhi, intv1 )
347 ! call spline ( x_int, yv2_int, n, 1.E30, 1.E30, y2 )
348 ! call splint_integral ( x_int, yv2_int, y2, n, xlo, xhi, intv2 )
349 !
350 
351  !dF_drho_FMT(i,k) = int0/dhs(k) + 0.5*int1 + PI*dhs(k)*int2 + PI*int3 + intv1/dhs(k) + 2.0*PI*intv2
352  df_drho_fmt(i,k) = integral*parame(k,1)
353 
354 End Do
355 
356 
357 End Subroutine fmt_dfdrho
358 
359 
360 End Module mod_dft_fmt
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