24 neighbor_kind_pairs_type
31 pair_potential_pp_type,&
32 pair_potential_single_type
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
63 TYPE(gal21_pot_type),
POINTER :: gal21
64 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
65 INTEGER,
INTENT(IN) :: iparticle, jparticle
66 TYPE(cell_type),
POINTER :: cell
67 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
68 TYPE(section_vals_type),
POINTER :: mm_section
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, &
76 TYPE(cp_logger_type),
POINTER :: logger
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)
109 IF (gal21%n_vectors(1, jparticle) == 0.0_dp .AND. &
110 gal21%n_vectors(2, jparticle) == 0.0_dp .AND. &
111 gal21%n_vectors(3, jparticle) == 0.0_dp)
THEN
112 gal21%n_vectors(:, jparticle) = normale(gal21, r_last_update_pbc, jparticle, &
116 nvec(:) = gal21%n_vectors(:, jparticle)
119 sum_weight = somme(gal21, r_last_update_pbc, iparticle, particle_set, cell)
122 weight = exp(-sqrt(dot_product(rji, rji))/gal21%r1)
127 CALL angular(anglepart, vh, gal21, r_last_update_pbc, iparticle, jparticle, cell, particle_set, nvec, &
131 IF (weight /= 0)
THEN
132 vang = weight*weight*anglepart/sum_weight
133 IF (gal21%express)
THEN
136 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
137 IF (index_outfile > 0)
WRITE (index_outfile, *)
"Fermi", weight*weight/sum_weight
139 "PRINT%PROGRAM_RUN_INFO")
146 drji2 = dot_product(rji, rji)
149 cosalpha = dot_product(rji, nvec)/sqrt(drji2)
150 IF (cosalpha < -1.0_dp) cosalpha = -1.0_dp
151 IF (cosalpha > +1.0_dp) cosalpha = +1.0_dp
152 sinalpha = sin(acos(cosalpha))
155 vgaussian = -1.0_dp*eps*exp(-bz*drji2*cosalpha*cosalpha &
156 - bxy*drji2*sinalpha*sinalpha)
159 ao = gal21%AO1 + gal21%AO2*gal21%gcn(jparticle)
160 bo = gal21%BO1 + gal21%BO2*gal21%gcn(jparticle)
163 vtt = ao*exp(-bo*sqrt(drji2)) - (1.0 - exp(-bo*sqrt(drji2)) &
164 - bo*sqrt(drji2)*exp(-bo*sqrt(drji2)) &
165 - (((bo*sqrt(drji2))**2)/2)*exp(-bo*sqrt(drji2)) &
166 - (((bo*sqrt(drji2))**3)/6)*exp(-bo*sqrt(drji2)) &
167 - (((bo*sqrt(drji2))**4)/24)*exp(-bo*sqrt(drji2)) &
168 - (((bo*sqrt(drji2))**5)/120)*exp(-bo*sqrt(drji2)) &
169 - (((bo*sqrt(drji2))**6)/720)*exp(-bo*sqrt(drji2))) &
170 *gal21%c/(sqrt(drji2)**6)
173 IF (gal21%express)
THEN
176 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
177 IF (index_outfile > 0)
WRITE (index_outfile, *)
"Gau", -1.0_dp*exp(-bz*drji2*cosalpha*cosalpha &
178 - bxy*drji2*sinalpha*sinalpha)
179 IF (weight == 0 .AND. index_outfile > 0)
WRITE (index_outfile, *)
"Fermi 0"
180 IF (index_outfile > 0)
WRITE (index_outfile, *)
"expO", exp(-bo*sqrt(drji2))
181 IF (index_outfile > 0)
WRITE (index_outfile, *)
"cstpart", -(1.0 - exp(-bo*sqrt(drji2)) &
182 - bo*sqrt(drji2)*exp(-bo*sqrt(drji2)) &
183 - (((bo*sqrt(drji2))**2)/2)*exp(-bo*sqrt(drji2)) &
184 - (((bo*sqrt(drji2))**3)/6)*exp(-bo*sqrt(drji2)) &
185 - (((bo*sqrt(drji2))**4)/24)*exp(-bo*sqrt(drji2)) &
186 - (((bo*sqrt(drji2))**5)/120)*exp(-bo*sqrt(drji2)) &
187 - (((bo*sqrt(drji2))**6)/720)*exp(-bo*sqrt(drji2))) &
188 *gal21%c/(sqrt(drji2)**6)
189 IF (index_outfile > 0)
WRITE (index_outfile, *)
"params_lin_eps", gal21%epsilon1, gal21%epsilon2, gal21%epsilon3
190 IF (index_outfile > 0)
WRITE (index_outfile, *)
"params_lin_A0", ao
192 "PRINT%PROGRAM_RUN_INFO")
195 pot_loc = vgaussian + vang + vtt + vh
213 FUNCTION normale(gal21, r_last_update_pbc, jparticle, particle_set, cell)
214 TYPE(gal21_pot_type),
POINTER :: gal21
215 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
216 INTEGER,
INTENT(IN) :: jparticle
217 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
218 TYPE(cell_type),
POINTER :: cell
219 REAL(kind=
dp) :: normale(3)
221 CHARACTER(LEN=2) :: element_symbol_k
222 INTEGER :: kparticle, natom
223 REAL(kind=
dp) :: drjk, rjk(3)
225 natom =
SIZE(particle_set)
228 DO kparticle = 1, natom
229 IF (kparticle == jparticle) cycle
230 CALL get_atomic_kind(atomic_kind=particle_set(kparticle)%atomic_kind, &
231 element_symbol=element_symbol_k)
232 IF (element_symbol_k /= gal21%met1 .AND. element_symbol_k /= gal21%met2) cycle
233 rjk(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(kparticle)%r(:), cell)
234 drjk = sqrt(dot_product(rjk, rjk))
235 IF (drjk > gal21%rcutsq) cycle
236 normale(:) = normale(:) - rjk(:)/(drjk*drjk*drjk*drjk*drjk)
240 normale(:) = normale(:)/sqrt(dot_product(normale, normale))
254 FUNCTION somme(gal21, r_last_update_pbc, iparticle, particle_set, cell)
255 TYPE(gal21_pot_type),
POINTER :: gal21
256 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
257 INTEGER,
INTENT(IN) :: iparticle
258 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
259 TYPE(cell_type),
POINTER :: cell
260 REAL(kind=
dp) :: somme
262 CHARACTER(LEN=2) :: element_symbol_k
263 INTEGER :: kparticle, natom
264 REAL(kind=
dp) :: rki(3)
266 natom =
SIZE(particle_set)
269 DO kparticle = 1, natom
270 CALL get_atomic_kind(atomic_kind=particle_set(kparticle)%atomic_kind, &
271 element_symbol=element_symbol_k)
272 IF (element_symbol_k /= gal21%met1 .AND. element_symbol_k /= gal21%met2) cycle
273 rki(:) =
pbc(r_last_update_pbc(kparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
274 IF (sqrt(dot_product(rki, rki)) > gal21%rcutsq) cycle
275 IF (element_symbol_k == gal21%met1) somme = somme + exp(-sqrt(dot_product(rki, rki))/gal21%r1)
276 IF (element_symbol_k == gal21%met2) somme = somme + exp(-sqrt(dot_product(rki, rki))/gal21%r2)
297 SUBROUTINE angular(anglepart, VH, gal21, r_last_update_pbc, iparticle, jparticle, cell, &
298 particle_set, nvec, energy, mm_section)
299 REAL(kind=
dp) :: anglepart, vh
300 TYPE(gal21_pot_type),
POINTER :: gal21
301 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
302 INTEGER,
INTENT(IN) :: iparticle, jparticle
303 TYPE(cell_type),
POINTER :: cell
304 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
305 REAL(kind=
dp),
DIMENSION(3) :: nvec
307 TYPE(section_vals_type),
POINTER :: mm_section
309 CHARACTER(LEN=2) :: element_symbol
310 INTEGER :: count_h, iatom, index_h1, index_h2, &
312 REAL(kind=
dp) :: a1, a2, a3, a4, bh, costheta, &
313 h_max_dist, rih(3), rih1(3), rih2(3), &
314 rix(3), rjh1(3), rjh2(3), theta
315 TYPE(cp_logger_type),
POINTER :: logger
321 natom =
SIZE(particle_set)
325 element_symbol=element_symbol)
326 IF (element_symbol /=
"H") cycle
327 rih(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(iatom)%r(:), cell)
328 IF (sqrt(dot_product(rih, rih)) >= h_max_dist) cycle
329 count_h = count_h + 1
330 IF (count_h == 1)
THEN
332 ELSEIF (count_h == 2)
THEN
338 IF (count_h /= 2)
THEN
339 CALL cp_abort(__location__, &
340 " Error: Found "//cp_to_string(count_h)//
" H atoms for O atom "//cp_to_string(iparticle))
343 a1 = gal21%a11 + gal21%a12*gal21%gcn(jparticle) + gal21%a13*gal21%gcn(jparticle)*gal21%gcn(jparticle)
344 a2 = gal21%a21 + gal21%a22*gal21%gcn(jparticle) + gal21%a23*gal21%gcn(jparticle)*gal21%gcn(jparticle)
345 a3 = gal21%a31 + gal21%a32*gal21%gcn(jparticle) + gal21%a33*gal21%gcn(jparticle)*gal21%gcn(jparticle)
346 a4 = gal21%a41 + gal21%a42*gal21%gcn(jparticle) + gal21%a43*gal21%gcn(jparticle)*gal21%gcn(jparticle)
348 rih1(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
349 rih2(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
350 rix(:) = rih1(:) + rih2(:)
351 costheta = dot_product(rix, nvec)/sqrt(dot_product(rix, rix))
352 IF (costheta < -1.0_dp) costheta = -1.0_dp
353 IF (costheta > +1.0_dp) costheta = +1.0_dp
354 theta = acos(costheta)
355 anglepart = a1*costheta + a2*cos(2.0_dp*theta) + a3*cos(3.0_dp*theta) &
356 + a4*cos(4.0_dp*theta)
358 bh = gal21%BH1 + gal21%gcn(jparticle)*gal21%BH2
360 rjh1(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
361 rjh2(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
362 vh = (gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)*(exp(-bh*sqrt(dot_product(rjh1, rjh1))) + &
363 exp(-bh*sqrt(dot_product(rjh2, rjh2))))
366 IF (gal21%express .AND. energy)
THEN
369 "PRINT%PROGRAM_RUN_INFO", extension=
".mmLog")
371 IF (index_outfile > 0)
WRITE (index_outfile, *)
"Fourier", costheta, cos(2.0_dp*theta), cos(3.0_dp*theta), &
373 IF (index_outfile > 0)
WRITE (index_outfile, *)
"H_rep", exp(-bh*sqrt(dot_product(rjh1, rjh1))) + &
374 exp(-bh*sqrt(dot_product(rjh2, rjh2)))
378 "PRINT%PROGRAM_RUN_INFO")
396 SUBROUTINE gal21_forces(gal21, r_last_update_pbc, iparticle, jparticle, f_nonbond, pv_nonbond, &
397 use_virial, cell, particle_set)
398 TYPE(gal21_pot_type),
POINTER :: gal21
399 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
400 INTEGER,
INTENT(IN) :: iparticle, jparticle
401 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond, pv_nonbond
402 LOGICAL,
INTENT(IN) :: use_virial
403 TYPE(cell_type),
POINTER :: cell
404 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
406 CHARACTER(LEN=2) :: element_symbol
407 REAL(kind=
dp) :: anglepart, ao, bo, bxy, bz, cosalpha, dgauss(3), drji, drjicosalpha(3), &
408 drjisinalpha(3), dtt(3), dweight(3), eps, nvec(3), prefactor, rji(3), rji_hat(3), &
409 sinalpha, sum_weight, vgaussian, vh, weight
410 TYPE(section_vals_type),
POINTER :: mm_section
412 CALL get_atomic_kind(atomic_kind=particle_set(iparticle)%atomic_kind, &
413 element_symbol=element_symbol)
415 IF (element_symbol ==
"O")
THEN
417 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
418 drji = sqrt(dot_product(rji, rji))
419 rji_hat(:) = rji(:)/drji
421 IF (.NOT.
ALLOCATED(gal21%n_vectors))
THEN
422 ALLOCATE (gal21%n_vectors(3,
SIZE(particle_set)))
423 gal21%n_vectors(:, :) = 0.0_dp
427 eps = gal21%epsilon1*gal21%gcn(jparticle)*gal21%gcn(jparticle) + gal21%epsilon2*gal21%gcn(jparticle) + gal21%epsilon3
428 bxy = gal21%bxy1 + gal21%bxy2*gal21%gcn(jparticle)
429 bz = gal21%bz1 + gal21%bz2*gal21%gcn(jparticle)
434 IF (gal21%n_vectors(1, jparticle) == 0.0_dp .AND. &
435 gal21%n_vectors(2, jparticle) == 0.0_dp .AND. &
436 gal21%n_vectors(3, jparticle) == 0.0_dp)
THEN
437 gal21%n_vectors(:, jparticle) = normale(gal21, r_last_update_pbc, jparticle, &
441 nvec(:) = gal21%n_vectors(:, jparticle)
444 sum_weight = somme(gal21, r_last_update_pbc, iparticle, particle_set, cell)
447 weight = exp(-drji/gal21%r1)
448 dweight(:) = 1.0_dp/gal21%r1*weight*rji_hat(:)
454 CALL angular(anglepart, vh, gal21, r_last_update_pbc, iparticle, jparticle, cell, particle_set, nvec, &
458 IF (weight /= 0)
THEN
460 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) + 2.0_dp*dweight(1:3)*weight* &
464 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rji(1)*2.0_dp*dweight(1:3)*weight* &
466 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rji(2)*2.0_dp*dweight(1:3)*weight* &
468 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rji(3)*2.0_dp*dweight(1:3)*weight* &
473 CALL somme_d(gal21, r_last_update_pbc, iparticle, jparticle, &
474 f_nonbond, pv_nonbond, use_virial, particle_set, cell, anglepart, sum_weight)
476 prefactor = (-1.0_dp)*weight*weight/sum_weight
479 CALL angular_d(gal21, r_last_update_pbc, iparticle, jparticle, &
480 f_nonbond, pv_nonbond, use_virial, prefactor, cell, particle_set, nvec)
486 cosalpha = dot_product(rji, nvec)/drji
487 IF (cosalpha < -1.0_dp) cosalpha = -1.0_dp
488 IF (cosalpha > +1.0_dp) cosalpha = +1.0_dp
489 sinalpha = sin(acos(cosalpha))
492 vgaussian = -1.0_dp*eps*exp(-bz*dot_product(rji, rji)*cosalpha*cosalpha &
493 - bxy*dot_product(rji, rji)*sinalpha*sinalpha)
496 drjicosalpha(:) = rji_hat(:)*cosalpha + nvec(:) - cosalpha*rji_hat(:)
497 drjisinalpha(:) = rji_hat(:)*sinalpha - (cosalpha/sinalpha)*(nvec(:) - cosalpha*rji_hat(:))
498 dgauss(:) = (-1.0_dp*bz*2*drji*cosalpha*drjicosalpha - &
499 1.0_dp*bxy*2*drji*sinalpha*drjisinalpha)*vgaussian*(-1.0_dp)
502 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) + dgauss(1:3)
505 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rji(1)*dgauss(1:3)
506 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rji(2)*dgauss(1:3)
507 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rji(3)*dgauss(1:3)
511 ao = gal21%AO1 + gal21%AO2*gal21%gcn(jparticle)
512 bo = gal21%BO1 + gal21%BO2*gal21%gcn(jparticle)
515 dtt(:) = (-(ao*bo + (bo**7)*gal21%c/720)*exp(-bo*drji) + 6*(gal21%c/drji**7)* &
516 (1.0 - exp(-bo*drji) &
517 - bo*drji*exp(-bo*drji) &
518 - (((bo*drji)**2)/2)*exp(-bo*drji) &
519 - (((bo*drji)**3)/6)*exp(-bo*drji) &
520 - (((bo*drji)**4)/24)*exp(-bo*drji) &
521 - (((bo*drji)**5)/120)*exp(-bo*drji) &
522 - (((bo*drji)**6)/720)*exp(-bo*drji)) &
526 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) - dtt(1:3)
529 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) - rji(1)*dtt(1:3)
530 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) - rji(2)*dtt(1:3)
531 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) - rji(3)*dtt(1:3)
552 SUBROUTINE somme_d(gal21, r_last_update_pbc, iparticle, jparticle, &
553 f_nonbond, pv_nonbond, use_virial, particle_set, cell, anglepart, sum_weight)
554 TYPE(gal21_pot_type),
POINTER :: gal21
555 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
556 INTEGER,
INTENT(IN) :: iparticle, jparticle
557 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond, pv_nonbond
558 LOGICAL,
INTENT(IN) :: use_virial
559 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
560 TYPE(cell_type),
POINTER :: cell
561 REAL(kind=
dp),
INTENT(IN) :: anglepart, sum_weight
563 CHARACTER(LEN=2) :: element_symbol_k
564 INTEGER :: kparticle, natom
565 REAL(kind=
dp) :: drki, dwdr(3), rji(3), rki(3), &
566 rki_hat(3), weight_rji
568 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
569 weight_rji = exp(-sqrt(dot_product(rji, rji))/gal21%r1)
571 natom =
SIZE(particle_set)
572 DO kparticle = 1, natom
573 CALL get_atomic_kind(atomic_kind=particle_set(kparticle)%atomic_kind, &
574 element_symbol=element_symbol_k)
575 IF (element_symbol_k /= gal21%met1 .AND. element_symbol_k /= gal21%met2) cycle
576 rki(:) =
pbc(r_last_update_pbc(kparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
577 IF (sqrt(dot_product(rki, rki)) > gal21%rcutsq) cycle
578 drki = sqrt(dot_product(rki, rki))
579 rki_hat(:) = rki(:)/drki
581 IF (element_symbol_k == gal21%met1) dwdr(:) = (-1.0_dp)*(1.0_dp/gal21%r1)*exp(-drki/gal21%r1)*rki_hat(:)
582 IF (element_symbol_k == gal21%met2) dwdr(:) = (-1.0_dp)*(1.0_dp/gal21%r2)*exp(-drki/gal21%r2)*rki_hat(:)
584 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) + dwdr(1:3)*weight_rji &
585 *weight_rji*anglepart/(sum_weight**2)
588 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rki(1)*dwdr(1:3)*weight_rji &
589 *weight_rji*anglepart/(sum_weight**2)
590 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rki(2)*dwdr(1:3)*weight_rji &
591 *weight_rji*anglepart/(sum_weight**2)
592 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rki(3)*dwdr(1:3)*weight_rji &
593 *weight_rji*anglepart/(sum_weight**2)
598 END SUBROUTINE somme_d
614 SUBROUTINE angular_d(gal21, r_last_update_pbc, iparticle, jparticle, f_nonbond, &
615 pv_nonbond, use_virial, prefactor, cell, particle_set, nvec)
616 TYPE(gal21_pot_type),
POINTER :: gal21
617 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
618 INTEGER,
INTENT(IN) :: iparticle, jparticle
619 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond, pv_nonbond
620 LOGICAL,
INTENT(IN) :: use_virial
621 REAL(kind=
dp),
INTENT(IN) :: prefactor
622 TYPE(cell_type),
POINTER :: cell
623 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
624 REAL(kind=
dp),
DIMENSION(3) :: nvec
626 CHARACTER(LEN=2) :: element_symbol
627 INTEGER :: count_h, iatom, index_h1, index_h2, natom
628 REAL(kind=
dp) :: a1, a2, a3, a4, bh, costheta, &
629 dsumdtheta, h_max_dist, theta
630 REAL(kind=
dp),
DIMENSION(3) :: dangular, dcostheta, rih, rih1, rih2, &
631 rix, rix_hat, rjh1, rjh2, rji, rji_hat
637 natom =
SIZE(particle_set)
641 element_symbol=element_symbol)
642 IF (element_symbol /=
"H") cycle
643 rih(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(iatom)%r(:), cell)
644 IF (sqrt(dot_product(rih, rih)) >= h_max_dist) cycle
645 count_h = count_h + 1
646 IF (count_h == 1)
THEN
648 ELSEIF (count_h == 2)
THEN
654 IF (count_h /= 2)
THEN
655 CALL cp_abort(__location__, &
656 " Error: Found "//cp_to_string(count_h)//
" H atoms for O atom "//cp_to_string(iparticle))
659 a1 = gal21%a11 + gal21%a12*gal21%gcn(jparticle) + gal21%a13*gal21%gcn(jparticle)*gal21%gcn(jparticle)
660 a2 = gal21%a21 + gal21%a22*gal21%gcn(jparticle) + gal21%a23*gal21%gcn(jparticle)*gal21%gcn(jparticle)
661 a3 = gal21%a31 + gal21%a32*gal21%gcn(jparticle) + gal21%a33*gal21%gcn(jparticle)*gal21%gcn(jparticle)
662 a4 = gal21%a41 + gal21%a42*gal21%gcn(jparticle) + gal21%a43*gal21%gcn(jparticle)*gal21%gcn(jparticle)
664 rji(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(iparticle)%r(:), cell)
665 rji_hat(:) = rji(:)/sqrt(dot_product(rji, rji))
668 rih1(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
669 rih2(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
670 rix(:) = rih1(:) + rih2(:)
671 rix_hat(:) = rix(:)/sqrt(dot_product(rix, rix))
672 costheta = dot_product(rix, nvec)/sqrt(dot_product(rix, rix))
673 IF (costheta < -1.0_dp) costheta = -1.0_dp
674 IF (costheta > +1.0_dp) costheta = +1.0_dp
675 theta = acos(costheta)
678 dsumdtheta = -1.0_dp*a1*sin(theta) - a2*2.0_dp*sin(2.0_dp*theta) - &
679 a3*3.0_dp*sin(3.0_dp*theta) - a4*4.0_dp*sin(4.0_dp*theta)
680 dcostheta(:) = (1.0_dp/sqrt(dot_product(rix, rix)))*(nvec(:) - costheta*rix_hat(:))
681 dangular(:) = prefactor*dsumdtheta*(-1.0_dp/sin(theta))*dcostheta(:)
684 f_nonbond(1:3, iparticle) = f_nonbond(1:3, iparticle) - dangular(1:3)*2.0_dp
685 f_nonbond(1:3, index_h1) = f_nonbond(1:3, index_h1) + dangular(1:3)
686 f_nonbond(1:3, index_h2) = f_nonbond(1:3, index_h2) + dangular(1:3)
689 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rix(1)*dangular(1:3)
690 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rix(2)*dangular(1:3)
691 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rix(3)*dangular(1:3)
694 bh = gal21%BH1 + gal21%gcn(jparticle)*gal21%BH2
696 rjh1(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
697 f_nonbond(1:3, index_h1) = f_nonbond(1:3, index_h1) + (gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
698 bh*exp(-bh*sqrt(dot_product(rjh1, rjh1)))*rjh1(:)/sqrt(dot_product(rjh1, rjh1))
701 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rjh1(1)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
702 bh*exp(-bh*sqrt(dot_product(rjh1, rjh1)))) &
703 *rjh1(:)/sqrt(dot_product(rjh1, rjh1))
704 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rjh1(2)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
705 bh*exp(-bh*sqrt(dot_product(rjh1, rjh1)))) &
706 *rjh1(:)/sqrt(dot_product(rjh1, rjh1))
707 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rjh1(3)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
708 bh*exp(-bh*sqrt(dot_product(rjh1, rjh1)))) &
709 *rjh1(:)/sqrt(dot_product(rjh1, rjh1))
712 rjh2(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
713 f_nonbond(1:3, index_h2) = f_nonbond(1:3, index_h2) + ((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
714 bh*exp(-bh*sqrt(dot_product(rjh2, rjh2)))) &
715 *rjh2(:)/sqrt(dot_product(rjh2, rjh2))
718 pv_nonbond(1, 1:3) = pv_nonbond(1, 1:3) + rjh2(1)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
719 bh*exp(-bh*sqrt(dot_product(rjh2, rjh2)))) &
720 *rjh2(:)/sqrt(dot_product(rjh2, rjh2))
721 pv_nonbond(2, 1:3) = pv_nonbond(2, 1:3) + rjh2(2)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
722 bh*exp(-bh*sqrt(dot_product(rjh2, rjh2)))) &
723 *rjh2(:)/sqrt(dot_product(rjh2, rjh2))
724 pv_nonbond(3, 1:3) = pv_nonbond(3, 1:3) + rjh2(3)*((gal21%AH2*gal21%gcn(jparticle) + gal21%AH1)* &
725 bh*exp(-bh*sqrt(dot_product(rjh2, rjh2)))) &
726 *rjh2(:)/sqrt(dot_product(rjh2, rjh2))
729 END SUBROUTINE angular_d
742 glob_loc_list_a, cell)
743 TYPE(fist_neighbor_type),
POINTER :: nonbonded
744 TYPE(pair_potential_pp_type),
POINTER :: potparm
745 INTEGER,
DIMENSION(:, :),
POINTER :: glob_loc_list
746 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: glob_cell_v
747 INTEGER,
DIMENSION(:),
POINTER :: glob_loc_list_a
748 TYPE(cell_type),
POINTER :: cell
750 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_gal21_arrays'
752 INTEGER :: handle, i, iend, igrp, ikind, ilist, &
753 ipair, istart, jkind, nkinds, npairs, &
755 INTEGER,
DIMENSION(:),
POINTER :: work_list, work_list2
756 INTEGER,
DIMENSION(:, :),
POINTER ::
list
757 REAL(kind=
dp),
DIMENSION(3) :: cell_v, cvi
758 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: rwork_list
759 TYPE(neighbor_kind_pairs_type),
POINTER :: neighbor_kind_pair
760 TYPE(pair_potential_single_type),
POINTER :: pot
762 cpassert(.NOT.
ASSOCIATED(glob_loc_list))
763 cpassert(.NOT.
ASSOCIATED(glob_loc_list_a))
764 cpassert(.NOT.
ASSOCIATED(glob_cell_v))
765 CALL timeset(routinen, handle)
767 nkinds =
SIZE(potparm%pot, 1)
768 DO ilist = 1, nonbonded%nlists
769 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
770 npairs = neighbor_kind_pair%npairs
771 IF (npairs == 0) cycle
772 kind_group_loop1:
DO igrp = 1, neighbor_kind_pair%ngrp_kind
773 istart = neighbor_kind_pair%grp_kind_start(igrp)
774 iend = neighbor_kind_pair%grp_kind_end(igrp)
775 ikind = neighbor_kind_pair%ij_kind(1, igrp)
776 jkind = neighbor_kind_pair%ij_kind(2, igrp)
777 pot => potparm%pot(ikind, jkind)%pot
778 npairs = iend - istart + 1
780 DO i = 1,
SIZE(pot%type)
781 IF (pot%type(i) ==
gal21_type) npairs_tot = npairs_tot + npairs
783 END DO kind_group_loop1
785 ALLOCATE (work_list(npairs_tot))
786 ALLOCATE (work_list2(npairs_tot))
787 ALLOCATE (glob_loc_list(2, npairs_tot))
788 ALLOCATE (glob_cell_v(3, npairs_tot))
791 DO ilist = 1, nonbonded%nlists
792 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
793 npairs = neighbor_kind_pair%npairs
794 IF (npairs == 0) cycle
795 kind_group_loop2:
DO igrp = 1, neighbor_kind_pair%ngrp_kind
796 istart = neighbor_kind_pair%grp_kind_start(igrp)
797 iend = neighbor_kind_pair%grp_kind_end(igrp)
798 ikind = neighbor_kind_pair%ij_kind(1, igrp)
799 jkind = neighbor_kind_pair%ij_kind(2, igrp)
800 list => neighbor_kind_pair%list
801 cvi = neighbor_kind_pair%cell_vector
802 pot => potparm%pot(ikind, jkind)%pot
803 npairs = iend - istart + 1
805 cell_v = matmul(cell%hmat, cvi)
806 DO i = 1,
SIZE(pot%type)
810 glob_loc_list(:, npairs_tot + ipair) =
list(:, istart - 1 + ipair)
811 glob_cell_v(1:3, npairs_tot + ipair) = cell_v(1:3)
813 npairs_tot = npairs_tot + npairs
816 END DO kind_group_loop2
819 CALL sort(glob_loc_list(1, :), npairs_tot, work_list)
820 DO ipair = 1, npairs_tot
821 work_list2(ipair) = glob_loc_list(2, work_list(ipair))
823 glob_loc_list(2, :) = work_list2
824 DEALLOCATE (work_list2)
825 ALLOCATE (rwork_list(3, npairs_tot))
826 DO ipair = 1, npairs_tot
827 rwork_list(:, ipair) = glob_cell_v(:, work_list(ipair))
829 glob_cell_v = rwork_list
830 DEALLOCATE (rwork_list)
831 DEALLOCATE (work_list)
832 ALLOCATE (glob_loc_list_a(npairs_tot))
833 glob_loc_list_a = glob_loc_list(1, :)
834 CALL timestop(handle)
844 INTEGER,
DIMENSION(:, :),
POINTER :: glob_loc_list
845 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: glob_cell_v
846 INTEGER,
DIMENSION(:),
POINTER :: glob_loc_list_a
848 IF (
ASSOCIATED(glob_loc_list))
THEN
849 DEALLOCATE (glob_loc_list)
851 IF (
ASSOCIATED(glob_loc_list_a))
THEN
852 DEALLOCATE (glob_loc_list_a)
854 IF (
ASSOCIATED(glob_cell_v))
THEN
855 DEALLOCATE (glob_cell_v)
871 INTEGER,
INTENT(INOUT) :: nr_ions
872 TYPE(section_vals_type),
POINTER :: mm_section
873 TYPE(mp_para_env_type),
OPTIONAL,
POINTER :: para_env
874 LOGICAL,
INTENT(IN) :: print_oh, print_h3o, print_o
877 TYPE(cp_logger_type),
POINTER :: logger
881 CALL para_env%sum(nr_ions)
887 IF (iw > 0 .AND. nr_ions > 0 .AND. print_oh)
THEN
888 WRITE (iw,
'(/,A,T71,I10,/)')
" gal21: number of OH- ions at surface", nr_ions
890 IF (iw > 0 .AND. nr_ions > 0 .AND. print_h3o)
THEN
891 WRITE (iw,
'(/,A,T71,I10,/)')
" gal21: number of H3O+ ions at surface", nr_ions
893 IF (iw > 0 .AND. nr_ions > 0 .AND. print_o)
THEN
894 WRITE (iw,
'(/,A,T71,I10,/)')
" gal21: number of O^2- ions at surface", nr_ions
subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
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.