38#include "../base/base_uses.f90"
44 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'tmc_calculations'
69 LOGICAL :: exact_approx_pot
74 REAL(kind=
dp) :: e_pot, rnd
79 cpassert(
ASSOCIATED(conf))
81 cpassert(
ASSOCIATED(tmc_env))
83 SELECT CASE (tmc_env%params%task_type)
87 IF (tmc_env%params%pressure >= 0.0_dp)
THEN
89 CALL get_scaled_cell(cell=tmc_env%params%cell, box_scale=conf%box_scale, &
91 CALL set_cell(env_id=env_id, new_cell=tmp_cell%hmat, ierr=ierr)
98 IF (flag .EQV. .true.)
THEN
99 IF (tmc_env%params%print_forces .OR. &
103 CALL calc_force(env_id=env_id, pos=conf%pos, n_el_pos=
SIZE(conf%pos), &
104 e_pot=e_pot, force=conf%frc, &
105 n_el_force=
SIZE(conf%frc), ierr=ierr)
108 CALL calc_energy(env_id=env_id, pos=conf%pos, n_el=
SIZE(conf%pos), e_pot=e_pot, ierr=ierr)
116 CALL cp_abort(__location__, &
117 "worker task typ is unknown "// &
122 rnd = tmc_env%rng_stream%next()
133 IF (exact_approx_pot)
THEN
134 conf%potential = e_pot
136 conf%e_pot_approx = e_pot
153 TYPE(
cell_type),
INTENT(IN),
POINTER :: cell
154 REAL(kind=
dp),
DIMENSION(:),
POINTER :: box_scale
155 REAL(kind=
dp),
DIMENSION(3, 3),
OPTIONAL :: scaled_hmat
156 TYPE(
cell_type),
OPTIONAL,
POINTER :: scaled_cell
157 REAL(kind=
dp),
OPTIONAL :: vol
158 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT),
OPTIONAL :: abc
159 REAL(kind=
dp),
DIMENSION(3),
OPTIONAL :: vec
161 LOGICAL :: new_scaled_cell
164 cpassert(
ASSOCIATED(cell))
165 cpassert(
ASSOCIATED(box_scale))
167 new_scaled_cell = .false.
169 IF (.NOT.
PRESENT(scaled_cell))
THEN
171 new_scaled_cell = .true.
173 tmp_cell => scaled_cell
175 CALL cell_copy(cell_in=cell, cell_out=tmp_cell)
176 tmp_cell%hmat(:, 1) = tmp_cell%hmat(:, 1)*box_scale(1)
177 tmp_cell%hmat(:, 2) = tmp_cell%hmat(:, 2)*box_scale(2)
178 tmp_cell%hmat(:, 3) = tmp_cell%hmat(:, 3)*box_scale(3)
181 IF (
PRESENT(scaled_hmat))
THEN
182 scaled_hmat(:, :) = tmp_cell%hmat
185 IF (
PRESENT(vec))
THEN
186 vec =
pbc(r=vec, cell=tmp_cell)
189 IF (
PRESENT(vol))
CALL get_cell(cell=tmp_cell, deth=vol)
190 IF (
PRESENT(abc))
CALL get_cell(cell=tmp_cell, abc=abc)
191 IF (new_scaled_cell)
DEALLOCATE (tmp_cell)
203 TYPE(
cell_type),
INTENT(IN),
POINTER :: cell
204 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: scaled_hmat
205 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: box_scale
207 REAL(kind=
dp),
DIMENSION(3) :: abc_new, abc_orig
210 cpassert(
ASSOCIATED(cell))
213 CALL cell_copy(cell_in=cell, cell_out=tmp_cell)
214 tmp_cell%hmat(:, :) = scaled_hmat(:, :)
216 CALL get_cell(cell=cell, abc=abc_orig)
217 CALL get_cell(cell=tmp_cell, abc=abc_new)
219 box_scale(:) = abc_new(:)/abc_orig(:)
221 DEALLOCATE (tmp_cell)
234 REAL(kind=
dp),
DIMENSION(:) :: x1, x2
236 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL,
POINTER :: box_scale
239 REAL(kind=
dp),
DIMENSION(3) :: dist_vec
240 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tmp_box_scale
242 NULLIFY (tmp_box_scale)
244 cpassert(
ASSOCIATED(cell))
245 cpassert(
SIZE(x1) == 3)
246 cpassert(
SIZE(x2) == 3)
248 dist_vec(:) = x2(:) - x1(:)
249 ALLOCATE (tmp_box_scale(3))
250 IF (
PRESENT(box_scale))
THEN
251 cpassert(
SIZE(box_scale) == 3)
252 tmp_box_scale(:) = box_scale
254 tmp_box_scale(:) = 1.0_dp
257 res = sqrt(sum(dist_vec(:)*dist_vec(:)))
258 DEALLOCATE (tmp_box_scale)
269 REAL(kind=
dp),
DIMENSION(:) :: pos
270 REAL(kind=
dp),
DIMENSION(:),
POINTER :: center
272 CHARACTER(LEN=*),
PARAMETER :: routinen =
'geometrical_center'
276 cpassert(
ASSOCIATED(center))
277 cpassert(
SIZE(pos) >=
SIZE(center))
280 CALL timeset(routinen, handle)
283 DO i = 1,
SIZE(pos),
SIZE(center)
284 center(:) = center(:) + &
285 pos(i:i +
SIZE(center) - 1)/(
SIZE(pos)/real(
SIZE(center), kind=
dp))
288 CALL timestop(handle)
302 REAL(kind=
dp),
DIMENSION(:) :: pos
304 REAL(kind=
dp),
DIMENSION(:),
POINTER :: center
306 CHARACTER(LEN=*),
PARAMETER :: routinen =
'center_of_mass'
309 REAL(kind=
dp) :: mass_sum, mass_tmp
311 cpassert(
ASSOCIATED(center))
312 cpassert(
SIZE(pos) >=
SIZE(center))
315 CALL timeset(routinen, handle)
319 DO i = 1,
SIZE(pos),
SIZE(center)
320 IF (
PRESENT(atoms))
THEN
321 cpassert(
SIZE(atoms) ==
SIZE(pos)/
SIZE(center))
322 mass_tmp = atoms(int(i/real(
SIZE(center), kind=
dp)) + 1)%mass
323 center(:) = center(:) + pos(i:i +
SIZE(center) - 1)/ &
324 (
SIZE(pos)/real(
SIZE(center), kind=
dp))*mass_tmp
325 mass_sum = mass_sum + mass_tmp
327 cpwarn(
"try to calculate center of mass without any mass.")
328 center(:) = center(:) + pos(i:i +
SIZE(center) - 1)/ &
329 (
SIZE(pos)/real(
SIZE(center), kind=
dp))
333 center(:) = center(:)/mass_sum
335 CALL timestop(handle)
348 SUBROUTINE init_vel(vel, atoms, temerature, rng_stream, rnd_seed)
349 REAL(kind=
dp),
DIMENSION(:),
POINTER :: vel
351 REAL(kind=
dp) :: temerature
353 REAL(kind=
dp),
DIMENSION(3, 2, 3) :: rnd_seed
356 REAL(kind=
dp) :: kb, mass_tmp, rnd1, rnd2
360 cpassert(
ASSOCIATED(vel))
361 cpassert(
ASSOCIATED(atoms))
363 CALL rng_stream%set(bg=rnd_seed(:, :, 1), cg=rnd_seed(:, :, 2), ig=rnd_seed(:, :, 3))
365 rnd1 = rng_stream%next()
366 rnd2 = rng_stream%next()
368 mass_tmp = atoms(int(i/real(3, kind=
dp)) + 1)%mass
370 vel(i) = sqrt(-2.0_dp*log(rnd1))*cos(2.0_dp*
pi*rnd2)* &
371 sqrt(kb*temerature/mass_tmp)
373 CALL rng_stream%get(bg=rnd_seed(:, :, 1), cg=rnd_seed(:, :, 2), ig=rnd_seed(:, :, 3))
386 REAL(kind=
dp),
DIMENSION(:),
POINTER :: vel
388 REAL(kind=
dp) :: ekin
391 REAL(kind=
dp) :: mass_tmp
393 cpassert(
ASSOCIATED(vel))
394 cpassert(
ASSOCIATED(atoms))
398 mass_tmp = atoms(int(i/real(3, kind=
dp)) + 1)%mass
399 ekin = ekin + 0.5_dp*mass_tmp*vel(i)*vel(i)
413 SUBROUTINE three_point_extrapolate(v1, v2, v3, extrapolate, res_err)
414 REAL(kind=
dp) :: v1, v2, v3
415 REAL(kind=
dp),
INTENT(OUT) :: extrapolate, res_err
417 REAL(kind=
dp) :: e1, e2, e3
418 REAL(kind=
dp) :: a, b, c, d12, d23, ddd
420 extrapolate = huge(extrapolate)
430 e1 = v1; e2 = v2; e3 = v3
439 IF (d12 == 0 .OR. d23 == 0 .OR. abs(ddd) == 0)
THEN
445 b = (d12**3/(d23*ddd))
446 c = e2 - (d12*d23)/ddd
449 extrapolate = a**7*b + c
450 res_err = e3 - extrapolate
452 cpassert(extrapolate /= huge(extrapolate))
459 SUBROUTINE swap(x1, x2)
460 REAL(kind=
dp) :: x1, x2
470 END SUBROUTINE three_point_extrapolate
490 FUNCTION compute_prob(E_n_mu, E_n_sigma, E_o_mu, E_o_sigma, E_classical_diff, &
491 prior_mu, prior_sigma, p, beta)
RESULT(prob)
492 REAL(kind=
dp) :: e_n_mu, e_n_sigma, e_o_mu, e_o_sigma, &
493 e_classical_diff, prior_mu, &
494 prior_sigma, p, beta, prob
499 prob = 0.5_dp*erfc(-0.5_dp*sqrt(2.0_dp)*( &
500 (-prior_sigma**2 - e_o_sigma**2 - e_n_sigma**2)*log(p) + &
501 ((e_classical_diff - e_n_mu + e_o_mu)*prior_sigma**2 - prior_mu*(e_n_sigma**2 + e_o_sigma**2))*beta)/ &
502 (sqrt(e_o_sigma**2 + e_n_sigma**2)*sqrt(prior_sigma**2 + e_o_sigma**2 + e_n_sigma**2)*prior_sigma*beta))
504 prob = min(1.0_dp - epsilon(1.0_dp), max(epsilon(1.0_dp), prob))
506 END FUNCTION compute_prob
522 rnd_nr, beta, tmc_params)
RESULT(prob)
523 TYPE(
tree_type),
POINTER :: elem_old, elem_new
524 REAL(kind=
dp) :: e_classical_diff, rnd_nr, beta
526 REAL(kind=
dp) :: prob
528 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_estimated_prob'
531 REAL(kind=
dp) :: e_mu_tmp, e_n_mu, e_n_sigma, e_o_mu, &
532 e_o_sigma, e_sigma_tmp, prior_sigma
534 cpassert(
ASSOCIATED(elem_old))
535 cpassert(
ASSOCIATED(elem_new))
536 cpassert(rnd_nr > 0.0_dp)
539 CALL timeset(routinen, handle)
542 IF ((elem_new%scf_energies_count >= 3) .AND. &
543 (elem_old%scf_energies_count >= 3) .AND. &
544 tmc_params%prior_NMC_acc%counter >= 10)
THEN
549 CALL three_point_extrapolate(v1=elem_new%scf_energies(mod(elem_new%scf_energies_count - 3, 4) + 1), &
550 v2=elem_new%scf_energies(mod(elem_new%scf_energies_count - 2, 4) + 1), &
551 v3=elem_new%scf_energies(mod(elem_new%scf_energies_count - 1, 4) + 1), &
552 extrapolate=e_mu_tmp, res_err=e_sigma_tmp)
553 IF ((elem_new%scf_energies_count > 3))
THEN
554 CALL three_point_extrapolate(v1=elem_new%scf_energies(mod(elem_new%scf_energies_count - 4, 4) + 1), &
555 v2=elem_new%scf_energies(mod(elem_new%scf_energies_count - 3, 4) + 1), &
556 v3=elem_new%scf_energies(mod(elem_new%scf_energies_count - 2, 4) + 1), &
557 extrapolate=e_n_mu, res_err=e_n_sigma)
558 e_n_sigma = max(e_n_sigma, abs(e_n_mu - e_mu_tmp))
560 e_n_sigma = e_sigma_tmp
565 CALL three_point_extrapolate(v1=elem_old%scf_energies(mod(elem_old%scf_energies_count - 3, 4) + 1), &
566 v2=elem_old%scf_energies(mod(elem_old%scf_energies_count - 2, 4) + 1), &
567 v3=elem_old%scf_energies(mod(elem_old%scf_energies_count - 1, 4) + 1), &
568 extrapolate=e_mu_tmp, res_err=e_sigma_tmp)
569 IF ((elem_old%scf_energies_count > 3))
THEN
570 CALL three_point_extrapolate(v1=elem_old%scf_energies(mod(elem_old%scf_energies_count - 4, 4) + 1), &
571 v2=elem_old%scf_energies(mod(elem_old%scf_energies_count - 3, 4) + 1), &
572 v3=elem_old%scf_energies(mod(elem_old%scf_energies_count - 2, 4) + 1), &
573 extrapolate=e_o_mu, res_err=e_o_sigma)
574 e_o_sigma = max(e_o_sigma, abs(e_o_mu - e_mu_tmp))
576 e_o_sigma = e_sigma_tmp
581 prior_sigma = sqrt(abs(tmc_params%prior_NMC_acc%aver_2 &
582 - tmc_params%prior_NMC_acc%aver**2))
586 prob = compute_prob(e_n_mu=e_n_mu, e_n_sigma=e_n_sigma, e_o_mu=e_o_mu, e_o_sigma=e_o_sigma, &
587 e_classical_diff=e_classical_diff, &
588 prior_mu=tmc_params%prior_NMC_acc%aver, prior_sigma=prior_sigma, &
592 CALL timestop(handle)
604 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eff
608 cpassert(
ASSOCIATED(tmc_env))
609 cpassert(
ASSOCIATED(tmc_env%params))
610 cpassert(
ASSOCIATED(tmc_env%m_env))
614 DO i = 1, tmc_env%params%nr_temp
615 IF (tmc_env%m_env%tree_node_count(i) > 0)
THEN
616 eff(i) = tmc_env%params%move_types%mv_count(0, i)/ &
617 (tmc_env%m_env%tree_node_count(i)*1.0_dp)
619 eff(0) = eff(0) + tmc_env%params%move_types%mv_count(0, i)/ &
620 (sum(tmc_env%m_env%tree_node_count(1:))*1.0_dp)
Handles all functions related to the CELL.
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
Handles all functions related to the CELL.
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
subroutine, public cell_copy(cell_in, cell_out, tag)
Copy cell variable.
various routines to log and control the output. The idea is that decisions about where to log should ...
interface to use cp2k as library
subroutine, public get_cell(env_id, cell, per, ierr)
gets a cell
recursive subroutine, public calc_energy(env_id, pos, n_el, e_pot, ierr)
returns the energy of the configuration given by the positions passed as argument
subroutine, public set_cell(env_id, new_cell, ierr)
sets a new cell
recursive subroutine, public calc_force(env_id, pos, n_el_pos, e_pot, force, n_el_force, ierr)
returns the energy of the configuration given by the positions passed as argument
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
Definition of physical constants:
real(kind=dp), parameter, public boltzmann
real(kind=dp), parameter, public joule
calculation section for TreeMonteCarlo
subroutine, public init_vel(vel, atoms, temerature, rng_stream, rnd_seed)
routine sets initial velocity, using the Box-Muller Method for Normal (Gaussian) Deviates
subroutine, public geometrical_center(pos, center)
calculate the geometrical center of an amount of atoms array size should be multiple of dim_per_elem
real(kind=dp) function, public compute_estimated_prob(elem_old, elem_new, e_classical_diff, rnd_nr, beta, tmc_params)
extimates the probability of acceptance considering the intermetiate step energies
subroutine, public get_scaled_cell(cell, box_scale, scaled_hmat, scaled_cell, vol, abc, vec)
handles properties and calculations of a scaled cell
subroutine, public get_subtree_efficiency(tmc_env, eff)
calculated the rate of used tree elements to created tree elements for every temperature
subroutine, public get_cell_scaling(cell, scaled_hmat, box_scale)
handles properties and calculations of a scaled cell
real(kind=dp) function, public calc_e_kin(vel, atoms)
routine calculates the kinetic energy, using the velocities and atom mass, both in atomic units
subroutine, public center_of_mass(pos, atoms, center)
calculate the center of mass of an amount of atoms array size should be multiple of dim_per_elem
subroutine, public calc_potential_energy(conf, env_id, exact_approx_pot, tmc_env)
start the calculation of the energy (distinguish between exact and approximate)
real(kind=dp) function, public nearest_distance(x1, x2, cell, box_scale)
neares distance of atoms within the periodic boundary condition
tree nodes creation, searching, deallocation, references etc.
integer, parameter, public mv_type_md
tree nodes creation, searching, deallocation, references etc.
integer, parameter, public task_type_gaussian_adaptation
integer, parameter, public task_type_mc
integer, parameter, public task_type_ideal_gas
module handles definition of the tree nodes for the global and the subtrees binary tree parent elemen...
module handles definition of the tree nodes for the global and the subtrees binary tree parent elemen...
Type defining parameters related to the simulation cell.