From 9f2c98d8dbc090347555e539435770ff1e221673 Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Tue, 24 Dec 2024 23:06:30 +0100 Subject: [PATCH] Functionalities to incorporate rotational averaging in i-PI (#372) * Added functions to manipulate rotations * Added some utilities for rotational averaging * GenericCell object handling non-triangular cells This in no way allows using generic cells in i-PI, but allows us to handle arbitrary rotations from the forcefield to the socket * Added an example, and options, to use lebedev grids in o3-averaging * Implement defining and storing a separate PRNG for the random rotations * smaller box size for geop examples these make the tests run much faster --- drivers/f90/LJ.f90 | 13 +- drivers/f90/distance.f90 | 11 + drivers/f90/driver.f90 | 48 +++- .../thermodynamic_uq/input.xml | 2 +- examples/features/o3_averaging/README.md | 21 ++ .../direct_liquid_water/input.xml | 42 ++++ .../o3_averaging/direct_liquid_water/run.sh | 16 ++ .../direct_liquid_water/test_settings.dat | 3 + .../direct_liquid_water/water_216.xyz | 1 + .../o3_averaging/grid_liquid_water/input.xml | 44 ++++ .../o3_averaging/grid_liquid_water/run.sh | 18 ++ .../grid_liquid_water/test_settings.dat | 4 + .../grid_liquid_water/water_216.xyz | 1 + .../lebedev_liquid_water/input.xml | 43 ++++ .../o3_averaging/lebedev_liquid_water/run.sh | 18 ++ .../lebedev_liquid_water/test_settings.dat | 4 + .../lebedev_liquid_water/water_216.xyz | 1 + .../o3_averaging/noo3_liquid_water/input.xml | 38 +++ .../o3_averaging/noo3_liquid_water/run.sh | 18 ++ .../noo3_liquid_water/test_settings.dat | 4 + .../noo3_liquid_water/water_216.xyz | 1 + .../random_liquid_water/input.xml | 43 ++++ .../o3_averaging/random_liquid_water/run.sh | 18 ++ .../random_liquid_water/test_settings.dat | 4 + .../random_liquid_water/water_216.xyz | 1 + examples/temp/lammps/h2o-piglet.2/data.lmp | 1 + .../temp/pes/geop/waterbox/bfgs/input.xml | 2 +- .../temp/pes/geop/waterbox/bfgs/water_216.xyz | 1 - .../temp/pes/geop/waterbox/bfgs/water_64.xyz | 1 + examples/temp/pes/geop/waterbox/cg/input.xml | 2 +- .../temp/pes/geop/waterbox/cg/water_216.xyz | 1 - .../temp/pes/geop/waterbox/cg/water_64.xyz | 1 + .../temp/pes/geop/waterbox/lbfgs/input.xml | 2 +- .../pes/geop/waterbox/lbfgs/water_216.xyz | 1 - .../temp/pes/geop/waterbox/lbfgs/water_64.xyz | 1 + examples/temp/pes/geop/waterbox/sd/input.xml | 2 +- .../temp/pes/geop/waterbox/sd/water_216.xyz | 1 - .../temp/pes/geop/waterbox/sd/water_64.xyz | 1 + ipi/engine/atoms.py | 8 +- ipi/engine/cell.py | 53 +++- ipi/engine/forcefields.py | 227 +++++++++++++++++- ipi/inputs/forcefields.py | 129 +++++++++- ipi/inputs/simulation.py | 11 +- ipi/utils/__init__.py | 1 + ipi/utils/lebedev_grids.npy | Bin 0 -> 549870 bytes ipi/utils/mathtools.py | 127 ++++++++++ ipi/utils/setup.py | 12 +- ipi_tests/examples/exampletools.py | 5 +- ipi_tests/test_tools.py | 15 +- setup.cfg | 2 +- setup.py | 3 + 51 files changed, 979 insertions(+), 48 deletions(-) create mode 100644 examples/features/o3_averaging/README.md create mode 100644 examples/features/o3_averaging/direct_liquid_water/input.xml create mode 100644 examples/features/o3_averaging/direct_liquid_water/run.sh create mode 100644 examples/features/o3_averaging/direct_liquid_water/test_settings.dat create mode 120000 examples/features/o3_averaging/direct_liquid_water/water_216.xyz create mode 100644 examples/features/o3_averaging/grid_liquid_water/input.xml create mode 100644 examples/features/o3_averaging/grid_liquid_water/run.sh create mode 100644 examples/features/o3_averaging/grid_liquid_water/test_settings.dat create mode 120000 examples/features/o3_averaging/grid_liquid_water/water_216.xyz create mode 100644 examples/features/o3_averaging/lebedev_liquid_water/input.xml create mode 100644 examples/features/o3_averaging/lebedev_liquid_water/run.sh create mode 100644 examples/features/o3_averaging/lebedev_liquid_water/test_settings.dat create mode 120000 examples/features/o3_averaging/lebedev_liquid_water/water_216.xyz create mode 100644 examples/features/o3_averaging/noo3_liquid_water/input.xml create mode 100644 examples/features/o3_averaging/noo3_liquid_water/run.sh create mode 100644 examples/features/o3_averaging/noo3_liquid_water/test_settings.dat create mode 120000 examples/features/o3_averaging/noo3_liquid_water/water_216.xyz create mode 100644 examples/features/o3_averaging/random_liquid_water/input.xml create mode 100644 examples/features/o3_averaging/random_liquid_water/run.sh create mode 100644 examples/features/o3_averaging/random_liquid_water/test_settings.dat create mode 120000 examples/features/o3_averaging/random_liquid_water/water_216.xyz delete mode 120000 examples/temp/pes/geop/waterbox/bfgs/water_216.xyz create mode 120000 examples/temp/pes/geop/waterbox/bfgs/water_64.xyz delete mode 120000 examples/temp/pes/geop/waterbox/cg/water_216.xyz create mode 120000 examples/temp/pes/geop/waterbox/cg/water_64.xyz delete mode 120000 examples/temp/pes/geop/waterbox/lbfgs/water_216.xyz create mode 120000 examples/temp/pes/geop/waterbox/lbfgs/water_64.xyz delete mode 120000 examples/temp/pes/geop/waterbox/sd/water_216.xyz create mode 120000 examples/temp/pes/geop/waterbox/sd/water_64.xyz create mode 100644 ipi/utils/lebedev_grids.npy diff --git a/drivers/f90/LJ.f90 b/drivers/f90/LJ.f90 index 67343ef08..ab21d7b13 100644 --- a/drivers/f90/LJ.f90 +++ b/drivers/f90/LJ.f90 @@ -190,7 +190,7 @@ SUBROUTINE LJ_getall(rc, sigma, eps, natoms, atoms, cell_h, cell_ih, index_list, pot = pot + pot_ij DO k = 1, 3 DO l = k, 3 - ! Only the upper triangular elements calculated. + ! only upper triangular part is returned virial(k,l) = virial(k,l) + fij(k)*rij(l) ENDDO ENDDO @@ -199,8 +199,8 @@ SUBROUTINE LJ_getall(rc, sigma, eps, natoms, atoms, cell_h, cell_ih, index_list, start = index_list(i) + 1 ENDDO - ! Assuming an upper-triangular vector matrix for the simulation box. - volume = cell_h(1,1)*cell_h(2,2)*cell_h(3,3) + ! Works with a generic cell, even if usually it'll be upper-triuangular + volume = CELL_VOLUME(cell_h) !cell_h(1,1)*cell_h(2,2)*cell_h(3,3) CALL LJ_longrange(rc, sigma, eps, natoms, volume, pot_lr, vir_lr) pot = pot + pot_lr DO k = 1, 3 @@ -272,8 +272,7 @@ SUBROUTINE LJMix_getall(n_type2, rc, sigma, eps, natoms, atoms, cell_h, cell_ih, forces(n_list(j),:) = forces(n_list(j),:) - fij pot = pot + pot_ij DO k = 1, 3 - DO l = k, 3 - ! Only the upper triangular elements calculated. + DO l = k, 3 ! only upper-tri part is returned virial(k,l) = virial(k,l) + fij(k)*rij(l) ENDDO ENDDO @@ -282,8 +281,8 @@ SUBROUTINE LJMix_getall(n_type2, rc, sigma, eps, natoms, atoms, cell_h, cell_ih, start = index_list(i) + 1 ENDDO - ! Assuming an upper-triangular vector matrix for the simulation box. - volume = cell_h(1,1)*cell_h(2,2)*cell_h(3,3) + ! Works with a generic cell, even if usually it'll be upper-triuangular + volume = CELL_VOLUME(cell_h) ! cell_h(1,1)*cell_h(2,2)*cell_h(3,3) CALL LJ_longrange(rc, sigma*(1-n_type2*0.4/natoms), eps*(1-n_type2*0.4/natoms), natoms, volume, pot_lr, vir_lr) pot = pot + pot_lr DO k = 1, 3 diff --git a/drivers/f90/distance.f90 b/drivers/f90/distance.f90 index c15213030..c74c2a624 100644 --- a/drivers/f90/distance.f90 +++ b/drivers/f90/distance.f90 @@ -31,6 +31,17 @@ MODULE DISTANCE CONTAINS + DOUBLE PRECISION function CELL_VOLUME(m) + + DOUBLE PRECISION m(3, 3) + + CELL_VOLUME = DABS(m(1, 1) * (m(2, 2) * m(3, 3) - m(3, 2) * m(2, 3)) - & + m(1, 2) * (m(2, 1) * m(3, 3) - m(3, 1) * m(2, 3)) + & + m(1, 3) * (m(2, 1) * m(3, 2) - m(3, 1) * m(2, 2)) ) + + return + end + SUBROUTINE vector_separation(cell_h, cell_ih, ri, rj, rij, r2) ! Calculates the vector separating two atoms. ! diff --git a/drivers/f90/driver.f90 b/drivers/f90/driver.f90 index c1554f0fd..5f210c6da 100644 --- a/drivers/f90/driver.f90 +++ b/drivers/f90/driver.f90 @@ -32,6 +32,7 @@ PROGRAM DRIVER USE SG USE PSWATER USE F90SOCKETS, ONLY : open_socket, writebuffer, readbuffer, f_sleep + USE DISTANCE, only: CELL_VOLUME IMPLICIT NONE ! SOCKET VARIABLES @@ -191,13 +192,15 @@ PROGRAM DRIVER vstyle = 64 ELSEIF (trim(cmdbuffer) == "qtip4pf-c-json-delta") THEN vstyle = 65 + ELSEIF (trim(cmdbuffer) == "noo3-h2o") THEN + vstyle = 70 ELSEIF (trim(cmdbuffer) == "gas") THEN vstyle = 0 ! ideal gas ELSEIF (trim(cmdbuffer) == "dummy") THEN vstyle = 99 ! returns non-zero but otherwise meaningless values ELSE WRITE(*,*) " Unrecognized potential type ", trim(cmdbuffer) - WRITE(*,*) " Use -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4pf-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|harmonic_bath|meanfield_bath|ljmix|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json|qtip4pf-c-1-delta|qtip4pf-c-2-delta|qtip4pf-c-json-delta] " + WRITE(*,*) " Use -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4pf-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|harmonic_bath|meanfield_bath|ljmix|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json|qtip4pf-c-1-delta|qtip4pf-c-2-delta|qtip4pf-c-json-delta|noo3-h2o] " STOP "ENDED" ENDIF ELSEIF (ccmd == 4) THEN @@ -385,7 +388,7 @@ PROGRAM DRIVER enddo ENDIF isinit = .true. - ELSEIF (vstyle == 1) THEN + ELSEIF (1 == vstyle) THEN IF (par_count /= 3) THEN WRITE(*,*) "Error: parameters not initialized correctly." WRITE(*,*) "For LJ potential use -o sigma,epsilon,cutoff " @@ -519,8 +522,8 @@ PROGRAM DRIVER ! units and storage mode used in the driver. cell_h = transpose(cell_h) cell_ih = transpose(cell_ih) - ! We assume an upper triangular cell-vector matrix - volume = cell_h(1,1)*cell_h(2,2)*cell_h(3,3) + ! We compute for a generic cell, just in case (even though usually i-PI passes an upper triangular cell-vector matrix) + volume = CELL_VOLUME(cell_h) !cell_h(1,1)*cell_h(2,2)*cell_h(3,3) CALL readbuffer(socket, cbuf) ! The number of atoms in the cell IF (verbose > 1) WRITE(*,*) " !read!=> cbuf: ", cbuf @@ -790,6 +793,41 @@ PROGRAM DRIVER CALL LJ_getall(rc, 2.1d0, -12d-6, nat, atoms, cell_h, cell_ih, index_list, n_list, pot, forces, virial) CALL LJ_getall(rc, 2.5d0, 1d-6, nat, atoms, cell_h, cell_ih, index_list, n_list, pot, forces, virial) ENDIF + ELSEIF (70 == vstyle) THEN + ! potential that can be applied on top of water molecules to add a orientation-dependent term to + ! test non-equivariant terms in the potential + vpars(1) = cell_h(1,1) + vpars(2) = cell_h(2,2) + vpars(3) = cell_h(3,3) + + pot = 0 + forces = 0 + DO i=1,nat,3 + dip = 0.5 * (atoms(i+1,:) + atoms(i+2,:)) - atoms(i,:) + vpars(4) = sqrt(dip(1)**2+dip(2)**2+dip(3)**2) + vpars(1) = exp(dip(1)/vpars(4)*1.0) + vpars(2) = exp(dip(2)/vpars(4)*0.5) + vpars(3) = exp(dip(3)/vpars(4)*2.0) + pot = pot + 2e-2*(vpars(1)+vpars(2)+vpars(3)) + vpars(1) = 2e-2*vpars(1)*1.0/vpars(4)**3 + vpars(2) = 2e-2*vpars(2)*0.5/vpars(4)**3 + vpars(3) = 2e-2*vpars(3)*2.0/vpars(4)**3 + ! gradients on O + vpars(4) = -vpars(1)*(dip(2)**2+dip(3)**2) + vpars(2)*dip(1)*dip(2) + vpars(3)*dip(3)*dip(1) + vpars(5) = -vpars(2)*(dip(1)**2+dip(3)**2) + vpars(1)*dip(1)*dip(2) + vpars(3)*dip(2)*dip(3) + vpars(6) = -vpars(3)*(dip(1)**2+dip(2)**2) + vpars(1)*dip(1)*dip(3) + vpars(2)*dip(3)*dip(2) + forces(i,1) = forces(i,1) - vpars(4) + forces(i,2) = forces(i,2) - vpars(5) + forces(i,3) = forces(i,3) - vpars(6) + ! gradients from H are just from Newton's law + forces(i+1,1) = forces(i+1,1) + vpars(4)*0.5 + forces(i+1,2) = forces(i+1,2) + vpars(5)*0.5 + forces(i+1,3) = forces(i+1,3) + vpars(6)*0.5 + forces(i+2,1) = forces(i+2,1) + vpars(4)*0.5 + forces(i+2,2) = forces(i+2,2) + vpars(5)*0.5 + forces(i+2,3) = forces(i+2,3) + vpars(6)*0.5 + ENDDO + ELSEIF (vstyle == 11) THEN ! efield potential. IF (mod(nat,3)/=0) THEN WRITE(*,*) " Expecting water molecules O H H O H H O H H but got ", nat, "atoms" @@ -1055,7 +1093,7 @@ PROGRAM DRIVER SUBROUTINE helpmessage ! Help banner - WRITE(*,*) " SYNTAX: driver.x [-u] -a address [-p port] -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4p-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|harmonic_bath|meanfield_bath|ljmix|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json|qtip4pf-c-1-delta|qtip4pf-c-2-delta|qtip4pf-c-json-delta]" + WRITE(*,*) " SYNTAX: driver.x [-u] -a address [-p port] -m [dummy|gas|lj|sg|harm|harm3d|morse|morsedia|zundel|qtip4pf|pswater|lepsm1|lepsm2|qtip4p-efield|eckart|ch4hcbe|ljpolymer|MB|doublewell|doublewell_1D|water_dip_pol|harmonic_bath|meanfield_bath|ljmix|qtip4pf-sr|qtip4pf-c-1|qtip4pf-c-2|qtip4pf-c-json|qtip4pf-c-1-delta|qtip4pf-c-2-delta|qtip4pf-c-json-delta|noo3-h2o]" WRITE(*,*) " -o 'comma_separated_parameters' [-S sockets_prefix] [-v] " WRITE(*,*) "" WRITE(*,*) " For LJ potential use -o sigma,epsilon,cutoff " diff --git a/examples/features/committee_models/thermodynamic_uq/input.xml b/examples/features/committee_models/thermodynamic_uq/input.xml index ef96ac06d..df838e593 100644 --- a/examples/features/committee_models/thermodynamic_uq/input.xml +++ b/examples/features/committee_models/thermodynamic_uq/input.xml @@ -12,7 +12,7 @@ 31415 - + 1.0 active 0.05 diff --git a/examples/features/o3_averaging/README.md b/examples/features/o3_averaging/README.md new file mode 100644 index 000000000..85cbd576c --- /dev/null +++ b/examples/features/o3_averaging/README.md @@ -0,0 +1,21 @@ +O3 rotational averaging. +======================== + +Examples of the averaging module to handle non-equivariant potentials. +The `` socket allows to evaluate a potential multiple times, +using random rotations or a grid of rotations, to reduce the impact of the +lack of rotational equivariance on the quality of the dynamics. +The examples use the `noo3_h2o` potential, that assumes the structure is +a sequence of H2O molecules and adds a orientation-dependent potential to each +water molecule. + + +`noo3`: no correction is applied. The structure of the liquid will be badly + disrupted. +`random`: the structure is randomly oriented at each evaluation. + This effectively introduces a noise in the forces, that must be contrasted + by an aggressive thermostat. There is a large drift in the conserved quantity + but the mean potential is OK and water molecules do not orient artificially +`grid`: the potential is averaged over a grid of rotations. + This reduces the orientational error, but comes at the cost of many additional + energy evaluations per step. diff --git a/examples/features/o3_averaging/direct_liquid_water/input.xml b/examples/features/o3_averaging/direct_liquid_water/input.xml new file mode 100644 index 000000000..2d85ee633 --- /dev/null +++ b/examples/features/o3_averaging/direct_liquid_water/input.xml @@ -0,0 +1,42 @@ + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{megapascal}, stress_md{megapascal} ] + extras_component_raw(1) + positions{angstrom} + + + 1000 + + 31415 + + +
h2o-base
+
+ + + dummy + + True + + + + water_216.xyz + 300 + + + + + + + + 0.5 + + 10 + + + + + 300 + + +
diff --git a/examples/features/o3_averaging/direct_liquid_water/run.sh b/examples/features/o3_averaging/direct_liquid_water/run.sh new file mode 100644 index 000000000..be4dcec32 --- /dev/null +++ b/examples/features/o3_averaging/direct_liquid_water/run.sh @@ -0,0 +1,16 @@ +ipi=i-pi +driver1="i-pi-driver -m qtip4pf -u -a h2o-base" +sleep_time=4 + +${ipi} input.xml > log.i-pi & +echo "# i-PI is running" + +echo "# Waiting for ${sleep_time} (s) before executing driver" +sleep ${sleep_time} + +${driver1} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/examples/features/o3_averaging/direct_liquid_water/test_settings.dat b/examples/features/o3_averaging/direct_liquid_water/test_settings.dat new file mode 100644 index 000000000..931f44954 --- /dev/null +++ b/examples/features/o3_averaging/direct_liquid_water/test_settings.dat @@ -0,0 +1,3 @@ +#Settings file for automatic test +driver_model qtip4pf +nsteps 10 diff --git a/examples/features/o3_averaging/direct_liquid_water/water_216.xyz b/examples/features/o3_averaging/direct_liquid_water/water_216.xyz new file mode 120000 index 000000000..58a9ede12 --- /dev/null +++ b/examples/features/o3_averaging/direct_liquid_water/water_216.xyz @@ -0,0 +1 @@ +../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/features/o3_averaging/grid_liquid_water/input.xml b/examples/features/o3_averaging/grid_liquid_water/input.xml new file mode 100644 index 000000000..fe86ed9e5 --- /dev/null +++ b/examples/features/o3_averaging/grid_liquid_water/input.xml @@ -0,0 +1,44 @@ + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{megapascal}, stress_md{megapascal} ] + extras_component_raw(1) + positions{angstrom} + + + 1000 + + 31415 + + +
h2o-base
+
+ + +
h2o-noo3
+
+ 2 + legendre + True +
+ + + water_216.xyz + 300 + + + + + + + + 0.5 + + 100 + + + + + 300 + + +
diff --git a/examples/features/o3_averaging/grid_liquid_water/run.sh b/examples/features/o3_averaging/grid_liquid_water/run.sh new file mode 100644 index 000000000..504a1eb18 --- /dev/null +++ b/examples/features/o3_averaging/grid_liquid_water/run.sh @@ -0,0 +1,18 @@ +ipi=i-pi +driver1="i-pi-driver -m noo3-h2o -u -a h2o-noo3" +driver2="i-pi-driver -m qtip4pf -u -a h2o-base" +sleep_time=4 + +${ipi} input.xml > log.i-pi & +echo "# i-PI is running" + +echo "# Waiting for ${sleep_time} (s) before executing driver" +sleep ${sleep_time} + +${driver1} > /dev/null & +${driver2} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/examples/features/o3_averaging/grid_liquid_water/test_settings.dat b/examples/features/o3_averaging/grid_liquid_water/test_settings.dat new file mode 100644 index 000000000..5eb138751 --- /dev/null +++ b/examples/features/o3_averaging/grid_liquid_water/test_settings.dat @@ -0,0 +1,4 @@ +#Settings file for automatic test +driver_model qtip4pf +driver_model2 noo3-h2o +nsteps 10 diff --git a/examples/features/o3_averaging/grid_liquid_water/water_216.xyz b/examples/features/o3_averaging/grid_liquid_water/water_216.xyz new file mode 120000 index 000000000..58a9ede12 --- /dev/null +++ b/examples/features/o3_averaging/grid_liquid_water/water_216.xyz @@ -0,0 +1 @@ +../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/features/o3_averaging/lebedev_liquid_water/input.xml b/examples/features/o3_averaging/lebedev_liquid_water/input.xml new file mode 100644 index 000000000..118ffd54b --- /dev/null +++ b/examples/features/o3_averaging/lebedev_liquid_water/input.xml @@ -0,0 +1,43 @@ + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{megapascal}, stress_md{megapascal} ] + extras_component_raw(1) + positions{angstrom} + + + 1000 + + 31415 + + +
h2o-base
+
+ + +
h2o-noo3
+
+ 3 lebedev + True +
+ + + water_216.xyz + 300 + + + + + + + + 0.5 + + 100 + + + + + 300 + + +
diff --git a/examples/features/o3_averaging/lebedev_liquid_water/run.sh b/examples/features/o3_averaging/lebedev_liquid_water/run.sh new file mode 100644 index 000000000..504a1eb18 --- /dev/null +++ b/examples/features/o3_averaging/lebedev_liquid_water/run.sh @@ -0,0 +1,18 @@ +ipi=i-pi +driver1="i-pi-driver -m noo3-h2o -u -a h2o-noo3" +driver2="i-pi-driver -m qtip4pf -u -a h2o-base" +sleep_time=4 + +${ipi} input.xml > log.i-pi & +echo "# i-PI is running" + +echo "# Waiting for ${sleep_time} (s) before executing driver" +sleep ${sleep_time} + +${driver1} > /dev/null & +${driver2} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/examples/features/o3_averaging/lebedev_liquid_water/test_settings.dat b/examples/features/o3_averaging/lebedev_liquid_water/test_settings.dat new file mode 100644 index 000000000..5eb138751 --- /dev/null +++ b/examples/features/o3_averaging/lebedev_liquid_water/test_settings.dat @@ -0,0 +1,4 @@ +#Settings file for automatic test +driver_model qtip4pf +driver_model2 noo3-h2o +nsteps 10 diff --git a/examples/features/o3_averaging/lebedev_liquid_water/water_216.xyz b/examples/features/o3_averaging/lebedev_liquid_water/water_216.xyz new file mode 120000 index 000000000..58a9ede12 --- /dev/null +++ b/examples/features/o3_averaging/lebedev_liquid_water/water_216.xyz @@ -0,0 +1 @@ +../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/features/o3_averaging/noo3_liquid_water/input.xml b/examples/features/o3_averaging/noo3_liquid_water/input.xml new file mode 100644 index 000000000..f6b509717 --- /dev/null +++ b/examples/features/o3_averaging/noo3_liquid_water/input.xml @@ -0,0 +1,38 @@ + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{megapascal}, stress_md{megapascal} ] + positions{angstrom} + + + 1000 + + 31415 + + +
h2o-base
+
+ +
h2o-noo3
+
+ + + water_216.xyz + 300 + + + + + + + + 0.5 + + 100 + + + + + 300 + + +
diff --git a/examples/features/o3_averaging/noo3_liquid_water/run.sh b/examples/features/o3_averaging/noo3_liquid_water/run.sh new file mode 100644 index 000000000..504a1eb18 --- /dev/null +++ b/examples/features/o3_averaging/noo3_liquid_water/run.sh @@ -0,0 +1,18 @@ +ipi=i-pi +driver1="i-pi-driver -m noo3-h2o -u -a h2o-noo3" +driver2="i-pi-driver -m qtip4pf -u -a h2o-base" +sleep_time=4 + +${ipi} input.xml > log.i-pi & +echo "# i-PI is running" + +echo "# Waiting for ${sleep_time} (s) before executing driver" +sleep ${sleep_time} + +${driver1} > /dev/null & +${driver2} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/examples/features/o3_averaging/noo3_liquid_water/test_settings.dat b/examples/features/o3_averaging/noo3_liquid_water/test_settings.dat new file mode 100644 index 000000000..5eb138751 --- /dev/null +++ b/examples/features/o3_averaging/noo3_liquid_water/test_settings.dat @@ -0,0 +1,4 @@ +#Settings file for automatic test +driver_model qtip4pf +driver_model2 noo3-h2o +nsteps 10 diff --git a/examples/features/o3_averaging/noo3_liquid_water/water_216.xyz b/examples/features/o3_averaging/noo3_liquid_water/water_216.xyz new file mode 120000 index 000000000..58a9ede12 --- /dev/null +++ b/examples/features/o3_averaging/noo3_liquid_water/water_216.xyz @@ -0,0 +1 @@ +../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/features/o3_averaging/random_liquid_water/input.xml b/examples/features/o3_averaging/random_liquid_water/input.xml new file mode 100644 index 000000000..e8b196b7e --- /dev/null +++ b/examples/features/o3_averaging/random_liquid_water/input.xml @@ -0,0 +1,43 @@ + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{megapascal}, stress_md{megapascal} ] + extras_component_raw(1) + positions{angstrom} + + + 1000 + + 31415 + + +
h2o-base
+
+ + +
h2o-noo3
+
+ True + 54321 +
+ + + water_216.xyz + 300 + + + + + + + + 0.5 + + 10 + + + + + 300 + + +
diff --git a/examples/features/o3_averaging/random_liquid_water/run.sh b/examples/features/o3_averaging/random_liquid_water/run.sh new file mode 100644 index 000000000..504a1eb18 --- /dev/null +++ b/examples/features/o3_averaging/random_liquid_water/run.sh @@ -0,0 +1,18 @@ +ipi=i-pi +driver1="i-pi-driver -m noo3-h2o -u -a h2o-noo3" +driver2="i-pi-driver -m qtip4pf -u -a h2o-base" +sleep_time=4 + +${ipi} input.xml > log.i-pi & +echo "# i-PI is running" + +echo "# Waiting for ${sleep_time} (s) before executing driver" +sleep ${sleep_time} + +${driver1} > /dev/null & +${driver2} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/examples/features/o3_averaging/random_liquid_water/test_settings.dat b/examples/features/o3_averaging/random_liquid_water/test_settings.dat new file mode 100644 index 000000000..5eb138751 --- /dev/null +++ b/examples/features/o3_averaging/random_liquid_water/test_settings.dat @@ -0,0 +1,4 @@ +#Settings file for automatic test +driver_model qtip4pf +driver_model2 noo3-h2o +nsteps 10 diff --git a/examples/features/o3_averaging/random_liquid_water/water_216.xyz b/examples/features/o3_averaging/random_liquid_water/water_216.xyz new file mode 120000 index 000000000..58a9ede12 --- /dev/null +++ b/examples/features/o3_averaging/random_liquid_water/water_216.xyz @@ -0,0 +1 @@ +../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/temp/lammps/h2o-piglet.2/data.lmp b/examples/temp/lammps/h2o-piglet.2/data.lmp index 13c75e993..f91ddfb1d 100644 --- a/examples/temp/lammps/h2o-piglet.2/data.lmp +++ b/examples/temp/lammps/h2o-piglet.2/data.lmp @@ -11,6 +11,7 @@ LAMMPS Description 0 35.233 xlo xhi 0 35.233 ylo yhi 0 35.233 zlo zhi + 1e-4 1e-4 1e-4 xy xz yz Masses diff --git a/examples/temp/pes/geop/waterbox/bfgs/input.xml b/examples/temp/pes/geop/waterbox/bfgs/input.xml index 9e9c3897d..643d27e13 100644 --- a/examples/temp/pes/geop/waterbox/bfgs/input.xml +++ b/examples/temp/pes/geop/waterbox/bfgs/input.xml @@ -12,7 +12,7 @@ - water_216.xyz + water_64.xyz diff --git a/examples/temp/pes/geop/waterbox/bfgs/water_216.xyz b/examples/temp/pes/geop/waterbox/bfgs/water_216.xyz deleted file mode 120000 index 95291df24..000000000 --- a/examples/temp/pes/geop/waterbox/bfgs/water_216.xyz +++ /dev/null @@ -1 +0,0 @@ -../../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/bfgs/water_64.xyz b/examples/temp/pes/geop/waterbox/bfgs/water_64.xyz new file mode 120000 index 000000000..683f52959 --- /dev/null +++ b/examples/temp/pes/geop/waterbox/bfgs/water_64.xyz @@ -0,0 +1 @@ +../../../../init_files/water_64.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/cg/input.xml b/examples/temp/pes/geop/waterbox/cg/input.xml index 11feb189b..e6ea9da5f 100644 --- a/examples/temp/pes/geop/waterbox/cg/input.xml +++ b/examples/temp/pes/geop/waterbox/cg/input.xml @@ -12,7 +12,7 @@ - water_216.xyz + water_64.xyz diff --git a/examples/temp/pes/geop/waterbox/cg/water_216.xyz b/examples/temp/pes/geop/waterbox/cg/water_216.xyz deleted file mode 120000 index 95291df24..000000000 --- a/examples/temp/pes/geop/waterbox/cg/water_216.xyz +++ /dev/null @@ -1 +0,0 @@ -../../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/cg/water_64.xyz b/examples/temp/pes/geop/waterbox/cg/water_64.xyz new file mode 120000 index 000000000..683f52959 --- /dev/null +++ b/examples/temp/pes/geop/waterbox/cg/water_64.xyz @@ -0,0 +1 @@ +../../../../init_files/water_64.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/lbfgs/input.xml b/examples/temp/pes/geop/waterbox/lbfgs/input.xml index 9d1eb692e..279dc0257 100644 --- a/examples/temp/pes/geop/waterbox/lbfgs/input.xml +++ b/examples/temp/pes/geop/waterbox/lbfgs/input.xml @@ -12,7 +12,7 @@ - water_216.xyz + water_64.xyz diff --git a/examples/temp/pes/geop/waterbox/lbfgs/water_216.xyz b/examples/temp/pes/geop/waterbox/lbfgs/water_216.xyz deleted file mode 120000 index 95291df24..000000000 --- a/examples/temp/pes/geop/waterbox/lbfgs/water_216.xyz +++ /dev/null @@ -1 +0,0 @@ -../../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/lbfgs/water_64.xyz b/examples/temp/pes/geop/waterbox/lbfgs/water_64.xyz new file mode 120000 index 000000000..683f52959 --- /dev/null +++ b/examples/temp/pes/geop/waterbox/lbfgs/water_64.xyz @@ -0,0 +1 @@ +../../../../init_files/water_64.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/sd/input.xml b/examples/temp/pes/geop/waterbox/sd/input.xml index 85c49914f..ff259cf1f 100644 --- a/examples/temp/pes/geop/waterbox/sd/input.xml +++ b/examples/temp/pes/geop/waterbox/sd/input.xml @@ -12,7 +12,7 @@ - water_216.xyz + water_64.xyz diff --git a/examples/temp/pes/geop/waterbox/sd/water_216.xyz b/examples/temp/pes/geop/waterbox/sd/water_216.xyz deleted file mode 120000 index 95291df24..000000000 --- a/examples/temp/pes/geop/waterbox/sd/water_216.xyz +++ /dev/null @@ -1 +0,0 @@ -../../../../init_files/water_216.xyz \ No newline at end of file diff --git a/examples/temp/pes/geop/waterbox/sd/water_64.xyz b/examples/temp/pes/geop/waterbox/sd/water_64.xyz new file mode 120000 index 000000000..683f52959 --- /dev/null +++ b/examples/temp/pes/geop/waterbox/sd/water_64.xyz @@ -0,0 +1 @@ +../../../../init_files/water_64.xyz \ No newline at end of file diff --git a/ipi/engine/atoms.py b/ipi/engine/atoms.py index 73b4c1ce4..8638a82c2 100644 --- a/ipi/engine/atoms.py +++ b/ipi/engine/atoms.py @@ -148,7 +148,7 @@ def __init__(self, natoms, _prebind=None): name="kstress", func=self.get_kstress, dependencies=[self._p, self._m] ) - def copy(self): + def clone(self): """Creates a new Atoms object. Returns: @@ -156,9 +156,9 @@ def copy(self): """ newat = Atoms(self.natoms) - newat.q[:] = self.q - newat.p[:] = self.p - newat.m[:] = self.m + newat.q[:] = dstrip(self.q) + newat.p[:] = dstrip(self.p) + newat.m[:] = dstrip(self.m) newat.names[:] = self.names return newat diff --git a/ipi/engine/cell.py b/ipi/engine/cell.py index ca69a20d2..e60eda0bb 100644 --- a/ipi/engine/cell.py +++ b/ipi/engine/cell.py @@ -14,7 +14,7 @@ from ipi.utils.mathtools import * -__all__ = ["Cell"] +__all__ = ["Cell", "GenericCell"] class Cell: @@ -95,15 +95,14 @@ def array_pbc(self, pos): system box. """ - s = dstrip(pos).copy() - s.shape = (len(pos) // 3, 3) + s = dstrip(pos).copy().reshape(-1, 3) s = np.dot(dstrip(self.ih), s.T) s = s - np.round(s) s = np.dot(dstrip(self.h), s).T - pos[:] = s.reshape((len(s) * 3)) + pos[:] = s.reshape(-1) def minimum_distance(self, atom1, atom2): """Takes two atoms and tries to find the smallest vector between two @@ -130,3 +129,49 @@ def minimum_distance(self, atom1, atom2): dproperties(Cell, ["h", "ih", "V"]) + + +class GenericCell(Cell): + """A cell class that does not assume upper-triangular values. + + Depend objects: + h: An array giving the lattice vector matrix. + ih: An array giving the inverse of the lattice vector matrix. + V: The volume of the cell. + """ + + def __init__(self, h=None): + """Initialises base cell class. + + Args: + h: Optional array giving the initial lattice vector matrix. The + reference cell matrix is set equal to this. + """ + + if h is None: + h = np.zeros((3, 3), float) + + self._h = depend_array(name="h", value=h) + self._ih = depend_array( + name="ih", + value=np.zeros((3, 3), float), + func=self.get_ih, + dependencies=[self._h], + ) + self._V = depend_value(name="V", func=self.get_volume, dependencies=[self._h]) + + def clone(self): + return GenericCell(dstrip(self.h).copy()) + + def get_ih(self): + """Inverts the lattice vector matrix.""" + + return np.linalg.inv(self.h) + + def get_volume(self): + """Calculates the volume of the system box.""" + + return np.linalg.det(self.h) + + +dproperties(GenericCell, ["h", "ih", "V"]) diff --git a/ipi/engine/forcefields.py b/ipi/engine/forcefields.py index d764902b6..bb3c026cd 100644 --- a/ipi/engine/forcefields.py +++ b/ipi/engine/forcefields.py @@ -13,9 +13,12 @@ import threading import json import sys +from contextlib import nullcontext import numpy as np +from ipi.engine.cell import GenericCell +from ipi.utils.prng import Random from ipi.utils.softexit import softexit from ipi.utils.messages import info, verbosity, warning from ipi.interfaces.sockets import InterfaceSocket @@ -24,6 +27,11 @@ from ipi.utils.units import unit_to_internal from ipi.utils.distance import vector_separation from ipi.pes import __drivers__ +from ipi.utils.mathtools import ( + get_rotation_quadrature_legendre, + get_rotation_quadrature_lebedev, + random_rotation, +) plumed = None @@ -67,7 +75,7 @@ class ForceField: def __init__( self, - latency=1.0, + latency=1e-4, offset=0.0, name="", pars=None, @@ -223,22 +231,26 @@ def _poll_loop(self): finished. """ - info(" @ForceField: Starting the polling thread main loop.", verbosity.low) + info( + f" @ForceField ({self.name}): Starting the polling thread main loop.", + verbosity.low, + ) while self._doloop[0]: time.sleep(self.latency) if len(self.requests) > 0: self.poll() - def release(self, request): + def release(self, request, lock=True): """Removes a request from the evaluation queue. Args: request: The id of the job to release. + lock: whether we should apply a threadlock here """ """Frees up a request.""" - with self._threadlock: + with self._threadlock if lock else nullcontext(): if request in self.requests: try: self.requests.remove(request) @@ -419,6 +431,8 @@ def __init__( super().__init__(latency, offset, name, pars, dopbc, active, threaded) + if pars is None: + pars = {} # defaults no pars self.pes = pes try: self.driver = __drivers__[self.pes](verbose=verbosity.high, **pars) @@ -1159,7 +1173,7 @@ def __init__( pars=pars, dopbc=dopbc, active=active, - threaded=True, + threaded=True, # hardcoded, otherwise won't work! ) if len(fflist) == 0: raise ValueError( @@ -1442,6 +1456,209 @@ def poll(self): r["status"] = "Done" +class FFRotations(ForceField): + """Forcefield to manipulate models that are not exactly rotationally equivariant. + Can be used to evaluate a different random rotation at each evaluation, or to average + over a regular grid of Euler angles""" + + def __init__( + self, + latency=1.0, + offset=0.0, + name="", + pars=None, + dopbc=True, + active=np.array([-1]), + threaded=True, + prng=None, + ffsocket=None, + ffdirect=None, + random=False, + inversion=False, + grid_order=1, + grid_mode="lebedev", + ): + super( + FFRotations, self + ).__init__( # force threaded execution to handle sub-ffield + latency, offset, name, pars, dopbc, active, threaded=True + ) + + if prng is None: + warning("No PRNG provided, will initialize one", verbosity.low) + self.prng = Random() + else: + self.prng = prng + self.ffsocket = ffsocket + self.ffdirect = ffdirect + if ffsocket is None or self.ffsocket.name == "__DUMMY__": + if ffdirect is None or self.ffdirect.name == "__DUMMY__": + raise ValueError( + "Must specify a non-default value for either `ffsocket` or `ffdirect` into `ffrotations`" + ) + else: + self.ff = self.ffdirect + elif ffdirect is None or self.ffdirect.name == "__DUMMY__": + self.ff = self.ffsocket + else: + raise ValueError( + "Cannot specify both `ffsocket` and `ffdirect` into `ffrotations`" + ) + + self.random = random + self.inversion = inversion + self.grid_order = grid_order + self.grid_mode = grid_mode + + if self.grid_mode == "lebedev": + self._rotations = get_rotation_quadrature_lebedev(self.grid_order) + elif self.grid_mode == "legendre": + self._rotations = get_rotation_quadrature_legendre(self.grid_order) + else: + raise ValueError(f"Invalid quadrature {self.grid_mode}") + info( + f""" +# Generating {self.grid_mode} rotation quadrature of order {self.grid_order}. +# Grid contains {len(self._rotations)} proper rotations. +{("# Inversion is also active, doubling the number of evaluations." if self.inversion else "")}""", + verbosity.low, + ) + + def bind(self, output_maker=None): + super().bind(output_maker) + self.ff.bind(output_maker) + + def start(self): + super().start() + self.ff.start() + + def queue(self, atoms, cell, reqid=-1): + + # launches requests for all of the rotations FF objects + ffh = [] # this is the list of "inner" FF requests + rots = [] # this is a list of tuples of (rotation matrix, weight) + if self.random: + R_random = random_rotation(self.prng, improper=True) + else: + R_random = np.eye(3) + + for R, w, _ in self._rotations: + R = R @ R_random + + rot_atoms = atoms.clone() + rot_cell = GenericCell( + R @ dstrip(cell.h).copy() + ) # NB we need generic cell orientation + rot_atoms.q[:] = (dstrip(rot_atoms.q).reshape(-1, 3) @ R.T).flatten() + + rots.append((R, w)) + ffh.append(self.ff.queue(rot_atoms, rot_cell, reqid)) + + if self.inversion: + # also add a "flipped rotation" to the evaluation list + R = R * -1 + + rot_cell = GenericCell(R @ dstrip(cell.h).copy()) + rot_atoms = atoms.clone() + rot_atoms.q[:] = (dstrip(rot_atoms.q).reshape(-1, 3) @ R.T).flatten() + + rots.append((R, w)) + ffh.append(self.ff.queue(rot_atoms, rot_cell, reqid)) + + # creates the request with the help of the base class, + # making sure it already contains a handle to the list of FF + # requests + req = ForceField.queue( + self, atoms, cell, reqid, template=dict(ff_handles=ffh, rots=rots) + ) + req["status"] = "Running" + req["t_dispatched"] = time.time() + return req + + def check_finish(self, r): + """Checks if all sub-requests associated with a given + request are finished""" + + for ff_r in r["ff_handles"]: + if ff_r["status"] != "Done": + return False + return True + + def gather(self, r): + """Collects results from all sub-requests, and assemble the committee of models.""" + + r["result"] = [ + 0.0, + np.zeros(len(r["pos"]), float), + np.zeros((3, 3), float), + "", + ] + + # list of pointers to the forcefield requests. shallow copy so we can remove stuff + rot_handles = r["ff_handles"].copy() + rots = r["rots"].copy() + + # Gathers the forcefield energetics and extras + pots = [] + frcs = [] + virs = [] + xtrs = [] + quad_w = [] + for ff_r, (R, w) in zip(rot_handles, rots): + pots.append(ff_r["result"][0]) + # must rotate forces and virial back into the original reference frame + frcs.append((ff_r["result"][1].reshape(-1, 3) @ R).flatten()) + virs.append((R.T @ ff_r["result"][2] @ R)) + xtrs.append(ff_r["result"][3]) + quad_w.append(w) + + quad_w = np.array(quad_w) + pots = np.array(pots) + frcs = np.array(frcs).reshape(len(frcs), -1) + virs = np.array(virs).reshape(-1, 3, 3) + + # Computes the mean energetics (using the quadrature weights) + mean_pot = np.sum(pots * quad_w, axis=0) / quad_w.sum() + mean_frc = np.sum(frcs * quad_w[:, np.newaxis], axis=0) / quad_w.sum() + mean_vir = ( + np.sum(virs * quad_w[:, np.newaxis, np.newaxis], axis=0) / quad_w.sum() + ) + + # Sets the output of the committee model. + r["result"][0] = mean_pot + r["result"][1] = mean_frc + r["result"][2] = mean_vir + r["result"][3] = { + "o3grid_pots": pots + } # this is the list of potentials on a grid, for monitoring + + # "dissolve" the extras dictionaries into a list + if isinstance(xtrs[0], dict): + for k in xtrs[0].keys(): + r["result"][3][k] = [] + for x in xtrs: + r["result"][3][k].append(x[k]) + else: + r["result"][3]["raw"] = [] + for x in xtrs: + r["result"][3]["raw"].append(x) + + for ff_r in r["ff_handles"]: + self.ff.release(ff_r) + + def poll(self): + """Polls the forcefield object to check if it has finished.""" + + with self._threadlock: + for r in self.requests: + if "ff_handles" in r and r["status"] != "Done" and self.check_finish(r): + r["t_finished"] = time.time() + self.gather(r) + r["result"][0] -= self.offset + r["status"] = "Done" + self.release(r, lock=False) + + class PhotonDriver: """ Photon driver for a single cavity mode diff --git a/ipi/inputs/forcefields.py b/ipi/inputs/forcefields.py index 5174a8c23..245908219 100644 --- a/ipi/inputs/forcefields.py +++ b/ipi/inputs/forcefields.py @@ -20,6 +20,7 @@ FFCommittee, FFdmd, FFCavPhSocket, + FFRotations, ) from ipi.interfaces.sockets import InterfaceSocket from ipi.pes import __drivers__ @@ -27,6 +28,8 @@ from ipi.inputs.initializer import * from ipi.utils.inputvalue import * from ipi.utils.messages import verbosity, warning +from ipi.utils.prng import Random +from ipi.inputs.prng import InputRandom __all__ = [ "InputFFSocket", @@ -39,6 +42,7 @@ "InputFFCommittee", "InputFFdmd", "InputFFCavPhSocket", + "InputFFRotations", ] @@ -263,7 +267,7 @@ def store(self, ff): ff: A ForceField object with a FFSocket forcemodel object. """ - if (not type(ff) is FFSocket) and (not type(ff) is FFCavPhSocket): + if type(ff) not in [FFSocket, FFCavPhSocket]: raise TypeError( "The type " + type(ff).__name__ + " is not a valid socket forcefield" ) @@ -471,7 +475,7 @@ class InputFFDebye(InputForceField): "default": input_default(factory=np.zeros, args=(0,)), "help": "Specifies the Hessian of the harmonic potential. " "Default units are atomic. Units can be specified only by xml attribute. " - r"Implemented options are: 'atomic_unit', 'ev/ang\^2'", + r"Implemented options are: 'atomic_unit', 'ev/ang^2'", "dimension": "hessian", }, ), @@ -921,6 +925,127 @@ def fetch(self): ) +class InputFFRotations(InputForceField): + default_help = """ +Wraps around another forcefield to evaluate it over one or more +rotated copies of the physical system. This is useful when +interacting with models that are not exactly invariant/covariant +with respect to rigid rotations. +Besides the parameters defining how averaging is to be performed +(using an integration grid, and/or randomizing the orientation at +each step) the should contain either a +or a block that computes the "base" model. Note that +this forcefield should be given a separate `name`, but that you +cannot access this "inner" forcefield from other parts of the +input file. +""" + default_label = "FFROTATIONS" + + fields = copy(InputForceField.fields) + + fields["random"] = ( + InputValue, + { + "dtype": bool, + "default": False, + "help": """Applies a random rotation at each evaluation. """, + }, + ) + + fields["grid_order"] = ( + InputValue, + { + "dtype": int, + "default": 1, + "help": """Sums over a grid of rotations of the given order. + Note that the number of rotations increases rapidly with the order: + e.g. for a legendre grid + '1' leads to a single rotation, '2' to 18, '3' to 75 rotations, while + for a lebedev grid '3' contains 18 rotations, '5' 70 rotations and so on. + """, + }, + ) + + fields["grid_mode"] = ( + InputValue, + { + "dtype": str, + "options": ["legendre", "lebedev"], + "default": "legendre", + "help": """Defines the type of integration grid. + Lebedev grids are usually more efficient in integrating. + """, + }, + ) + + fields["inversion"] = ( + InputValue, + { + "dtype": bool, + "default": False, + "help": """Always applies the improper version of each rotation in the + grid (or the randomly-sampled rotation). Doubles the evaluations and makes + the model exactly equivariant to inversion.""", + }, + ) + + fields["prng"] = ( + InputRandom, + { + "help": InputRandom.default_help, + "default": input_default(factory=Random), + }, + ) + + fields["ffsocket"] = ( + InputFFSocket, + { + "help": InputFFSocket.default_help, + "default": input_default(factory=FFSocket, kwargs={"name": "__DUMMY__"}), + }, + ) + + fields["ffdirect"] = ( + InputFFDirect, + { + "help": InputFFDirect.default_help, + "default": input_default(factory=FFDirect, kwargs={"name": "__DUMMY__"}), + }, + ) + + def store(self, ff): + """Store the base and rotation quadrature parameters""" + + super(InputFFRotations, self).store(ff) + self.inversion.store(ff.inversion) + self.grid_order.store(ff.grid_order) + self.grid_mode.store(ff.grid_mode) + self.random.store(ff.random) + self.prng.store(ff.prng) + self.ffsocket.store(ff.ffsocket) + self.ffdirect.store(ff.ffdirect) + + def fetch(self): + """Fetches all of the FF objects""" + + return FFRotations( + pars=self.parameters.fetch(), + name=self.name.fetch(), + latency=self.latency.fetch(), + offset=self.offset.fetch(), + dopbc=self.pbc.fetch(), + active=self.activelist.fetch(), + threaded=self.threaded.fetch(), + prng=self.prng.fetch(), + ffsocket=self.ffsocket.fetch(), + ffdirect=self.ffdirect.fetch(), + grid_order=self.grid_order.fetch(), + grid_mode=self.grid_mode.fetch(), + random=self.random.fetch(), + inversion=self.inversion.fetch(), + ) + + class InputFFCavPhSocket(InputFFSocket): default_help = """A cavity molecular dynamics driver for vibraitonal strong coupling. In the current implementation, only a single cavity mode polarized along the x and y directions is coupled to the molecules. diff --git a/ipi/inputs/simulation.py b/ipi/inputs/simulation.py index 796316d59..3c1c4054f 100644 --- a/ipi/inputs/simulation.py +++ b/ipi/inputs/simulation.py @@ -187,6 +187,10 @@ class InputSimulation(Input): iforcefields.InputFFCommittee, {"help": iforcefields.InputFFCommittee.default_help}, ), + "ffrotations": ( + iforcefields.InputFFRotations, + {"help": iforcefields.InputFFRotations.default_help}, + ), "ffsgdml": ( iforcefields.InputFFsGDML, {"help": iforcefields.InputFFsGDML.default_help}, @@ -246,7 +250,7 @@ def store(self, simul): _obj, ) in enumerate(_fflist + simul.syslist): if self.extra[_ii] == 0: - if isinstance(_obj, eforcefields.FFSocket): + if type(_obj) is eforcefields.FFSocket: _iobj = iforcefields.InputFFSocket() _iobj.store(_obj) self.extra[_ii] = ("ffsocket", _iobj) @@ -282,6 +286,10 @@ def store(self, simul): _iobj = iforcefields.InputFFCommittee() _iobj.store(_obj) self.extra[_ii] = ("ffcommittee", _iobj) + elif isinstance(_obj, eforcefields.FFRotations): + _iobj = iforcefields.InputFFRotations() + _iobj.store(_obj) + self.extra[_ii] = ("ffrotations", _iobj) elif isinstance(_obj, eforcefields.FFCavPhSocket): _iobj = iforcefields.InputFFCavPhSocket() _iobj.store(_obj) @@ -340,6 +348,7 @@ def fetch(self): "ffsgdml", "ffyaff", "ffcommittee", + "ffrotations", "ffcavphsocket", ]: new_ff = v.fetch() diff --git a/ipi/utils/__init__.py b/ipi/utils/__init__.py index 24b383cd3..808781bfd 100644 --- a/ipi/utils/__init__.py +++ b/ipi/utils/__init__.py @@ -16,6 +16,7 @@ "messages", "softexit", "setup", + "tools", "io", "constrtools", ] diff --git a/ipi/utils/lebedev_grids.npy b/ipi/utils/lebedev_grids.npy new file mode 100644 index 0000000000000000000000000000000000000000..e8c36c3be1a1b99b605d3bb549378c3a49936fda GIT binary patch literal 549870 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 F{|~y#`Q-or literal 0 HcmV?d00001 diff --git a/ipi/utils/mathtools.py b/ipi/utils/mathtools.py index 000043233..e6a6341b5 100644 --- a/ipi/utils/mathtools.py +++ b/ipi/utils/mathtools.py @@ -6,6 +6,7 @@ import math +from importlib import resources import numpy as np @@ -25,6 +26,8 @@ "logsumlog", "sinch", "gaussian_inv", + "get_rotation_quadrature_legendre", + "get_rotation_quadrature_lebedev", ] @@ -521,3 +524,127 @@ def f(w): )[0] return 2 * integral / np.pi + + +def quat2rot(q): + """ + Convert a normalized quaternion into a 3x3 rotation matrix. + + Args: + q : list or array-like + A normalized quaternion [q1, q2, q3, q4] where q1 is the scalar part. + + Returns: + numpy.ndarray + The corresponding 3x3 rotation matrix. + """ + + q1, q2, q3, q4 = q + + # Compute the rotation matrix elements + R = np.array( + [ + [1 - 2 * (q3**2 + q4**2), 2 * (q2 * q3 - q1 * q4), 2 * (q2 * q4 + q1 * q3)], + [2 * (q2 * q3 + q1 * q4), 1 - 2 * (q2**2 + q4**2), 2 * (q3 * q4 - q1 * q2)], + [2 * (q2 * q4 - q1 * q3), 2 * (q3 * q4 + q1 * q2), 1 - 2 * (q2**2 + q3**2)], + ] + ) + + return R + + +def euler_zxz_to_matrix(theta, v, w): + """ + Generate a rotation matrix from Euler angles [theta, v, w] in the ZXZ convention. + + Args: + theta, v, w : float + Euler angles in radians. + + Returns: + numpy.ndarray + The corresponding 3x3 rotation matrix. + """ + + # Rotation matrix around the Z-axis by theta + R_z_theta = np.array( + [ + [np.cos(theta), -np.sin(theta), 0], + [np.sin(theta), np.cos(theta), 0], + [0, 0, 1], + ] + ) + + # Rotation matrix around the X-axis by v + R_x_v = np.array([[1, 0, 0], [0, np.cos(v), -np.sin(v)], [0, np.sin(v), np.cos(v)]]) + + # Rotation matrix around the Z-axis by w + R_z_w = np.array([[np.cos(w), -np.sin(w), 0], [np.sin(w), np.cos(w), 0], [0, 0, 1]]) + + # Total rotation matrix is the product of these matrices: R_z(w) * R_x(v) * R_z(theta) + rotation_matrix = R_z_w @ R_x_v @ R_z_theta + + return rotation_matrix + + +def roots_legendre(L): + """Replicates scipy.special.roots_legendre using only numpy""" + + legendre_poly = np.polynomial.legendre.Legendre.basis(L) + roots = np.polynomial.legendre.legroots(legendre_poly.coef) + legendre_poly_deriv = legendre_poly.deriv() + + # Calculate weights using the formula + weights = 2 / ((1 - roots**2) * (legendre_poly_deriv(roots) ** 2)) + + return roots, weights + + +def get_rotation_quadrature_legendre(L): + if L == 1: + # returns the identity (for some reason this algo below generates a different rotation) + return [(np.eye(3), 2.0, [0, 0, 0])] + quads = [] + for theta_index in range(0, 2 * L - 1): + for w_index in range(0, 2 * L - 1): + theta = 2 * np.pi * theta_index / (2 * L - 1) + w = 2 * np.pi * w_index / (2 * L - 1) + roots_legendre_now, weights_now = roots_legendre(L) + all_v = np.arccos(roots_legendre_now) + for v, weight in zip(all_v, weights_now): + angles = [theta, v, w] + rotation_matrix = euler_zxz_to_matrix(*angles) + quads.append((rotation_matrix, weight, angles)) + + return quads + + +def get_rotation_quadrature_lebedev(L): + with resources.path("ipi.utils", "lebedev_grids.npy") as file_path: + lebedev = np.load(file_path, allow_pickle=True).item() + if not L in lebedev: + raise ValueError(f"There is no Lebedev grid of order {L} available") + leb_quad = lebedev[L] + quads = [] + for theta_index in range(0, L): + theta = 2 * np.pi * theta_index / L + for w, v, weight in leb_quad: + angles = [w, v, theta] + rotation_matrix = euler_zxz_to_matrix(*angles) + quads.append((rotation_matrix, weight, angles)) + return quads + + +def random_rotation(prng, improper=True): + """Generates a (uniform) random rotation matrix""" + + quaternion = prng.gvec(shape=(4,)) + quaternion /= np.sqrt((quaternion**2).sum()) + + rot = quat2rot(quaternion) + + # randomly generate an improper rotation + if improper and prng.u < 0.5: + rot *= -1.0 + + return rot diff --git a/ipi/utils/setup.py b/ipi/utils/setup.py index d8fd38ab2..264ec43ce 100644 --- a/ipi/utils/setup.py +++ b/ipi/utils/setup.py @@ -64,7 +64,13 @@ def install_driver(force_install=False): try: subprocess.run(["git", "init"], cwd=temp_dir) subprocess.run( - ["git", "remote", "add", "origin", "https://github.com/i-pi/i-pi.git"], + [ + "git", + "remote", + "add", + "origin", + "https://github.com/lab-cosmo/i-pi.git", + ], cwd=temp_dir, ) subprocess.run( @@ -74,7 +80,9 @@ def install_driver(force_install=False): os.path.join(temp_dir, ".git", "info", "sparse-checkout"), "w" ) as f: f.write("drivers/f90\n") - subprocess.run(["git", "pull", "--depth=1", "origin", "main"], cwd=temp_dir) + subprocess.run( + ["git", "pull", "--depth=1", "origin", "feat/equivator"], cwd=temp_dir + ) except: warning( "Failed to fetch the drivers folder from i-PI github repository", diff --git a/ipi_tests/examples/exampletools.py b/ipi_tests/examples/exampletools.py index a78ac3c5d..f29ef10ae 100644 --- a/ipi_tests/examples/exampletools.py +++ b/ipi_tests/examples/exampletools.py @@ -55,5 +55,6 @@ def create_client_list(self, driver_info, nid, test_settings): test_settings, ) return clients - except: - raise RuntimeError("Couldn't modify the xml file") + except Exception as ex: + print("Couldn't modify the xml file") + raise ex diff --git a/ipi_tests/test_tools.py b/ipi_tests/test_tools.py index b4f4dff35..f43b25ecf 100644 --- a/ipi_tests/test_tools.py +++ b/ipi_tests/test_tools.py @@ -9,6 +9,7 @@ clean_all = False debug = False +TIMEOUT = 20 fortran_driver_models = [ "dummy", @@ -31,6 +32,7 @@ "doublewell_1D", "doublewell", "gas", + "noo3-h2o", ] # We should do this automatically but for now we do it explicitly here @@ -185,10 +187,11 @@ def modify_xml_4_dummy_test( root = tree.getroot() clients = list() + ff_roots = [root] if len(root.findall("ffcommittee")) > 0: - ff_roots = root.findall("ffcommittee") - else: - ff_roots = [root] + ff_roots += root.findall("ffcommittee") + if len(root.findall("ffrotations")) > 0: + ff_roots += root.findall("ffrotations") ff_sockets = [] for ff_root in ff_roots: @@ -322,7 +325,7 @@ def run(self, cwd, nid): print("List all files /tmp/ipi_*") for filename in glob.glob("/tmp/ipi_*"): print(filename) - ipi_error = ipi.communicate(timeout=120)[1].decode("ascii") + ipi_error = ipi.communicate(timeout=TIMEOUT)[1].decode("ascii") print(ipi_error) return "Could not find the i-PI UNIX socket" @@ -375,13 +378,13 @@ def run(self, cwd, nid): drivers.append(driver) # check i-pi errors - ipi_out, ipi_error = ipi.communicate(timeout=60) + ipi_out, ipi_error = ipi.communicate(timeout=TIMEOUT) assert ipi.returncode == 0, "i-PI error occurred: {}".format(ipi_error) # check driver errors for driver in drivers: # if i-PI has ended, we can wait for the driver to quit - driver_out, driver_err = driver.communicate(timeout=60) + driver_out, driver_err = driver.communicate(timeout=TIMEOUT) assert ( driver.returncode == 0 ), "Driver error occurred: {}\n Driver Output: {}".format( diff --git a/setup.cfg b/setup.cfg index eda5e7f97..bf28c22a5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,10 +21,10 @@ classifiers = Operating System :: POSIX :: Linux License :: OSI Approved :: GNU General Public License v3 (GPLv3) Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Topic :: Scientific/Engineering :: Chemistry Topic :: Scientific/Engineering :: Physics diff --git a/setup.py b/setup.py index e865e9c79..a4d3c095f 100644 --- a/setup.py +++ b/setup.py @@ -7,5 +7,8 @@ setup( packages=[*find_packages(exclude=["ipi_tests*"])], + package_data={ + "ipi.utils": ["lebedev_grids.npy"], # Include the npy file here + }, scripts=scripts, )