27 neighbor_kind_pairs_type
33 pair_potential_single_type,&
38 #include "./base/base_uses.f90"
46 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'manybody_siepmann'
68 SUBROUTINE siepmann_energy(pot_loc, siepmann, r_last_update_pbc, atom_a, atom_b, &
69 nloc_size, full_loc_list, cell_v, cell, drij, particle_set, &
72 REAL(kind=
dp),
INTENT(OUT) :: pot_loc
73 TYPE(siepmann_pot_type),
POINTER :: siepmann
74 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
75 INTEGER,
INTENT(IN) :: atom_a, atom_b, nloc_size
76 INTEGER,
DIMENSION(2, 1:nloc_size) :: full_loc_list
77 REAL(kind=
dp),
DIMENSION(3) :: cell_v
78 TYPE(cell_type),
POINTER :: cell
80 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
81 INTEGER,
INTENT(INOUT) :: nr_oh, nr_h3o, nr_o
83 REAL(kind=
dp) :: a_ij, d, e, f2, phi_ij, pot_loc_v2, &
86 a_ij = siep_a_ij(siepmann, r_last_update_pbc, atom_a, atom_b, nloc_size, &
87 full_loc_list, cell_v, siepmann%rcutsq, particle_set, &
89 phi_ij = siep_phi_ij(siepmann, r_last_update_pbc, atom_a, atom_b, &
90 cell_v, cell, siepmann%rcutsq, particle_set, nr_oh, nr_h3o, nr_o)
91 f2 = siep_f2(siepmann, drij)
96 pot_loc_v2 = -d*f2*drij**(-3)*phi_ij
99 pot_loc_v3 = e*f2*drij**(-siepmann%beta)*a_ij
101 pot_loc = pot_loc_v2 + pot_loc_v3
111 FUNCTION siep_f2(siepmann, r)
112 TYPE(siepmann_pot_type),
POINTER :: siepmann
113 REAL(kind=
dp),
INTENT(IN) :: r
114 REAL(kind=
dp) :: siep_f2
116 REAL(kind=
dp) :: rcut
118 rcut = sqrt(siepmann%rcutsq)
121 siep_f2 = exp(siepmann%B/(r - rcut))
131 FUNCTION siep_f2_d(siepmann, r)
132 TYPE(siepmann_pot_type),
POINTER :: siepmann
133 REAL(kind=
dp),
INTENT(IN) :: r
134 REAL(kind=
dp) :: siep_f2_d
136 REAL(kind=
dp) :: b, rcut
138 rcut = sqrt(siepmann%rcutsq)
142 siep_f2_d = -b*exp(b/(r - rcut))/(r - rcut)**2
145 END FUNCTION siep_f2_d
164 FUNCTION siep_a_ij(siepmann, r_last_update_pbc, iparticle, jparticle, n_loc_size, &
165 full_loc_list, cell_v, rcutsq, particle_set, cell)
166 TYPE(siepmann_pot_type),
POINTER :: siepmann
167 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
168 INTEGER,
INTENT(IN) :: iparticle, jparticle, n_loc_size
169 INTEGER,
DIMENSION(2, 1:n_loc_size) :: full_loc_list
170 REAL(kind=
dp),
DIMENSION(3) :: cell_v
171 REAL(kind=
dp),
INTENT(IN) :: rcutsq
172 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
173 TYPE(cell_type),
POINTER :: cell
174 REAL(kind=
dp) :: siep_a_ij
176 CHARACTER(LEN=2) :: element_symbol
177 INTEGER :: ilist, kparticle
178 REAL(kind=
dp) :: costheta, drji, drjk, f, rab2_max, &
179 rji(3), rjk(3), theta
184 CALL get_atomic_kind(atomic_kind=particle_set(iparticle)%atomic_kind, &
185 element_symbol=element_symbol)
186 IF (element_symbol /=
"O")
RETURN
187 rji(:) = -1.0_dp*(r_last_update_pbc(jparticle)%r(:) - r_last_update_pbc(iparticle)%r(:) + cell_v)
188 drji = sqrt(dot_product(rji, rji))
189 DO ilist = 1, n_loc_size
190 kparticle = full_loc_list(2, ilist)
191 IF (kparticle == jparticle) cycle
192 rjk(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(kparticle)%r(:), cell)
193 drjk = dot_product(rjk, rjk)
194 IF (drjk > rab2_max) cycle
196 costheta = dot_product(rji, rjk)/(drji*drjk)
197 IF (costheta < -1.0_dp) costheta = -1.0_dp
198 IF (costheta > +1.0_dp) costheta = +1.0_dp
199 theta = acos(costheta)
200 siep_a_ij = siep_a_ij + exp(f*(cos(theta/2.0_dp))**2)
202 END FUNCTION siep_a_ij
221 SUBROUTINE siep_a_ij_d(siepmann, r_last_update_pbc, iparticle, jparticle, f_nonbond, &
222 prefactor, n_loc_size, full_loc_list, &
223 cell_v, cell, rcutsq, use_virial)
224 TYPE(siepmann_pot_type),
POINTER :: siepmann
225 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
226 INTEGER,
INTENT(IN) :: iparticle, jparticle
227 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond
228 REAL(kind=
dp),
INTENT(IN) :: prefactor
229 INTEGER,
INTENT(IN) :: n_loc_size
230 INTEGER,
DIMENSION(2, 1:n_loc_size) :: full_loc_list
231 REAL(kind=
dp),
DIMENSION(3) :: cell_v
232 TYPE(cell_type),
POINTER :: cell
233 REAL(kind=
dp),
INTENT(IN) :: rcutsq
234 LOGICAL,
INTENT(IN) :: use_virial
236 INTEGER :: ilist, kparticle, nparticle
237 REAL(kind=
dp) :: costheta, d_expterm, dcos_thetahalf, &
238 drji, drjk, f, rab2_max, theta
239 REAL(kind=
dp),
DIMENSION(3) :: dcosdri, dcosdrj, dcosdrk, dri, drj, &
240 drk, rji, rji_hat, rjk, rjk_hat
245 rji(:) = -1.0_dp*(r_last_update_pbc(jparticle)%r(:) - r_last_update_pbc(iparticle)%r(:) + cell_v)
246 drji = sqrt(dot_product(rji, rji))
247 rji_hat(:) = rji(:)/drji
249 nparticle =
SIZE(r_last_update_pbc)
250 DO ilist = 1, n_loc_size
251 kparticle = full_loc_list(2, ilist)
252 IF (kparticle == jparticle) cycle
253 rjk(:) =
pbc(r_last_update_pbc(jparticle)%r(:), r_last_update_pbc(kparticle)%r(:), cell)
254 drjk = dot_product(rjk, rjk)
255 IF (drjk > rab2_max) cycle
257 rjk_hat(:) = rjk(:)/drjk
258 costheta = dot_product(rji, rjk)/(drji*drjk)
259 IF (costheta < -1.0_dp) costheta = -1.0_dp
260 IF (costheta > +1.0_dp) costheta = +1.0_dp
262 dcosdri(:) = (1.0_dp/(drji))*(rjk_hat(:) - costheta*rji_hat(:))
263 dcosdrk(:) = (1.0_dp/(drjk))*(rji_hat(:) - costheta*rjk_hat(:))
264 dcosdrj(:) = -(dcosdri(:) + dcosdrk(:))
266 theta = acos(costheta)
267 dcos_thetahalf = -1.0_dp/(2.0_dp*sqrt(1 - costheta**2))
268 d_expterm = -2.0_dp*f*cos(theta/2.0_dp)*sin(theta/2.0_dp) &
269 *exp(f*(cos(theta/2.0_dp))**2)
271 dri = d_expterm*dcos_thetahalf*dcosdri
273 drj = d_expterm*dcos_thetahalf*dcosdrj
275 drk = d_expterm*dcos_thetahalf*dcosdrk
277 f_nonbond(1, iparticle) = f_nonbond(1, iparticle) + prefactor*dri(1)
278 f_nonbond(2, iparticle) = f_nonbond(2, iparticle) + prefactor*dri(2)
279 f_nonbond(3, iparticle) = f_nonbond(3, iparticle) + prefactor*dri(3)
281 f_nonbond(1, jparticle) = f_nonbond(1, jparticle) + prefactor*drj(1)
282 f_nonbond(2, jparticle) = f_nonbond(2, jparticle) + prefactor*drj(2)
283 f_nonbond(3, jparticle) = f_nonbond(3, jparticle) + prefactor*drj(3)
285 f_nonbond(1, kparticle) = f_nonbond(1, kparticle) + prefactor*drk(1)
286 f_nonbond(2, kparticle) = f_nonbond(2, kparticle) + prefactor*drk(2)
287 f_nonbond(3, kparticle) = f_nonbond(3, kparticle) + prefactor*drk(3)
290 CALL cp_abort(__location__, &
291 "using virial with Siepmann-Sprik"// &
295 END SUBROUTINE siep_a_ij_d
313 FUNCTION siep_phi_ij(siepmann, r_last_update_pbc, iparticle, jparticle, &
314 cell_v, cell, rcutsq, particle_set, nr_oh, nr_h3o, nr_o)
315 TYPE(siepmann_pot_type),
POINTER :: siepmann
316 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
317 INTEGER,
INTENT(IN) :: iparticle, jparticle
318 REAL(kind=
dp),
DIMENSION(3) :: cell_v
319 TYPE(cell_type),
POINTER :: cell
320 REAL(kind=
dp),
INTENT(IN) :: rcutsq
321 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
322 INTEGER,
INTENT(INOUT),
OPTIONAL :: nr_oh, nr_h3o, nr_o
323 REAL(kind=
dp) :: siep_phi_ij
325 CHARACTER(LEN=2) :: element_symbol
326 INTEGER :: count_h, iatom, index_h1, index_h2, natom
327 REAL(kind=
dp) :: cosphi, drih, drix, drji, h_max_dist, &
328 rab2_max, rih(3), rih1(3), rih2(3), &
337 natom =
SIZE(particle_set)
338 CALL get_atomic_kind(atomic_kind=particle_set(iparticle)%atomic_kind, &
339 element_symbol=element_symbol)
340 IF (element_symbol /=
"O")
RETURN
341 rji(:) = -1.0_dp*(r_last_update_pbc(jparticle)%r(:) - r_last_update_pbc(iparticle)%r(:) + cell_v)
342 drji = sqrt(dot_product(rji, rji))
346 element_symbol=element_symbol)
347 IF (element_symbol /=
"H") cycle
348 rih(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(iatom)%r(:), cell)
349 drih = sqrt(dot_product(rih, rih))
350 IF (drih >= h_max_dist) cycle
351 count_h = count_h + 1
352 IF (count_h == 1)
THEN
354 ELSEIF (count_h == 2)
THEN
359 IF (count_h == 0)
THEN
360 IF (siepmann%allow_o_formation)
THEN
361 IF (
PRESENT(nr_o)) nr_o = nr_o + 1
364 cpabort(
"No H atoms for O found")
366 ELSEIF (count_h == 1)
THEN
367 IF (siepmann%allow_oh_formation)
THEN
368 IF (
PRESENT(nr_oh)) nr_oh = nr_oh + 1
371 cpabort(
"Only one H atom of O atom found")
373 ELSEIF (count_h == 3)
THEN
374 IF (siepmann%allow_h3o_formation)
THEN
375 IF (
PRESENT(nr_h3o)) nr_h3o = nr_h3o + 1
378 cpabort(
"Three H atoms for O atom found")
380 ELSEIF (count_h > 3)
THEN
381 cpabort(
"Error in Siepmann-Sprik part: too many H atoms for O")
384 IF (count_h == 2)
THEN
386 rih1(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
387 rih2(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
388 rix(:) = rih1(:) + rih2(:)
389 drix = sqrt(dot_product(rix, rix))
390 cosphi = dot_product(rji, rix)/(drji*drix)
391 IF (cosphi < -1.0_dp) cosphi = -1.0_dp
392 IF (cosphi > +1.0_dp) cosphi = +1.0_dp
393 siep_phi_ij = exp(-8.0_dp*((cosphi - 1)/4.0_dp)**4)
395 END FUNCTION siep_phi_ij
413 SUBROUTINE siep_phi_ij_d(siepmann, r_last_update_pbc, iparticle, jparticle, f_nonbond, &
414 prefactor, cell_v, cell, rcutsq, use_virial, particle_set)
415 TYPE(siepmann_pot_type),
POINTER :: siepmann
416 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
417 INTEGER,
INTENT(IN) :: iparticle, jparticle
418 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond
419 REAL(kind=
dp),
INTENT(IN) :: prefactor
420 REAL(kind=
dp),
DIMENSION(3) :: cell_v
421 TYPE(cell_type),
POINTER :: cell
422 REAL(kind=
dp),
INTENT(IN) :: rcutsq
423 LOGICAL,
INTENT(IN) :: use_virial
424 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
426 CHARACTER(LEN=2) :: element_symbol
427 INTEGER :: count_h, iatom, index_h1, index_h2, natom
428 REAL(kind=
dp) :: cosphi, dphi, drih, drix, drji, &
429 h_max_dist, phi_ij, rab2_max
430 REAL(kind=
dp),
DIMENSION(3) :: dcosdrh, dcosdri, dcosdrj, drh, dri, &
431 drj, rih, rih1, rih2, rix, rix_hat, &
439 natom =
SIZE(particle_set)
440 phi_ij = siep_phi_ij(siepmann, r_last_update_pbc, iparticle, jparticle, &
441 cell_v, cell, rcutsq, &
443 rji(:) = -1.0_dp*(r_last_update_pbc(jparticle)%r(:) - r_last_update_pbc(iparticle)%r(:) + cell_v)
444 drji = sqrt(dot_product(rji, rji))
445 rji_hat(:) = rji(:)/drji
449 element_symbol=element_symbol)
450 IF (element_symbol /=
"H") cycle
451 rih(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(iatom)%r(:), cell)
452 drih = sqrt(dot_product(rih, rih))
453 IF (drih >= h_max_dist) cycle
454 count_h = count_h + 1
455 IF (count_h == 1)
THEN
457 ELSEIF (count_h == 2)
THEN
462 IF (count_h == 0 .AND. .NOT. siepmann%allow_o_formation)
THEN
463 cpabort(
"No H atoms for O found")
464 ELSEIF (count_h == 1 .AND. .NOT. siepmann%allow_oh_formation)
THEN
465 cpabort(
"Only one H atom for O atom found")
466 ELSEIF (count_h == 3 .AND. .NOT. siepmann%allow_h3o_formation)
THEN
467 cpabort(
"Three H atoms for O atom found")
468 ELSEIF (count_h > 3)
THEN
469 cpabort(
"Error in Siepmann-Sprik part: too many H atoms for O")
472 IF (count_h == 2)
THEN
474 rih1(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h1)%r(:), cell)
475 rih2(:) =
pbc(r_last_update_pbc(iparticle)%r(:), r_last_update_pbc(index_h2)%r(:), cell)
476 rix(:) = rih1(:) + rih2(:)
477 drix = sqrt(dot_product(rix, rix))
478 rix_hat(:) = rix(:)/drix
479 cosphi = dot_product(rji, rix)/(drji*drix)
480 IF (cosphi < -1.0_dp) cosphi = -1.0_dp
481 IF (cosphi > +1.0_dp) cosphi = +1.0_dp
483 dcosdrj(:) = (1.0_dp/(drji))*(-rix_hat(:) + cosphi*rji_hat(:))
485 dcosdrh(:) = (1.0_dp/(drix))*(rji_hat(:) - cosphi*rix_hat(:))
486 dcosdri(:) = -dcosdrj - 2.0_dp*dcosdrh
488 dphi = phi_ij*(-8.0_dp)*((cosphi - 1)/4.0_dp)**3
494 f_nonbond(1, iparticle) = f_nonbond(1, iparticle) + prefactor*dri(1)
495 f_nonbond(2, iparticle) = f_nonbond(2, iparticle) + prefactor*dri(2)
496 f_nonbond(3, iparticle) = f_nonbond(3, iparticle) + prefactor*dri(3)
498 f_nonbond(1, jparticle) = f_nonbond(1, jparticle) + prefactor*drj(1)
499 f_nonbond(2, jparticle) = f_nonbond(2, jparticle) + prefactor*drj(2)
500 f_nonbond(3, jparticle) = f_nonbond(3, jparticle) + prefactor*drj(3)
502 f_nonbond(1, index_h1) = f_nonbond(1, index_h1) + prefactor*drh(1)
503 f_nonbond(2, index_h1) = f_nonbond(2, index_h1) + prefactor*drh(2)
504 f_nonbond(3, index_h1) = f_nonbond(3, index_h1) + prefactor*drh(3)
506 f_nonbond(1, index_h2) = f_nonbond(1, index_h2) + prefactor*drh(1)
507 f_nonbond(2, index_h2) = f_nonbond(2, index_h2) + prefactor*drh(2)
508 f_nonbond(3, index_h2) = f_nonbond(3, index_h2) + prefactor*drh(3)
511 CALL cp_abort(__location__, &
512 "using virial with Siepmann-Sprik"// &
517 END SUBROUTINE siep_phi_ij_d
537 full_loc_list, iparticle, jparticle, f_nonbond, &
538 use_virial, rcutsq, cell, particle_set)
539 TYPE(siepmann_pot_type),
POINTER :: siepmann
540 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
541 REAL(kind=
dp),
DIMENSION(3) :: cell_v
542 INTEGER,
INTENT(IN) :: n_loc_size
543 INTEGER,
DIMENSION(2, 1:n_loc_size) :: full_loc_list
544 INTEGER,
INTENT(IN) :: iparticle, jparticle
545 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond
546 LOGICAL,
INTENT(IN) :: use_virial
547 REAL(kind=
dp),
INTENT(IN) :: rcutsq
548 TYPE(cell_type),
POINTER :: cell
549 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
551 CHARACTER(LEN=2) :: element_symbol
552 REAL(kind=
dp) :: a_ij, beta, drji, e, f2, f2_d, f_a1, &
553 f_a2,
fac, prefactor, rji(3), &
559 CALL get_atomic_kind(atomic_kind=particle_set(iparticle)%atomic_kind, &
560 element_symbol=element_symbol)
561 IF (element_symbol /=
"O")
RETURN
563 rji(:) = -1.0_dp*(r_last_update_pbc(jparticle)%r(:) - r_last_update_pbc(iparticle)%r(:) + cell_v)
564 drji = sqrt(dot_product(rji, rji))
565 rji_hat(:) = rji(:)/drji
568 a_ij = siep_a_ij(siepmann, r_last_update_pbc, iparticle, jparticle, n_loc_size, &
569 full_loc_list, cell_v, rcutsq, particle_set, cell)
570 f2 = siep_f2(siepmann, drji)
571 f2_d = siep_f2_d(siepmann, drji)
574 f_a1 = e*f2_d*drji**(-beta)*a_ij*
fac*(1.0_dp/drji)
575 f_nonbond(1, iparticle) = f_nonbond(1, iparticle) + f_a1*rji(1)
576 f_nonbond(2, iparticle) = f_nonbond(2, iparticle) + f_a1*rji(2)
577 f_nonbond(3, iparticle) = f_nonbond(3, iparticle) + f_a1*rji(3)
578 f_nonbond(1, jparticle) = f_nonbond(1, jparticle) - f_a1*rji(1)
579 f_nonbond(2, jparticle) = f_nonbond(2, jparticle) - f_a1*rji(2)
580 f_nonbond(3, jparticle) = f_nonbond(3, jparticle) - f_a1*rji(3)
583 CALL cp_abort(__location__, &
584 "using virial with Siepmann-Sprik"// &
589 f_a2 = e*f2*(-beta)*drji**(-beta - 1)*a_ij*
fac*(1.0_dp/drji)
590 f_nonbond(1, iparticle) = f_nonbond(1, iparticle) + f_a2*rji(1)
591 f_nonbond(2, iparticle) = f_nonbond(2, iparticle) + f_a2*rji(2)
592 f_nonbond(3, iparticle) = f_nonbond(3, iparticle) + f_a2*rji(3)
593 f_nonbond(1, jparticle) = f_nonbond(1, jparticle) - f_a2*rji(1)
594 f_nonbond(2, jparticle) = f_nonbond(2, jparticle) - f_a2*rji(2)
595 f_nonbond(3, jparticle) = f_nonbond(3, jparticle) - f_a2*rji(3)
598 CALL cp_abort(__location__, &
599 "using virial with Siepmann-Sprik"// &
604 prefactor = e*f2*drji**(-beta)*
fac
605 CALL siep_a_ij_d(siepmann, r_last_update_pbc, iparticle, jparticle, f_nonbond, &
606 prefactor, n_loc_size, full_loc_list, cell_v, &
607 cell, rcutsq, use_virial)
627 iparticle, jparticle, f_nonbond, use_virial, rcutsq, particle_set)
628 TYPE(siepmann_pot_type),
POINTER :: siepmann
629 TYPE(pos_type),
DIMENSION(:),
POINTER :: r_last_update_pbc
630 REAL(kind=
dp),
DIMENSION(3) :: cell_v
631 TYPE(cell_type),
POINTER :: cell
632 INTEGER,
INTENT(IN) :: iparticle, jparticle
633 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: f_nonbond
634 LOGICAL,
INTENT(IN) :: use_virial
635 REAL(kind=
dp),
INTENT(IN) :: rcutsq
636 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
638 CHARACTER(LEN=2) :: element_symbol
639 REAL(kind=
dp) :: d, drji, f2, f2_d, f_a1, f_a2,
fac, &
640 phi_ij, prefactor, rji(3)
644 CALL get_atomic_kind(atomic_kind=particle_set(iparticle)%atomic_kind, &
645 element_symbol=element_symbol)
646 IF (element_symbol /=
"O")
RETURN
648 rji(:) = -1.0_dp*(r_last_update_pbc(jparticle)%r(:) - r_last_update_pbc(iparticle)%r(:) + cell_v)
649 drji = sqrt(dot_product(rji, rji))
652 phi_ij = siep_phi_ij(siepmann, r_last_update_pbc, iparticle, jparticle, &
653 cell_v, cell, rcutsq, particle_set)
654 f2 = siep_f2(siepmann, drji)
655 f2_d = siep_f2_d(siepmann, drji)
658 f_a1 = -d*f2_d*drji**(-3)*phi_ij*
fac*(1.0_dp/drji)
659 f_nonbond(1, iparticle) = f_nonbond(1, iparticle) + f_a1*rji(1)
660 f_nonbond(2, iparticle) = f_nonbond(2, iparticle) + f_a1*rji(2)
661 f_nonbond(3, iparticle) = f_nonbond(3, iparticle) + f_a1*rji(3)
662 f_nonbond(1, jparticle) = f_nonbond(1, jparticle) - f_a1*rji(1)
663 f_nonbond(2, jparticle) = f_nonbond(2, jparticle) - f_a1*rji(2)
664 f_nonbond(3, jparticle) = f_nonbond(3, jparticle) - f_a1*rji(3)
667 CALL cp_abort(__location__, &
668 "using virial with Siepmann-Sprik"// &
673 f_a2 = -d*f2*(-3.0_dp)*drji**(-4)*phi_ij*
fac*(1.0_dp/drji)
674 f_nonbond(1, iparticle) = f_nonbond(1, iparticle) + f_a2*rji(1)
675 f_nonbond(2, iparticle) = f_nonbond(2, iparticle) + f_a2*rji(2)
676 f_nonbond(3, iparticle) = f_nonbond(3, iparticle) + f_a2*rji(3)
677 f_nonbond(1, jparticle) = f_nonbond(1, jparticle) - f_a2*rji(1)
678 f_nonbond(2, jparticle) = f_nonbond(2, jparticle) - f_a2*rji(2)
679 f_nonbond(3, jparticle) = f_nonbond(3, jparticle) - f_a2*rji(3)
682 CALL cp_abort(__location__, &
683 "using virial with Siepmann-Sprik"// &
688 prefactor = -d*f2*drji**(-3)*
fac
689 CALL siep_phi_ij_d(siepmann, r_last_update_pbc, iparticle, jparticle, f_nonbond, &
690 prefactor, cell_v, cell, &
691 rcutsq, use_virial, particle_set)
706 glob_loc_list_a, cell)
707 TYPE(fist_neighbor_type),
POINTER :: nonbonded
708 TYPE(pair_potential_pp_type),
POINTER :: potparm
709 INTEGER,
DIMENSION(:, :),
POINTER :: glob_loc_list
710 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: glob_cell_v
711 INTEGER,
DIMENSION(:),
POINTER :: glob_loc_list_a
712 TYPE(cell_type),
POINTER :: cell
714 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_siepmann_arrays'
716 INTEGER :: handle, i, iend, igrp, ikind, ilist, &
717 ipair, istart, jkind, nkinds, npairs, &
719 INTEGER,
DIMENSION(:),
POINTER :: work_list, work_list2
720 INTEGER,
DIMENSION(:, :),
POINTER ::
list
721 REAL(kind=
dp),
DIMENSION(3) :: cell_v, cvi
722 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: rwork_list
723 TYPE(neighbor_kind_pairs_type),
POINTER :: neighbor_kind_pair
724 TYPE(pair_potential_single_type),
POINTER :: pot
726 cpassert(.NOT.
ASSOCIATED(glob_loc_list))
727 cpassert(.NOT.
ASSOCIATED(glob_loc_list_a))
728 cpassert(.NOT.
ASSOCIATED(glob_cell_v))
729 CALL timeset(routinen, handle)
731 nkinds =
SIZE(potparm%pot, 1)
732 DO ilist = 1, nonbonded%nlists
733 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
734 npairs = neighbor_kind_pair%npairs
735 IF (npairs == 0) cycle
736 kind_group_loop1:
DO igrp = 1, neighbor_kind_pair%ngrp_kind
737 istart = neighbor_kind_pair%grp_kind_start(igrp)
738 iend = neighbor_kind_pair%grp_kind_end(igrp)
739 ikind = neighbor_kind_pair%ij_kind(1, igrp)
740 jkind = neighbor_kind_pair%ij_kind(2, igrp)
741 pot => potparm%pot(ikind, jkind)%pot
742 npairs = iend - istart + 1
744 DO i = 1,
SIZE(pot%type)
745 IF (pot%type(i) ==
siepmann_type) npairs_tot = npairs_tot + npairs
747 END DO kind_group_loop1
749 ALLOCATE (work_list(npairs_tot))
750 ALLOCATE (work_list2(npairs_tot))
751 ALLOCATE (glob_loc_list(2, npairs_tot))
752 ALLOCATE (glob_cell_v(3, npairs_tot))
755 DO ilist = 1, nonbonded%nlists
756 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
757 npairs = neighbor_kind_pair%npairs
758 IF (npairs == 0) cycle
759 kind_group_loop2:
DO igrp = 1, neighbor_kind_pair%ngrp_kind
760 istart = neighbor_kind_pair%grp_kind_start(igrp)
761 iend = neighbor_kind_pair%grp_kind_end(igrp)
762 ikind = neighbor_kind_pair%ij_kind(1, igrp)
763 jkind = neighbor_kind_pair%ij_kind(2, igrp)
764 list => neighbor_kind_pair%list
765 cvi = neighbor_kind_pair%cell_vector
766 pot => potparm%pot(ikind, jkind)%pot
767 npairs = iend - istart + 1
769 cell_v = matmul(cell%hmat, cvi)
770 DO i = 1,
SIZE(pot%type)
774 glob_loc_list(:, npairs_tot + ipair) =
list(:, istart - 1 + ipair)
775 glob_cell_v(1:3, npairs_tot + ipair) = cell_v(1:3)
777 npairs_tot = npairs_tot + npairs
780 END DO kind_group_loop2
783 CALL sort(glob_loc_list(1, :), npairs_tot, work_list)
784 DO ipair = 1, npairs_tot
785 work_list2(ipair) = glob_loc_list(2, work_list(ipair))
787 glob_loc_list(2, :) = work_list2
788 DEALLOCATE (work_list2)
789 ALLOCATE (rwork_list(3, npairs_tot))
790 DO ipair = 1, npairs_tot
791 rwork_list(:, ipair) = glob_cell_v(:, work_list(ipair))
793 glob_cell_v = rwork_list
794 DEALLOCATE (rwork_list)
795 DEALLOCATE (work_list)
796 ALLOCATE (glob_loc_list_a(npairs_tot))
797 glob_loc_list_a = glob_loc_list(1, :)
798 CALL timestop(handle)
808 INTEGER,
DIMENSION(:, :),
POINTER :: glob_loc_list
809 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: glob_cell_v
810 INTEGER,
DIMENSION(:),
POINTER :: glob_loc_list_a
812 IF (
ASSOCIATED(glob_loc_list))
THEN
813 DEALLOCATE (glob_loc_list)
815 IF (
ASSOCIATED(glob_loc_list_a))
THEN
816 DEALLOCATE (glob_loc_list_a)
818 IF (
ASSOCIATED(glob_cell_v))
THEN
819 DEALLOCATE (glob_cell_v)
835 INTEGER,
INTENT(INOUT) :: nr_ions
836 TYPE(section_vals_type),
POINTER :: mm_section
837 TYPE(mp_para_env_type),
OPTIONAL,
POINTER :: para_env
838 LOGICAL,
INTENT(IN) :: print_oh, print_h3o, print_o
841 TYPE(cp_logger_type),
POINTER :: logger
845 CALL para_env%sum(nr_ions)
851 IF (iw > 0 .AND. nr_ions > 0 .AND. print_oh)
THEN
852 WRITE (iw,
'(/,A,T71,I10,/)')
" SIEPMANN: number of OH- ions at surface", nr_ions
854 IF (iw > 0 .AND. nr_ions > 0 .AND. print_h3o)
THEN
855 WRITE (iw,
'(/,A,T71,I10,/)')
" SIEPMANN: number of H3O+ ions at surface", nr_ions
857 IF (iw > 0 .AND. nr_ions > 0 .AND. print_o)
THEN
858 WRITE (iw,
'(/,A,T71,I10,/)')
" SIEPMANN: 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)
...
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
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 dipole and three-body part of Siepmann-Sprik potential dipole term: 3rd term in Eq....
subroutine, public siepmann_energy(pot_loc, siepmann, r_last_update_pbc, atom_a, atom_b, nloc_size, full_loc_list, cell_v, cell, drij, particle_set, nr_oh, nr_h3o, nr_o)
energy of two-body dipole term and three-body term
subroutine, public setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public siepmann_forces_v2(siepmann, r_last_update_pbc, cell_v, cell, iparticle, jparticle, f_nonbond, use_virial, rcutsq, particle_set)
forces generated by the dipole term
subroutine, public siepmann_forces_v3(siepmann, r_last_update_pbc, cell_v, n_loc_size, full_loc_list, iparticle, jparticle, f_nonbond, use_virial, rcutsq, cell, particle_set)
forces generated by the three-body term
subroutine, public print_nr_ions_siepmann(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 destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
Interface to the message passing library MPI.
integer, parameter, public siepmann_type
Define the data structure for the particle information.
All kind of helpful little routines.