(git:98357aa)
Loading...
Searching...
No Matches
mc_coordinates.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief contains miscellaneous subroutines used in the Monte Carlo runs,mostly
10!> geared towards changes in coordinates
11!> \author MJM
12! **************************************************************************************************
14 USE cell_types, ONLY: cell_type,&
21 USE kinds, ONLY: dp
22 USE mathconstants, ONLY: pi
31 USE physcon, ONLY: angstrom
32#include "../../base/base_uses.f90"
33
34 IMPLICIT NONE
35
36 PRIVATE
37
38 PRIVATE :: generate_avbmc_insertion
39
40 PUBLIC :: generate_cbmc_swap_config, &
47
48 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mc_coordinates'
49
50CONTAINS
51
52! **************************************************************************************************
53!> \brief looks for overlaps (intermolecular distances less than rmin)
54!> \param force_env the force environment containing the coordinates
55!> \param nchains the number of molecules of each type in the box
56!> \param nunits the number of interaction sites for each molecule
57!> \param loverlap returns .TRUE. if atoms overlap
58!> \param mol_type an array that indicates the type of each molecule
59!> \param cell_length the length of the box...if none is specified,
60!> it uses the cell found in the force_env
61!> \param molecule_number if present, just look for overlaps with this
62!> molecule
63!>
64!> Suitable for parallel use.
65!> \author MJM
66! **************************************************************************************************
67 SUBROUTINE check_for_overlap(force_env, nchains, nunits, loverlap, mol_type, &
68 cell_length, molecule_number)
69
70 TYPE(force_env_type), POINTER :: force_env
71 INTEGER, DIMENSION(:), INTENT(IN) :: nchains, nunits
72 LOGICAL, INTENT(OUT) :: loverlap
73 INTEGER, DIMENSION(:), INTENT(IN) :: mol_type
74 REAL(kind=dp), DIMENSION(1:3), INTENT(IN), &
75 OPTIONAL :: cell_length
76 INTEGER, INTENT(IN), OPTIONAL :: molecule_number
77
78 CHARACTER(len=*), PARAMETER :: routinen = 'check_for_overlap'
79
80 INTEGER :: handle, imol, iunit, jmol, jstart, &
81 junit, nend, nstart, nunit, nunits_i, &
82 nunits_j
83 LOGICAL :: lall
84 REAL(kind=dp) :: dist, rmin
85 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: r
86 REAL(kind=dp), DIMENSION(1:3) :: abc, box_length, rij
87 TYPE(cell_type), POINTER :: cell
88 TYPE(cp_subsys_type), POINTER :: oldsys
89 TYPE(particle_list_type), POINTER :: particles
90
91! begin the timing of the subroutine
92
93 CALL timeset(routinen, handle)
94
95 NULLIFY (oldsys, particles)
96
97! initialize some stuff
98 loverlap = .false.
99 rmin = 1.28558315_dp ! 0.6 angstrom squared
100
101! get the particle coordinates and the cell length
102 CALL force_env_get(force_env, cell=cell, subsys=oldsys)
103 CALL get_cell(cell, abc=abc)
104 CALL cp_subsys_get(oldsys, particles=particles)
105
106 ALLOCATE (r(1:3, 1:maxval(nunits), 1:sum(nchains)))
107
108 IF (PRESENT(cell_length)) THEN
109 box_length(1:3) = cell_length(1:3)
110 ELSE
111 box_length(1:3) = abc(1:3)
112 END IF
113
114! put the coordinates into an easier matrix to manipulate
115 junit = 0
116 DO imol = 1, sum(nchains)
117 nunit = nunits(mol_type(imol))
118 DO iunit = 1, nunit
119 junit = junit + 1
120 r(1:3, iunit, imol) = particles%els(junit)%r(1:3)
121 END DO
122 END DO
123
124! now let's find the LJ energy between all the oxygens and
125! the charge interactions
126 lall = .true.
127 jstart = 1
128 IF (PRESENT(molecule_number)) THEN
129 lall = .false.
130 nstart = molecule_number
131 nend = molecule_number
132 ELSE
133 nstart = 1
134 nend = sum(nchains(:))
135 END IF
136 DO imol = nstart, nend
137 IF (lall) jstart = imol + 1
138 nunits_i = nunits(mol_type(imol))
139 DO jmol = jstart, sum(nchains(:))
140 IF (imol == jmol) cycle
141 nunits_j = nunits(mol_type(jmol))
142
143 DO iunit = 1, nunits_i
144 DO junit = 1, nunits_j
145! find the minimum image distance
146 rij(1) = r(1, iunit, imol) - r(1, junit, jmol) - &
147 box_length(1)*anint( &
148 (r(1, iunit, imol) - r(1, junit, jmol))/box_length(1))
149 rij(2) = r(2, iunit, imol) - r(2, junit, jmol) - &
150 box_length(2)*anint( &
151 (r(2, iunit, imol) - r(2, junit, jmol))/box_length(2))
152 rij(3) = r(3, iunit, imol) - r(3, junit, jmol) - &
153 box_length(3)*anint( &
154 (r(3, iunit, imol) - r(3, junit, jmol))/box_length(3))
155
156 dist = rij(1)**2 + rij(2)**2 + rij(3)**2
157
158 IF (dist < rmin) THEN
159 loverlap = .true.
160 DEALLOCATE (r)
161
162 CALL timestop(handle)
163 RETURN
164 END IF
165
166 END DO
167 END DO
168 END DO
169 END DO
170
171 DEALLOCATE (r)
172
173! end the timing
174 CALL timestop(handle)
175
176 END SUBROUTINE check_for_overlap
177
178! **************************************************************************************************
179!> \brief calculates the center of mass of a given molecule
180!> \param coordinates the coordinates of the atoms in the molecule
181!> \param natom the number of atoms in the molecule
182!> \param center_of_mass the coordinates of the center of mass
183!> \param mass the mass of the atoms in the molecule
184!>
185!> Designed for parallel use.
186!> \author MJM
187! **************************************************************************************************
188 SUBROUTINE get_center_of_mass(coordinates, natom, center_of_mass, &
189 mass)
190
191 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: coordinates
192 INTEGER, INTENT(IN) :: natom
193 REAL(kind=dp), DIMENSION(1:3), INTENT(OUT) :: center_of_mass
194 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: mass
195
196 CHARACTER(len=*), PARAMETER :: routinen = 'get_center_of_mass'
197
198 INTEGER :: handle, i, iatom
199 REAL(kind=dp) :: total_mass
200
201! begin the timing of the subroutine
202
203 CALL timeset(routinen, handle)
204
205 total_mass = sum(mass(1:natom))
206 center_of_mass(:) = 0.0e0_dp
207
208 DO iatom = 1, natom
209 DO i = 1, 3
210 center_of_mass(i) = center_of_mass(i) + &
211 mass(iatom)*coordinates(i, iatom)
212 END DO
213 END DO
214
215 center_of_mass(1:3) = center_of_mass(1:3)/total_mass
216
217! end the timing
218 CALL timestop(handle)
219
220 END SUBROUTINE get_center_of_mass
221
222! **************************************************************************************************
223!> \brief folds all the coordinates into the center simulation box using
224!> a center of mass cutoff
225!> \param coordinates the coordinates of the atoms in the system
226!> \param nchains_tot the total number of molecules in the box
227!> \param mol_type an array that indicates the type of every molecule in the box
228!> \param mass the mass of every atom for all molecule types
229!> \param nunits the number of interaction sites for each molecule type
230!> \param box_length an array for the lengths of the simulation box sides
231!>
232!> Designed for parallel use.
233!> \author MJM
234! **************************************************************************************************
235 SUBROUTINE mc_coordinate_fold(coordinates, nchains_tot, mol_type, mass, nunits, box_length)
236
237 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: coordinates
238 INTEGER, INTENT(IN) :: nchains_tot
239 INTEGER, DIMENSION(:), INTENT(IN) :: mol_type
240 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: mass
241 INTEGER, DIMENSION(:), INTENT(IN) :: nunits
242 REAL(kind=dp), DIMENSION(1:3), INTENT(IN) :: box_length
243
244 CHARACTER(len=*), PARAMETER :: routinen = 'mc_coordinate_fold'
245
246 INTEGER :: end_atom, handle, iatom, imolecule, &
247 jatom, molecule_type, natoms, &
248 start_atom
249 REAL(kind=dp), DIMENSION(1:3) :: center_of_mass
250
251! begin the timing of the subroutine
252
253 CALL timeset(routinen, handle)
254
255! loop over all molecules
256 end_atom = 0
257 DO imolecule = 1, nchains_tot
258 molecule_type = mol_type(imolecule)
259 natoms = nunits(molecule_type)
260 start_atom = end_atom + 1
261 end_atom = start_atom + natoms - 1
262 CALL get_center_of_mass(coordinates(:, start_atom:end_atom), &
263 natoms, center_of_mass(:), mass(:, molecule_type))
264 DO iatom = 1, natoms
265 jatom = iatom + start_atom - 1
266 coordinates(1, jatom) = coordinates(1, jatom) - &
267 box_length(1)*floor(center_of_mass(1)/box_length(1))
268 coordinates(2, jatom) = coordinates(2, jatom) - &
269 box_length(2)*floor(center_of_mass(2)/box_length(2))
270 coordinates(3, jatom) = coordinates(3, jatom) - &
271 box_length(3)*floor(center_of_mass(3)/box_length(2))
272 END DO
273
274 END DO
275
276! end the timing
277 CALL timestop(handle)
278
279 END SUBROUTINE mc_coordinate_fold
280
281! **************************************************************************************************
282!> \brief takes the last molecule in a force environment and moves it around
283!> to different center of mass positions and orientations, selecting one
284!> based on the rosenbluth weight
285!> \param force_env the force environment containing the coordinates
286!> \param BETA the value of 1/kT for this simulations, in a.u.
287!> \param max_val ...
288!> \param min_val ...
289!> \param exp_max_val ...
290!> \param exp_min_val ...
291!> \param nswapmoves the number of desired trial configurations
292!> \param rosenbluth_weight the Rosenbluth weight for this set of configs
293!> \param start_atom the atom number that the molecule to be swapped starts on
294!> \param natoms_tot the total number of interaction sites in the box
295!> \param nunits the number of interaction sites for every molecule_type
296!> \param nunits_mol ...
297!> \param mass the mass for every interaction site of every molecule type
298!> \param loverlap the flag that indicates if all of the configs have an
299!> atomic overlap
300!> \param choosen_energy the energy of the chosen config
301!> \param old_energy the energy that we subtract from all of the trial
302!> energies to prevent numerical overflows
303!> \param ionode indicates if we're on the main CPU
304!> \param lremove is this the Rosenbluth weight for a removal box?
305!> \param mol_type an array that contains the molecule type for every atom in the box
306!> \param nchains the number of molecules of each type in this box
307!> \param source the MPI source value, for broadcasts
308!> \param group the MPI group value, for broadcasts
309!> \param rng_stream the random number stream that we draw from
310!> \param avbmc_atom ...
311!> \param rmin ...
312!> \param rmax ...
313!> \param move_type ...
314!> \param target_atom ...
315!> \par Optional Avbmc Flags
316!> - avbmc_atom: the atom number that serves for the target atom in each
317!> molecule (1 is the first atom in the molecule, etc.)
318!> - rmin: the minimum AVBMC radius for the shell around the target
319!> - rmax: the maximum AVBMC radius for the shell around the target
320!> - move_type: generate configs in the "in" or "out" volume
321!> - target_atom: the number of the avbmc atom in the target molecule
322!> \par
323!> Suitable for parallel.
324!> \author MJM
325! **************************************************************************************************
326 SUBROUTINE generate_cbmc_swap_config(force_env, BETA, max_val, min_val, exp_max_val, &
327 exp_min_val, nswapmoves, rosenbluth_weight, start_atom, natoms_tot, nunits, nunits_mol, &
328 mass, loverlap, choosen_energy, old_energy, ionode, lremove, mol_type, nchains, source, &
329 group, rng_stream, avbmc_atom, rmin, rmax, move_type, target_atom)
330
331 TYPE(force_env_type), POINTER :: force_env
332 REAL(kind=dp), INTENT(IN) :: beta, max_val, min_val, exp_max_val, &
333 exp_min_val
334 INTEGER, INTENT(IN) :: nswapmoves
335 REAL(kind=dp), INTENT(OUT) :: rosenbluth_weight
336 INTEGER, INTENT(IN) :: start_atom, natoms_tot
337 INTEGER, DIMENSION(:), INTENT(IN) :: nunits
338 INTEGER, INTENT(IN) :: nunits_mol
339 REAL(dp), DIMENSION(1:nunits_mol), INTENT(IN) :: mass
340 LOGICAL, INTENT(OUT) :: loverlap
341 REAL(kind=dp), INTENT(OUT) :: choosen_energy
342 REAL(kind=dp), INTENT(IN) :: old_energy
343 LOGICAL, INTENT(IN) :: ionode, lremove
344 INTEGER, DIMENSION(:), INTENT(IN) :: mol_type, nchains
345 INTEGER, INTENT(IN) :: source
346 TYPE(mp_comm_type) :: group
347 TYPE(rng_stream_type), INTENT(INOUT) :: rng_stream
348 INTEGER, INTENT(IN), OPTIONAL :: avbmc_atom
349 REAL(kind=dp), INTENT(IN), OPTIONAL :: rmin, rmax
350 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: move_type
351 INTEGER, INTENT(IN), OPTIONAL :: target_atom
352
353 CHARACTER(len=*), PARAMETER :: routinen = 'generate_cbmc_swap_config'
354
355 INTEGER :: atom_number, choosen, end_atom, handle, &
356 i, iatom, imolecule, imove, &
357 molecule_number
358 LOGICAL :: all_overlaps
359 LOGICAL, ALLOCATABLE, DIMENSION(:) :: loverlap_array
360 REAL(kind=dp) :: bias_energy, exponent, rand, &
361 total_running_weight
362 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: boltz_weights, trial_energy
363 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: r_old
364 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: r
365 REAL(kind=dp), DIMENSION(1:3) :: abc, center_of_mass, diff, r_insert
366 TYPE(cell_type), POINTER :: cell
367 TYPE(cp_subsys_type), POINTER :: oldsys
368 TYPE(particle_list_type), POINTER :: particles
369
370! begin the timing of the subroutine
371
372 CALL timeset(routinen, handle)
373
374 NULLIFY (oldsys)
375! get the particle coordinates and the cell length
376 CALL force_env_get(force_env, cell=cell, subsys=oldsys)
377 CALL get_cell(cell, abc=abc)
378 CALL cp_subsys_get(oldsys, particles=particles)
379
380! do some checking to make sure we have all the data we need
381 IF (PRESENT(avbmc_atom)) THEN
382 IF (.NOT. PRESENT(rmin) .OR. .NOT. PRESENT(rmax) .OR. &
383 .NOT. PRESENT(move_type) .OR. .NOT. PRESENT(target_atom)) THEN
384 cpabort('AVBMC swap move is missing information!')
385 END IF
386 END IF
387
388 ALLOCATE (r_old(1:3, 1:natoms_tot))
389 ALLOCATE (r(1:3, 1:natoms_tot, 1:nswapmoves))
390 ALLOCATE (trial_energy(1:nswapmoves))
391 ALLOCATE (boltz_weights(1:nswapmoves))
392 ALLOCATE (loverlap_array(1:nswapmoves))
393
394! initialize the arrays that need it
395 loverlap_array(:) = .false.
396 loverlap = .false.
397 boltz_weights(:) = 0.0_dp
398 trial_energy(:) = 0.0_dp
399 r(:, :, :) = 0.0_dp
400 choosen_energy = 0.0_dp
401 rosenbluth_weight = 0.0_dp
402
403! save the positions of the molecules
404 DO imove = 1, nswapmoves
405 DO iatom = 1, natoms_tot
406 r(1:3, iatom, imove) = particles%els(iatom)%r(1:3)
407 END DO
408 END DO
409
410! save the remove coordinates
411 DO iatom = 1, natoms_tot
412 r_old(1:3, iatom) = r(1:3, iatom, 1)
413 END DO
414
415! figure out the numbers of the first and last atoms in the molecule
416 end_atom = start_atom + nunits_mol - 1
417! figure out which molecule number we're on
418 molecule_number = 0
419 atom_number = 1
420 DO imolecule = 1, sum(nchains(:))
421 IF (atom_number == start_atom) THEN
422 molecule_number = imolecule
423 EXIT
424 END IF
425 atom_number = atom_number + nunits(mol_type(imolecule))
426 END DO
427 IF (molecule_number == 0) CALL cp_abort(__location__, &
428 'CBMC swap move cannot find which molecule number it needs')
429
430 IF (lremove) THEN
431 CALL check_for_overlap(force_env, nchains, nunits, loverlap_array(1), &
432 mol_type)
433 CALL group%bcast(loverlap_array(1), source)
434
435 IF (loverlap_array(1)) THEN
436 IF (ionode) THEN
437 WRITE (*, *) start_atom, end_atom, natoms_tot
438 DO iatom = 1, natoms_tot
439 WRITE (*, *) r(1:3, iatom, 1)
440 END DO
441 END IF
442 cpabort('CBMC swap move found an overlap in the old config')
443 END IF
444 END IF
445
446 DO imove = 1, nswapmoves
447
448! drop into serial
449 IF (ionode) THEN
450
451 IF (PRESENT(avbmc_atom)) THEN
452! find an AVBMC insertion point
453 CALL generate_avbmc_insertion(rmin, rmax, &
454 r_old(1:3, target_atom), &
455 move_type, r_insert(:), abc(:), rng_stream)
456
457 DO i = 1, 3
458 diff(i) = r_insert(i) - r_old(i, start_atom + avbmc_atom - 1)
459 END DO
460
461 ELSE
462! find a new insertion point somewhere in the box
463 DO i = 1, 3
464 rand = rng_stream%next()
465 r_insert(i) = rand*abc(i)
466 END DO
467
468! find the center of mass of the insertion molecule
469 CALL get_center_of_mass(r(:, start_atom:end_atom, imove), nunits_mol, &
470 center_of_mass(:), mass(:))
471
472! move the molecule to the insertion point
473
474 DO i = 1, 3
475 diff(i) = r_insert(i) - center_of_mass(i)
476 END DO
477
478 END IF
479
480 DO iatom = start_atom, end_atom
481 r(1:3, iatom, imove) = r(1:3, iatom, imove) + diff(1:3)
482 END DO
483
484! rotate the molecule...this routine is only made for serial use
485 CALL rotate_molecule(r(:, start_atom:end_atom, imove), mass(:), &
486 nunits_mol, rng_stream)
487
488 IF (imove == 1 .AND. lremove) THEN
489 DO iatom = 1, natoms_tot
490 r(1:3, iatom, 1) = r_old(1:3, iatom)
491 END DO
492 END IF
493
494 END IF
495
496 CALL group%bcast(r(:, :, imove), source)
497
498! calculate the energy and boltzman weight of the config
499 DO iatom = start_atom, end_atom
500 particles%els(iatom)%r(1:3) = r(1:3, iatom, imove)
501 END DO
502
503 CALL check_for_overlap(force_env, nchains, nunits, loverlap_array(imove), &
504 mol_type, molecule_number=molecule_number)
505 IF (loverlap_array(imove)) THEN
506 boltz_weights(imove) = 0.0_dp
507 cycle
508 END IF
509
510 CALL force_env_calc_energy_force(force_env, calc_force=.false.)
511 CALL force_env_get(force_env, &
512 potential_energy=bias_energy)
513
514 trial_energy(imove) = (bias_energy - old_energy)
515 exponent = -beta*trial_energy(imove)
516
517 IF (exponent > exp_max_val) THEN
518 boltz_weights(imove) = max_val
519 ELSE IF (exponent < exp_min_val) THEN
520 boltz_weights(imove) = min_val
521 ELSE
522 boltz_weights(imove) = exp(exponent)
523 END IF
524
525 END DO
526
527! now we need to pick a configuration based on the Rosenbluth weight,
528! which is just the sum of the Boltzmann weights
529 rosenbluth_weight = sum(boltz_weights(:))
530 IF (rosenbluth_weight == 0.0_dp .AND. lremove) THEN
531! should never have 0.0 for an old weight...causes a divide by zero
532! in the acceptance rule
533 IF (ionode) THEN
534 WRITE (*, *) boltz_weights(1:nswapmoves)
535 WRITE (*, *) start_atom, end_atom, lremove
536 WRITE (*, *) loverlap_array(1:nswapmoves)
537 WRITE (*, *) natoms_tot
538 WRITE (*, *)
539 DO iatom = 1, natoms_tot
540 WRITE (*, *) r(1:3, iatom, 1)*angstrom
541 END DO
542 END IF
543 cpabort('CBMC swap move found a bad old weight')
544 END IF
545 all_overlaps = .true.
546 total_running_weight = 0.0e0_dp
547 choosen = 0
548 IF (ionode) THEN
549 rand = rng_stream%next()
550! CALL random_number(rand)
551 END IF
552 CALL group%bcast(rand, source)
553 DO imove = 1, nswapmoves
554 IF (loverlap_array(imove)) cycle
555 all_overlaps = .false.
556 total_running_weight = total_running_weight + boltz_weights(imove)
557 IF (total_running_weight >= rand*rosenbluth_weight) THEN
558 choosen = imove
559 EXIT
560 END IF
561 END DO
562
563 IF (all_overlaps) THEN
564 loverlap = .true.
565
566! if this is an old configuration, we always choose the first one...
567! this should never be the case, but I'm testing something
568 IF (lremove) THEN
569 IF (ionode) THEN
570 WRITE (*, *) boltz_weights(1:nswapmoves)
571 WRITE (*, *) start_atom, end_atom, lremove
572 WRITE (*, *) loverlap_array(1:nswapmoves)
573 DO iatom = 1, natoms_tot
574 WRITE (*, *) r(1:3, iatom, 1)
575 END DO
576 END IF
577 cpabort('CBMC swap move found all overlaps for the remove config')
578 END IF
579
580 DEALLOCATE (r_old)
581 DEALLOCATE (r)
582 DEALLOCATE (trial_energy)
583 DEALLOCATE (boltz_weights)
584 DEALLOCATE (loverlap_array)
585 CALL timestop(handle)
586 RETURN
587 END IF
588
589! make sure a configuration was chosen
590 IF (choosen == 0) THEN
591 cpabort('CBMC swap move failed to select config')
592 END IF
593
594! if this is an old configuration, we always choose the first one
595 IF (lremove) choosen = 1
596
597! set the energy for the configuration
598 choosen_energy = trial_energy(choosen)
599
600! copy the coordinates to the force environment
601 DO iatom = 1, natoms_tot
602 particles%els(iatom)%r(1:3) = r(1:3, iatom, choosen)
603 END DO
604
605 DEALLOCATE (r_old)
606 DEALLOCATE (r)
607 DEALLOCATE (trial_energy)
608 DEALLOCATE (boltz_weights)
609 DEALLOCATE (loverlap_array)
610
611! end the timing
612 CALL timestop(handle)
613
614 END SUBROUTINE generate_cbmc_swap_config
615
616! **************************************************************************************************
617!> \brief rotates a molecule randomly around the center of mass,
618!> sequentially in x, y, and z directions
619!> \param r the coordinates of the molecule to rotate
620!> \param mass the mass of all the atoms in the molecule
621!> \param natoms the number of atoms in the molecule
622!> \param rng_stream the stream we pull random numbers from
623!>
624!> Use only in serial.
625!> \author MJM
626! **************************************************************************************************
627 SUBROUTINE rotate_molecule(r, mass, natoms, rng_stream)
628
629 INTEGER, INTENT(IN) :: natoms
630 REAL(kind=dp), DIMENSION(1:natoms), INTENT(IN) :: mass
631 REAL(kind=dp), DIMENSION(1:3, 1:natoms), &
632 INTENT(INOUT) :: r
633 TYPE(rng_stream_type), INTENT(INOUT) :: rng_stream
634
635 CHARACTER(len=*), PARAMETER :: routinen = 'rotate_molecule'
636
637 INTEGER :: handle, iunit
638 REAL(kind=dp) :: cosdg, dgamma, rand, rx, rxnew, ry, &
639 rynew, rz, rznew, sindg
640 REAL(kind=dp), DIMENSION(1:3) :: center_of_mass
641
642! begin the timing of the subroutine
643
644 CALL timeset(routinen, handle)
645
646! find the center of mass of the molecule
647 CALL get_center_of_mass(r(:, :), natoms, center_of_mass(:), mass(:))
648
649! call a random number to figure out how far we're moving
650 rand = rng_stream%next()
651 dgamma = pi*(rand - 0.5e0_dp)*2.0e0_dp
652
653! *** set up the rotation matrix ***
654
655 cosdg = cos(dgamma)
656 sindg = sin(dgamma)
657
658! *** ROTATE UNITS OF I AROUND X-AXIS ***
659
660 DO iunit = 1, natoms
661 ry = r(2, iunit) - center_of_mass(2)
662 rz = r(3, iunit) - center_of_mass(3)
663 rynew = cosdg*ry + sindg*rz
664 rznew = cosdg*rz - sindg*ry
665
666 r(2, iunit) = rynew + center_of_mass(2)
667 r(3, iunit) = rznew + center_of_mass(3)
668
669 END DO
670
671! *** ROTATE UNITS OF I AROUND y-AXIS ***
672
673 DO iunit = 1, natoms
674 rx = r(1, iunit) - center_of_mass(1)
675 rz = r(3, iunit) - center_of_mass(3)
676 rxnew = cosdg*rx + sindg*rz
677 rznew = cosdg*rz - sindg*rx
678
679 r(1, iunit) = rxnew + center_of_mass(1)
680 r(3, iunit) = rznew + center_of_mass(3)
681
682 END DO
683
684! *** ROTATE UNITS OF I AROUND z-AXIS ***
685
686 DO iunit = 1, natoms
687 rx = r(1, iunit) - center_of_mass(1)
688 ry = r(2, iunit) - center_of_mass(2)
689 rxnew = cosdg*rx + sindg*ry
690 rynew = cosdg*ry - sindg*rx
691
692 r(1, iunit) = rxnew + center_of_mass(1)
693 r(2, iunit) = rynew + center_of_mass(2)
694
695 END DO
696
697! end the timing
698 CALL timestop(handle)
699
700 END SUBROUTINE rotate_molecule
701
702! **************************************************************************************************
703!> \brief selects a molecule at random to perform a MC move on...you can specify
704!> the box the molecule should be in, its type, both, or neither
705!> \param mc_molecule_info the structure that contains some global molecule data
706!> \param start_atom the number of the first atom in the chosen molecule in relation
707!> to the force_env it's in
708!> \param box_number the box the chosen molecule is in
709!> \param molecule_type the type of molecule the chosen molecule is
710!> \param rng_stream the stream we pull random numbers from
711!> \param box if present, tells the routine which box to grab a molecule from
712!> \param molecule_type_old if present, tells the routine which molecule type to select from
713!> \author MJM
714! **************************************************************************************************
715 SUBROUTINE find_mc_test_molecule(mc_molecule_info, start_atom, &
716 box_number, molecule_type, rng_stream, box, molecule_type_old)
717
718 TYPE(mc_molecule_info_type), POINTER :: mc_molecule_info
719 INTEGER, INTENT(OUT) :: start_atom, box_number, molecule_type
720 TYPE(rng_stream_type), INTENT(INOUT) :: rng_stream
721 INTEGER, INTENT(IN), OPTIONAL :: box, molecule_type_old
722
723 CHARACTER(LEN=*), PARAMETER :: routinen = 'find_mc_test_molecule'
724
725 INTEGER :: handle, ibox, imol_type, imolecule, &
726 jbox, molecule_number, nchains_tot, &
727 start_mol
728 INTEGER, DIMENSION(:), POINTER :: mol_type, nunits
729 INTEGER, DIMENSION(:, :), POINTER :: nchains
730 REAL(kind=dp) :: rand
731
732! begin the timing of the subroutine
733
734 CALL timeset(routinen, handle)
735
736 NULLIFY (nunits, mol_type, nchains)
737 CALL get_mc_molecule_info(mc_molecule_info, nchains=nchains, nunits=nunits, &
738 mol_type=mol_type)
739
740! initialize the outgoing variables
741 start_atom = 0
742 box_number = 0
743 molecule_type = 0
744
745 IF (PRESENT(box) .AND. PRESENT(molecule_type_old)) THEN
746! only need to find the atom number the molecule starts on
747 rand = rng_stream%next()
748 molecule_number = ceiling(rand*real(nchains(molecule_type_old, box), kind=dp))
749
750 start_mol = 1
751 DO jbox = 1, box - 1
752 start_mol = start_mol + sum(nchains(:, jbox))
753 END DO
754
755! adjust to take into account molecules of other types in the box
756 DO imol_type = 1, molecule_type_old - 1
757 molecule_number = molecule_number + nchains(imol_type, box)
758 END DO
759
760 start_atom = 1
761 DO imolecule = 1, molecule_number - 1
762 start_atom = start_atom + nunits(mol_type(start_mol + imolecule - 1))
763 END DO
764
765 ELSE IF (PRESENT(box)) THEN
766! any molecule in box...need to find molecule type and start atom
767 rand = rng_stream%next()
768 molecule_number = ceiling(rand*real(sum(nchains(:, box)), kind=dp))
769
770 start_mol = 1
771 DO jbox = 1, box - 1
772 start_mol = start_mol + sum(nchains(:, jbox))
773 END DO
774
775 molecule_type = mol_type(start_mol + molecule_number - 1)
776
777! now the starting atom
778 start_atom = 1
779 DO imolecule = 1, molecule_number - 1
780 start_atom = start_atom + nunits(mol_type(start_mol + imolecule - 1))
781 END DO
782
783 ELSE IF (PRESENT(molecule_type_old)) THEN
784! any molecule of type molecule_type_old...need to find box number and start atom
785 rand = rng_stream%next()
786 molecule_number = ceiling(rand*real(sum(nchains(molecule_type_old, :)), kind=dp))
787
788! find which box it's in
789 nchains_tot = 0
790 DO ibox = 1, SIZE(nchains(molecule_type_old, :))
791 IF (molecule_number <= nchains(molecule_type_old, ibox)) THEN
792 box_number = ibox
793 EXIT
794 END IF
795 molecule_number = molecule_number - nchains(molecule_type_old, ibox)
796 END DO
797
798 start_mol = 1
799 DO jbox = 1, box_number - 1
800 start_mol = start_mol + sum(nchains(:, jbox))
801 END DO
802
803! now find the starting atom number
804 DO imol_type = 1, molecule_type_old - 1
805 molecule_number = molecule_number + nchains(imol_type, box_number)
806 END DO
807 start_atom = 1
808 DO imolecule = 1, molecule_number - 1
809 start_atom = start_atom + nunits(mol_type(start_mol + imolecule - 1))
810 END DO
811
812 ELSE
813! no restrictions...need to find all pieces of data
814 nchains_tot = 0
815 DO ibox = 1, SIZE(nchains(1, :))
816 nchains_tot = nchains_tot + sum(nchains(:, ibox))
817 END DO
818 rand = rng_stream%next()
819 molecule_number = ceiling(rand*real(nchains_tot, kind=dp))
820
821 molecule_type = mol_type(molecule_number)
822
823! now which box it's in
824 DO ibox = 1, sum(nchains(1, :))
825 IF (molecule_number <= sum(nchains(:, ibox))) THEN
826 box_number = ibox
827 EXIT
828 END IF
829 molecule_number = molecule_number - sum(nchains(:, ibox))
830 END DO
831
832! now find the starting atom number
833 start_mol = 1
834 DO jbox = 1, box_number - 1
835 start_mol = start_mol + sum(nchains(:, jbox))
836 END DO
837 start_atom = 1
838 DO imolecule = 1, molecule_number - 1
839 start_atom = start_atom + nunits(mol_type(start_mol + imolecule - 1))
840 END DO
841
842 END IF
843
844! make sure things are good
845 IF (PRESENT(box)) box_number = box
846 IF (PRESENT(molecule_type_old)) molecule_type = molecule_type_old
847
848 cpassert(start_atom /= 0)
849 cpassert(box_number /= 0)
850 cpassert(molecule_type /= 0)
851
852! end the timing
853 CALL timestop(handle)
854
855 END SUBROUTINE find_mc_test_molecule
856
857! **************************************************************************************************
858!> \brief generates an array that tells us which sides of the simulation
859!> cell we can increase or decrease using a discrete volume move
860!> \param cell the lengths of the sides of the cell
861!> \param discrete_array the array that indicates which sides we can move
862!> \param step_size the size of the discrete volume move
863!>
864!> Suitable for parallel.
865!> \author MJM
866! **************************************************************************************************
867 SUBROUTINE create_discrete_array(cell, discrete_array, step_size)
868
869! 1 is for increase, 2 is for decrease
870! 1 is for "yes, we can do the move", 0 is for no
871
872 REAL(dp), DIMENSION(1:3), INTENT(IN) :: cell
873 INTEGER, DIMENSION(1:3, 1:2), INTENT(OUT) :: discrete_array
874 REAL(dp), INTENT(IN) :: step_size
875
876 INTEGER :: iside
877 REAL(dp) :: high_value, length1, length2, low_value
878
879 discrete_array(:, :) = 0
880
881 length1 = abs(cell(1) - cell(2))
882 length2 = abs(cell(2) - cell(3))
883
884! now let's figure out all the different cases
885 IF (length1 < 0.01_dp*step_size .AND. &
886 length2 < 0.01_dp*step_size) THEN
887! all sides are equal, so we can move up or down
888 discrete_array(1:3, 1) = 1
889 discrete_array(1:3, 2) = 1
890 ELSE
891
892! find the low value and the high value
893 high_value = -1.0_dp
894 low_value = cell(1)*cell(2)*cell(3)
895 DO iside = 1, 3
896 IF (cell(iside) < low_value) low_value = cell(iside)
897 IF (cell(iside) > high_value) high_value = cell(iside)
898 END DO
899 DO iside = 1, 3
900! now we see if the value is a high value or a low value...it can only be
901! one of the two
902 IF (abs(cell(iside) - low_value) < 0.01_dp*step_size) THEN
903! low value, we can only increase the cell size
904 discrete_array(iside, 1) = 1
905 discrete_array(iside, 2) = 0
906 ELSE
907! high value, we can only decrease the cell size
908 discrete_array(iside, 1) = 0
909 discrete_array(iside, 2) = 1
910 END IF
911 END DO
912 END IF
913
914 END SUBROUTINE create_discrete_array
915
916! **************************************************************************************************
917!> \brief generates an insertion point in either the "in" or the "out" volume
918!> of a target atom, where the "in" volume is a shell with inner radius
919!> rmin and outer radius rmax
920!> \param rmin the minimum AVBMC radius for the shell around the target
921!> \param rmax the maximum AVBMC radius for the shell around the target
922!> \param r_target the coordinates of the target atom
923!> \param move_type generate configs in the "in" or "out" volume
924!> \param r_insert the output insertion site
925!> \param abc the lengths of the sides of the simulation box
926!> \param rng_stream the random number stream that we draw from
927!>
928!> Use only in serial.
929!> \author MJM
930! **************************************************************************************************
931 SUBROUTINE generate_avbmc_insertion(rmin, rmax, r_target, &
932 move_type, r_insert, abc, rng_stream)
933
934 REAL(kind=dp), INTENT(IN) :: rmin, rmax
935 REAL(kind=dp), DIMENSION(1:3), INTENT(IN) :: r_target
936 CHARACTER(LEN=*), INTENT(IN) :: move_type
937 REAL(kind=dp), DIMENSION(1:3), INTENT(OUT) :: r_insert
938 REAL(kind=dp), DIMENSION(1:3), INTENT(IN) :: abc
939 TYPE(rng_stream_type), INTENT(INOUT) :: rng_stream
940
941 INTEGER :: i
942 REAL(dp) :: dist, eta_1, eta_2, eta_sq, rand
943 REAL(dp), DIMENSION(1:3) :: rij
944
945 r_insert(1:3) = 0.0_dp
946
947 IF (move_type == 'in') THEN
948! generate a random unit vector, from Allen and Tildesley
949 DO
950 eta_1 = rng_stream%next()
951 eta_2 = rng_stream%next()
952 eta_sq = eta_1**2 + eta_2**2
953 IF (eta_sq < 1.0_dp) THEN
954 r_insert(1) = 2.0_dp*eta_1*sqrt(1.0_dp - eta_sq)
955 r_insert(2) = 2.0_dp*eta_2*sqrt(1.0_dp - eta_sq)
956 r_insert(3) = 1.0_dp - 2.0_dp*eta_sq
957 EXIT
958 END IF
959 END DO
960
961! now scale that vector to be within the "in" region
962 rand = rng_stream%next()
963 r_insert(1:3) = r_insert(1:3)*(rand*(rmax**3 - rmin**3) + rmin**3)** &
964 (1.0_dp/3.0_dp)
965
966 r_insert(1:3) = r_target(1:3) + r_insert(1:3)
967 ELSE
968
969! find a new insertion point somewhere in the box
970 DO
971 DO i = 1, 3
972 rand = rng_stream%next()
973 r_insert(i) = rand*abc(i)
974 END DO
975
976! make sure it's not in the "in" region
977 rij(1) = r_insert(1) - r_target(1) - abc(1)* &
978 anint((r_insert(1) - r_target(1))/abc(1))
979 rij(2) = r_insert(2) - r_target(2) - abc(2)* &
980 anint((r_insert(2) - r_target(2))/abc(2))
981 rij(3) = r_insert(3) - r_target(3) - abc(3)* &
982 anint((r_insert(3) - r_target(3))/abc(3))
983
984 dist = rij(1)**2 + rij(2)**2 + rij(3)**2
985
986 IF (dist < rmin**2 .OR. dist > rmax**2) THEN
987 EXIT
988 END IF
989
990 END DO
991 END IF
992
993 END SUBROUTINE generate_avbmc_insertion
994
995! *****************************************************************************
996! **************************************************************************************************
997!> \brief determine the number of cluster present in the given configuration
998!> based on the rclus value
999!> \param mc_par the mc parameters for the force env
1000!> \param force_env the force environment containing the coordinates
1001!> \param cluster ...
1002!> \param nchains the number of molecules of each type in the box
1003!> \param nunits the number of interaction sites for each molecule
1004!> \param mol_type an array that indicates the type of each molecule
1005!> \param total_clus ...
1006!> \par
1007!> Original Multiparticle/Cluster Translation paper:
1008!> Orkoulas, Gerassimos, and Athanassios Z. Panagiotopoulos. Free energy and
1009!> phase equilibria for the restricted primitive model of ionic fluids from Monte
1010!> Carlo simulations. J. Chem. Phys. 1994,101.2,1452-1459.
1011!> \author Himanshu Goel
1012! **************************************************************************************************
1013
1014 SUBROUTINE cluster_search(mc_par, force_env, cluster, nchains, nunits, mol_type, total_clus)
1015
1016 TYPE(mc_simpar_type), POINTER :: mc_par
1017 TYPE(force_env_type), POINTER :: force_env
1018 INTEGER, DIMENSION(:, :), INTENT(INOUT) :: cluster
1019 INTEGER, DIMENSION(:), INTENT(IN) :: nchains, nunits, mol_type
1020 INTEGER, INTENT(INOUT) :: total_clus
1021
1022 CHARACTER(len=*), PARAMETER :: routinen = 'cluster_search'
1023
1024 INTEGER :: counter, handle, imol, iunit, jmol, &
1025 junit, nend, nstart, nunit, nunits_i, &
1026 nunits_j
1027 INTEGER, ALLOCATABLE, DIMENSION(:) :: clusmat, decision
1028 LOGICAL :: lclus
1029 REAL(kind=dp) :: dx, dy, dz, rclus, rclussquare, rsquare
1030 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: xcoord, ycoord, zcoord
1031 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: r
1032 REAL(kind=dp), DIMENSION(1:3) :: abc
1033 TYPE(cell_type), POINTER :: cell
1034 TYPE(cp_subsys_type), POINTER :: oldsys
1035 TYPE(particle_list_type), POINTER :: particles
1036
1037! begin the timing of the subroutine
1038
1039 CALL timeset(routinen, handle)
1040
1041 NULLIFY (oldsys, particles)
1042
1043! Getting Particle Coordinates
1044
1045 CALL force_env_get(force_env, cell=cell, subsys=oldsys)
1046 CALL get_cell(cell, abc=abc)
1047 CALL cp_subsys_get(oldsys, particles=particles)
1048 CALL get_mc_par(mc_par, rclus=rclus)
1049
1050 ALLOCATE (r(1:3, 1:maxval(nunits), 1:sum(nchains)))
1051
1052! Arranging particles coordinates into an easier matrix
1053 nend = sum(nchains(:))
1054 junit = 0
1055 DO imol = 1, nend
1056 nunit = nunits(mol_type(imol))
1057 DO iunit = 1, nunit
1058 junit = junit + 1
1059 r(1:3, iunit, imol) = particles%els(junit)%r(1:3)
1060 END DO
1061 END DO
1062
1063 counter = 0
1064
1065! Allocating the size of matrix and decision matrix
1066 ALLOCATE (clusmat(nend), decision(nend))
1067
1068!Initialize
1069 DO imol = 1, nend
1070 decision(imol) = 0
1071 clusmat(imol) = 0
1072 END DO
1073
1074 rclussquare = rclus*rclus
1075! Starting the cluster count loop
1076 DO WHILE (sum(decision) < nend)
1077 DO nstart = 1, nend
1078 IF (clusmat(nstart) == 0) THEN
1079 counter = counter + 1
1080 clusmat(nstart) = counter
1081 EXIT
1082 END IF
1083 END DO
1084
1085 lclus = .true.
1086 DO WHILE (lclus .EQV. .true.)
1087 DO imol = 1, nend
1088 nunits_i = nunits(mol_type(imol))
1089! Allocating the xcoord,ycoord,zcoord based upon the size of molecule nunits
1090 lclus = .false.
1091 IF (clusmat(imol) == counter .AND. decision(imol) == 0) THEN
1092 ALLOCATE (xcoord(nunits_i), ycoord(nunits_i), zcoord(nunits_i))
1093 decision(imol) = 1
1094 lclus = .true.
1095 DO iunit = 1, nunits_i
1096 xcoord(iunit) = r(1, iunit, imol)
1097 ycoord(iunit) = r(2, iunit, imol)
1098 zcoord(iunit) = r(3, iunit, imol)
1099 END DO
1100 EXIT
1101 END IF
1102 END DO
1103 IF (lclus .EQV. .true.) THEN
1104 DO jmol = 1, nend
1105 nunits_j = nunits(mol_type(jmol))
1106 IF (clusmat(jmol) == 0 .AND. decision(jmol) == 0) THEN
1107!Calculating the distance between atoms
1108 DO iunit = 1, nunits_i
1109 DO junit = 1, nunits_j
1110 dx = xcoord(iunit) - r(1, junit, jmol)
1111 dy = ycoord(iunit) - r(2, junit, jmol)
1112 dz = zcoord(iunit) - r(3, junit, jmol)
1113 dx = dx - abc(1)*anint(dx/abc(1))
1114 dy = dy - abc(2)*anint(dy/abc(2))
1115 dz = dz - abc(3)*anint(dz/abc(3))
1116 rsquare = (dx*dx) + (dy*dy) + (dz*dz)
1117!Checking the distance based on rclus square(rclussq)
1118 IF (rsquare < rclussquare) THEN
1119 clusmat(jmol) = counter
1120 END IF
1121 END DO
1122 END DO
1123 END IF
1124 END DO
1125 DEALLOCATE (xcoord, ycoord, zcoord)
1126 END IF
1127 END DO
1128 END DO
1129
1130!Putting cluster information in a cluster matrix
1131 total_clus = counter
1132
1133 DO imol = 1, counter
1134 DO jmol = 1, nend
1135 IF (imol == clusmat(jmol)) THEN
1136 cluster(imol, jmol) = jmol
1137 END IF
1138 END DO
1139 END DO
1140 DEALLOCATE (r)
1141 DEALLOCATE (decision)
1142 DEALLOCATE (clusmat)
1143
1144! end the timing
1145 CALL timestop(handle)
1146
1147 END SUBROUTINE cluster_search
1148
1149END MODULE mc_coordinates
1150
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
Definition cell_types.F:233
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell)
returns information about various attributes of the given subsys
Interface for the force calculations.
recursive subroutine, public force_env_calc_energy_force(force_env, calc_force, consistent_energies, skip_external_control, eval_energy_forces, require_consistent_energy_force, linres, calc_stress_tensor)
Interface routine for force and energy calculations.
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env, ipi_env)
returns various attributes about the force environment
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
contains miscellaneous subroutines used in the Monte Carlo runs,mostly geared towards changes in coor...
subroutine, public generate_cbmc_swap_config(force_env, beta, max_val, min_val, exp_max_val, exp_min_val, nswapmoves, rosenbluth_weight, start_atom, natoms_tot, nunits, nunits_mol, mass, loverlap, choosen_energy, old_energy, ionode, lremove, mol_type, nchains, source, group, rng_stream, avbmc_atom, rmin, rmax, move_type, target_atom)
takes the last molecule in a force environment and moves it around to different center of mass positi...
subroutine, public get_center_of_mass(coordinates, natom, center_of_mass, mass)
calculates the center of mass of a given molecule
subroutine, public check_for_overlap(force_env, nchains, nunits, loverlap, mol_type, cell_length, molecule_number)
looks for overlaps (intermolecular distances less than rmin)
subroutine, public mc_coordinate_fold(coordinates, nchains_tot, mol_type, mass, nunits, box_length)
folds all the coordinates into the center simulation box using a center of mass cutoff
subroutine, public find_mc_test_molecule(mc_molecule_info, start_atom, box_number, molecule_type, rng_stream, box, molecule_type_old)
selects a molecule at random to perform a MC move on...you can specify the box the molecule should be...
subroutine, public rotate_molecule(r, mass, natoms, rng_stream)
rotates a molecule randomly around the center of mass, sequentially in x, y, and z directions
subroutine, public create_discrete_array(cell, discrete_array, step_size)
generates an array that tells us which sides of the simulation cell we can increase or decrease using...
subroutine, public cluster_search(mc_par, force_env, cluster, nchains, nunits, mol_type, total_clus)
determine the number of cluster present in the given configuration based on the rclus value
holds all the structure types needed for Monte Carlo, except the mc_environment_type
Definition mc_types.F:15
subroutine, public get_mc_par(mc_par, nstep, nvirial, iuptrans, iupcltrans, iupvolume, nmoves, nswapmoves, rm, cl, diff, nstart, source, group, lbias, ionode, lrestart, lstop, rmvolume, rmcltrans, rmbond, rmangle, rmrot, rmtrans, temperature, pressure, rclus, beta, pmswap, pmvolume, pmtraion, pmtrans, pmcltrans, ensemble, program, restart_file_name, molecules_file, moves_file, coords_file, energy_file, displacement_file, cell_file, dat_file, data_file, box2_file, fft_lib, iprint, rcut, ldiscrete, discrete_step, pmavbmc, pbias, avbmc_atom, avbmc_rmin, avbmc_rmax, rmdihedral, input_file, mc_molecule_info, pmswap_mol, pmavbmc_mol, pmtrans_mol, pmrot_mol, pmtraion_mol, mc_input_file, mc_bias_file, pmvol_box, pmclus_box, virial_temps, exp_min_val, exp_max_val, min_val, max_val, eta, pmhmc, pmhmc_box, lhmc, rand2skip)
...
Definition mc_types.F:405
subroutine, public get_mc_molecule_info(mc_molecule_info, nmol_types, nchain_total, nboxes, names, conf_prob, nchains, nunits, mol_type, nunits_tot, in_box, atom_names, mass)
...
Definition mc_types.F:554
Interface to the message passing library MPI.
Define the data structure for the molecule information.
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
represent a simple array based list of the given type
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represents a system: atoms, molecules, their pos,vel,...
wrapper to abstract the force evaluation of the various methods