82 local_molecules, particle_set, shell_particle_set, core_particle_set, &
83 pot_bond, pot_bend, pot_urey_bradley, pot_torsion, pot_imp_torsion, &
84 pot_opbend, pot_shell, pv_bond, pv_bend, pv_urey_bradley, pv_torsion, &
85 pv_imp_torsion, pv_opbend, f_bond, f_bend, f_torsion, f_ub, &
86 f_imptor, f_opbend, cell, use_virial, atprop_env)
91 TYPE(
particle_type),
POINTER :: particle_set(:), shell_particle_set(:), &
93 REAL(kind=
dp),
INTENT(INOUT) :: pot_bond, pot_bend, pot_urey_bradley, &
94 pot_torsion, pot_imp_torsion, &
96 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: pv_bond, pv_bend, pv_urey_bradley, &
97 pv_torsion, pv_imp_torsion, pv_opbend
98 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
99 OPTIONAL :: f_bond, f_bend, f_torsion, f_ub, &
102 LOGICAL,
INTENT(IN) :: use_virial
105 CHARACTER(len=*),
PARAMETER :: routinen =
'force_intra_control'
107 INTEGER :: first_atom, handle, i, ibend, ibond, ikind, imol, imul, index_a, index_b, &
108 index_c, index_d, iopbend, ishell, itorsion, nbends, nbonds, nimptors, nkind, &
109 nmol_per_kind, nopbends, nshell, ntorsions, nub
111 REAL(kind=
dp) :: d12, d32, dist, dist1, dist2, energy, &
112 fscalar, id12, id32, is32, ism, isn, &
113 k2_spring, k4_spring, r2, s32, sm, sn, &
115 REAL(kind=
dp),
DIMENSION(3) :: b12, b32, g1, g2, g3, gt1, gt2, gt3, &
116 gt4, k1, k2, k3, k4, rij, t12, t32, &
117 t34, t41, t42, t43, tm, tn
118 REAL(kind=
dp),
DIMENSION(:),
POINTER :: ener_a
128 TYPE(
ub_type),
POINTER :: ub_list(:)
130 CALL timeset(routinen, handle)
134 IF (
PRESENT(f_bond)) f_bond = 0.0_dp
135 IF (
PRESENT(f_bend)) f_bend = 0.0_dp
136 IF (
PRESENT(f_torsion)) f_torsion = 0.0_dp
137 IF (
PRESENT(f_imptor)) f_imptor = 0.0_dp
138 IF (
PRESENT(f_ub)) f_ub = 0.0_dp
142 pot_urey_bradley = 0.0_dp
144 pot_imp_torsion = 0.0_dp
148 atener = atprop_env%energy
149 IF (atener) ener_a => atprop_env%atener
151 nkind =
SIZE(molecule_kind_set)
152 mol:
DO ikind = 1, nkind
153 nmol_per_kind = local_molecules%n_el(ikind)
155 DO imol = 1, nmol_per_kind
156 i = local_molecules%list(ikind)%array(imol)
157 molecule => molecule_set(i)
158 molecule_kind => molecule%molecule_kind
160 nimpr=nimptors, nub=nub, ntorsion=ntorsions, &
161 nopbend=nopbends, nshell=nshell, &
162 bond_list=bond_list, ub_list=ub_list, &
163 bend_list=bend_list, torsion_list=torsion_list, &
164 impr_list=impr_list, opbend_list=opbend_list, &
165 shell_list=shell_list)
169 bond:
DO ibond = 1, nbonds
170 index_a = bond_list(ibond)%a + first_atom - 1
171 index_b = bond_list(ibond)%b + first_atom - 1
172 rij = particle_set(index_a)%r - particle_set(index_b)%r
174 CALL force_bonds(bond_list(ibond)%bond_kind%id_type, rij, &
175 bond_list(ibond)%bond_kind%r0, &
176 bond_list(ibond)%bond_kind%k, &
177 bond_list(ibond)%bond_kind%cs, &
179 pot_bond = pot_bond + energy
181 ener_a(index_a) = ener_a(index_a) + 0.5_dp*energy
182 ener_a(index_b) = ener_a(index_b) + 0.5_dp*energy
185 particle_set(index_a)%f(1) = particle_set(index_a)%f(1) - rij(1)*fscalar
186 particle_set(index_a)%f(2) = particle_set(index_a)%f(2) - rij(2)*fscalar
187 particle_set(index_a)%f(3) = particle_set(index_a)%f(3) - rij(3)*fscalar
188 particle_set(index_b)%f(1) = particle_set(index_b)%f(1) + rij(1)*fscalar
189 particle_set(index_b)%f(2) = particle_set(index_b)%f(2) + rij(2)*fscalar
190 particle_set(index_b)%f(3) = particle_set(index_b)%f(3) + rij(3)*fscalar
197 IF (
PRESENT(f_bond))
THEN
198 f_bond(1, index_a) = f_bond(1, index_a) - rij(1)*fscalar
199 f_bond(2, index_a) = f_bond(2, index_a) - rij(2)*fscalar
200 f_bond(3, index_a) = f_bond(3, index_a) - rij(3)*fscalar
201 f_bond(1, index_b) = f_bond(1, index_b) + rij(1)*fscalar
202 f_bond(2, index_b) = f_bond(2, index_b) + rij(2)*fscalar
203 f_bond(3, index_b) = f_bond(3, index_b) + rij(3)*fscalar
208 shell:
DO ishell = 1, nshell
209 index_a = shell_list(ishell)%a + first_atom - 1
210 index_b = particle_set(index_a)%shell_index
211 rij = core_particle_set(index_b)%r - shell_particle_set(index_b)%r
213 k2_spring = shell_list(ishell)%shell_kind%k2_spring
214 k4_spring = shell_list(ishell)%shell_kind%k4_spring
215 r2 = dot_product(rij, rij)
216 energy = 0.5_dp*(k2_spring + k4_spring*r2/12.0_dp)*r2
217 fscalar = k2_spring + k4_spring*r2/6.0_dp
218 pot_shell = pot_shell + energy
220 ener_a(index_a) = ener_a(index_a) + energy
222 core_particle_set(index_b)%f(1) = core_particle_set(index_b)%f(1) - rij(1)*fscalar
223 core_particle_set(index_b)%f(2) = core_particle_set(index_b)%f(2) - rij(2)*fscalar
224 core_particle_set(index_b)%f(3) = core_particle_set(index_b)%f(3) - rij(3)*fscalar
225 shell_particle_set(index_b)%f(1) = shell_particle_set(index_b)%f(1) + rij(1)*fscalar
226 shell_particle_set(index_b)%f(2) = shell_particle_set(index_b)%f(2) + rij(2)*fscalar
227 shell_particle_set(index_b)%f(3) = shell_particle_set(index_b)%f(3) + rij(3)*fscalar
235 urey_bradley:
DO ibend = 1, nub
236 index_a = ub_list(ibend)%a + first_atom - 1
237 index_b = ub_list(ibend)%c + first_atom - 1
238 rij = particle_set(index_a)%r - particle_set(index_b)%r
240 CALL force_bonds(ub_list(ibend)%ub_kind%id_type, rij, &
241 ub_list(ibend)%ub_kind%r0, &
242 ub_list(ibend)%ub_kind%k, 0.0_dp, energy, fscalar)
243 pot_urey_bradley = pot_urey_bradley + energy
245 ener_a(index_a) = ener_a(index_a) + 0.5_dp*energy
246 ener_a(index_b) = ener_a(index_b) + 0.5_dp*energy
248 particle_set(index_a)%f(1) = particle_set(index_a)%f(1) - rij(1)*fscalar
249 particle_set(index_a)%f(2) = particle_set(index_a)%f(2) - rij(2)*fscalar
250 particle_set(index_a)%f(3) = particle_set(index_a)%f(3) - rij(3)*fscalar
251 particle_set(index_b)%f(1) = particle_set(index_b)%f(1) + rij(1)*fscalar
252 particle_set(index_b)%f(2) = particle_set(index_b)%f(2) + rij(2)*fscalar
253 particle_set(index_b)%f(3) = particle_set(index_b)%f(3) + rij(3)*fscalar
257 IF (use_virial)
CALL get_pv_bond(k2, rij, pv_urey_bradley)
260 IF (
PRESENT(f_ub))
THEN
261 f_ub(:, index_a) = f_ub(:, index_a) - rij*fscalar
262 f_ub(:, index_b) = f_ub(:, index_b) + rij*fscalar
267 bend:
DO ibend = 1, nbends
268 index_a = bend_list(ibend)%a + first_atom - 1
269 index_b = bend_list(ibend)%b + first_atom - 1
270 index_c = bend_list(ibend)%c + first_atom - 1
271 b12 = particle_set(index_a)%r - particle_set(index_b)%r
272 b32 = particle_set(index_c)%r - particle_set(index_b)%r
275 d12 = sqrt(dot_product(b12, b12))
277 d32 = sqrt(dot_product(b32, b32))
279 dist = dot_product(b12, b32)
280 theta = (dist*id12*id32)
281 IF (theta < -1.0_dp) theta = -1.0_dp
282 IF (theta > +1.0_dp) theta = +1.0_dp
284 CALL force_bends(bend_list(ibend)%bend_kind%id_type, &
285 b12, b32, d12, d32, id12, id32, dist, theta, &
286 bend_list(ibend)%bend_kind%theta0, &
287 bend_list(ibend)%bend_kind%k, &
288 bend_list(ibend)%bend_kind%cb, &
289 bend_list(ibend)%bend_kind%r012, &
290 bend_list(ibend)%bend_kind%r032, &
291 bend_list(ibend)%bend_kind%kbs12, &
292 bend_list(ibend)%bend_kind%kbs32, &
293 bend_list(ibend)%bend_kind%kss, &
294 bend_list(ibend)%bend_kind%legendre, &
295 g1, g2, g3, energy, fscalar)
296 pot_bend = pot_bend + energy
298 ener_a(index_a) = ener_a(index_a) + energy/3._dp
299 ener_a(index_b) = ener_a(index_b) + energy/3._dp
300 ener_a(index_c) = ener_a(index_c) + energy/3._dp
302 particle_set(index_a)%f(1) = particle_set(index_a)%f(1) + g1(1)*fscalar
303 particle_set(index_a)%f(2) = particle_set(index_a)%f(2) + g1(2)*fscalar
304 particle_set(index_a)%f(3) = particle_set(index_a)%f(3) + g1(3)*fscalar
305 particle_set(index_b)%f(1) = particle_set(index_b)%f(1) + g2(1)*fscalar
306 particle_set(index_b)%f(2) = particle_set(index_b)%f(2) + g2(2)*fscalar
307 particle_set(index_b)%f(3) = particle_set(index_b)%f(3) + g2(3)*fscalar
308 particle_set(index_c)%f(1) = particle_set(index_c)%f(1) + g3(1)*fscalar
309 particle_set(index_c)%f(2) = particle_set(index_c)%f(2) + g3(2)*fscalar
310 particle_set(index_c)%f(3) = particle_set(index_c)%f(3) + g3(3)*fscalar
315 IF (use_virial)
CALL get_pv_bend(k1, k3, b12, b32, pv_bend)
318 IF (
PRESENT(f_bend))
THEN
319 f_bend(:, index_a) = f_bend(:, index_a) + fscalar*g1
320 f_bend(:, index_b) = f_bend(:, index_b) + fscalar*g2
321 f_bend(:, index_c) = f_bend(:, index_c) + fscalar*g3
325 torsion:
DO itorsion = 1, ntorsions
326 index_a = torsion_list(itorsion)%a + first_atom - 1
327 index_b = torsion_list(itorsion)%b + first_atom - 1
328 index_c = torsion_list(itorsion)%c + first_atom - 1
329 index_d = torsion_list(itorsion)%d + first_atom - 1
330 t12 = particle_set(index_a)%r - particle_set(index_b)%r
331 t32 = particle_set(index_c)%r - particle_set(index_b)%r
332 t34 = particle_set(index_c)%r - particle_set(index_d)%r
333 t43 = particle_set(index_d)%r - particle_set(index_c)%r
339 tm(1) = t12(2)*t32(3) - t32(2)*t12(3)
340 tm(2) = -t12(1)*t32(3) + t32(1)*t12(3)
341 tm(3) = t12(1)*t32(2) - t32(1)*t12(2)
343 tn(1) = t32(2)*t34(3) - t34(2)*t32(3)
344 tn(2) = -t32(1)*t34(3) + t34(1)*t32(3)
345 tn(3) = t32(1)*t34(2) - t34(1)*t32(2)
346 sm = sqrt(dot_product(tm, tm))
348 sn = sqrt(dot_product(tn, tn))
350 s32 = sqrt(dot_product(t32, t32))
352 dist1 = dot_product(t12, t32)
353 dist2 = dot_product(t34, t32)
354 DO imul = 1, torsion_list(itorsion)%torsion_kind%nmul
355 CALL force_torsions(torsion_list(itorsion)%torsion_kind%id_type, &
356 s32, is32, ism, isn, dist1, dist2, tm, tn, t12, &
357 torsion_list(itorsion)%torsion_kind%k(imul), &
358 torsion_list(itorsion)%torsion_kind%phi0(imul), &
359 torsion_list(itorsion)%torsion_kind%m(imul), &
360 gt1, gt2, gt3, gt4, energy, fscalar)
361 pot_torsion = pot_torsion + energy
363 ener_a(index_a) = ener_a(index_a) + energy*0.25_dp
364 ener_a(index_b) = ener_a(index_b) + energy*0.25_dp
365 ener_a(index_c) = ener_a(index_c) + energy*0.25_dp
366 ener_a(index_d) = ener_a(index_d) + energy*0.25_dp
368 particle_set(index_a)%f(1) = particle_set(index_a)%f(1) + gt1(1)*fscalar
369 particle_set(index_a)%f(2) = particle_set(index_a)%f(2) + gt1(2)*fscalar
370 particle_set(index_a)%f(3) = particle_set(index_a)%f(3) + gt1(3)*fscalar
371 particle_set(index_b)%f(1) = particle_set(index_b)%f(1) + gt2(1)*fscalar
372 particle_set(index_b)%f(2) = particle_set(index_b)%f(2) + gt2(2)*fscalar
373 particle_set(index_b)%f(3) = particle_set(index_b)%f(3) + gt2(3)*fscalar
374 particle_set(index_c)%f(1) = particle_set(index_c)%f(1) + gt3(1)*fscalar
375 particle_set(index_c)%f(2) = particle_set(index_c)%f(2) + gt3(2)*fscalar
376 particle_set(index_c)%f(3) = particle_set(index_c)%f(3) + gt3(3)*fscalar
377 particle_set(index_d)%f(1) = particle_set(index_d)%f(1) + gt4(1)*fscalar
378 particle_set(index_d)%f(2) = particle_set(index_d)%f(2) + gt4(2)*fscalar
379 particle_set(index_d)%f(3) = particle_set(index_d)%f(3) + gt4(3)*fscalar
385 IF (use_virial)
CALL get_pv_torsion(k1, k3, k4, t12, t32, t43, pv_torsion)
388 IF (
PRESENT(f_torsion))
THEN
389 f_torsion(:, index_a) = f_torsion(:, index_a) + fscalar*gt1
390 f_torsion(:, index_b) = f_torsion(:, index_b) + fscalar*gt2
391 f_torsion(:, index_c) = f_torsion(:, index_c) + fscalar*gt3
392 f_torsion(:, index_d) = f_torsion(:, index_d) + fscalar*gt4
397 imp_torsion:
DO itorsion = 1, nimptors
398 index_a = impr_list(itorsion)%a + first_atom - 1
399 index_b = impr_list(itorsion)%b + first_atom - 1
400 index_c = impr_list(itorsion)%c + first_atom - 1
401 index_d = impr_list(itorsion)%d + first_atom - 1
402 t12 = particle_set(index_a)%r - particle_set(index_b)%r
403 t32 = particle_set(index_c)%r - particle_set(index_b)%r
404 t34 = particle_set(index_c)%r - particle_set(index_d)%r
405 t43 = particle_set(index_d)%r - particle_set(index_c)%r
411 tm(1) = t12(2)*t32(3) - t32(2)*t12(3)
412 tm(2) = -t12(1)*t32(3) + t32(1)*t12(3)
413 tm(3) = t12(1)*t32(2) - t32(1)*t12(2)
415 tn(1) = t32(2)*t34(3) - t34(2)*t32(3)
416 tn(2) = -t32(1)*t34(3) + t34(1)*t32(3)
417 tn(3) = t32(1)*t34(2) - t34(1)*t32(2)
418 sm = sqrt(dot_product(tm, tm))
420 sn = sqrt(dot_product(tn, tn))
422 s32 = sqrt(dot_product(t32, t32))
424 dist1 = dot_product(t12, t32)
425 dist2 = dot_product(t34, t32)
427 s32, is32, ism, isn, dist1, dist2, tm, tn, t12, &
428 impr_list(itorsion)%impr_kind%k, &
429 impr_list(itorsion)%impr_kind%phi0, &
430 gt1, gt2, gt3, gt4, energy, fscalar)
431 pot_imp_torsion = pot_imp_torsion + energy
433 ener_a(index_a) = ener_a(index_a) + energy*0.25_dp
434 ener_a(index_b) = ener_a(index_b) + energy*0.25_dp
435 ener_a(index_c) = ener_a(index_c) + energy*0.25_dp
436 ener_a(index_d) = ener_a(index_d) + energy*0.25_dp
438 particle_set(index_a)%f(1) = particle_set(index_a)%f(1) + gt1(1)*fscalar
439 particle_set(index_a)%f(2) = particle_set(index_a)%f(2) + gt1(2)*fscalar
440 particle_set(index_a)%f(3) = particle_set(index_a)%f(3) + gt1(3)*fscalar
441 particle_set(index_b)%f(1) = particle_set(index_b)%f(1) + gt2(1)*fscalar
442 particle_set(index_b)%f(2) = particle_set(index_b)%f(2) + gt2(2)*fscalar
443 particle_set(index_b)%f(3) = particle_set(index_b)%f(3) + gt2(3)*fscalar
444 particle_set(index_c)%f(1) = particle_set(index_c)%f(1) + gt3(1)*fscalar
445 particle_set(index_c)%f(2) = particle_set(index_c)%f(2) + gt3(2)*fscalar
446 particle_set(index_c)%f(3) = particle_set(index_c)%f(3) + gt3(3)*fscalar
447 particle_set(index_d)%f(1) = particle_set(index_d)%f(1) + gt4(1)*fscalar
448 particle_set(index_d)%f(2) = particle_set(index_d)%f(2) + gt4(2)*fscalar
449 particle_set(index_d)%f(3) = particle_set(index_d)%f(3) + gt4(3)*fscalar
455 IF (use_virial)
CALL get_pv_torsion(k1, k3, k4, t12, t32, t43, pv_imp_torsion)
458 IF (
PRESENT(f_imptor))
THEN
459 f_imptor(:, index_a) = f_imptor(:, index_a) + fscalar*gt1
460 f_imptor(:, index_b) = f_imptor(:, index_b) + fscalar*gt2
461 f_imptor(:, index_c) = f_imptor(:, index_c) + fscalar*gt3
462 f_imptor(:, index_d) = f_imptor(:, index_d) + fscalar*gt4
466 opbend:
DO iopbend = 1, nopbends
467 index_a = opbend_list(iopbend)%a + first_atom - 1
468 index_b = opbend_list(iopbend)%b + first_atom - 1
469 index_c = opbend_list(iopbend)%c + first_atom - 1
470 index_d = opbend_list(iopbend)%d + first_atom - 1
472 t12 = particle_set(index_a)%r - particle_set(index_b)%r
473 t32 = particle_set(index_c)%r - particle_set(index_b)%r
474 t34 = particle_set(index_c)%r - particle_set(index_d)%r
475 t43 = particle_set(index_d)%r - particle_set(index_c)%r
476 t41 = particle_set(index_d)%r - particle_set(index_a)%r
477 t42 =
pbc(t41 + t12, cell)
483 tm(1) = t32(2)*t12(3) - t12(2)*t32(3)
484 tm(2) = -t32(1)*t12(3) + t12(1)*t32(3)
485 tm(3) = t32(1)*t12(2) - t12(1)*t32(2)
486 sm = sqrt(dot_product(tm, tm))
487 s32 = sqrt(dot_product(t32, t32))
488 CALL force_opbends(opbend_list(iopbend)%opbend_kind%id_type, &
489 s32, tm, t41, t42, t43, &
490 opbend_list(iopbend)%opbend_kind%k, &
491 opbend_list(iopbend)%opbend_kind%phi0, &
492 gt1, gt2, gt3, gt4, energy, fscalar)
493 pot_opbend = pot_opbend + energy
495 ener_a(index_a) = ener_a(index_a) + energy*0.25_dp
496 ener_a(index_b) = ener_a(index_b) + energy*0.25_dp
497 ener_a(index_c) = ener_a(index_c) + energy*0.25_dp
498 ener_a(index_d) = ener_a(index_d) + energy*0.25_dp
500 particle_set(index_a)%f(1) = particle_set(index_a)%f(1) + gt1(1)*fscalar
501 particle_set(index_a)%f(2) = particle_set(index_a)%f(2) + gt1(2)*fscalar
502 particle_set(index_a)%f(3) = particle_set(index_a)%f(3) + gt1(3)*fscalar
503 particle_set(index_b)%f(1) = particle_set(index_b)%f(1) + gt2(1)*fscalar
504 particle_set(index_b)%f(2) = particle_set(index_b)%f(2) + gt2(2)*fscalar
505 particle_set(index_b)%f(3) = particle_set(index_b)%f(3) + gt2(3)*fscalar
506 particle_set(index_c)%f(1) = particle_set(index_c)%f(1) + gt3(1)*fscalar
507 particle_set(index_c)%f(2) = particle_set(index_c)%f(2) + gt3(2)*fscalar
508 particle_set(index_c)%f(3) = particle_set(index_c)%f(3) + gt3(3)*fscalar
509 particle_set(index_d)%f(1) = particle_set(index_d)%f(1) + gt4(1)*fscalar
510 particle_set(index_d)%f(2) = particle_set(index_d)%f(2) + gt4(2)*fscalar
511 particle_set(index_d)%f(3) = particle_set(index_d)%f(3) + gt4(3)*fscalar
518 IF (use_virial)
CALL get_pv_torsion(k1, k3, k4, t12, t32, t43, pv_opbend)
521 IF (
PRESENT(f_opbend))
THEN
522 f_opbend(:, index_a) = f_opbend(:, index_a) + fscalar*gt1
523 f_opbend(:, index_b) = f_opbend(:, index_b) + fscalar*gt2
524 f_opbend(:, index_c) = f_opbend(:, index_c) + fscalar*gt3
525 f_opbend(:, index_d) = f_opbend(:, index_d) + fscalar*gt4
531 CALL timestop(handle)