35#include "./base/base_uses.f90"
43 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'manybody_gal21'
59 SUBROUTINE gal21_energy(pot_loc, gal21, r_last_update_pbc, iparticle, jparticle, &
60 cell, particle_set, mm_section)
62 REAL(kind=
dp),
INTENT(OUT) :: pot_loc
64 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
65 INTEGER,
INTENT(IN) :: iparticle, jparticle
70 CHARACTER(LEN=2) :: element_symbol
71 INTEGER :: index_outfile
72 REAL(kind=
dp) :: anglepart, ao, bo, bxy, bz, cosalpha, &
73 drji2, eps, nvec(3), rji(3), sinalpha, &
74 sum_weight, vang, vgaussian, vh, vtt, &
80 element_symbol=element_symbol)
82 IF (element_symbol ==
"O")
THEN
84 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
86 IF (.NOT.
ALLOCATED(gal21%n_vectors))
THEN
87 ALLOCATE (gal21%n_vectors(3,
SIZE(particle_set)))
88 gal21%n_vectors(:, :) = 0.0_dp
91 IF (gal21%express)
THEN
94 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
95 IF (index_outfile > 0)
WRITE (index_outfile, *)
"GCN", gal21%gcn(jparticle)
97 "PRINT%PROGRAM_RUN_INFO")
101 eps = gal21%epsilon1*gal21%gcn(jparticle)*gal21%gcn(jparticle) + gal21%epsilon2*gal21%gcn(jparticle) + gal21%epsilon3
102 bxy = gal21%bxy1 + gal21%bxy2*gal21%gcn(jparticle)
103 bz = gal21%bz1 + gal21%bz2*gal21%gcn(jparticle)
110 IF (gal21%n_vectors(1, jparticle) == 0.0_dp .AND. &
111 gal21%n_vectors(2, jparticle) == 0.0_dp .AND. &
112 gal21%n_vectors(3, jparticle) == 0.0_dp)
THEN
113 gal21%n_vectors(:, jparticle) = normale(gal21, r_last_update_pbc, jparticle, &
118 nvec(:) = gal21%n_vectors(:, jparticle)
121 sum_weight = somme(gal21, r_last_update_pbc, iparticle, particle_set, cell)
124 weight = exp(-norm2(rji)/gal21%r1)
129 CALL angular(anglepart, vh, gal21, r_last_update_pbc, iparticle, jparticle, cell, particle_set, nvec, &
133 IF (weight /= 0)
THEN
134 vang = weight*weight*anglepart/sum_weight
135 IF (gal21%express)
THEN
138 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
139 IF (index_outfile > 0)
WRITE (index_outfile, *)
"Fermi", weight*weight/sum_weight
141 "PRINT%PROGRAM_RUN_INFO")
148 drji2 = dot_product(rji, rji)
151 cosalpha = dot_product(rji, nvec)/sqrt(drji2)
152 IF (cosalpha < -1.0_dp) cosalpha = -1.0_dp
153 IF (cosalpha > +1.0_dp) cosalpha = +1.0_dp
154 sinalpha = sin(acos(cosalpha))
157 vgaussian = -1.0_dp*eps*exp(-bz*drji2*cosalpha*cosalpha &
158 - bxy*drji2*sinalpha*sinalpha)
161 ao = gal21%AO1 + gal21%AO2*gal21%gcn(jparticle)
162 bo = gal21%BO1 + gal21%BO2*gal21%gcn(jparticle)
165 vtt = ao*exp(-bo*sqrt(drji2)) - (1.0 - exp(-bo*sqrt(drji2)) &
166 - bo*sqrt(drji2)*exp(-bo*sqrt(drji2)) &
167 - (((bo*sqrt(drji2))**2)/2)*exp(-bo*sqrt(drji2)) &
168 - (((bo*sqrt(drji2))**3)/6)*exp(-bo*sqrt(drji2)) &
169 - (((bo*sqrt(drji2))**4)/24)*exp(-bo*sqrt(drji2)) &
170 - (((bo*sqrt(drji2))**5)/120)*exp(-bo*sqrt(drji2)) &
171 - (((bo*sqrt(drji2))**6)/720)*exp(-bo*sqrt(drji2))) &
172 *gal21%c/(sqrt(drji2)**6)
175 IF (gal21%express)
THEN
178 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
179 IF (index_outfile > 0)
WRITE (index_outfile, *)
"Gau", -1.0_dp*exp(-bz*drji2*cosalpha*cosalpha &
180 - bxy*drji2*sinalpha*sinalpha)
181 IF (weight == 0 .AND. index_outfile > 0)
WRITE (index_outfile, *)
"Fermi 0"
182 IF (index_outfile > 0)
WRITE (index_outfile, *)
"expO", exp(-bo*sqrt(drji2))
183 IF (index_outfile > 0)
WRITE (index_outfile, *)
"cstpart", -(1.0 - exp(-bo*sqrt(drji2)) &
184 - bo*sqrt(drji2)*exp(-bo*sqrt(drji2)) &
185 - (((bo*sqrt(drji2))**2)/2)*exp(-bo*sqrt(drji2)) &
186 - (((bo*sqrt(drji2))**3)/6)*exp(-bo*sqrt(drji2)) &
187 - (((bo*sqrt(drji2))**4)/24)*exp(-bo*sqrt(drji2)) &
188 - (((bo*sqrt(drji2))**5)/120)*exp(-bo*sqrt(drji2)) &
189 - (((bo*sqrt(drji2))**6)/720)*exp(-bo*sqrt(drji2))) &
190 *gal21%c/(sqrt(drji2)**6)
191 IF (index_outfile > 0)
WRITE (index_outfile, *)
"params_lin_eps", gal21%epsilon1, gal21%epsilon2, gal21%epsilon3
192 IF (index_outfile > 0)
WRITE (index_outfile, *)
"params_lin_A0", ao
194 "PRINT%PROGRAM_RUN_INFO")
197 pot_loc = vgaussian + vang + vtt + vh
215 FUNCTION normale(gal21, r_last_update_pbc, jparticle, particle_set, cell)
217 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
218 INTEGER,
INTENT(IN) :: jparticle
221 REAL(kind=
dp) :: normale(3)
223 CHARACTER(LEN=2) :: element_symbol_k
224 INTEGER :: kparticle, natom
225 REAL(kind=
dp) :: drjk, rjk(3)
227 natom =
SIZE(particle_set)
230 DO kparticle = 1, natom
231 IF (kparticle == jparticle) cycle
232 CALL get_atomic_kind(atomic_kind=particle_set(kparticle)%atomic_kind, &
233 element_symbol=element_symbol_k)
235 IF (element_symbol_k /= gal21%met1 .AND. element_symbol_k /= gal21%met2) cycle
236 rjk(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(kparticle)%r(:), cell)
239 IF (drjk > gal21%rcutsq) cycle
241 normale(:) = normale(:) - rjk(:)/(drjk*drjk*drjk*drjk*drjk)
245 normale(:) = normale(:)/norm2(normale)
259 FUNCTION somme(gal21, r_last_update_pbc, iparticle, particle_set, cell)
261 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
262 INTEGER,
INTENT(IN) :: iparticle
265 REAL(kind=
dp) :: somme
267 CHARACTER(LEN=2) :: element_symbol_k
268 INTEGER :: kparticle, natom
269 REAL(kind=
dp) :: rki(3)
271 natom =
SIZE(particle_set)
274 DO kparticle = 1, natom
275 CALL get_atomic_kind(atomic_kind=particle_set(kparticle)%atomic_kind, &
276 element_symbol=element_symbol_k)
278 IF (element_symbol_k /= gal21%met1 .AND. element_symbol_k /= gal21%met2) cycle
279 rki(:) =
pbc(r_last_update_pbc(kparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
281 IF (norm2(rki) > gal21%rcutsq) cycle
283 IF (element_symbol_k == gal21%met1) somme = somme + exp(-norm2(rki)/gal21%r1)
284 IF (element_symbol_k == gal21%met2) somme = somme + exp(-norm2(rki)/gal21%r2)
305 SUBROUTINE angular(anglepart, VH, gal21, r_last_update_pbc, iparticle, jparticle, cell, &
306 particle_set, nvec, energy, mm_section)
307 REAL(kind=
dp) :: anglepart, vh
309 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
310 INTEGER,
INTENT(IN) :: iparticle, jparticle
313 REAL(kind=
dp),
DIMENSION(3) :: nvec
317 CHARACTER(LEN=2) :: element_symbol
318 INTEGER :: count_h, iatom, index_h1, index_h2, &
320 REAL(kind=
dp) :: a1, a2, a3, a4, bh, costheta, &
321 h_max_dist, rih(3), rih1(3), rih2(3), &
322 rix(3), rjh1(3), rjh2(3), theta
329 natom =
SIZE(particle_set)
333 element_symbol=element_symbol)
334 IF (element_symbol /=
"H") cycle
335 rih(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(iatom)%r(:), cell)
336 IF (norm2(rih) >= h_max_dist) cycle
337 count_h = count_h + 1
338 IF (count_h == 1)
THEN
340 ELSE IF (count_h == 2)
THEN
346 IF (count_h /= 2)
THEN
347 CALL cp_abort(__location__, &
351 a1 = gal21%a11 + gal21%a12*gal21%gcn(jparticle) + gal21%a13*gal21%gcn(jparticle)*gal21%gcn(jparticle)
352 a2 = gal21%a21 + gal21%a22*gal21%gcn(jparticle) + gal21%a23*gal21%gcn(jparticle)*gal21%gcn(jparticle)
353 a3 = gal21%a31 + gal21%a32*gal21%gcn(jparticle) + gal21%a33*gal21%gcn(jparticle)*gal21%gcn(jparticle)
354 a4 = gal21%a41 + gal21%a42*gal21%gcn(jparticle) + gal21%a43*gal21%gcn(jparticle)*gal21%gcn(jparticle)
356 rih1(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
357 rih2(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
358 rix(:) = rih1(:) + rih2(:)
359 costheta = dot_product(rix, nvec)/norm2(rix)
360 IF (costheta < -1.0_dp) costheta = -1.0_dp
361 IF (costheta > +1.0_dp) costheta = +1.0_dp
362 theta = acos(costheta)
363 anglepart = a1*costheta + a2*cos(2.0_dp*theta) + a3*cos(3.0_dp*theta) &
364 + a4*cos(4.0_dp*theta)
366 bh = gal21%BH1 + gal21%gcn(jparticle)*gal21%BH2
368 rjh1(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
369 rjh2(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
370 vh = (gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)*(exp(-bh*norm2(rjh1)) + exp(-bh*norm2(rjh2)))
373 IF (gal21%express .AND. energy)
THEN
376 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
378 IF (index_outfile > 0)
WRITE (index_outfile, *)
"Fourier", costheta, cos(2.0_dp*theta), cos(3.0_dp*theta), &
380 IF (index_outfile > 0)
WRITE (index_outfile, *)
"H_rep", exp(-bh*norm2(rjh1)) + &
384 "PRINT%PROGRAM_RUN_INFO")
387 END SUBROUTINE angular
402 SUBROUTINE gal21_forces(gal21, r_last_update_pbc, iparticle, jparticle, f_nonbond, pv_nonbond, &
403 use_virial, cell, particle_set)
405 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
406 INTEGER,
INTENT(IN) :: iparticle, jparticle
407 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond, pv_nonbond
408 LOGICAL,
INTENT(IN) :: use_virial
412 CHARACTER(LEN=2) :: element_symbol
413 REAL(kind=
dp) :: anglepart, ao, bo, bxy, bz, cosalpha, dgauss(3), drji, drjicosalpha(3), &
414 drjisinalpha(3), dtt(3), dweight(3), eps, nvec(3), prefactor, rji(3), rji_hat(3), &
415 sinalpha, sum_weight, vgaussian, vh, weight
418 CALL get_atomic_kind(atomic_kind=particle_set(iparticle)%atomic_kind, &
419 element_symbol=element_symbol)
421 IF (element_symbol ==
"O")
THEN
423 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
425 rji_hat(:) = rji(:)/drji
427 IF (.NOT.
ALLOCATED(gal21%n_vectors))
THEN
428 ALLOCATE (gal21%n_vectors(3,
SIZE(particle_set)))
429 gal21%n_vectors(:, :) = 0.0_dp
433 eps = gal21%epsilon1*gal21%gcn(jparticle)*gal21%gcn(jparticle) + gal21%epsilon2*gal21%gcn(jparticle) + gal21%epsilon3
434 bxy = gal21%bxy1 + gal21%bxy2*gal21%gcn(jparticle)
435 bz = gal21%bz1 + gal21%bz2*gal21%gcn(jparticle)
441 IF (gal21%n_vectors(1, jparticle) == 0.0_dp .AND. &
442 gal21%n_vectors(2, jparticle) == 0.0_dp .AND. &
443 gal21%n_vectors(3, jparticle) == 0.0_dp)
THEN
444 gal21%n_vectors(:, jparticle) = normale(gal21, r_last_update_pbc, jparticle, &
448 nvec(:) = gal21%n_vectors(:, jparticle)
451 sum_weight = somme(gal21, r_last_update_pbc, iparticle, particle_set, cell)
454 weight = exp(-drji/gal21%r1)
455 dweight(:) = 1.0_dp/gal21%r1*weight*rji_hat(:)
461 CALL angular(anglepart, vh, gal21, r_last_update_pbc, iparticle, jparticle, cell, particle_set, nvec, &
465 IF (weight /= 0)
THEN
467 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) + 2.0_dp*dweight(1:3)*weight* &
471 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rji(1)*2.0_dp*dweight(1:3)*weight* &
473 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rji(2)*2.0_dp*dweight(1:3)*weight* &
475 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rji(3)*2.0_dp*dweight(1:3)*weight* &
480 CALL somme_d(gal21, r_last_update_pbc, iparticle, jparticle, &
481 f_nonbond, pv_nonbond, use_virial, particle_set, cell, anglepart, sum_weight)
483 prefactor = (-1.0_dp)*weight*weight/sum_weight
486 CALL angular_d(gal21, r_last_update_pbc, iparticle, jparticle, &
487 f_nonbond, pv_nonbond, use_virial, prefactor, cell, particle_set, nvec)
493 cosalpha = dot_product(rji, nvec)/drji
494 IF (cosalpha < -1.0_dp) cosalpha = -1.0_dp
495 IF (cosalpha > +1.0_dp) cosalpha = +1.0_dp
496 sinalpha = sin(acos(cosalpha))
499 vgaussian = -1.0_dp*eps*exp(-bz*dot_product(rji, rji)*cosalpha*cosalpha &
500 - bxy*dot_product(rji, rji)*sinalpha*sinalpha)
503 drjicosalpha(:) = rji_hat(:)*cosalpha + nvec(:) - cosalpha*rji_hat(:)
504 drjisinalpha(:) = rji_hat(:)*sinalpha - (cosalpha/sinalpha)*(nvec(:) - cosalpha*rji_hat(:))
505 dgauss(:) = (-1.0_dp*bz*2*drji*cosalpha*drjicosalpha - &
506 1.0_dp*bxy*2*drji*sinalpha*drjisinalpha)*vgaussian*(-1.0_dp)
509 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) + dgauss(1:3)
512 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rji(1)*dgauss(1:3)
513 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rji(2)*dgauss(1:3)
514 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rji(3)*dgauss(1:3)
518 ao = gal21%AO1 + gal21%AO2*gal21%gcn(jparticle)
519 bo = gal21%BO1 + gal21%BO2*gal21%gcn(jparticle)
522 dtt(:) = (-(ao*bo + (bo**7)*gal21%c/720)*exp(-bo*drji) + 6*(gal21%c/drji**7)* &
523 (1.0 - exp(-bo*drji) &
524 - bo*drji*exp(-bo*drji) &
525 - (((bo*drji)**2)/2)*exp(-bo*drji) &
526 - (((bo*drji)**3)/6)*exp(-bo*drji) &
527 - (((bo*drji)**4)/24)*exp(-bo*drji) &
528 - (((bo*drji)**5)/120)*exp(-bo*drji) &
529 - (((bo*drji)**6)/720)*exp(-bo*drji)) &
533 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) - dtt(1:3)
536 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) - rji(1)*dtt(1:3)
537 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) - rji(2)*dtt(1:3)
538 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) - rji(3)*dtt(1:3)
559 SUBROUTINE somme_d(gal21, r_last_update_pbc, iparticle, jparticle, &
560 f_nonbond, pv_nonbond, use_virial, particle_set, cell, anglepart, sum_weight)
562 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
563 INTEGER,
INTENT(IN) :: iparticle, jparticle
564 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond, pv_nonbond
565 LOGICAL,
INTENT(IN) :: use_virial
568 REAL(kind=
dp),
INTENT(IN) :: anglepart, sum_weight
570 CHARACTER(LEN=2) :: element_symbol_k
571 INTEGER :: kparticle, natom
572 REAL(kind=
dp) :: drki, dwdr(3), rji(3), rki(3), &
573 rki_hat(3), weight_rji
575 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
576 weight_rji = exp(-norm2(rji)/gal21%r1)
578 natom =
SIZE(particle_set)
579 DO kparticle = 1, natom
580 CALL get_atomic_kind(atomic_kind=particle_set(kparticle)%atomic_kind, &
581 element_symbol=element_symbol_k)
583 IF (element_symbol_k /= gal21%met1 .AND. element_symbol_k /= gal21%met2) cycle
584 rki(:) =
pbc(r_last_update_pbc(kparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
586 IF (norm2(rki) > gal21%rcutsq) cycle
588 rki_hat(:) = rki(:)/drki
591 IF (element_symbol_k == gal21%met1) dwdr(:) = (-1.0_dp)*(1.0_dp/gal21%r1)*exp(-drki/gal21%r1)*rki_hat(:)
592 IF (element_symbol_k == gal21%met2) dwdr(:) = (-1.0_dp)*(1.0_dp/gal21%r2)*exp(-drki/gal21%r2)*rki_hat(:)
594 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) + dwdr(1:3)*weight_rji &
595 *weight_rji*anglepart/(sum_weight**2)
598 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rki(1)*dwdr(1:3)*weight_rji &
599 *weight_rji*anglepart/(sum_weight**2)
600 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rki(2)*dwdr(1:3)*weight_rji &
601 *weight_rji*anglepart/(sum_weight**2)
602 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rki(3)*dwdr(1:3)*weight_rji &
603 *weight_rji*anglepart/(sum_weight**2)
608 END SUBROUTINE somme_d
624 SUBROUTINE angular_d(gal21, r_last_update_pbc, iparticle, jparticle, f_nonbond, &
625 pv_nonbond, use_virial, prefactor, cell, particle_set, nvec)
627 TYPE(
pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
628 INTEGER,
INTENT(IN) :: iparticle, jparticle
629 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond, pv_nonbond
630 LOGICAL,
INTENT(IN) :: use_virial
631 REAL(kind=
dp),
INTENT(IN) :: prefactor
634 REAL(kind=
dp),
DIMENSION(3) :: nvec
636 CHARACTER(LEN=2) :: element_symbol
637 INTEGER :: count_h, iatom, index_h1, index_h2, natom
638 REAL(kind=
dp) :: a1, a2, a3, a4, bh, costheta, &
639 dsumdtheta, h_max_dist, theta
640 REAL(kind=
dp),
DIMENSION(3) :: dangular, dcostheta, rih, rih1, rih2, &
641 rix, rix_hat, rjh1, rjh2, rji, rji_hat
647 natom =
SIZE(particle_set)
651 element_symbol=element_symbol)
652 IF (element_symbol /=
"H") cycle
653 rih(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(iatom)%r(:), cell)
654 IF (norm2(rih) >= h_max_dist) cycle
655 count_h = count_h + 1
656 IF (count_h == 1)
THEN
658 ELSE IF (count_h == 2)
THEN
664 IF (count_h /= 2)
THEN
665 CALL cp_abort(__location__, &
669 a1 = gal21%a11 + gal21%a12*gal21%gcn(jparticle) + gal21%a13*gal21%gcn(jparticle)*gal21%gcn(jparticle)
670 a2 = gal21%a21 + gal21%a22*gal21%gcn(jparticle) + gal21%a23*gal21%gcn(jparticle)*gal21%gcn(jparticle)
671 a3 = gal21%a31 + gal21%a32*gal21%gcn(jparticle) + gal21%a33*gal21%gcn(jparticle)*gal21%gcn(jparticle)
672 a4 = gal21%a41 + gal21%a42*gal21%gcn(jparticle) + gal21%a43*gal21%gcn(jparticle)*gal21%gcn(jparticle)
674 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
675 rji_hat(:) = rji(:)/norm2(rji)
678 rih1(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
679 rih2(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
680 rix(:) = rih1(:) + rih2(:)
681 rix_hat(:) = rix(:)/norm2(rix)
682 costheta = dot_product(rix, nvec)/norm2(rix)
683 IF (costheta < -1.0_dp) costheta = -1.0_dp
684 IF (costheta > +1.0_dp) costheta = +1.0_dp
685 theta = acos(costheta)
688 dsumdtheta = -1.0_dp*a1*sin(theta) - a2*2.0_dp*sin(2.0_dp*theta) - &
689 a3*3.0_dp*sin(3.0_dp*theta) - a4*4.0_dp*sin(4.0_dp*theta)
690 dcostheta(:) = (1.0_dp/norm2(rix))*(nvec(:) - costheta*rix_hat(:))
691 dangular(:) = prefactor*dsumdtheta*(-1.0_dp/sin(theta))*dcostheta(:)
694 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) - dangular(1:3)*2.0_dp
695 f_nonbond(1:3, index_h1) = f_nonbond(1:3, index_h1) + dangular(1:3)
696 f_nonbond(1:3, index_h2) = f_nonbond(1:3, index_h2) + dangular(1:3)
699 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rix(1)*dangular(1:3)
700 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rix(2)*dangular(1:3)
701 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rix(3)*dangular(1:3)
704 bh = gal21%BH1 + gal21%gcn(jparticle)*gal21%BH2
706 rjh1(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
707 f_nonbond(1:3, index_h1) = f_nonbond(1:3, index_h1) + (gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
708 bh*exp(-bh*norm2(rjh1))*rjh1(:)/norm2(rjh1)
711 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rjh1(1)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
712 bh*exp(-bh*norm2(rjh1))) &
714 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rjh1(2)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
715 bh*exp(-bh*norm2(rjh1))) &
717 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rjh1(3)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
718 bh*exp(-bh*norm2(rjh1))) &
722 rjh2(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
723 f_nonbond(1:3, index_h2) = f_nonbond(1:3, index_h2) + ((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
724 bh*exp(-bh*norm2(rjh2))) &
728 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rjh2(1)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
729 bh*exp(-bh*norm2(rjh2))) &
731 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rjh2(2)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
732 bh*exp(-bh*norm2(rjh2))) &
734 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rjh2(3)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
735 bh*exp(-bh*norm2(rjh2))) &
739 END SUBROUTINE angular_d
752 glob_loc_list_a, cell)
755 INTEGER,
DIMENSION(:, :),
POINTER :: glob_loc_list
756 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: glob_cell_v
757 INTEGER,
DIMENSION(:),
POINTER :: glob_loc_list_a
760 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_gal21_arrays'
762 INTEGER :: handle, i, iend, igrp, ikind, ilist, &
763 ipair, istart, jkind, nkinds, npairs, &
765 INTEGER,
DIMENSION(:),
POINTER :: work_list, work_list2
766 INTEGER,
DIMENSION(:, :),
POINTER ::
list
767 REAL(kind=
dp),
DIMENSION(3) :: cell_v, cvi
768 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: rwork_list
772 cpassert(.NOT.
ASSOCIATED(glob_loc_list))
773 cpassert(.NOT.
ASSOCIATED(glob_loc_list_a))
774 cpassert(.NOT.
ASSOCIATED(glob_cell_v))
775 CALL timeset(routinen, handle)
777 nkinds =
SIZE(potparm%pot, 1)
778 DO ilist = 1, nonbonded%nlists
779 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
780 npairs = neighbor_kind_pair%npairs
781 IF (npairs == 0) cycle
782 kind_group_loop1:
DO igrp = 1, neighbor_kind_pair%ngrp_kind
783 istart = neighbor_kind_pair%grp_kind_start(igrp)
784 iend = neighbor_kind_pair%grp_kind_end(igrp)
785 ikind = neighbor_kind_pair%ij_kind(1, igrp)
786 jkind = neighbor_kind_pair%ij_kind(2, igrp)
787 pot => potparm%pot(ikind, jkind)%pot
788 npairs = iend - istart + 1
789 IF (pot%no_mb) cycle kind_group_loop1
790 DO i = 1,
SIZE(pot%type)
791 IF (pot%type(i) ==
gal21_type) npairs_tot = npairs_tot + npairs
793 END DO kind_group_loop1
795 ALLOCATE (work_list(npairs_tot))
796 ALLOCATE (work_list2(npairs_tot))
797 ALLOCATE (glob_loc_list(2, npairs_tot))
798 ALLOCATE (glob_cell_v(3, npairs_tot))
801 DO ilist = 1, nonbonded%nlists
802 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
803 npairs = neighbor_kind_pair%npairs
804 IF (npairs == 0) cycle
805 kind_group_loop2:
DO igrp = 1, neighbor_kind_pair%ngrp_kind
806 istart = neighbor_kind_pair%grp_kind_start(igrp)
807 iend = neighbor_kind_pair%grp_kind_end(igrp)
808 ikind = neighbor_kind_pair%ij_kind(1, igrp)
809 jkind = neighbor_kind_pair%ij_kind(2, igrp)
810 list => neighbor_kind_pair%list
811 cvi = neighbor_kind_pair%cell_vector
812 pot => potparm%pot(ikind, jkind)%pot
813 npairs = iend - istart + 1
814 IF (pot%no_mb) cycle kind_group_loop2
815 cell_v = matmul(cell%hmat, cvi)
816 DO i = 1,
SIZE(pot%type)
820 glob_loc_list(:, npairs_tot + ipair) =
list(:, istart - 1 + ipair)
821 glob_cell_v(1:3, npairs_tot + ipair) = cell_v(1:3)
823 npairs_tot = npairs_tot + npairs
826 END DO kind_group_loop2
829 CALL sort(glob_loc_list(1, :), npairs_tot, work_list)
830 DO ipair = 1, npairs_tot
831 work_list2(ipair) = glob_loc_list(2, work_list(ipair))
833 glob_loc_list(2, :) = work_list2
834 DEALLOCATE (work_list2)
835 ALLOCATE (rwork_list(3, npairs_tot))
836 DO ipair = 1, npairs_tot
837 rwork_list(:, ipair) = glob_cell_v(:, work_list(ipair))
839 glob_cell_v = rwork_list
840 DEALLOCATE (rwork_list)
841 DEALLOCATE (work_list)
842 ALLOCATE (glob_loc_list_a(npairs_tot))
843 glob_loc_list_a = glob_loc_list(1, :)
844 CALL timestop(handle)
854 INTEGER,
DIMENSION(:, :),
POINTER :: glob_loc_list
855 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: glob_cell_v
856 INTEGER,
DIMENSION(:),
POINTER :: glob_loc_list_a
858 IF (
ASSOCIATED(glob_loc_list))
THEN
859 DEALLOCATE (glob_loc_list)
861 IF (
ASSOCIATED(glob_loc_list_a))
THEN
862 DEALLOCATE (glob_loc_list_a)
864 IF (
ASSOCIATED(glob_cell_v))
THEN
865 DEALLOCATE (glob_cell_v)
881 INTEGER,
INTENT(INOUT) :: nr_ions
884 LOGICAL,
INTENT(IN) :: print_oh, print_h3o, print_o
891 CALL para_env%sum(nr_ions)
897 IF (iw > 0 .AND. nr_ions > 0 .AND. print_oh)
THEN
898 WRITE (iw,
'(/,A,T71,I10,/)')
" gal21: number of OH- ions at surface", nr_ions
900 IF (iw > 0 .AND. nr_ions > 0 .AND. print_h3o)
THEN
901 WRITE (iw,
'(/,A,T71,I10,/)')
" gal21: number of H3O+ ions at surface", nr_ions
903 IF (iw > 0 .AND. nr_ions > 0 .AND. print_o)
THEN
904 WRITE (iw,
'(/,A,T71,I10,/)')
" gal21: number of O^2- ions at surface", nr_ions
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
Define the neighbor list data types and the corresponding functionality.
Defines the basic variable types.
integer, parameter, public dp
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Implementation of the GAL21 potential.
subroutine, public destroy_gal21_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
subroutine, public gal21_forces(gal21, r_last_update_pbc, iparticle, jparticle, f_nonbond, pv_nonbond, use_virial, cell, particle_set)
forces generated by the GAL2119 potential
subroutine, public setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public print_nr_ions_gal21(nr_ions, mm_section, para_env, print_oh, print_h3o, print_o)
prints the number of OH- ions or H3O+ ions near surface
subroutine, public gal21_energy(pot_loc, gal21, r_last_update_pbc, iparticle, jparticle, cell, particle_set, mm_section)
Main part of the energy evaluation of GAL2119.
Interface to the message passing library MPI.
integer, parameter, public gal21_type
Define the data structure for the particle information.
All kind of helpful little routines.
Type defining parameters related to the simulation cell.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment