114 SUBROUTINE mc_run_ensemble(mc_env, para_env, globenv, input_declaration, nboxes, rng_stream)
120 INTEGER,
INTENT(IN) :: nboxes
123 CHARACTER(len=*),
PARAMETER :: routinen =
'mc_run_ensemble'
125 CHARACTER(default_string_length),
ALLOCATABLE, &
126 DIMENSION(:) :: atom_names_box
127 CHARACTER(default_string_length), &
128 DIMENSION(:, :),
POINTER :: atom_names
129 CHARACTER(LEN=20) :: ensemble
130 CHARACTER(LEN=40) :: cbox, cstep,
fft_lib, move_type, &
132 INTEGER,
DIMENSION(:, :),
POINTER :: nchains
133 INTEGER,
DIMENSION(:),
POINTER :: avbmc_atom, mol_type, nchains_box, &
135 INTEGER,
DIMENSION(1:nboxes) :: box_flag, cl, data_unit, diff, istep, &
137 INTEGER,
DIMENSION(1:3, 1:2) :: discrete_array
138 INTEGER :: atom_number, box_number, cell_unit, com_crd, com_ene, com_mol, end_mol, handle, &
139 ibox, idum, imol_type, imolecule, imove, iparticle, iprint, itype, iunit, iuptrans, &
140 iupvolume, iw, jbox, jdum, molecule_type, molecule_type_swap, molecule_type_target, &
141 nchain_total, nmol_types, nmoves, nnstep, nstart, nstep, source, start_atom, &
142 start_atom_swap, start_atom_target, start_mol
143 CHARACTER(LEN=default_string_length) :: unit_str
144 CHARACTER(LEN=40),
DIMENSION(1:nboxes) :: cell_file, coords_file, data_file, &
145 displacement_file, energy_file, &
146 molecules_file, moves_file
147 LOGICAL :: ionode, lbias, ldiscrete, lhmc, &
148 lnew_bias_env, loverlap, lreject, &
149 lstop, print_kind, should_stop
150 REAL(
dp),
DIMENSION(:),
POINTER :: pbias, pmavbmc_mol, pmclus_box, &
151 pmhmc_box, pmrot_mol, pmtraion_mol, &
152 pmtrans_mol, pmvol_box
153 REAL(
dp),
DIMENSION(:, :),
POINTER :: conf_prob, mass
154 REAL(kind=
dp) :: discrete_step, pmavbmc, pmcltrans, &
155 pmhmc, pmswap, pmtraion, pmtrans, &
156 pmvolume, rand, test_energy, unit_conv
157 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: r_temp
158 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: r_old
159 REAL(kind=
dp),
DIMENSION(1:3, 1:nboxes) :: abc
160 REAL(kind=
dp),
DIMENSION(1:nboxes) :: bias_energy, energy_check, final_energy, &
161 initial_energy, last_bias_energy, &
173 DIMENSION(:),
POINTER :: mc_par
179 CALL timeset(routinen, handle)
182 NULLIFY (moves, move_updates, test_moves, root_section)
185 ALLOCATE (force_env(1:nboxes))
186 ALLOCATE (bias_env(1:nboxes))
187 ALLOCATE (cell(1:nboxes))
188 ALLOCATE (particles_old(1:nboxes))
189 ALLOCATE (oldsys(1:nboxes))
190 ALLOCATE (averages(1:nboxes))
191 ALLOCATE (mc_par(1:nboxes))
192 ALLOCATE (pmvol_box(1:nboxes))
193 ALLOCATE (pmclus_box(1:nboxes))
194 ALLOCATE (pmhmc_box(1:nboxes))
198 mc_par=mc_par(ibox)%mc_par, &
199 force_env=force_env(ibox)%force_env)
203 root_section => force_env(1)%force_env%root_section
212 ionode=ionode, source=source, group=group, &
213 data_file=data_file(1), moves_file=moves_file(1), &
214 cell_file=cell_file(1), coords_file=coords_file(1), &
215 energy_file=energy_file(1), displacement_file=displacement_file(1), &
216 lstop=lstop, nstep=nstep, nstart=nstart, pmvolume=pmvolume, pmhmc=pmhmc, &
217 molecules_file=molecules_file(1), pmswap=pmswap, nmoves=nmoves, &
218 pmtraion=pmtraion, pmtrans=pmtrans, pmcltrans=pmcltrans, iuptrans=iuptrans, &
219 iupvolume=iupvolume, ldiscrete=ldiscrete, pmtraion_mol=pmtraion_mol, &
220 lbias=lbias, iprint=iprint, pmavbmc_mol=pmavbmc_mol, &
221 discrete_step=discrete_step,
fft_lib=
fft_lib, avbmc_atom=avbmc_atom, &
222 pmavbmc=pmavbmc, pbias=pbias, mc_molecule_info=mc_molecule_info, &
223 pmrot_mol=pmrot_mol, pmtrans_mol=pmtrans_mol, pmvol_box=pmvol_box(1), &
224 pmclus_box=pmclus_box(1), ensemble=ensemble, pmhmc_box=pmhmc_box(1), lhmc=lhmc)
228 nchains=nchains, nmol_types=nmol_types, nunits_tot=nunits_tot, &
229 mol_type=mol_type, nchain_total=nchain_total, nunits=nunits, &
230 atom_names=atom_names, mass=mass)
233 ALLOCATE (moves(1:nmol_types, 1:nboxes))
234 ALLOCATE (move_updates(1:nmol_types, 1:nboxes))
236 IF (nboxes .GT. 1)
THEN
239 data_file=data_file(ibox), &
240 moves_file=moves_file(ibox), &
241 cell_file=cell_file(ibox), coords_file=coords_file(ibox), &
242 energy_file=energy_file(ibox), &
243 displacement_file=displacement_file(ibox), &
244 molecules_file=molecules_file(ibox), pmvol_box=pmvol_box(ibox), &
245 pmclus_box=pmclus_box(ibox), pmhmc_box=pmhmc_box(ibox))
250 IF (pmvol_box(nboxes) .LT. 1.0e0_dp)
THEN
251 cpabort(
'The last value of PMVOL_BOX needs to be 1.0')
253 IF (pmclus_box(nboxes) .LT. 1.0e0_dp)
THEN
254 cpabort(
'The last value of PMVOL_BOX needs to be 1.0')
256 IF (pmhmc_box(nboxes) .LT. 1.0e0_dp)
THEN
257 cpabort(
'The last value of PMHMC_BOX needs to be 1.0')
261 ALLOCATE (r_old(3, sum(nunits_tot), 1:nboxes))
269 WRITE (iw, *)
'Beginning the Monte Carlo calculation.'
275 energy_check(:) = 0.0e0_dp
282 DO itype = 1, nmol_types
289 IF (sum(nchains(:, ibox)) .NE. 0)
THEN
293 potential_energy=old_energy(ibox))
295 old_energy(ibox) = 0.0e0_dp
297 initial_energy(ibox) = old_energy(ibox)
304 DO jbox = 1, ibox - 1
305 start_mol = start_mol + sum(nchains(:, jbox))
307 end_mol = start_mol + sum(nchains(:, ibox)) - 1
309 nunits, loverlap, mol_type(start_mol:end_mol))
310 IF (loverlap) cpabort(
"overlap in an initial configuration")
315 subsys=oldsys(ibox)%subsys, cell=cell(ibox)%cell)
316 CALL get_cell(cell(ibox)%cell, abc=abc(:, ibox))
318 particles=particles_old(ibox)%list)
320 DO iparticle = 1, nunits_tot(ibox)
321 r_old(1:3, iparticle, ibox) = &
322 particles_old(ibox)%list%els(iparticle)%r(1:3)
328 ALLOCATE (atom_names_box(1:nunits_tot(ibox)))
331 DO imolecule = 1, sum(nchains(:, ibox))
332 DO iunit = 1, nunits(mol_type(imolecule + start_mol - 1))
333 atom_names_box(atom_number) = &
334 atom_names(iunit, mol_type(imolecule + start_mol - 1))
335 atom_number = atom_number + 1
339 CALL get_mc_par(mc_par(ibox)%mc_par, mc_bias_file=mc_bias_file)
340 nchains_box => nchains(:, ibox)
342 r_old(:, :, ibox), atom_names_box(:), nunits_tot(ibox), &
343 para_env, abc(:, ibox), nchains_box, input_declaration, mc_bias_file, &
345 IF (sum(nchains(:, ibox)) .NE. 0)
THEN
349 potential_energy=last_bias_energy(ibox))
352 last_bias_energy(ibox) = 0.0e0_dp
354 bias_energy(ibox) = last_bias_energy(ibox)
355 DEALLOCATE (atom_names_box)
357 lnew_bias_env = .false.
365 CALL open_file(file_name=
'mc_cell_length', &
366 unit_number=cell_unit, file_position=
'APPEND', &
367 file_action=
'WRITE', file_status=
'UNKNOWN')
368 CALL open_file(file_name=
'mc_energies', &
369 unit_number=com_ene, file_position=
'APPEND', &
370 file_action=
'WRITE', file_status=
'UNKNOWN')
371 CALL open_file(file_name=
'mc_coordinates', &
372 unit_number=com_crd, file_position=
'APPEND', &
373 file_action=
'WRITE', file_status=
'UNKNOWN')
374 CALL open_file(file_name=
'mc_molecules', &
375 unit_number=com_mol, file_position=
'APPEND', &
376 file_action=
'WRITE', file_status=
'UNKNOWN')
377 WRITE (com_ene, *)
'Initial Energies: ', &
380 WRITE (com_mol, *)
'Initial Molecules: ', &
384 WRITE (cell_unit, *)
'Initial: ', &
386 WRITE (cbox,
'(I4)') ibox
387 CALL open_file(file_name=
'energy_differences_box'// &
388 trim(adjustl(cbox)), &
389 unit_number=diff(ibox), file_position=
'APPEND', &
390 file_action=
'WRITE', file_status=
'UNKNOWN')
391 IF (sum(nchains(:, ibox)) == 0)
THEN
392 WRITE (com_crd, *)
' 0'
393 WRITE (com_crd, *)
'INITIAL BOX '//trim(adjustl(cbox))
396 com_crd,
dump_xmol,
'POS',
'INITIAL BOX '//trim(adjustl(cbox)), &
397 unit_conv=unit_conv, print_kind=print_kind)
399 CALL open_file(file_name=data_file(ibox), &
400 unit_number=data_unit(ibox), file_position=
'APPEND', &
401 file_action=
'WRITE', file_status=
'UNKNOWN')
402 CALL open_file(file_name=moves_file(ibox), &
403 unit_number=move_unit(ibox), file_position=
'APPEND', &
404 file_action=
'WRITE', file_status=
'UNKNOWN')
405 CALL open_file(file_name=displacement_file(ibox), &
406 unit_number=rm(ibox), file_position=
'APPEND', &
407 file_action=
'WRITE', file_status=
'UNKNOWN')
408 CALL open_file(file_name=cell_file(ibox), &
409 unit_number=cl(ibox), file_position=
'APPEND', &
410 file_action=
'WRITE', file_status=
'UNKNOWN')
418 CALL group%bcast(cl(ibox), source)
419 CALL group%bcast(rm(ibox), source)
420 CALL group%bcast(diff(ibox), source)
422 CALL set_mc_par(mc_par(ibox)%mc_par, cl=cl(ibox), rm=rm(ibox), &
430 cpabort(
'ldiscrete=.true. ONLY for systems with 1 box')
437 IF (.NOT. lstop)
THEN
438 nstep = nstep*nchain_total
439 iuptrans = iuptrans*nchain_total
440 iupvolume = iupvolume*nchain_total
443 DO nnstep = nstart + 1, nstart + nstep
445 IF (mod(nnstep, iprint) == 0 .AND. (iw > 0))
THEN
447 WRITE (iw, *)
"------- On Monte Carlo Step ", nnstep
450 IF (ionode) rand = rng_stream%next()
452 CALL group%bcast(rand, source)
454 IF (rand .LT. pmvolume)
THEN
456 IF (mod(nnstep, iprint) == 0 .AND. (iw > 0))
THEN
457 WRITE (iw, *)
"Attempting a volume move"
461 SELECT CASE (ensemble)
464 force_env(1)%force_env, &
465 moves(1, 1)%moves, move_updates(1, 1)%moves, &
467 energy_check(1), r_old(:, :, 1), iw, discrete_array(:, :), &
471 move_updates, nnstep, old_energy, energy_check, &
475 IF (ionode) rand = rng_stream%next()
476 CALL group%bcast(rand, source)
479 IF (rand .LE. pmvol_box(ibox))
THEN
486 force_env(box_number)%force_env, &
487 moves(1, box_number)%moves, &
488 move_updates(1, box_number)%moves, &
489 old_energy(box_number), box_number, &
490 energy_check(box_number), r_old(:, :, box_number), iw, &
491 discrete_array(:, :), &
498 subsys=oldsys(ibox)%subsys, cell=cell(ibox)%cell)
499 CALL get_cell(cell(ibox)%cell, abc=abc(:, ibox))
501 particles=particles_old(ibox)%list)
509 ALLOCATE (atom_names_box(1:nunits_tot(ibox)))
511 DO jbox = 1, ibox - 1
512 start_mol = start_mol + sum(nchains(:, jbox))
514 end_mol = start_mol + sum(nchains(:, ibox)) - 1
516 DO imolecule = 1, sum(nchains(:, ibox))
517 DO iunit = 1, nunits(mol_type(imolecule + start_mol - 1))
518 atom_names_box(atom_number) = &
519 atom_names(iunit, mol_type(imolecule + start_mol - 1))
520 atom_number = atom_number + 1
526 subsys=oldsys(ibox)%subsys, cell=cell(ibox)%cell)
527 CALL get_cell(cell(ibox)%cell, abc=abc(:, ibox))
530 mc_bias_file=mc_bias_file)
531 nchains_box => nchains(:, ibox)
534 r_old(:, :, ibox), atom_names_box(:), nunits_tot(ibox), &
535 para_env, abc(:, ibox), nchains_box, input_declaration, &
536 mc_bias_file, ionode)
538 IF (sum(nchains(:, ibox)) .NE. 0)
THEN
540 bias_env(ibox)%force_env, &
543 potential_energy=last_bias_energy(ibox))
545 last_bias_energy(ibox) = 0.0e0_dp
547 bias_energy(ibox) = last_bias_energy(ibox)
548 DEALLOCATE (atom_names_box)
552 ELSEIF (rand .LT. pmswap)
THEN
555 IF (mod(nnstep, iprint) == 0 .AND. (iw > 0))
THEN
556 WRITE (iw, *)
"Attempting a swap move"
561 energy_check(:), r_old(:, :, :), old_energy(:), input_declaration, &
562 para_env, bias_energy(:), last_bias_energy(:), rng_stream)
566 CALL get_mc_par(mc_par(1)%mc_par, mc_molecule_info=mc_molecule_info)
568 nchains=nchains, nmol_types=nmol_types, nunits_tot=nunits_tot, &
569 mol_type=mol_type, nchain_total=nchain_total, nunits=nunits, &
570 atom_names=atom_names, mass=mass)
572 ELSEIF (rand .LT. pmhmc)
THEN
574 IF (mod(nnstep, iprint) == 0 .AND. (iw > 0))
THEN
575 WRITE (iw, *)
"Attempting a hybrid Monte Carlo move"
580 IF (ionode) rand = rng_stream%next()
581 CALL group%bcast(rand, source)
584 IF (rand .LE. pmhmc_box(ibox))
THEN
591 force_env(box_number)%force_env, globenv, &
592 moves(1, box_number)%moves, &
593 move_updates(1, box_number)%moves, &
594 old_energy(box_number), box_number, &
595 energy_check(box_number), r_old(:, :, box_number), &
598 ELSEIF (rand .LT. pmavbmc)
THEN
600 IF (mod(nnstep, iprint) == 0 .AND. (iw > 0))
THEN
601 WRITE (iw, *)
"Attempting an AVBMC1 move"
606 IF (ionode) rand = rng_stream%next()
607 CALL group%bcast(rand, source)
609 IF (nboxes .EQ. 2)
THEN
610 IF (rand .LT. 0.1e0_dp)
THEN
620 IF (ionode) rand = rng_stream%next()
621 CALL group%bcast(rand, source)
622 molecule_type_swap = 0
623 DO imol_type = 1, nmol_types
624 IF (rand .LT. pmavbmc_mol(imol_type))
THEN
625 molecule_type_swap = imol_type
629 IF (molecule_type_swap == 0) &
630 cpabort(
'Did not choose a molecule type to swap...check AVBMC input')
634 IF (sum(nchains(:, box_number)) .LE. 1)
THEN
636 moves(molecule_type_swap, box_number)%moves%empty_avbmc = &
637 moves(molecule_type_swap, box_number)%moves%empty_avbmc + 1
643 start_atom_swap, idum, jdum, rng_stream, &
644 box=box_number, molecule_type_old=molecule_type_swap)
649 start_atom_target, idum, molecule_type_target, &
650 rng_stream, box=box_number)
651 IF (start_atom_swap .NE. start_atom_target)
THEN
652 start_atom_target = start_atom_target + &
653 avbmc_atom(molecule_type_target) - 1
660 rand = rng_stream%next()
663 CALL group%bcast(start_atom_swap, source)
664 CALL group%bcast(box_number, source)
665 CALL group%bcast(start_atom_target, source)
666 CALL group%bcast(rand, source)
668 IF (rand .LT. pbias(molecule_type_swap))
THEN
669 move_type_avbmc =
'in'
671 move_type_avbmc =
'out'
675 force_env(box_number)%force_env, &
676 bias_env(box_number)%force_env, &
677 moves(molecule_type_swap, box_number)%moves, &
678 energy_check(box_number), &
679 r_old(:, :, box_number), old_energy(box_number), &
680 start_atom_swap, start_atom_target, molecule_type_swap, &
681 box_number, bias_energy(box_number), &
682 last_bias_energy(box_number), &
683 move_type_avbmc, rng_stream)
689 IF (mod(nnstep, iprint) == 0 .AND. (iw > 0))
THEN
690 WRITE (iw, *)
"Attempting an inner move"
696 IF (ionode) rand = rng_stream%next()
697 CALL group%bcast(rand, source)
698 IF (rand .LT. pmtraion)
THEN
701 IF (ionode) rand = rng_stream%next()
702 CALL group%bcast(rand, source)
703 IF (nboxes .EQ. 2)
THEN
704 IF (rand .LT. 0.75e0_dp)
THEN
714 IF (ionode) rand = rng_stream%next()
715 CALL group%bcast(rand, source)
717 DO imol_type = 1, nmol_types
718 IF (rand .LT. pmtraion_mol(imol_type))
THEN
719 molecule_type = imol_type
723 IF (molecule_type == 0)
CALL cp_abort( &
725 'Did not choose a molecule type to conf change...PMTRAION_MOL should not be all 0.0')
729 IF (nchains(molecule_type, box_number) == 0)
THEN
731 moves(molecule_type, box_number)%moves%empty_conf = &
732 moves(molecule_type, box_number)%moves%empty_conf + 1
739 box=box_number, molecule_type_old=molecule_type)
742 rand = rng_stream%next()
744 CALL group%bcast(rand, source)
745 CALL group%bcast(start_atom, source)
746 CALL group%bcast(box_number, source)
747 CALL group%bcast(molecule_type, source)
750 IF (rand .LT. conf_prob(1, molecule_type))
THEN
752 ELSEIF (rand .LT. (conf_prob(1, molecule_type) + &
753 conf_prob(2, molecule_type)))
THEN
756 move_type =
'dihedral'
758 box_flag(box_number) = 1
760 force_env(box_number)%force_env, &
761 bias_env(box_number)%force_env, &
762 moves(molecule_type, box_number)%moves, &
763 move_updates(molecule_type, box_number)%moves, &
764 start_atom, molecule_type, box_number, &
765 bias_energy(box_number), &
766 move_type, lreject, rng_stream)
769 ELSEIF (rand .LT. pmtrans)
THEN
772 IF (ionode) rand = rng_stream%next()
773 CALL group%bcast(rand, source)
775 DO imol_type = 1, nmol_types
776 IF (rand .LT. pmtrans_mol(imol_type))
THEN
777 molecule_type = imol_type
781 IF (molecule_type == 0)
CALL cp_abort( &
783 'Did not choose a molecule type to translate...PMTRANS_MOL should not be all 0.0')
788 start_atom, box_number, idum, rng_stream, &
789 molecule_type_old=molecule_type)
790 CALL group%bcast(start_atom, source)
791 CALL group%bcast(box_number, source)
792 box_flag(box_number) = 1
794 force_env(box_number)%force_env, &
795 bias_env(box_number)%force_env, &
796 moves(molecule_type, box_number)%moves, &
797 move_updates(molecule_type, box_number)%moves, &
798 start_atom, box_number, bias_energy(box_number), &
799 molecule_type, lreject, rng_stream)
801 ELSEIF (rand .LT. pmcltrans)
THEN
804 IF (ionode) rand = rng_stream%next()
805 CALL group%bcast(rand, source)
808 IF (rand .LE. pmclus_box(ibox))
THEN
813 box_flag(box_number) = 1
815 force_env(box_number)%force_env, &
816 bias_env(box_number)%force_env, &
817 moves(1, box_number)%moves, &
818 move_updates(1, box_number)%moves, &
819 box_number, bias_energy(box_number), &
825 IF (ionode) rand = rng_stream%next()
826 CALL group%bcast(rand, source)
828 DO imol_type = 1, nmol_types
829 IF (rand .LT. pmrot_mol(imol_type))
THEN
830 molecule_type = imol_type
834 IF (molecule_type == 0)
CALL cp_abort( &
836 'Did not choose a molecule type to rotate...PMROT_MOL should not be all 0.0')
840 start_atom, box_number, idum, rng_stream, &
841 molecule_type_old=molecule_type)
842 CALL group%bcast(start_atom, source)
843 CALL group%bcast(box_number, source)
844 box_flag(box_number) = 1
846 force_env(box_number)%force_env, &
847 bias_env(box_number)%force_env, &
848 moves(molecule_type, box_number)%moves, &
849 move_updates(molecule_type, box_number)%moves, &
850 box_number, start_atom, &
851 molecule_type, bias_energy(box_number), &
860 moves, lreject, move_updates, energy_check(:), r_old(:, :, :), &
861 nnstep, old_energy(:), bias_energy(:), last_bias_energy(:), &
862 nboxes, box_flag(:), oldsys, particles_old, &
863 rng_stream, unit_conv)
871 subsys=oldsys(ibox)%subsys, cell=cell(ibox)%cell)
872 CALL get_cell(cell(ibox)%cell, abc=abc(:, ibox))
874 particles=particles_old(ibox)%list)
879 IF (mod(nnstep, iprint) == 0)
THEN
880 WRITE (com_ene, *) nnstep, old_energy(1:nboxes)
885 WRITE (com_mol, *) nnstep, nchains(:, ibox)
888 DO itype = 1, nmol_types
890 nnstep, move_unit(ibox))
895 nchains(:, ibox), force_env(ibox)%force_env)
898 WRITE (cell_unit, *) nnstep, abc(1:3, ibox)*
angstrom
901 WRITE (cbox,
'(I4)') ibox
902 WRITE (cstep,
'(I8)') nnstep
903 IF (sum(nchains(:, ibox)) == 0)
THEN
904 WRITE (com_crd, *)
' 0'
905 WRITE (com_crd, *)
'BOX '//trim(adjustl(cbox))// &
906 ', STEP '//trim(adjustl(cstep))
909 particles_old(ibox)%list%els, &
911 'BOX '//trim(adjustl(cbox))// &
912 ', STEP '//trim(adjustl(cstep)), &
920 averages(ibox)%averages%ave_energy = &
921 averages(ibox)%averages%ave_energy*real(nnstep - &
922 nstart - 1,
dp)/real(nnstep - nstart,
dp) + &
923 old_energy(ibox)/real(nnstep - nstart,
dp)
924 averages(ibox)%averages%molecules = &
925 averages(ibox)%averages%molecules*real(nnstep - &
926 nstart - 1,
dp)/real(nnstep - nstart,
dp) + &
927 REAL(sum(nchains(:, ibox)),
dp)/
REAL(nnstep - nstart,
dp)
928 averages(ibox)%averages%ave_volume = &
929 averages(ibox)%averages%ave_volume* &
930 REAL(nnstep - nstart - 1,
dp)/
REAL(nnstep - nstart, dp) + &
931 abc(1, ibox)*abc(2, ibox)*abc(3, ibox)/ &
932 REAL(nnstep - nstart,
dp)
956 IF (should_stop)
EXIT
960 IF (mod(nnstep - nstart, iuptrans) == 0)
THEN
961 DO itype = 1, nmol_types
963 move_updates(itype, ibox)%moves, itype, &
964 "trans", nnstep, ionode)
968 IF (mod(nnstep - nstart, iupvolume) == 0)
THEN
970 move_updates(1, ibox)%moves, 1337, &
971 "volume", nnstep, ionode)
979 IF (sum(nchains(:, ibox)) .NE. 0)
THEN
981 DO jbox = 1, ibox - 1
982 start_mol = start_mol + sum(nchains(:, jbox))
984 end_mol = start_mol + sum(nchains(:, ibox)) - 1
986 nchains(:, ibox), nunits, loverlap, &
987 mol_type(start_mol:end_mol))
989 IF (iw > 0)
WRITE (iw, *) nnstep
990 cpabort(
'coordinate overlap at the end of the above step')
994 ALLOCATE (r_temp(1:3, 1:nunits_tot(ibox)))
996 DO iunit = 1, nunits_tot(ibox)
997 r_temp(1:3, iunit) = &
998 particles_old(ibox)%list%els(iunit)%r(1:3)
1002 sum(nchains(:, ibox)), mol_type(start_mol:end_mol), &
1003 mass, nunits, abc(1:3, ibox))
1006 DO iunit = 1, nunits_tot(ibox)
1007 r_old(1:3, iunit, ibox) = r_temp(1:3, iunit)
1008 particles_old(ibox)%list%els(iunit)%r(1:3) = &
1017 particles=particles_bias)
1019 DO iunit = 1, nunits_tot(ibox)
1020 particles_bias%els(iunit)%r(1:3) = &
1032 IF (debug_this_module)
THEN
1034 IF (sum(nchains(:, ibox)) .NE. 0)
THEN
1038 potential_energy=test_energy)
1040 test_energy = 0.0e0_dp
1043 IF (abs(initial_energy(ibox) + energy_check(ibox) - &
1044 test_energy) .GT. 0.0000001e0_dp)
THEN
1046 WRITE (iw, *)
'!!!!!!! We have an energy problem. !!!!!!!!'
1047 WRITE (iw,
'(A,T64,F16.10)')
'Final Energy = ', test_energy
1048 WRITE (iw,
'(A,T64,F16.10)')
'Initial Energy+energy_check=', &
1049 initial_energy(ibox) + energy_check(ibox)
1050 WRITE (iw, *)
'Box ', ibox
1051 WRITE (iw, *)
'nchains ', nchains(:, ibox)
1053 cpabort(
'!!!!!!! We have an energy problem. !!!!!!!!')
1063 nchains(:, ibox), force_env(ibox)%force_env)
1069 IF (sum(nchains(:, ibox)) .NE. 0)
THEN
1073 potential_energy=final_energy(ibox))
1075 final_energy(ibox) = 0.0e0_dp
1083 IF (ionode .OR. (iw > 0))
THEN
1085 WRITE (com_ene, *)
'Final Energies: ', &
1086 final_energy(1:nboxes)
1089 WRITE (cbox,
'(I4)') ibox
1090 IF (sum(nchains(:, ibox)) == 0)
THEN
1091 WRITE (com_crd, *)
' 0'
1092 WRITE (com_crd, *)
'BOX '//trim(adjustl(cbox))
1095 particles_old(ibox)%list%els, &
1097 'FINAL BOX '//trim(adjustl(cbox)), unit_conv=unit_conv)
1102 '------------------------------------------------'
1103 WRITE (iw,
'(A,I1,A)') &
1107 '------------------------------------------------'
1108 test_moves => moves(:, ibox)
1110 iw, energy_check(ibox), &
1111 initial_energy(ibox), final_energy(ibox), &
1112 averages(ibox)%averages)
1131 mc_par=mc_par(ibox)%mc_par, &
1132 force_env=force_env(ibox)%force_env)
1135 DO itype = 1, nmol_types
1142 DEALLOCATE (pmhmc_box)
1143 DEALLOCATE (pmvol_box)
1144 DEALLOCATE (pmclus_box)
1146 DEALLOCATE (force_env)
1147 DEALLOCATE (bias_env)
1149 DEALLOCATE (particles_old)
1151 DEALLOCATE (averages)
1153 DEALLOCATE (move_updates)
1157 CALL timestop(handle)
1182 INTEGER :: current_division, end_atom, ibin, idivision, iparticle, iprint, itemp, iunit, &
1183 ivirial, iw, nbins, nchain_total, nintegral_divisions, nmol_types, nvirial, &
1184 nvirial_temps, source, start_atom
1185 INTEGER,
DIMENSION(:),
POINTER :: mol_type, nunits, nunits_tot
1186 INTEGER,
DIMENSION(:, :),
POINTER :: nchains
1187 LOGICAL :: ionode, loverlap
1188 REAL(
dp),
DIMENSION(:),
POINTER :: beta, virial_cutoffs, virial_stepsize, &
1190 REAL(
dp),
DIMENSION(:, :),
POINTER :: mass, mayer, r_old
1191 REAL(kind=
dp) :: ave_virial, current_value, distance, exp_max_val, exp_min_val, exponent, &
1192 integral, previous_value, square_value, trial_energy, triangle_value
1193 REAL(kind=
dp),
DIMENSION(1:3) :: abc, center_of_mass
1199 DIMENSION(:),
POINTER :: mc_par
1207 nintegral_divisions = 3
1208 ALLOCATE (virial_cutoffs(1:nintegral_divisions))
1209 ALLOCATE (virial_stepsize(1:nintegral_divisions))
1210 virial_cutoffs(1) = 8.0
1211 virial_cutoffs(2) = 13.0
1212 virial_cutoffs(3) = 22.0
1213 virial_stepsize(1) = 0.04
1214 virial_stepsize(2) = 0.1
1215 virial_stepsize(3) = 0.2
1217 nbins = ceiling(virial_cutoffs(1)/virial_stepsize(1) + (virial_cutoffs(2) - virial_cutoffs(1))/ &
1218 virial_stepsize(2) + (virial_cutoffs(3) - virial_cutoffs(2))/virial_stepsize(3))
1224 ALLOCATE (force_env(1:1))
1225 ALLOCATE (cell(1:1))
1226 ALLOCATE (particles(1:1))
1227 ALLOCATE (subsys(1:1))
1228 ALLOCATE (mc_par(1:1))
1231 mc_par=mc_par(1)%mc_par, &
1232 force_env=force_env(1)%force_env)
1236 exp_max_val=exp_max_val, &
1237 exp_min_val=exp_min_val, nvirial=nvirial, &
1238 ionode=ionode, source=source, group=group, &
1239 mc_molecule_info=mc_molecule_info, virial_temps=virial_temps)
1244 WRITE (iw, *)
'Beginning the calculation of the second virial coefficient'
1251 nchains=nchains, nmol_types=nmol_types, nunits_tot=nunits_tot, &
1252 mol_type=mol_type, nchain_total=nchain_total, nunits=nunits, &
1255 nvirial_temps =
SIZE(virial_temps)
1256 ALLOCATE (beta(1:nvirial_temps))
1258 DO itemp = 1, nvirial_temps
1264 subsys=subsys(1)%subsys, cell=cell(1)%cell)
1265 CALL get_cell(cell(1)%cell, abc=abc(:))
1267 particles=particles(1)%list)
1270 IF (abc(1) .NE. abc(2) .OR. abc(2) .NE. abc(3))
THEN
1271 cpabort(
'The box needs to be cubic for a virial calculation (it is easiest).')
1273 IF (virial_cutoffs(nintegral_divisions) .GT. abc(1)/2.0e0_dp)
THEN
1275 WRITE (iw, *)
"Box length ", abc(1)*
angstrom,
" virial cutoff ", &
1276 virial_cutoffs(nintegral_divisions)*
angstrom
1277 cpabort(
'You need a bigger box to deal with this virial cutoff (see above).')
1281 ALLOCATE (r_old(1:3, 1:nunits_tot(1)))
1283 DO iparticle = 1, nunits_tot(1)
1284 r_old(1:3, iparticle) = &
1285 particles(1)%list%els(iparticle)%r(1:3)
1290 end_atom = nunits(mol_type(1))
1292 center_of_mass(:), mass(1:nunits(mol_type(1)), mol_type(1)))
1293 DO iunit = start_atom, end_atom
1294 r_old(:, iunit) = r_old(:, iunit) - center_of_mass(:)
1297 DO iparticle = start_atom, end_atom
1298 particles(1)%list%els(iparticle)%r(1:3) = r_old(1:3, iparticle)
1302 iprint = floor(real(nvirial, kind=
dp)/100.0_dp)
1303 IF (iprint == 0) iprint = 1
1307 ALLOCATE (mayer(1:nvirial_temps, 1:nbins))
1309 mayer(:, :) = 0.0_dp
1312 DO ivirial = 1, nvirial
1315 start_atom = nunits(mol_type(1)) + 1
1316 end_atom = nunits_tot(1)
1318 center_of_mass(:), mass(1:nunits(mol_type(2)), mol_type(2)))
1319 DO iunit = start_atom, end_atom
1320 r_old(:, iunit) = r_old(:, iunit) - center_of_mass(:)
1327 mass(1:nunits(mol_type(2)), mol_type(2)), &
1328 nunits(mol_type(2)), rng_stream)
1330 CALL group%bcast(r_old(:, :), source)
1336 current_division = 0
1337 DO idivision = 1, nintegral_divisions
1338 IF (distance .LT. virial_cutoffs(idivision) - virial_stepsize(idivision)/2.0e0_dp)
THEN
1339 current_division = idivision
1343 IF (current_division == 0)
EXIT
1344 distance = distance + virial_stepsize(current_division)
1347 DO iparticle = start_atom, end_atom
1348 particles(1)%list%els(iparticle)%r(1) = r_old(1, iparticle) + distance
1349 particles(1)%list%els(iparticle)%r(2) = r_old(2, iparticle)
1350 particles(1)%list%els(iparticle)%r(3) = r_old(3, iparticle)
1354 CALL check_for_overlap(force_env(1)%force_env, nchains(:, 1), nunits, loverlap, mol_type)
1359 DO itemp = 1, nvirial_temps
1360 mayer(itemp, ibin) = mayer(itemp, ibin) - 1.0_dp
1366 potential_energy=trial_energy)
1368 DO itemp = 1, nvirial_temps
1370 exponent = -beta(itemp)*trial_energy
1372 IF (exponent .GT. exp_max_val)
THEN
1373 exponent = exp_max_val
1374 ELSEIF (exponent .LT. exp_min_val)
THEN
1375 exponent = exp_min_val
1377 mayer(itemp, ibin) = mayer(itemp, ibin) + exp(exponent) - 1.0_dp
1385 IF (mod(ivirial, iprint) == 0) &
1386 WRITE (iw,
'(A,I6,A,I6)')
' Done with config ', ivirial,
' out of ', nvirial
1391 mayer(:, :) = mayer(:, :)/real(nvirial,
dp)
1393 DO itemp = 1, nvirial_temps
1395 previous_value = 0.0_dp
1399 current_division = 0
1400 DO idivision = 1, nintegral_divisions
1401 IF (distance .LT. virial_cutoffs(idivision) - virial_stepsize(idivision)/2.0e0_dp)
THEN
1402 current_division = idivision
1406 IF (current_division == 0)
EXIT
1407 distance = distance + virial_stepsize(current_division)
1411 current_value = mayer(itemp, ibin)*distance**2
1412 square_value = previous_value*virial_stepsize(current_division)
1415 triangle_value = 0.5e0_dp*((current_value - previous_value)*virial_stepsize(current_division))
1417 integral = integral + square_value + triangle_value
1418 previous_value = current_value
1423 ave_virial = -2.0e0_dp*
pi*integral
1430 WRITE (iw, *)
'*********************************************************************'
1431 WRITE (iw,
'(A,F12.6,A)')
' *** Temperature = ', virial_temps(itemp), &
1433 WRITE (iw, *)
'*** ***'
1434 WRITE (iw,
'(A,E12.6,A)')
' *** B2(T) = ', ave_virial, &
1436 WRITE (iw, *)
'*********************************************************************'
1444 DEALLOCATE (force_env)
1445 DEALLOCATE (particles)
1447 DEALLOCATE (virial_cutoffs)
1448 DEALLOCATE (virial_stepsize)