From aac88ea6ea993a334f2a628cc946db6d8ccb055c Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 30 Oct 2024 11:41:48 +0100 Subject: [PATCH 01/47] Add SO3LR calculator (#388) * Add SO3LR calculator What is says on the tin. This is pending some fixes on the side of So3LR and MLFF, but this is all that's needed from the i-pi end. --- drivers/py/pes/so3lr.py | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 drivers/py/pes/so3lr.py diff --git a/drivers/py/pes/so3lr.py b/drivers/py/pes/so3lr.py new file mode 100644 index 000000000..ee9599684 --- /dev/null +++ b/drivers/py/pes/so3lr.py @@ -0,0 +1,42 @@ +""" An interface for the [SO3LR](https://github.com/general-molecular-simulations/so3lr) calculator """ + +from .ase import ASEDriver + +try: + from so3lr import So3lrCalculator +except: + So3lrCalculator = None + +__DRIVER_NAME__ = "so3lr" +__DRIVER_CLASS__ = "SO3LR_driver" + +ERROR_MSG = """ +SO3LR driver requires a template file that describes the chemical makeup of the structure. + +Optionally, lr_cutoff and dispersion_energy_lr_cutoff_damping can be specified. + +Example: python driver.py -m so3lr -u -o template.xyz,lr_cutoff=12,dispersion_energy_lr_cutoff_damping=2 +""" + + +class SO3LR_driver(ASEDriver): + def __init__(self, args=None, verbose=False): + if So3lrCalculator is None: + raise ImportError("Couldn't load so3lr bindings") + + super().__init__(args, verbose, ERROR_MSG) + + def check_arguments(self): + super().check_arguments() + + args = self.args + + kwargs = {} + if len(args) >= 2: + _ = args[0] # template we don't need + + for arg in args[1:]: + key, value = arg.split("=") + kwargs[key] = float(value) + + self.ase_calculator = So3lrCalculator(**kwargs) From 4eaef2041329ddba2fa0e8b7e851f60eca18d0f1 Mon Sep 17 00:00:00 2001 From: Filippo Bigi <98903385+frostedoyster@users.noreply.github.com> Date: Sat, 2 Nov 2024 16:45:18 +0100 Subject: [PATCH 02/47] Prevent new `xtb` module from crashing simulations (#389) * Update xtb.py * Smarter import error --- drivers/py/pes/xtb.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/py/pes/xtb.py b/drivers/py/pes/xtb.py index c2b7947fd..144a07c67 100644 --- a/drivers/py/pes/xtb.py +++ b/drivers/py/pes/xtb.py @@ -13,10 +13,9 @@ try: import tblite.interface as tb -except ImportError as e: - raise ModuleNotFoundError( - "Could not find tblite for xtb driver. Please install tblite-python with mamba" - ) from e +except ImportError: + tb = None + __DRIVER_NAME__ = "xtb" __DRIVER_CLASS__ = "TBLiteDriver" @@ -31,6 +30,12 @@ def __init__( verbose=False, ): """Initialized dummy drivers""" + + if tb is None: + raise ModuleNotFoundError( + "Could not find tblite for xtb driver. Please install tblite-python with mamba" + ) + config = json.loads(args) try: self.method = config["method"] From 516ec4d6ea7ac02810b3b645123630a61ad8586e Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 13:59:49 +0200 Subject: [PATCH 03/47] removed python resources from docs --- docs/src/onlinereso.rst | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index 62f971018..530185440 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -17,17 +17,6 @@ Several examples of usage of i-PI to perform advanced molecular simulations can be found among the recipes of the `atomistic cookbook `_. -Python resources -~~~~~~~~~~~~~~~~ - -For help with Python programming, see -`www.python.org `__. For information about the NumPy -mathematical library, see `www.numpy.org `__, and for -worked examples of its capabilities see -`www.scipy.org/Tentative_NumPy_Tutorial `__. -Finally, see http://hgomersall.github.io/pyFFTW/ for documentation on -the Python FFTW library that is currently implemented with i-PI. - Client code resources ~~~~~~~~~~~~~~~~~~~~~ From d87d9cd690798f4d10dc1ce5fbfa5e7314e22abd Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 14:43:33 +0200 Subject: [PATCH 04/47] Finished moving materials from the website resources/tutorials section to online resources in docs --- docs/src/onlinereso.rst | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index 530185440..0970f1d2a 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -3,6 +3,14 @@ On-line resources ================= +Massive Open Online Course (MOOC) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The theory behind many types of simulation that i-PI can do and examples +of simulations with i-PI can also be found in an online course freely +available to everyone, and accessible from this +`link `_. + i-PI resources ~~~~~~~~~~~~~~ @@ -13,10 +21,34 @@ In http://gle4md.org/ one can also obtain colored-noise parameters to run Path Integral with Generalized Langevin Equation thermostat (PI+GLE/PIGLET) calculations. -Several examples of usage of i-PI to perform advanced molecular simulations -can be found among the recipes of the -`atomistic cookbook `_. +Tutorials +~~~~~~~~~ +A simple tutorial on how to run i-PI can be found in the documentation: +`a simple tutorial `_. + +You can try a set of guided examples that demonstrate some more +advanced features of i-PI. These Tutorials, from the 2021 CECAM +Flagship school, are available here: +`i-PI 2021 tutorials `_. +Tutorials from the 2023 CECAM Flagship school are available here: +`i-PI 2023 tutorials `_. + +Note that these examples use some features +(such as qTIP4P/F water and the Zundel cation potentials in the driver code, +and optionally also CP2K). Instructions on how to install and run these codes +with i-PI are contained in the tutorial. + +Atomistic recipes +~~~~~~~~~~~~~~~~~ + +Several examples of usage of i-PI to perform advanced molecular +simulations can be found among the recipes of the +`atomistic cookbook `_. +These include an +`introduction to path integral simulations `_, +a discussion of `how to compute quantum heat capacities `_, +and an example of `path integral metadynamics`_. Client code resources ~~~~~~~~~~~~~~~~~~~~~ From 299b2315712b53bea0c80d431875489e055beafd Mon Sep 17 00:00:00 2001 From: Mariana Rossi Date: Mon, 11 Nov 2024 14:01:19 +0100 Subject: [PATCH 05/47] Changing the default behaviour of the seed of the random number generator. I have modified input/prng.py and utils/prng.py. I updated all inputs in the regression tests for safety. Only the PLUMED ones were relying on the default seed 12345. The others were simulations where no random sequence should be generated, but I added the old default anyways. Tested behaviour in the output file and saving to restart files. --- ipi/inputs/prng.py | 5 +++-- ipi/utils/prng.py | 17 ++++++++++++++++- .../tests/GEOP/BFGS-TRM/harmonic/input.xml | 3 +++ .../tests/GEOP/BFGS-TRM/pswater/input.xml | 3 +++ .../tests/GEOP/BFGS/harmonic/input.xml | 3 +++ .../tests/GEOP/BFGS/pswater/input.xml | 3 +++ .../tests/GEOP/CG/harmonic/input.xml | 3 +++ .../tests/GEOP/LBFGS/harmonic/input.xml | 3 +++ .../tests/GEOP/LBFGS/pswater/input.xml | 3 +++ .../tests/INSTANTON/070K_D/input.xml | 3 +++ .../INSTANTON/100K_implicit_friction/input.xml | 3 +++ .../tests/INSTANTON/200K/input.xml | 3 +++ .../tests/NEB/DAMPED_BFGS/zundel/input.xml | 3 +++ .../tests/NEB/FIRE/zundel/input.xml | 3 +++ .../fd_phonons/ch4hcbe-with_fixdofs/input.xml | 3 +++ .../tests/PHONONS/fd_phonons/ch4hcbe/input.xml | 3 +++ .../tests/PLUMED/BIAS.NOAUTO/input.xml | 3 +++ .../tests/PLUMED/METAD.NOAUTO/input.xml | 3 +++ 18 files changed, 67 insertions(+), 3 deletions(-) diff --git a/ipi/inputs/prng.py b/ipi/inputs/prng.py index 9d83ced86..cf4c9b8f6 100644 --- a/ipi/inputs/prng.py +++ b/ipi/inputs/prng.py @@ -51,8 +51,9 @@ class InputRandom(Input): InputValue, { "dtype": int, - "default": 123456, - "help": "This is the seed number used to generate the initial state of the random number generator.", + # "default": 123456, + "default": -1, + "help": "This is the seed number used to generate the initial state of the random number generator. Previously, the seed was fixed as 123456. Currently, the seed is random and given by the system time (down to ms). This is done in utils/prng.py.", }, ), "state": ( diff --git a/ipi/utils/prng.py b/ipi/utils/prng.py index 273a7e0b4..c73bfb307 100644 --- a/ipi/utils/prng.py +++ b/ipi/utils/prng.py @@ -14,6 +14,9 @@ import numpy as np import concurrent.futures +import time +from ipi.utils.messages import verbosity, info +import threading __all__ = ["Random"] @@ -39,7 +42,7 @@ class Random(object): Gaussian random number returned. """ - def __init__(self, seed=12345, state=None, n_threads=1): + def __init__(self, seed=-1, state=None, n_threads=1): """Initialises Random. Args: @@ -49,7 +52,19 @@ def __init__(self, seed=12345, state=None, n_threads=1): arrays to be filled are large!) """ + # Here we make the seed random if it has not been specified in the input file + if seed == -1: + seed = int(time.time() * 1000) + self.seed = seed + + if threading.current_thread() == threading.main_thread(): + info( + "@ RANDOM SEED: The seed used in this calculation was " + + str(self.seed), + verbosity.low, + ) + self.rng = [ np.random.Generator(np.random.MT19937(s)) for s in np.random.SeedSequence(seed).spawn(n_threads) diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml index 51d87a02e..c74a0b4d7 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml index 5ea1d33ba..d80a0e79b 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml index ee9066b2d..4fe26e9c2 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml index c4979cc42..02ffd5e90 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml index 3470a0605..218b37a90 100644 --- a/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml index d09ca38d4..e2b6a9bd4 100644 --- a/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml index e14abf876..889abae0a 100644 --- a/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 12345 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml index 0cecd81da..1984ce9ca 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml @@ -2,6 +2,9 @@ [ step, potential{electronvolt}] + + 12345 + 1000
localhost
diff --git a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml index e6f349dcb..c3944a2bb 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml @@ -2,6 +2,9 @@ [ step, potential{electronvolt}] + + 12345 + 35
localhost
diff --git a/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml index 161af8767..7e52f5cbc 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml @@ -2,6 +2,9 @@ [ step, potential{electronvolt}] + + 12345 + 100
localhost
diff --git a/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml b/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml index 001bcabb5..c9faa4c1e 100644 --- a/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml +++ b/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml @@ -12,6 +12,9 @@ forces [step, bead_potentials] + + 12345 + diff --git a/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml b/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml index 4d1e70407..ed447d562 100644 --- a/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml +++ b/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml @@ -7,6 +7,9 @@ 600
localhost
+ + 12345 + positions{angstrom} forces diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml index aeb38b9e4..0955f7f27 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml @@ -3,6 +3,9 @@ [ step, potential{electronvolt}] x_centroid{angstrom} + + 12345 + 400
localhost
diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml index c88f42945..c359f100a 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml @@ -3,6 +3,9 @@ [ step, potential{electronvolt}] x_centroid{angstrom} + + 12345 + 400
localhost
diff --git a/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml b/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml index 37d944682..daf7f15d6 100644 --- a/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml +++ b/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml @@ -6,6 +6,9 @@ extras_bias extras_bias + + 12345 + 100
localhost
diff --git a/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml b/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml index 1f2237eda..3586e3cdd 100644 --- a/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml +++ b/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml @@ -5,6 +5,9 @@ f_centroid extras_bias + + 12345 + 100
localhost
From b123fa9b6ed113e0154baeebb05493c6948e6570 Mon Sep 17 00:00:00 2001 From: Mariana Rossi Date: Mon, 11 Nov 2024 14:11:18 +0100 Subject: [PATCH 06/47] Better explanation of default behaviour. --- ipi/inputs/prng.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipi/inputs/prng.py b/ipi/inputs/prng.py index cf4c9b8f6..2fa5ca34b 100644 --- a/ipi/inputs/prng.py +++ b/ipi/inputs/prng.py @@ -53,7 +53,7 @@ class InputRandom(Input): "dtype": int, # "default": 123456, "default": -1, - "help": "This is the seed number used to generate the initial state of the random number generator. Previously, the seed was fixed as 123456. Currently, the seed is random and given by the system time (down to ms). This is done in utils/prng.py.", + "help": "This specifies the seed number used to generate the initial state of the random number generator. Previously, the default seed was fixed as 123456. Currently, the default seed is random and given by the system time (down to ms). This is done in utils/prng.py.", }, ), "state": ( From b8ff3602e361fa5a9a95640964c3d34785871553 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 15:25:39 +0200 Subject: [PATCH 07/47] fixed typos --- docs/src/onlinereso.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index 0970f1d2a..cdfcc3705 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -1,7 +1,7 @@ .. _librarywebsites: -On-line resources -================= +Tutorials, recipes, and on-line resources +========================================= Massive Open Online Course (MOOC) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -48,7 +48,7 @@ simulations can be found among the recipes of the These include an `introduction to path integral simulations `_, a discussion of `how to compute quantum heat capacities `_, -and an example of `path integral metadynamics`_. +and an example of `path integral metadynamics `_. Client code resources ~~~~~~~~~~~~~~~~~~~~~ From 77625276fc78b1941ab5cde2b6737ab675e15349 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 15:27:42 +0200 Subject: [PATCH 08/47] brought up a simple tutorial up in the index --- docs/src/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/index.rst b/docs/src/index.rst index 37b4c4f72..c26c64435 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -27,6 +27,7 @@ This documentation is structured as follows: introduction onlinereso + tutorials features getting-started units @@ -35,7 +36,6 @@ This documentation is structured as follows: output-files output-tags distributed - tutorials faq troubleshooting contributing From b3d327744249528bd96fc86dd37e24bfa3d398d8 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 16:17:41 +0200 Subject: [PATCH 09/47] removed client code info from the resources page. No need for it, it appears on the main page of the website. --- docs/src/onlinereso.rst | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index cdfcc3705..095310fb1 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -50,34 +50,3 @@ These include an a discussion of `how to compute quantum heat capacities `_, and an example of `path integral metadynamics `_. -Client code resources -~~~~~~~~~~~~~~~~~~~~~ - -Several codes provide out-of-the-box an i-PI interface, including -ASE, -CASTEP, -CP2K, -DFTB+, -elphmod, -ffsGDML, -FHI-aims, -LAMMPS, -librascal, -Quantum ESPRESSO, -Siesta, -Yaff. - -If you are interested in interfacing your code to i-PI please get in -touch, we are always glad to help! - -There are several Fortran and C libraries that most client codes will -probably need to run, such as FFTW, BLAS and LAPACK. These can be found -at `www.fftw.org `__, -`www.netlib.org/blas `__ and -`www.netlib.org/lapack `__ respectively. - -These codes do not come as part of the i-PI package, and must be -downloaded separately. - -.. See chapter :ref:`clientinstall` for more details of how to do this. - From c1e551043f73be057dd789c8858b91a6960639c2 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 16:34:24 +0200 Subject: [PATCH 10/47] added demos and examples into the documentation under tutorials and online resources --- docs/src/onlinereso.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index 095310fb1..b2e996925 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -21,6 +21,29 @@ In http://gle4md.org/ one can also obtain colored-noise parameters to run Path Integral with Generalized Langevin Equation thermostat (PI+GLE/PIGLET) calculations. +Examples and demos +~~~~~~~~~~~~~~~~~~~ +The `examples` and `demos` folders in the i-PI `source code `_ +contain inputs for many different types of +calculations based on i-PI. Examples are typically minimal use-cases of specific +features, while demos are more structured, tutorial-like examples that show how +to realize more complex setups, and also provide a brief discussion of the +underlying algorithms. + +To run these examples, you should typically start i-PI, redirecting the output to +a log file, and then run a couple of instances of the driver code. The progress +of the wrapper is followed by monitoring the log file with the `tail` Linux command. + +Optionally, you can make a copy of the directory with the example somewhere +else if you want to keep the i-PI directory clean. For example:: + + bash + cd demos/para-h2-tutorial/tutorial-1/ + i-pi tutorial-1.xml > log & + i-pi-driver -a localhost -p 31415 -m sg -o 15 & + i-pi-driver -a localhost -p 31415 -m sg -o 15 & + tail -f log + Tutorials ~~~~~~~~~ A simple tutorial on how to run i-PI can be found in the documentation: From 2ab1ffb02789029ff5d59327f091c2cc7b311022 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 16:38:30 +0200 Subject: [PATCH 11/47] added link to docs tutorials and online resources to README --- README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 55756e5a5..0737ca4d5 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ -i-PI: a Universal Force Engine -============================== +# i-PI: a Universal Force Engine A Python interface for ab initio path integral molecular dynamics simulations (and more). -i-PI is a Python server (that does not need to be compiled and only requires a relatively -recent version of Python and Numpy) that applies an algorithm to update the positions of -the nuclei. One of many compatible external codes acts as client, and computes the +i-PI is a Python server (that does not need to be compiled and only requires a relatively +recent version of Python and Numpy) that applies an algorithm to update the positions of +the nuclei. One of many compatible external codes acts as client, and computes the electronic energy and forces. This is typically a patched version of an electronic structure code, but a @@ -13,17 +12,17 @@ potentials is included for test purposes. i-PI was originally developed to simulate the quantum mechanical nature of light nuclei by performing path integral molecular dynamics simulations, -and it implements most of the state-of-the-art methods to accelerate this kind of -calculations. It has since grown to also provide all sorts of simulation -strategies, from replica exchange to geometry optimization. +and it implements most of the state-of-the-art methods to accelerate this kind of +calculations. It has since grown to also provide all sorts of simulation +strategies, from replica exchange to geometry optimization. If you use i-PI in your research, please cite the accompanying publication: -for version 3, the relevant paper is -[Litman et al., *J. Chem. Phys.* 161, 062504 (2024)](https://doi.org/10.1063/5.0215869) +for version 3, the relevant paper is +[Litman et al., _J. Chem. Phys._ 161, 062504 (2024)](https://doi.org/10.1063/5.0215869) ``` @article{litman2024ipi, -title={i-PI 3.0: a flexible and efficient framework for advanced atomistic simulations}, +title={i-PI 3.0: a flexible and efficient framework for advanced atomistic simulations}, author={Yair Litman and Venkat Kapil and Yotam M. Y. Feldman and Davide Tisi and Tomislav Begušić and Karen Fidanyan and Guillaume Fraux and Jacob Higer and Matthias Kellner and Tao E. Li and Eszter S. Pós and Elia Stocco and George Trenins and Barak Hirshberg and Mariana Rossi and Michele Ceriotti}, journal = {J. Chem. Phys.}, pages = {062505}, @@ -32,8 +31,7 @@ year = {2024} } ``` -Quick Setup ------------ +## Quick Setup To use i-PI with an existing driver, install and update using `pip`: @@ -49,8 +47,7 @@ Last Release: pip install -U ipi ``` -Source installation -------------------- +## Source installation To develop i-PI or test it with the self-contained driver, follow these instructions. It is assumed that i-PI will @@ -63,10 +60,9 @@ git clone https://github.com/i-pi/i-pi.git ``` Source the environment settings file `env.sh` as `source env.sh` or `. -env.sh`. It is useful to put this in your `.bashrc` or other settings file if +env.sh`. It is useful to put this in your `.bashrc` or other settings file if you always want to have i-PI available. - ### Compile the driver code The built-in driver requires a FORTRAN compiler, and can be built as @@ -78,14 +74,14 @@ cd ../.. ``` There is also a Python driver available in `drivers/py`, which however has limited -functionalities. +functionalities. ### Examples and demos The `examples` and `demos` folders contain inputs for many different types of calculations based on i-PI. Examples are typically minimal use-cases of specific features, while demos are more structured, tutorial-like examples that show how -to realize more complex setups, and also provide a brief discussion of the +to realize more complex setups, and also provide a brief discussion of the underlying algorithms. To run these examples, you should typically start i-PI, redirecting the output to @@ -105,6 +101,11 @@ tail -f log The monitoring can be interrupted with CTRL+C when the run has finished (5000 steps). +### Tutorials and online resources + +The i-PI [documentation](https://docs.ipi-code.org/onlinereso.html) has a list of +avaialble tutorials, recipes and other useful online resources. + ### Run the automatic test suite The automatic test suite can be run by calling the i-pi-tests script. @@ -118,8 +119,7 @@ You may also need to install some dependencies, listed in `requirements.txt`. See more details in the README file inside the `ipi_tests` folder. -Contributing ------------- +## Contributing If you have new features you want to implement into i-PI, your contributions are much welcome. See `CONTRIBUTING.md` for a brief set of style guidelines and best practices. Before embarking From 6d7f8d2ba332a765cbdf3bc70a62b0bd83c24ccf Mon Sep 17 00:00:00 2001 From: Mariana Rossi Date: Mon, 11 Nov 2024 16:01:10 +0100 Subject: [PATCH 12/47] Changing to 12345*6* which was the atual previous default. Weirdly the PLUMED regtests did not complain. Are they actually being tested? --- .../regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml | 2 +- .../regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml | 2 +- ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml | 2 +- ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml | 2 +- ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml | 2 +- ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml | 2 +- ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml | 2 +- ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml | 2 +- .../tests/INSTANTON/100K_implicit_friction/input.xml | 2 +- ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml | 2 +- .../regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml | 2 +- ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml | 2 +- .../tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml | 2 +- .../regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml | 2 +- ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml | 2 +- ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml index c74a0b4d7..641e0690a 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml index d80a0e79b..ae2402bf4 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml index 4fe26e9c2..153a972cf 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml index 02ffd5e90..3efa27ed8 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml index 218b37a90..07b7b96d6 100644 --- a/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml index e2b6a9bd4..895b00640 100644 --- a/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml index 889abae0a..6cfafbec5 100644 --- a/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml @@ -5,7 +5,7 @@ f_centroid - 12345 + 123456 10 diff --git a/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml index 1984ce9ca..b4e10c099 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml @@ -3,7 +3,7 @@ [ step, potential{electronvolt}] - 12345 + 123456 1000 diff --git a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml index c3944a2bb..84f44a879 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml @@ -3,7 +3,7 @@ [ step, potential{electronvolt}] - 12345 + 123456 35 diff --git a/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml index 7e52f5cbc..0104b02b0 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml @@ -3,7 +3,7 @@ [ step, potential{electronvolt}] - 12345 + 123456 100 diff --git a/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml b/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml index c9faa4c1e..b81e1bc68 100644 --- a/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml +++ b/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml @@ -13,7 +13,7 @@ [step, bead_potentials] - 12345 + 123456 diff --git a/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml b/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml index ed447d562..1c251ec57 100644 --- a/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml +++ b/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml @@ -8,7 +8,7 @@
localhost
- 12345 + 123456 positions{angstrom} diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml index 0955f7f27..7daf71557 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml @@ -4,7 +4,7 @@ x_centroid{angstrom} - 12345 + 123456 400 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml index c359f100a..b3862e598 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml @@ -4,7 +4,7 @@ x_centroid{angstrom} - 12345 + 123456 400 diff --git a/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml b/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml index daf7f15d6..bdf83bea6 100644 --- a/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml +++ b/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml @@ -7,7 +7,7 @@ extras_bias - 12345 + 123456 100 diff --git a/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml b/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml index 3586e3cdd..567960428 100644 --- a/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml +++ b/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml @@ -6,7 +6,7 @@ extras_bias - 12345 + 123456 100 From 9a265e765229b9f7116788ddfce6a8c0d2250a30 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 17:46:39 +0200 Subject: [PATCH 13/47] added furo to requirements.txt; changed theme to furo in conf.py --- docs/requirements.txt | 1 + docs/src/conf.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 1d4517693..d322df967 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,3 +3,4 @@ jinja2 < 3.1 sphinxcontrib-bibtex==2.1.4 numpy pathlib +furo=2023.5.20 \ No newline at end of file diff --git a/docs/src/conf.py b/docs/src/conf.py index a1bccef5c..e94b835b8 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -54,7 +54,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "agogo" +html_theme = "furo" html_theme_options = { "rightsidebar": "false", } From 98291d1a640433a7dc0fe0a43528a184fd2c7122 Mon Sep 17 00:00:00 2001 From: BarakHirshberg Date: Mon, 11 Nov 2024 17:47:53 +0200 Subject: [PATCH 14/47] fixed typo --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index d322df967..f469284bd 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,4 +3,4 @@ jinja2 < 3.1 sphinxcontrib-bibtex==2.1.4 numpy pathlib -furo=2023.5.20 \ No newline at end of file +furo==2023.5.20 \ No newline at end of file From 4ae034b469fb1b7fbc7e3623625ce243f6d29e21 Mon Sep 17 00:00:00 2001 From: Mariana Rossi Date: Tue, 12 Nov 2024 09:44:36 +0100 Subject: [PATCH 15/47] Changing the default behaviour of the seed of the random number generator. (#393) * Changing the default behaviour of the seed of the random number generator. I have modified input/prng.py and utils/prng.py. I updated all inputs in the regression tests for safety. Only the PLUMED ones were relying on the default seed 12345. The others were simulations where no random sequence should be generated, but I added the old default anyways. Tested behaviour in the output file and saving to restart files. * Better explanation of default behaviour. * Changing to 12345*6* which was the atual previous default. Weirdly the PLUMED regtests did not complain. Are they actually being tested? --------- Co-authored-by: Mariana Rossi --- ipi/inputs/prng.py | 5 +++-- ipi/utils/prng.py | 17 ++++++++++++++++- .../tests/GEOP/BFGS-TRM/harmonic/input.xml | 3 +++ .../tests/GEOP/BFGS-TRM/pswater/input.xml | 3 +++ .../tests/GEOP/BFGS/harmonic/input.xml | 3 +++ .../tests/GEOP/BFGS/pswater/input.xml | 3 +++ .../tests/GEOP/CG/harmonic/input.xml | 3 +++ .../tests/GEOP/LBFGS/harmonic/input.xml | 3 +++ .../tests/GEOP/LBFGS/pswater/input.xml | 3 +++ .../tests/INSTANTON/070K_D/input.xml | 3 +++ .../INSTANTON/100K_implicit_friction/input.xml | 3 +++ .../tests/INSTANTON/200K/input.xml | 3 +++ .../tests/NEB/DAMPED_BFGS/zundel/input.xml | 3 +++ .../tests/NEB/FIRE/zundel/input.xml | 3 +++ .../fd_phonons/ch4hcbe-with_fixdofs/input.xml | 3 +++ .../tests/PHONONS/fd_phonons/ch4hcbe/input.xml | 3 +++ .../tests/PLUMED/BIAS.NOAUTO/input.xml | 3 +++ .../tests/PLUMED/METAD.NOAUTO/input.xml | 3 +++ 18 files changed, 67 insertions(+), 3 deletions(-) diff --git a/ipi/inputs/prng.py b/ipi/inputs/prng.py index 9d83ced86..2fa5ca34b 100644 --- a/ipi/inputs/prng.py +++ b/ipi/inputs/prng.py @@ -51,8 +51,9 @@ class InputRandom(Input): InputValue, { "dtype": int, - "default": 123456, - "help": "This is the seed number used to generate the initial state of the random number generator.", + # "default": 123456, + "default": -1, + "help": "This specifies the seed number used to generate the initial state of the random number generator. Previously, the default seed was fixed as 123456. Currently, the default seed is random and given by the system time (down to ms). This is done in utils/prng.py.", }, ), "state": ( diff --git a/ipi/utils/prng.py b/ipi/utils/prng.py index 273a7e0b4..c73bfb307 100644 --- a/ipi/utils/prng.py +++ b/ipi/utils/prng.py @@ -14,6 +14,9 @@ import numpy as np import concurrent.futures +import time +from ipi.utils.messages import verbosity, info +import threading __all__ = ["Random"] @@ -39,7 +42,7 @@ class Random(object): Gaussian random number returned. """ - def __init__(self, seed=12345, state=None, n_threads=1): + def __init__(self, seed=-1, state=None, n_threads=1): """Initialises Random. Args: @@ -49,7 +52,19 @@ def __init__(self, seed=12345, state=None, n_threads=1): arrays to be filled are large!) """ + # Here we make the seed random if it has not been specified in the input file + if seed == -1: + seed = int(time.time() * 1000) + self.seed = seed + + if threading.current_thread() == threading.main_thread(): + info( + "@ RANDOM SEED: The seed used in this calculation was " + + str(self.seed), + verbosity.low, + ) + self.rng = [ np.random.Generator(np.random.MT19937(s)) for s in np.random.SeedSequence(seed).spawn(n_threads) diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml index 51d87a02e..641e0690a 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml index 5ea1d33ba..ae2402bf4 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS-TRM/pswater/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml index ee9066b2d..153a972cf 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml index c4979cc42..3efa27ed8 100644 --- a/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/BFGS/pswater/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml index 3470a0605..07b7b96d6 100644 --- a/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/CG/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml b/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml index d09ca38d4..895b00640 100644 --- a/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/LBFGS/harmonic/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml b/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml index e14abf876..6cfafbec5 100644 --- a/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml +++ b/ipi_tests/regression_tests/tests/GEOP/LBFGS/pswater/input.xml @@ -4,6 +4,9 @@ x_centroid f_centroid + + 123456 + 10
localhost
diff --git a/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml index 0cecd81da..b4e10c099 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/070K_D/input.xml @@ -2,6 +2,9 @@ [ step, potential{electronvolt}] + + 123456 + 1000
localhost
diff --git a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml index e6f349dcb..84f44a879 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/input.xml @@ -2,6 +2,9 @@ [ step, potential{electronvolt}] + + 123456 + 35
localhost
diff --git a/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml b/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml index 161af8767..0104b02b0 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml +++ b/ipi_tests/regression_tests/tests/INSTANTON/200K/input.xml @@ -2,6 +2,9 @@ [ step, potential{electronvolt}] + + 123456 + 100
localhost
diff --git a/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml b/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml index 001bcabb5..b81e1bc68 100644 --- a/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml +++ b/ipi_tests/regression_tests/tests/NEB/DAMPED_BFGS/zundel/input.xml @@ -12,6 +12,9 @@ forces [step, bead_potentials] + + 123456 + diff --git a/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml b/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml index 4d1e70407..1c251ec57 100644 --- a/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml +++ b/ipi_tests/regression_tests/tests/NEB/FIRE/zundel/input.xml @@ -7,6 +7,9 @@ 600
localhost
+ + 123456 + positions{angstrom} forces diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml index aeb38b9e4..7daf71557 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml @@ -3,6 +3,9 @@ [ step, potential{electronvolt}] x_centroid{angstrom} + + 123456 + 400
localhost
diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml index c88f42945..b3862e598 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe/input.xml @@ -3,6 +3,9 @@ [ step, potential{electronvolt}] x_centroid{angstrom} + + 123456 + 400
localhost
diff --git a/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml b/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml index 37d944682..bdf83bea6 100644 --- a/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml +++ b/ipi_tests/regression_tests/tests/PLUMED/BIAS.NOAUTO/input.xml @@ -6,6 +6,9 @@ extras_bias extras_bias + + 123456 + 100
localhost
diff --git a/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml b/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml index 1f2237eda..567960428 100644 --- a/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml +++ b/ipi_tests/regression_tests/tests/PLUMED/METAD.NOAUTO/input.xml @@ -5,6 +5,9 @@ f_centroid extras_bias + + 123456 + 100
localhost
From ffce0d31b400de13d999819f1f7d9d9434831a6f Mon Sep 17 00:00:00 2001 From: Mariana Rossi Date: Tue, 12 Nov 2024 09:54:27 +0100 Subject: [PATCH 16/47] Making the dummy driver pass a json-formatted string for extras field (#395) * This commit json-formats the meaningless extra argument of the f90 and the py dummy drivers. Makes it possible to test examples such as the ones in examples/temp/pes/pswater/nvt that were not testable before. * linting * Enabling the fhi_aims test with dummy driver now, which should pass * Update excluded_test.txt --------- Co-authored-by: Mariana Rossi Co-authored-by: litman90 --- drivers/f90/driver.f90 | 3 +-- drivers/py/pes/dummy.py | 6 +++++- ipi_tests/examples/excluded_test.txt | 2 -- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/f90/driver.f90 b/drivers/f90/driver.f90 index 7fa0b378b..c1554f0fd 100644 --- a/drivers/f90/driver.f90 +++ b/drivers/f90/driver.f90 @@ -1000,8 +1000,7 @@ PROGRAM DRIVER CALL writebuffer(socket,initbuffer,cbuf) IF (verbose > 1) WRITE(*,*) " !write!=> extra: ", & & initbuffer(1:cbuf) -! ELSEIF (vstyle==5 .or. vstyle==6 .or. vstyle==8 .or. vstyle==99) THEN ! returns the dipole through initbuffer - ELSEIF (vstyle==5 .or. vstyle==6 .or. vstyle==8) THEN ! returns the dipole through initbuffer + ELSEIF (vstyle==5 .or. vstyle==6 .or. vstyle==8 .or. vstyle==99) THEN ! returns the dipole through initbuffer WRITE(initbuffer, '(a,3x,f15.8,a,f15.8,a,f15.8, & & 3x,a)') '{"dipole": [',dip(1),",",dip(2),",",dip(3),"]}" cbuf = LEN_TRIM(initbuffer) diff --git a/drivers/py/pes/dummy.py b/drivers/py/pes/dummy.py index ca756a54e..457c624a3 100644 --- a/drivers/py/pes/dummy.py +++ b/drivers/py/pes/dummy.py @@ -2,6 +2,8 @@ __DRIVER_NAME__ = "dummy" __DRIVER_CLASS__ = "Dummy_driver" +import json + class Dummy_driver(object): """Base class providing the structure of a PES for the python driver.""" @@ -24,5 +26,7 @@ def __call__(self, cell, pos): pot = 0.0 force = pos * 0.0 # makes a zero force with same shape as pos vir = cell * 0.0 # makes a zero virial with same shape as cell - extras = "nada" + extras = json.dumps( + {"dipole": [0.0, 0.0, 0.0]} + ) # have json formatting to potentially work with some test examples. meaningless value return pot, force, vir, extras diff --git a/ipi_tests/examples/excluded_test.txt b/ipi_tests/examples/excluded_test.txt index bb6434db1..49f775043 100644 --- a/ipi_tests/examples/excluded_test.txt +++ b/ipi_tests/examples/excluded_test.txt @@ -8,8 +8,6 @@ temp/ph2/rpmd # long and complicated # Needs infrastructure fixing -clients/fhi_aims/zundel # dummy driver has an issue with extra_type. example works with actual backends. - # Need of external dependency clients/yaff/mil53_ffyaff clients/yaff/mil53_ffsocket From fa574f2617431111342570253beec56d3000d97d Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Tue, 12 Nov 2024 15:56:54 +0000 Subject: [PATCH 17/47] README cleanup --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0737ca4d5..000645b7d 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Source the environment settings file `env.sh` as `source env.sh` or `. env.sh`. It is useful to put this in your `.bashrc` or other settings file if you always want to have i-PI available. -### Compile the driver code +## Compile the driver code The built-in driver requires a FORTRAN compiler, and can be built as @@ -76,7 +76,7 @@ cd ../.. There is also a Python driver available in `drivers/py`, which however has limited functionalities. -### Examples and demos +## Examples and demos The `examples` and `demos` folders contain inputs for many different types of calculations based on i-PI. Examples are typically minimal use-cases of specific @@ -89,7 +89,7 @@ a log file, and then run a couple of instances of the driver code. The progress of the wrapper is followed by monitoring the log file with the `tail` Linux command. Optionally, you can make a copy of the directory with the example somewhere -else if you want to keep the i-PI directory clean. For example +else if you want to keep the i-PI directory clean. For example, after sourcing the `env.sh` file, ```bash cd demos/para-h2-tutorial/tutorial-1/ @@ -101,12 +101,12 @@ tail -f log The monitoring can be interrupted with CTRL+C when the run has finished (5000 steps). -### Tutorials and online resources +## Tutorials and online resources The i-PI [documentation](https://docs.ipi-code.org/onlinereso.html) has a list of avaialble tutorials, recipes and other useful online resources. -### Run the automatic test suite +## Run the automatic test suite The automatic test suite can be run by calling the i-pi-tests script. You need to have the `pytest` package installed From 4ae8223d5b808244a9f1ea2dc1c2ec527ebd3d15 Mon Sep 17 00:00:00 2001 From: litman90 Date: Tue, 12 Nov 2024 16:09:57 +0000 Subject: [PATCH 18/47] Implement fixatoms_dof tag and variables (#394) * Implement fixatoms_dof tag and variables * lint * lint with proper black version * bugifix * bug fix * bugfix * bugfix * update some fixatoms to fixatoms_dof still remaining * more bugfix * bugfix * lint * bugfix * forgot about hesstools, now it is updated * sort and flatten fixatoms_dof * add regtest * upload ref_vib.out missing * imporve help-string fixdof * add examples inside geop * Removing unnecessary debug print statement --------- Co-authored-by: Mariana Rossi --- .../1_dataset_curation/get_pigs_dataset.py | 1 - .../SD_pswater_with_fixatoms/init.xyz | 5 + .../SD_pswater_with_fixatoms/input.xml | 31 +++ .../SD_pswater_with_fixatoms/run.sh | 16 ++ .../SD_pswater_with_fixdofs/init.xyz | 5 + .../SD_pswater_with_fixdofs/input.xml | 31 +++ .../SD_pswater_with_fixdofs/run.sh | 16 ++ ipi/engine/motion/al6xxx_kmc.py | 6 +- ipi/engine/motion/alchemy.py | 4 +- ipi/engine/motion/atomswap.py | 4 +- ipi/engine/motion/dynamics.py | 30 ++- ipi/engine/motion/geop.py | 68 +++--- ipi/engine/motion/instanton.py | 22 +- ipi/engine/motion/motion.py | 14 +- ipi/engine/motion/multi.py | 6 +- ipi/engine/motion/neb.py | 35 ++-- ipi/engine/motion/phonons.py | 35 ++-- ipi/engine/motion/planetary.py | 6 +- ipi/engine/motion/ramp.py | 4 +- ipi/engine/motion/replay.py | 4 +- ipi/engine/motion/scphonons.py | 4 +- ipi/engine/motion/stringmep.py | 136 ++++++------ ipi/engine/motion/vscf.py | 4 +- ipi/engine/properties.py | 11 +- ipi/inputs/motion/motion.py | 62 ++++-- ipi/utils/hesstools.py | 15 +- ipi/utils/instools.py | 16 +- ipi/utils/units.py | 1 - .../fd_phonons/ch4hcbe-with_fixatoms/RESTART | 196 ++++++++++++++++++ .../ch4hcbe-with_fixatoms/files_to_check.txt | 8 + .../fd_phonons/ch4hcbe-with_fixatoms/init.xyz | 8 + .../ch4hcbe-with_fixatoms/input.xml | 31 +++ .../ch4hcbe-with_fixatoms/ref_vib.out | 21 ++ .../ref_vib.phonons.dynmat | 16 ++ .../ref_vib.phonons.eigval | 16 ++ .../ref_vib.phonons.hess | 16 ++ .../ref_vib.phonons_full.hess | 19 ++ .../ch4hcbe-with_fixatoms/ref_vib.xc.xyz | 152 ++++++++++++++ .../ch4hcbe-with_fixatoms/test_settings.dat | 4 + .../fd_phonons/ch4hcbe-with_fixdofs/input.xml | 2 +- tools/py/Instanton_postproc.py | 1 - 41 files changed, 839 insertions(+), 243 deletions(-) create mode 100644 examples/features/geometry_optimization/SD_pswater_with_fixatoms/init.xyz create mode 100644 examples/features/geometry_optimization/SD_pswater_with_fixatoms/input.xml create mode 100644 examples/features/geometry_optimization/SD_pswater_with_fixatoms/run.sh create mode 100644 examples/features/geometry_optimization/SD_pswater_with_fixdofs/init.xyz create mode 100644 examples/features/geometry_optimization/SD_pswater_with_fixdofs/input.xml create mode 100755 examples/features/geometry_optimization/SD_pswater_with_fixdofs/run.sh create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/RESTART create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/files_to_check.txt create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/init.xyz create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/input.xml create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.out create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.dynmat create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.eigval create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.hess create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons_full.hess create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.xc.xyz create mode 100644 ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/test_settings.dat diff --git a/demos/te-pigs/1_dataset_curation/get_pigs_dataset.py b/demos/te-pigs/1_dataset_curation/get_pigs_dataset.py index be39f7274..63d72e23b 100644 --- a/demos/te-pigs/1_dataset_curation/get_pigs_dataset.py +++ b/demos/te-pigs/1_dataset_curation/get_pigs_dataset.py @@ -11,7 +11,6 @@ iread(centroid_force_filename), iread(physical_force_filename), ): - atoms = a_pos.copy() atoms.arrays["centroid_force"] = a_cforce.arrays["f_centroid"] diff --git a/examples/features/geometry_optimization/SD_pswater_with_fixatoms/init.xyz b/examples/features/geometry_optimization/SD_pswater_with_fixatoms/init.xyz new file mode 100644 index 000000000..3b64742f2 --- /dev/null +++ b/examples/features/geometry_optimization/SD_pswater_with_fixatoms/init.xyz @@ -0,0 +1,5 @@ +3 +# CELL(abcABC): 35.23300 35.23300 35.23300 90.00000 90.00000 90.00000 Traj: positions{angstrom} Step: 11 Bead: 0 + O 0.00000e+00 -2.00000e-02 0.00000e+00 + H 7.50000e-01 5.00000e-01 0.00000e+00 + H -7.50000e-01 5.00000e-01 0.00000e+00 diff --git a/examples/features/geometry_optimization/SD_pswater_with_fixatoms/input.xml b/examples/features/geometry_optimization/SD_pswater_with_fixatoms/input.xml new file mode 100644 index 000000000..bfca87a2e --- /dev/null +++ b/examples/features/geometry_optimization/SD_pswater_with_fixatoms/input.xml @@ -0,0 +1,31 @@ + + + [ step, potential ] + positions + + 1000 + + 32342 + + +
h2o-geop
+
+ + + init.xyz + + + + + + [0] + + + 1e-5 + 1e-5 + 1e-5 + + + + +
diff --git a/examples/features/geometry_optimization/SD_pswater_with_fixatoms/run.sh b/examples/features/geometry_optimization/SD_pswater_with_fixatoms/run.sh new file mode 100644 index 000000000..c3c631499 --- /dev/null +++ b/examples/features/geometry_optimization/SD_pswater_with_fixatoms/run.sh @@ -0,0 +1,16 @@ +ipi=i-pi +driver="i-pi-driver -m pswater -u -a h2o-geop" +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} + +${driver} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/examples/features/geometry_optimization/SD_pswater_with_fixdofs/init.xyz b/examples/features/geometry_optimization/SD_pswater_with_fixdofs/init.xyz new file mode 100644 index 000000000..3b64742f2 --- /dev/null +++ b/examples/features/geometry_optimization/SD_pswater_with_fixdofs/init.xyz @@ -0,0 +1,5 @@ +3 +# CELL(abcABC): 35.23300 35.23300 35.23300 90.00000 90.00000 90.00000 Traj: positions{angstrom} Step: 11 Bead: 0 + O 0.00000e+00 -2.00000e-02 0.00000e+00 + H 7.50000e-01 5.00000e-01 0.00000e+00 + H -7.50000e-01 5.00000e-01 0.00000e+00 diff --git a/examples/features/geometry_optimization/SD_pswater_with_fixdofs/input.xml b/examples/features/geometry_optimization/SD_pswater_with_fixdofs/input.xml new file mode 100644 index 000000000..72665cc3d --- /dev/null +++ b/examples/features/geometry_optimization/SD_pswater_with_fixdofs/input.xml @@ -0,0 +1,31 @@ + + + [ step, potential ] + positions + + 1000 + + 32342 + + +
h2o-geop
+
+ + + init.xyz + + + + + + [0,1,2] + + + 1e-5 + 1e-5 + 1e-5 + + + + +
diff --git a/examples/features/geometry_optimization/SD_pswater_with_fixdofs/run.sh b/examples/features/geometry_optimization/SD_pswater_with_fixdofs/run.sh new file mode 100755 index 000000000..c3c631499 --- /dev/null +++ b/examples/features/geometry_optimization/SD_pswater_with_fixdofs/run.sh @@ -0,0 +1,16 @@ +ipi=i-pi +driver="i-pi-driver -m pswater -u -a h2o-geop" +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} + +${driver} > /dev/null & +echo "# Driver is running" + +wait + +echo "# Simulation complete" diff --git a/ipi/engine/motion/al6xxx_kmc.py b/ipi/engine/motion/al6xxx_kmc.py index 34f73dbf2..e4908d420 100755 --- a/ipi/engine/motion/al6xxx_kmc.py +++ b/ipi/engine/motion/al6xxx_kmc.py @@ -68,7 +68,7 @@ def __init__( thermostat=None, barostat=None, fixcom=False, - fixatoms=None, + fixatoms_dof=None, nmts=None, max_cache_len=1000, ): @@ -165,7 +165,7 @@ def __init__( # the KMC step is variable and so it cannot be stored as proper timing self._dt = depend_value(name="dt", value=0.0) - self.fixatoms = np.asarray([]) + self.fixatoms_dof = np.asarray([]) self.fixcom = True self.optimizer = [None] * self.neval # geop should not trigger exit if there is early convergence, but just carry on. @@ -174,7 +174,7 @@ def __init__( for i in range(self.neval): # geometry optimizer should not have *any* hystory dependence self.optimizer[i] = GeopMotion( - fixcom=fixcom, fixatoms=fixatoms, **optimizer + fixcom=fixcom, fixatoms_dof=fixatoms_dof, **optimizer ) # mode="cg", ls_options={"tolerance": 1, "iter": 20, "step": 1e-3, "adaptive": 0.0}, tolerances={"energy": 1e-7, "force": 1e-2, "position": 1e-4}, ) #!TODO: set the geop parameters properly # dictionary of previous energy evaluations - kind of tricky to use this with the omaker thingie diff --git a/ipi/engine/motion/alchemy.py b/ipi/engine/motion/alchemy.py index ee4448409..cc5f4bb2a 100644 --- a/ipi/engine/motion/alchemy.py +++ b/ipi/engine/motion/alchemy.py @@ -30,7 +30,7 @@ class AlchemyMC(Motion): """ def __init__( - self, fixcom=False, fixatoms=None, mode=None, names=[], nxc=1, ealc=None + self, fixcom=False, fixatoms_dof=None, mode=None, names=[], nxc=1, ealc=None ): """Initialises a "alchemical exchange" motion object. @@ -40,7 +40,7 @@ def __init__( """ - super(AlchemyMC, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(AlchemyMC, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) self.names = names self.nxc = nxc diff --git a/ipi/engine/motion/atomswap.py b/ipi/engine/motion/atomswap.py index 99f62ab82..98570e4cf 100644 --- a/ipi/engine/motion/atomswap.py +++ b/ipi/engine/motion/atomswap.py @@ -25,7 +25,7 @@ class AtomSwap(Motion): """ def __init__( - self, fixcom=False, fixatoms=None, mode=None, names=[], nxc=1, ealc=None + self, fixcom=False, fixatoms_dof=None, mode=None, names=[], nxc=1, ealc=None ): """Initialises a "alchemical exchange" motion object. @@ -35,7 +35,7 @@ def __init__( """ - super(AtomSwap, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(AtomSwap, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) self.names = names self.nxc = nxc diff --git a/ipi/engine/motion/dynamics.py b/ipi/engine/motion/dynamics.py index 9e3f1f8c2..e0ffd2a19 100644 --- a/ipi/engine/motion/dynamics.py +++ b/ipi/engine/motion/dynamics.py @@ -53,7 +53,7 @@ def __init__( thermostat=None, barostat=None, fixcom=False, - fixatoms=None, + fixatoms_dof=None, nmts=None, efield=None, bec=None, @@ -66,7 +66,7 @@ def __init__( motion will be constrained or not. Defaults to False. """ - super(Dynamics, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(Dynamics, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # initialize time step. this is the main time step that covers a full time step self._dt = depend_value(name="dt", value=timestep) @@ -76,7 +76,7 @@ def __init__( else: if ( thermostat.__class__.__name__ is ("ThermoPILE_G" or "ThermoNMGLEG ") - ) and (len(fixatoms) > 0): + ) and (len(fixatoms_dof) > 0): softexit.trigger( status="bad", message="!! Sorry, fixed atoms and global thermostat on the centroid not supported. Use a local thermostat. !!", @@ -115,21 +115,17 @@ def __init__( # constraints self.fixcom = fixcom - if fixatoms is None: - self.fixatoms = np.zeros(0, int) - self.fixatoms3 = np.zeros(0, int) + if fixatoms_dof is None: + self.fixatoms_dof = np.zeros(0, int) else: - self.fixatoms = fixatoms - self.fixatoms3 = np.array( - [[3 * i, 3 * i + 1, 3 * i + 2] for i in self.fixatoms] - ).flatten() + self.fixatoms_dof = fixatoms_dof def get_fixdof(self): """Calculate the number of fixed degrees of freedom, required for temperature and pressure calculations. """ - fixdof = len(self.fixatoms) * 3 * self.beads.nbeads + fixdof = len(self.fixatoms_dof) * self.beads.nbeads if self.fixcom: fixdof += 3 return fixdof @@ -279,8 +275,7 @@ def bind(self, motion): self.thermostat = motion.thermostat self.barostat = motion.barostat self.fixcom = motion.fixcom - self.fixatoms = motion.fixatoms - self.fixatoms3 = motion.fixatoms3 + self.fixatoms_dof = motion.fixatoms_dof self.enstype = motion.enstype # no need to dpipe these are really just references @@ -368,13 +363,14 @@ def pconstraints(self): self.ensemble.eens += np.sum(vcom**2) * 0.5 * Mnb # COM kinetic energy - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: m3 = dstrip(beads.m3) p = dstrip(beads.p) - fixatoms3 = self.fixatoms3 - self.ensemble.eens += 0.5 * np.sum(p[:, fixatoms3] ** 2 / m3[:, fixatoms3]) - beads.p[:, fixatoms3] = 0.0 + self.ensemble.eens += 0.5 * np.sum( + p[:, self.fixatoms_dof] ** 2 / m3[:, self.fixatoms_dof] + ) + beads.p[:, self.fixatoms_dof] = 0.0 dproperties( diff --git a/ipi/engine/motion/geop.py b/ipi/engine/motion/geop.py index 9847b868e..ca924c8fb 100755 --- a/ipi/engine/motion/geop.py +++ b/ipi/engine/motion/geop.py @@ -53,7 +53,7 @@ class GeopMotion(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="lbfgs", exit_on_convergence=True, biggest_step=100.0, @@ -81,7 +81,7 @@ def __init__( # raise ValueError("The optimization algorithm with fixatoms is not implemented. " # "We stop here. Comment this line and continue only if you know what you are doing") - super(GeopMotion, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(GeopMotion, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # Optimization Options @@ -158,7 +158,7 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): # Binds optimizer self.optimizer.bind(self) - if len(self.fixatoms) == len(self.beads[0]): + if len(self.fixatoms_dof) == 3 * len(self.beads[0]): softexit.trigger( status="bad", message="WARNING: all atoms are fixed, geometry won't change. Exiting simulation", @@ -202,10 +202,8 @@ def bind(self, dumop): self.fixatoms_mask = np.ones( 3 * dumop.beads.natoms, dtype=bool ) # Mask to exclude fixed atoms from 3N-arrays - if len(dumop.fixatoms) > 0: - self.fixatoms_mask[3 * dumop.fixatoms] = 0 - self.fixatoms_mask[3 * dumop.fixatoms + 1] = 0 - self.fixatoms_mask[3 * dumop.fixatoms + 2] = 0 + if len(dumop.fixatoms_dof) > 0: + self.fixatoms_mask[dumop.fixatoms_dof] = 0 def set_dir(self, x0, mdir): self.x0 = x0.copy() @@ -256,10 +254,8 @@ def bind(self, dumop): self.fixatoms_mask = np.ones( 3 * dumop.beads.natoms, dtype=bool ) # Mask to exclude fixed atoms from 3N-arrays - if len(dumop.fixatoms) > 0: - self.fixatoms_mask[3 * dumop.fixatoms] = 0 - self.fixatoms_mask[3 * dumop.fixatoms + 1] = 0 - self.fixatoms_mask[3 * dumop.fixatoms + 2] = 0 + if len(dumop.fixatoms_dof) > 0: + self.fixatoms_mask[dumop.fixatoms_dof] = 0 def __call__(self, x): """computes energy and gradient for optimization step""" @@ -298,7 +294,7 @@ def bind(self, geop): self.cell = geop.cell self.forces = geop.forces self.fixcom = geop.fixcom - self.fixatoms = geop.fixatoms + self.fixatoms_dof = geop.fixatoms_dof self.mode = geop.mode self.tolerances = geop.tolerances @@ -360,12 +356,10 @@ def exitstep(self, fx, u0, x): info(" @GEOP: Updating bead positions", verbosity.debug) self.qtime += time.time() - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: ftmp = self.forces.f.copy() for dqb in ftmp: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 fmax = np.amax(np.absolute(ftmp)) else: fmax = np.amax(np.absolute(self.forces.f)) @@ -440,21 +434,17 @@ def step(self, step=None): np.dot(self.forces.f.flatten(), self.forces.f.flatten()) ) - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in self.d: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 self.old_x[:] = self.beads.q self.old_u[:] = self.forces.pot self.old_f[:] = self.forces.f - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in self.old_f: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 fdf0 = (self.old_u, -self.old_f[:, self.gm.fixatoms_mask]) @@ -551,11 +541,9 @@ def step(self, step=None): self.old_u[:] = self.forces.pot self.old_f[:] = self.forces.f - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in self.old_f: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 # Reduce dimensionality masked_old_x = self.old_x[:, self.gm.fixatoms_mask] @@ -659,11 +647,9 @@ def step(self, step=None): self.old_u[:] = self.forces.pot self.old_f[:] = self.forces.f - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in self.old_f: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 # Reduce the dimensionality masked_old_x = self.old_x[:, self.gm.fixatoms_mask] @@ -768,11 +754,9 @@ def step(self, step=None): self.old_u[:] = self.forces.pot self.old_f[:] = self.forces.f - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in self.old_f: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 fdf0 = (self.old_u, -self.old_f[:, self.gm.fixatoms_mask]) @@ -849,11 +833,9 @@ def step(self, step=None): self.old_f[:] = self.forces.f # Check for fixatoms - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in self.old_f: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 dq1 = dstrip(self.old_f) @@ -956,11 +938,9 @@ def step(self, step=None): self.d[:] = dq1 self.old_f[:] = gradf1 - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: for dqb in dq1_unit: - dqb[self.fixatoms * 3] = 0.0 - dqb[self.fixatoms * 3 + 1] = 0.0 - dqb[self.fixatoms * 3 + 2] = 0.0 + dqb[self.fixatoms_dof] = 0.0 self.lm.set_dir(dstrip(self.beads.q), dq1_unit) diff --git a/ipi/engine/motion/instanton.py b/ipi/engine/motion/instanton.py index d7eb2e935..bffb6edd2 100644 --- a/ipi/engine/motion/instanton.py +++ b/ipi/engine/motion/instanton.py @@ -83,7 +83,7 @@ class InstantonMotion(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="None", tolerances={"energy": 1e-5, "force": 1e-4, "position": 1e-3}, biggest_step=0.3, @@ -118,7 +118,7 @@ def __init__( ): """Initialises InstantonMotion.""" - super(InstantonMotion, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(InstantonMotion, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) self.options = {} # Optimization options @@ -862,7 +862,7 @@ def spring_hessian(natoms, nbeads, m3, omega2, mode="half", coef=None): class Mapper(object): """Creation of the multi-dimensional function that is the proxy between all the energy and force components and the optimization algorithm. - It also handles fixatoms""" + It also handles fixatoms_dof""" def __init__(self): """Initializes object for Mapper. @@ -894,7 +894,7 @@ def bind(self, dumop): self.nm = dumop.nm self.rp_factor = dumop.rp_factor - self.fixatoms = dumop.fixatoms + self.fixatoms_dof = dumop.fixatoms_dof self.fix = dumop.fix self.fixbeads = self.fix.fixbeads @@ -969,9 +969,9 @@ def bind(self, geop): self.cell = geop.cell self.forces = geop.forces self.fixcom = geop.fixcom - self.fixatoms = geop.fixatoms + self.fixatoms_dof = geop.fixatoms_dof - self.fix = Fix(self.fixatoms, self.beads, self.beads.nbeads) + self.fix = Fix(self.fixatoms_dof, self.beads, self.beads.nbeads) self.nm = geop.nm self.rp_factor = geop.rp_factor @@ -1055,7 +1055,7 @@ def initial_geo(self): verbosity.low, ) - fix_onebead = Fix(self.fixatoms, self.beads, 1) + fix_onebead = Fix(self.fixatoms_dof, self.beads, 1) active_hessian = fix_onebead.get_active_vector( self.optarrays["initial_hessian"], 2 ) @@ -1140,7 +1140,7 @@ def exitstep(self, d_x_max, step): x0=self.beads.q.copy(), natoms=self.beads.natoms, nbeads=self.beads.nbeads, - fixatoms=self.fixatoms, + fixatoms_dof=self.fixatoms_dof, friction=self.options["frictionSD"], ) @@ -1272,7 +1272,7 @@ def bind(self, geop): self.options["hessian_update"] = geop.options["hessian_update"] self.options["hessian_asr"] = geop.options["hessian_asr"] - if len(self.fixatoms) > 0: + if len(self.fixatoms_dof) > 0: info(" 'fixatoms' is enabled. Setting asr to None", verbosity.low) self.options["hessian_asr"] = "none" # self.output_maker = geop.output_maker @@ -1380,7 +1380,7 @@ def initialize(self, step): x0=self.beads.q.copy(), natoms=self.beads.natoms, nbeads=self.beads.nbeads, - fixatoms=self.fixatoms, + fixatoms_dof=self.fixatoms_dof, friction=self.options["frictionSD"], ) if self.options["friction"] and self.options["frictionSD"]: @@ -1422,7 +1422,7 @@ def update_hessian(self, update, active_hessian, new_x, d_x, d_g): x0=new_x, natoms=self.beads.natoms, nbeads=self.beads.nbeads, - fixatoms=self.fixatoms, + fixatoms_dof=self.fixatoms_dof, friction=self.options["frictionSD"], ) diff --git a/ipi/engine/motion/motion.py b/ipi/engine/motion/motion.py index abc484892..a1cb6e483 100644 --- a/ipi/engine/motion/motion.py +++ b/ipi/engine/motion/motion.py @@ -23,29 +23,29 @@ class Motion: each bead. fixcom: A boolean which decides whether the centre of mass motion will be constrained or not. - fixatoms: A list of atoms that should be held fixed to their + fixatoms_dof: A list of degrees of freedom that should be held fixed to their initial positions. Depend objects: none """ - def __init__(self, fixcom=False, fixatoms=None): + def __init__(self, fixcom=False, fixatoms_dof=None): """Initialises Motion object. Args: fixcom: An optional boolean which decides whether the centre of mass motion will be constrained or not. Defaults to False. - fixatoms: A list of atoms that should be held fixed to their - initial positions. + fixatoms_dof: A list of degrees of freedom that should be held fixed to their + initial positions. """ self._dt = depend_value(name="dt", value=0.0) self.fixcom = fixcom - if fixatoms is None: - self.fixatoms = np.zeros(0, int) + if fixatoms_dof is None: + self.fixatoms_dof = np.zeros(0, int) else: - self.fixatoms = fixatoms + self.fixatoms_dof = fixatoms_dof self.beads = self.cell = self.forces = self.prng = self.nm = self.enstype = None diff --git a/ipi/engine/motion/multi.py b/ipi/engine/motion/multi.py index 3e078e35d..3debd22d7 100644 --- a/ipi/engine/motion/multi.py +++ b/ipi/engine/motion/multi.py @@ -28,10 +28,10 @@ def __init__(self, motionlist=None): self.dt ) # DON'T ASK WHY BUT IF YOU DON'T DO THAT WEAKREFS TO SELF.DT WILL BE INVALIDATED - self.fixatoms = set(self.mlist[0].fixatoms) + self.fixatoms_dof = set(self.mlist[0].fixatoms_dof) for m in self.mlist: - self.fixatoms = self.fixatoms.intersection(m.fixatoms) - self.fixatoms = list(self.fixatoms) + self.fixatoms_dof = self.fixatoms_dof.intersection(m.fixatoms_dof) + self.fixatoms_dof = list(self.fixatoms_dof) self.fixcom = True # fixcom is true only if all movers are fixed for m in self.mlist: diff --git a/ipi/engine/motion/neb.py b/ipi/engine/motion/neb.py index 4b1c5068e..e72f17953 100644 --- a/ipi/engine/motion/neb.py +++ b/ipi/engine/motion/neb.py @@ -54,14 +54,11 @@ def bind(self, ens): self.dbeads = ens.beads.clone() self.dcell = ens.cell.clone() self.dforces = ens.forces.clone(self.dbeads, self.dcell) - self.fixatoms = ens.fixatoms.copy() + self.fixatoms_dof = ens.fixatoms_dof.copy() # Mask to exclude fixed atoms from 3N-arrays self.fixatoms_mask = np.ones(3 * ens.beads.natoms, dtype=bool) - if len(ens.fixatoms) > 0: - self.fixatoms_mask[3 * ens.fixatoms] = 0 - self.fixatoms_mask[3 * ens.fixatoms + 1] = 0 - self.fixatoms_mask[3 * ens.fixatoms + 2] = 0 + self.fixatoms_mask[ens.fixatoms_dof] = 0 # Create reduced bead and force object self.rbeads = Beads(ens.beads.natoms, ens.beads.nbeads - 2) @@ -111,12 +108,12 @@ def __call__(self, x): nimg = self.dbeads.nbeads # Number of atoms - nat = self.dbeads.natoms - len(self.fixatoms) + nactive_dof = 3 * self.dbeads.natoms - len(self.fixatoms_dof) # Array for spring constants kappa = np.zeros(nimg) - btau = np.zeros((nimg, 3 * nat), float) + btau = np.zeros((nimg, nactive_dof), float) for ii in range(1, nimg - 1): d1 = bq[ii] - bq[ii - 1] # tau minus d2 = bq[ii + 1] - bq[ii] # tau plus @@ -238,20 +235,18 @@ def bind(self, ens): """Creates reduced Beads object in order to calculate forces only for the climbing bead, and binds it to beads """ - self.fixatoms = ens.fixatoms.copy() + self.fixatoms_dof = ens.fixatoms_dof.copy() # A mask to exclude fixed atoms from 3N-arrays self.fixatoms_mask = np.ones(3 * ens.beads.natoms, dtype=bool) - if len(ens.fixatoms) > 0: - self.fixatoms_mask[3 * ens.fixatoms] = 0 - self.fixatoms_mask[3 * ens.fixatoms + 1] = 0 - self.fixatoms_mask[3 * ens.fixatoms + 2] = 0 + if len(ens.fixatoms_dof) > 0: + self.fixatoms_mask[self.fixatoms_dof] = 0 # Reduced Beads object is needed to calculate only required beads. self.rbeads = Beads(ens.beads.natoms, 1) self.rcell = ens.cell.clone() # Coords of the bead before and after the climbing one. - self.q_prev = np.zeros(3 * (ens.beads.natoms - len(ens.fixatoms))) - self.q_next = np.zeros(3 * (ens.beads.natoms - len(ens.fixatoms))) + self.q_prev = np.zeros(3 * ens.beads.natoms - len(ens.fixatoms_dof)) + self.q_next = np.zeros(3 * ens.beads.natoms - len(ens.fixatoms_dof)) # Make reduced forces dependent on reduced beads self.rforces = ens.forces.clone(self.rbeads, self.rcell) @@ -336,7 +331,7 @@ class NEBMover(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="damped_bfgs", biggest_step=0.5, old_coord=np.zeros(0, float), @@ -371,7 +366,7 @@ def __init__( motion will be constrained or not. Defaults to False. """ - super(NEBMover, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(NEBMover, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # Optimization options self.tolerances = tolerances @@ -420,7 +415,7 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): # and reduce it if needed, because someone may want to provide # existing hessian of the full system. if self.mode == "damped_bfgs": - n_activedim = beads.q[0].size - len(self.fixatoms) * 3 + n_activedim = beads.q[0].size - len(self.fixatoms_dof) if self.stage == "neb": if self.hessian.size == (n_activedim * (beads.nbeads - 2)) ** 2: # Desired dimension @@ -486,7 +481,7 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): else: raise ValueError("Hessian size does not match system size.") - if len(self.fixatoms) == len(self.beads[0]): + if len(self.fixatoms_dof) == 3 * len(self.beads[0]): softexit.trigger( status="bad", message="WARNING: all atoms are fixed, geometry won't change. Exiting simulation.", @@ -518,7 +513,7 @@ def init_climb(self): % (str(self.climbgm.q_prev.shape), str(self.climbgm.q_next.shape)), verbosity.debug, ) - n_activedim = self.beads.q[0].size - len(self.fixatoms) * 3 + n_activedim = self.beads.q[0].size - len(self.fixatoms_dof) if self.hessian.shape != (n_activedim, n_activedim): self.hessian = np.eye(n_activedim) @@ -591,7 +586,7 @@ def step(self, step=None): info(" @NEB STEP %d, stage: %s" % (step, self.stage), verbosity.debug) - n_activedim = self.beads.q[0].size - len(self.fixatoms) * 3 + n_activedim = self.beads.q[0].size - len(self.fixatoms_dof) # Check if we restarted a converged calculation (by mistake) if self.stage == "converged": diff --git a/ipi/engine/motion/phonons.py b/ipi/engine/motion/phonons.py index 5e1cd35e6..25dc5c0d8 100644 --- a/ipi/engine/motion/phonons.py +++ b/ipi/engine/motion/phonons.py @@ -34,7 +34,7 @@ class DynMatrixMover(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="fd", energy_shift=0.0, pos_shift=0.001, @@ -52,7 +52,7 @@ def __init__( refdynmatrix : A 3Nx3N array that stores the refined dynamic matrix. """ - super(DynMatrixMover, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(DynMatrixMover, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # Finite difference option. self.mode = mode @@ -77,13 +77,12 @@ def __init__( if self.prefix == "": self.prefix = "phonons" - if len(fixatoms) > 0: - fixdof = np.concatenate((3 * fixatoms, 3 * fixatoms + 1, 3 * fixatoms + 2)) - self.fixdof = np.sort(fixdof) + if len(fixatoms_dof) > 0: + self.fixatoms_dof = fixatoms_dof if self.mode == "enmfd" or self.mode == "nmfd": raise ValueError("Fixatoms is not implemented for the selected mode.") else: - self.fixdof = np.array([]) + self.fixatoms_dof = np.array([]) def bind(self, ens, beads, nm, cell, bforce, prng, omaker): super(DynMatrixMover, self).bind(ens, beads, nm, cell, bforce, prng, omaker) @@ -109,13 +108,15 @@ def step(self, step=None): else: self.phcalc.transform() self.refdynmatrix = self.apply_asr(self.refdynmatrix.copy()) - self.printall(self.prefix, self.refdynmatrix.copy(), fixdof=self.fixdof) + self.printall( + self.prefix, self.refdynmatrix.copy(), fixatoms_dof=self.fixatoms_dof + ) softexit.trigger( status="success", message="Dynamic matrix is calculated. Exiting simulation", ) - def printall(self, prefix, dmatx, deltaw=0.0, fixdof=np.array([])): + def printall(self, prefix, dmatx, deltaw=0.0, fixatoms_dof=np.array([])): """Prints out diagnostics for a given dynamical matrix.""" dmatx = dmatx + np.eye(len(dmatx)) * deltaw @@ -124,17 +125,19 @@ def printall(self, prefix, dmatx, deltaw=0.0, fixdof=np.array([])): else: wstr = "" - # get active arrays: - activedof = 3 * self.beads.natoms - fixdof.size - if fixdof.size > 0: - mask = np.delete(np.arange(3 * self.beads.natoms), fixdof) + # Get active arrays: + activedof = 3 * self.beads.natoms - fixatoms_dof.size + if fixatoms_dof.size > 0: + active_atoms_mask = np.delete( + np.arange(3 * self.beads.natoms), fixatoms_dof + ) else: - mask = np.arange(3 * self.beads.natoms) + active_atoms_mask = np.arange(3 * self.beads.natoms) dmatx_full = dmatx.copy() ism_full = self.ism.copy() - dmatx = dmatx[mask][:, mask] - ism = self.ism[mask] + dmatx = dmatx[active_atoms_mask][:, active_atoms_mask] + ism = self.ism[active_atoms_mask] # prints out the dynamical matrix outfile = self.output_maker.get_output(self.prefix + ".dynmat", "w") @@ -344,7 +347,7 @@ def bind(self, dm): def step(self, step=None): """Computes one row of the dynamic matrix.""" - if step not in self.dm.fixdof: + if step not in self.dm.fixatoms_dof: # initializes the finite deviation dev = np.zeros(3 * self.dm.beads.natoms, float) dev[step] = self.dm.deltax diff --git a/ipi/engine/motion/planetary.py b/ipi/engine/motion/planetary.py index 58ad1a553..11d36afff 100644 --- a/ipi/engine/motion/planetary.py +++ b/ipi/engine/motion/planetary.py @@ -53,7 +53,7 @@ def __init__( thermostat=None, barostat=None, fixcom=False, - fixatoms=None, + fixatoms_dof=None, nmts=None, ): """Initialises a "dynamics" motion object. @@ -73,7 +73,7 @@ def __init__( # the planetary step just computes constrained-centroid properties so it # should not advance the timer self._dt = depend_value(name="dt", value=0.0) - self.fixatoms = np.asarray([]) + self.fixatoms_dof = np.asarray([]) self.fixcom = True # nvt-cc means contstant-temperature with constrained centroid @@ -85,7 +85,7 @@ def __init__( thermostat=thermostat, nmts=nmts, fixcom=fixcom, - fixatoms=fixatoms, + fixatoms_dof=fixatoms_dof, ) def bind(self, ens, beads, nm, cell, bforce, prng, omaker): diff --git a/ipi/engine/motion/ramp.py b/ipi/engine/motion/ramp.py index 77a82fcf3..df5e21119 100644 --- a/ipi/engine/motion/ramp.py +++ b/ipi/engine/motion/ramp.py @@ -24,7 +24,7 @@ class TemperatureRamp(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, t_start=1.0, t_end=1.0, total_steps=0, @@ -75,7 +75,7 @@ class PressureRamp(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, p_start=1.0, p_end=1.0, total_steps=0, diff --git a/ipi/engine/motion/replay.py b/ipi/engine/motion/replay.py index c2de1cf8c..3f9cee312 100644 --- a/ipi/engine/motion/replay.py +++ b/ipi/engine/motion/replay.py @@ -39,7 +39,7 @@ class Replay(Motion): None really meaningful. """ - def __init__(self, fixcom=False, fixatoms=None, intraj=None): + def __init__(self, fixcom=False, fixatoms_dof=None, intraj=None): """Initialises Replay. Args: @@ -50,7 +50,7 @@ def __init__(self, fixcom=False, fixatoms=None, intraj=None): intraj: The input trajectory file. """ - super(Replay, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(Replay, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) if intraj is None: raise ValueError( "Must provide an initialized InitFile object to read trajectory from" diff --git a/ipi/engine/motion/scphonons.py b/ipi/engine/motion/scphonons.py index 9c6cdad00..95ee83459 100644 --- a/ipi/engine/motion/scphonons.py +++ b/ipi/engine/motion/scphonons.py @@ -45,7 +45,7 @@ class SCPhononsMover(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="sc", dynmat=np.zeros(0, float), prefix="", @@ -72,7 +72,7 @@ def __init__( delta: A 3Nx3N array that stores the dynamic matrix. """ - super(SCPhononsMover, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(SCPhononsMover, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # Finite difference option. self.dynmatrix = dynmat diff --git a/ipi/engine/motion/stringmep.py b/ipi/engine/motion/stringmep.py index 3a1fc9311..66420173f 100644 --- a/ipi/engine/motion/stringmep.py +++ b/ipi/engine/motion/stringmep.py @@ -64,14 +64,12 @@ def bind(self, ens): self.dbeads = ens.beads.clone() self.dcell = ens.cell.clone() self.dforces = ens.forces.clone(self.dbeads, self.dcell) - self.fixatoms = ens.fixatoms.copy() + self.fixatoms_dof = ens.fixatoms_dof.copy() # Mask to exclude fixed atoms from 3N-arrays - self.fixmask = np.ones(3 * ens.beads.natoms, dtype=bool) - if len(ens.fixatoms) > 0: - self.fixmask[3 * ens.fixatoms] = 0 - self.fixmask[3 * ens.fixatoms + 1] = 0 - self.fixmask[3 * ens.fixatoms + 2] = 0 + self.fixatoms_mask = np.ones(3 * ens.beads.natoms, dtype=bool) + if len(ens.fixatoms_dof) > 0: + self.fixatoms_mask[self.fixatoms_dof] = 0 # Create reduced bead and force object self.rbeads = Beads(ens.beads.natoms, ens.beads.nbeads - 2) @@ -84,18 +82,20 @@ def __call__(self, x): # Bead positions # Touch positions only if they have changed (to avoid triggering forces) # I need both dbeads and rbeads because of the endpoint tangents. - if (self.rbeads.q[:, self.fixmask] != x).any(): - self.rbeads.q[:, self.fixmask] = x - rbq = self.rbeads.q[:, self.fixmask] + if (self.rbeads.q[:, self.fixatoms_mask] != x).any(): + self.rbeads.q[:, self.fixatoms_mask] = x + rbq = self.rbeads.q[:, self.fixatoms_mask] # We need all beads, but only reduced number is being updated. - self.dbeads.q[1:-1, self.fixmask] = rbq + self.dbeads.q[1:-1, self.fixatoms_mask] = rbq # Forces and energies - rbf = dstrip(self.rforces.f).copy()[:, self.fixmask] + rbf = dstrip(self.rforces.f).copy()[:, self.fixatoms_mask] be = dstrip(self.rforces.pots).copy() # Calculate the force component perpendicular to the spline. - tangent = spline_derv(self.dbeads.q[:, self.fixmask], self.dbeads.nbeads)[1:-1] + tangent = spline_derv(self.dbeads.q[:, self.fixatoms_mask], self.dbeads.nbeads)[ + 1:-1 + ] rbf_perp = rbf - tangent * np.sum(rbf * tangent, axis=1)[:, np.newaxis] # Return potential energy of the whole string and minus f_perpendicular @@ -133,14 +133,12 @@ def bind(self, ens): self.dbeads = ens.beads.clone() self.dcell = ens.cell.clone() self.dforces = ens.forces.clone(self.dbeads, self.dcell) - self.fixatoms = ens.fixatoms.copy() + self.fixatoms_dof = ens.fixatoms_dof.copy() # Mask to exclude fixed atoms from 3N-arrays - self.fixmask = np.ones(3 * ens.beads.natoms, dtype=bool) - if len(ens.fixatoms) > 0: - self.fixmask[3 * ens.fixatoms] = 0 - self.fixmask[3 * ens.fixatoms + 1] = 0 - self.fixmask[3 * ens.fixatoms + 2] = 0 + self.fixatoms_mask = np.ones(3 * ens.beads.natoms, dtype=bool) + if len(ens.fixatoms_dof) > 0: + self.fixatoms_mask[self.fixatoms_dof] = 0 # Create reduced bead and force object self.rbeads = Beads(ens.beads.natoms, ens.beads.nbeads - 2) @@ -153,14 +151,14 @@ def __call__(self, x): # Bead positions # Touch positions only if they have changed (to avoid triggering forces) # I need both dbeads and rbeads because of the endpoint tangents. - if (self.rbeads.q[:, self.fixmask] != x).any(): - self.rbeads.q[:, self.fixmask] = x - rbq = self.rbeads.q[:, self.fixmask] + if (self.rbeads.q[:, self.fixatoms_mask] != x).any(): + self.rbeads.q[:, self.fixatoms_mask] = x + rbq = self.rbeads.q[:, self.fixatoms_mask] # We need all beads, but only reduced number is being updated. - self.dbeads.q[1:-1, self.fixmask] = rbq + self.dbeads.q[1:-1, self.fixatoms_mask] = rbq # Forces - rbf = dstrip(self.rforces.f).copy()[:, self.fixmask] + rbf = dstrip(self.rforces.f).copy()[:, self.fixatoms_mask] be = dstrip(self.rforces.pots).copy() # Return potential energy of the whole string and full force gradient @@ -189,20 +187,22 @@ def bind(self, ens): """Creates reduced Beads object in order to calculate forces only for the climbing bead, and binds it to beads """ - self.fixatoms = ens.fixatoms.copy() + self.fixatoms_dof = ens.fixatoms_dof.copy() # A mask to exclude fixed atoms from 3N-arrays - self.fixmask = np.ones(3 * ens.beads.natoms, dtype=bool) - if len(ens.fixatoms) > 0: - self.fixmask[3 * ens.fixatoms] = 0 - self.fixmask[3 * ens.fixatoms + 1] = 0 - self.fixmask[3 * ens.fixatoms + 2] = 0 + self.fixatoms_mask = np.ones(3 * ens.beads.natoms, dtype=bool) + if len(ens.fixatoms_dof) > 0: + self.ffixatoms_mask[ens.fixatoms_dof] = 0 # Reduced Beads object is needed to calculate only required beads. self.rbeads = Beads(ens.beads.natoms, 1) self.rcell = ens.cell.clone() # Coords of the bead before and after the climbing one. - self.q_prev = np.zeros(3 * (ens.beads.natoms - len(ens.fixatoms))) - self.q_next = np.zeros(3 * (ens.beads.natoms - len(ens.fixatoms))) + self.q_prev = np.zeros( + 3 * (ens.beads.natoms - len(ens.fixatoms)) + ) # ALBERTO HERE + self.q_next = np.zeros( + 3 * (ens.beads.natoms - len(ens.fixatoms)) + ) # ALBERTO HERE # Make reduced forces dependent on reduced beads self.rforces = ens.forces.clone(self.rbeads, self.rcell) @@ -216,15 +216,15 @@ def __call__(self, x): vrb.debug, ) # Touch positions only if they have changed (to avoid triggering forces) - if (self.rbeads.q[:, self.fixmask] != x).any(): - self.rbeads.q[:, self.fixmask] = x + if (self.rbeads.q[:, self.fixatoms_mask] != x).any(): + self.rbeads.q[:, self.fixatoms_mask] = x # Compared to stringgradientMapper, I need to flatten here, # otherwise it's (1, 3N) instead of just 3N. - rbq = self.rbeads.q[:, self.fixmask].flatten() + rbq = self.rbeads.q[:, self.fixatoms_mask].flatten() # Reduced forces # We don't need copy() because flatten() implies copying. - rbf = dstrip(self.rforces.f)[:, self.fixmask].flatten() + rbf = dstrip(self.rforces.f)[:, self.fixatoms_mask].flatten() # I think here it's better to use plain tangents. # Then we don't need energies of the neighboring beads. @@ -272,7 +272,7 @@ class StringMover(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="damped_bfgs", biggest_step=0.5, old_coord=np.zeros(0, float), @@ -306,7 +306,7 @@ def __init__( motion will be constrained or not. Defaults to False. """ - super(StringMover, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(StringMover, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # Optimization options self.tolerances = tolerances @@ -358,7 +358,7 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): # and reduce it if needed, because someone may want to provide # existing Hessian of the full system. if self.mode in ["damped_bfgs", "bfgstrm"]: - n_activedim = beads.q[0].size - len(self.fixatoms) * 3 + n_activedim = beads.q[0].size - len(self.fixatoms_dof) if self.stage == "string": if self.hessian.size == (n_activedim * (beads.nbeads - 2)) ** 2: # Desired dimension @@ -381,8 +381,8 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): ] )[ np.ix_( - np.tile(self.stringgm.fixmask, self.beads.nbeads - 2), - np.tile(self.stringgm.fixmask, self.beads.nbeads - 2), + np.tile(self.stringgm.fixatoms_mask, self.beads.nbeads - 2), + np.tile(self.stringgm.fixatoms_mask, self.beads.nbeads - 2), ) ] elif self.hessian.size == 0: @@ -412,7 +412,7 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): vrb.high, ) self.hessian = self.hessian[ - np.ix_(self.climbgm.fixmask, self.climbgm.fixmask) + np.ix_(self.climbgm.fixatoms_mask, self.climbgm.fixatoms_mask) ] if self.hessian.size == 0: info( @@ -424,7 +424,7 @@ def bind(self, ens, beads, nm, cell, bforce, prng, omaker): else: raise ValueError("Hessian size does not match system size.") - if len(self.fixatoms) == len(self.beads[0]): + if len(self.fixatoms_dof) == 3 * len(self.beads[0]): softexit.trigger( status="bad", message="WARNING: all atoms are fixed, geometry won't change. Exiting simulation.", @@ -449,8 +449,8 @@ def init_climb(self): status="bad", message="ERROR: climbing bead is the endpoint." ) self.climbgm.rbeads.q[:] = self.beads.q[cl_indx] - self.climbgm.q_prev[:] = self.beads.q[cl_indx - 1, self.climbgm.fixmask] - self.climbgm.q_next[:] = self.beads.q[cl_indx + 1, self.climbgm.fixmask] + self.climbgm.q_prev[:] = self.beads.q[cl_indx - 1, self.climbgm.fixatoms_mask] + self.climbgm.q_next[:] = self.beads.q[cl_indx + 1, self.climbgm.fixatoms_mask] info( "q_prev.shape: %s, q_next.shape: %s" % (str(self.climbgm.q_prev.shape), str(self.climbgm.q_next.shape)), @@ -459,12 +459,12 @@ def init_climb(self): info(" @STRING_CLIMB: call StringClimbGrMapper for the first time.", vrb.debug) self.stringpot, self.stringgrad = self.climbgm( - self.beads.q[cl_indx, self.climbgm.fixmask] + self.beads.q[cl_indx, self.climbgm.fixatoms_mask] ) if self.mode in ["damped_bfgs", "bfgstrm"]: # Initialize BFGS Hessian for a single bead - n_activedim = self.beads.q[0].size - len(self.fixatoms) * 3 + n_activedim = self.beads.q[0].size - len(self.fixatoms_dof) if self.hessian.shape != (n_activedim, n_activedim): self.hessian = np.eye(n_activedim) elif self.mode == "fire": @@ -475,7 +475,7 @@ def init_climb(self): self.N_up = 0 self.dt_fire = 0.1 - self.old_x = dstrip(self.beads.q[cl_indx, self.climbgm.fixmask]).copy() + self.old_x = dstrip(self.beads.q[cl_indx, self.climbgm.fixatoms_mask]).copy() self.stage = "climb" return cl_indx @@ -500,12 +500,12 @@ def path_step_textbook2002(self, step=None): # Shortcuts for prettier expresions nbeads = self.beads.nbeads natoms = self.beads.natoms - fixmask = self.stringgm.fixmask + fixatoms_mask = self.stringgm.fixatoms_mask - n_activedim = self.beads.q[0].size - len(self.fixatoms) * 3 + n_activedim = self.beads.q[0].size - len(self.fixatoms_dof) # Store 'old' resampled positions - self.old_x[:] = self.beads.q[1:-1, fixmask] + self.old_x[:] = self.beads.q[1:-1, fixatoms_mask] # 'Self' stringpot will be updated later on, # therefore we store the copy to check convergence in the end. @@ -599,7 +599,7 @@ def path_step_textbook2002(self, step=None): info(" @EULER: WARNING: hit the big_step.") dq *= self.big_step / np.amax(np.abs(dq)) info(" @EULER: maxdispl is %g" % np.amax(np.abs(dq))) - self.beads.q[1:-1, fixmask] += dq.reshape((nbeads - 2, -1)) + self.beads.q[1:-1, fixatoms_mask] += dq.reshape((nbeads - 2, -1)) # info(" @EULER: calling the mapper.", vrb.debug) self.stringgm.dbeads.q[:] = self.beads.q[:] # self.stringpot, self.stringgrad = self.stringgm(self.beads.q[1:-1, fixmask]) @@ -618,14 +618,16 @@ def path_step_textbook2002(self, step=None): # Resample the beads after an optimizer step. info(" @STRING: resampling beads uniformly.", vrb.debug) - self.beads.q[:, fixmask] = spline_resample( - self.beads.q[:, fixmask], + self.beads.q[:, fixatoms_mask] = spline_resample( + self.beads.q[:, fixatoms_mask], nbeads, ) # Here the forces are called on resampled positions. info(" @STRING: calling forces on resampled positions.", vrb.debug) - self.stringpot, self.stringgrad = self.stringgm(self.beads.q[1:-1, fixmask]) + self.stringpot, self.stringgrad = self.stringgm( + self.beads.q[1:-1, fixatoms_mask] + ) # This transfers forces from the mapper beads to the "main" beads, # so that recalculation won't be triggered after the step. # We need to keep forces up to date to be able to output @@ -645,16 +647,16 @@ def path_step_textbook2002(self, step=None): self.full_v = dstrip(self.forces.pots) # Calculate the force component perpendicular to the spline to check convergence. - tangent = spline_derv(self.beads.q[:, fixmask], nbeads)[1:-1] + tangent = spline_derv(self.beads.q[:, fixatoms_mask], nbeads)[1:-1] f_perp = ( - self.full_f[1:-1, fixmask] + self.full_f[1:-1, fixatoms_mask] - tangent - * np.sum(self.full_f[1:-1, fixmask] * tangent, axis=1)[:, np.newaxis] + * np.sum(self.full_f[1:-1, fixatoms_mask] * tangent, axis=1)[:, np.newaxis] ) # Check convergence at the resampled positions. # dx = current resampled position - previous resampled position. - dx = np.amax(np.abs(self.beads.q[1:-1, fixmask] - self.old_x)) + dx = np.amax(np.abs(self.beads.q[1:-1, fixatoms_mask] - self.old_x)) de = np.amax(np.abs(self.stringpot - old_stringpot)) / (nbeads * natoms) if ( (de <= self.tolerances["energy"]) @@ -720,7 +722,7 @@ def path_step_single_f_call(self, step=None): # natoms = self.beads.natoms # fixmask = self.stringgm.fixmask - # n_activedim = self.beads.q[0].size - len(self.fixatoms) * 3 + # n_activedim = self.beads.q[0].size - len(self.fixatoms_dof) # # Resample beads in the beginning of every step. # info(" @STRING: resampling beads uniformly.", vrb.debug) @@ -1023,17 +1025,17 @@ def climb_step(self, step=None): # Use to determine converged minimization # max displacement dx = np.amax( - np.abs(self.beads.q[self.cl_indx, self.climbgm.fixmask] - self.old_x) + np.abs(self.beads.q[self.cl_indx, self.climbgm.fixatoms_mask] - self.old_x) ) # Store old positions - self.old_x[:] = self.beads.q[self.cl_indx, self.climbgm.fixmask] + self.old_x[:] = self.beads.q[self.cl_indx, self.climbgm.fixatoms_mask] # This transfers forces from the climbing mapper to the "main" beads, # so that recalculation won't be triggered after the step. tmp_f = self.full_f.copy() tmp_v = self.full_v.copy() - tmp_f[self.cl_indx, self.climbgm.fixmask] = self.stringgrad + tmp_f[self.cl_indx, self.climbgm.fixatoms_mask] = self.stringgrad tmp_v[self.cl_indx] = self.stringpot self.forces.transfer_forces_manual( new_q=[ @@ -1119,8 +1121,8 @@ def step(self, step=None): if step == 0: # TODO add a condition when after the endpoints. # Make sure the beads are equidistant before we start info(" @STRING: resampling beads uniformly at step 0.", vrb.debug) - self.beads.q[:, self.stringgm.fixmask] = spline_resample( - self.beads.q[:, self.stringgm.fixmask], + self.beads.q[:, self.stringgm.fixatoms_mask] = spline_resample( + self.beads.q[:, self.stringgm.fixatoms_mask], self.beads.nbeads, ) @@ -1141,14 +1143,16 @@ def step(self, step=None): ) info(" @STRING: calling StringGradientMapper at step 0.", vrb.debug) self.stringpot, self.stringgrad = self.stringgm( - self.beads.q[1:-1, self.stringgm.fixmask] + self.beads.q[1:-1, self.stringgm.fixatoms_mask] ) info( " @STRING: StringGradientMapper returned stringpot and stringgrad.", vrb.debug, ) # Store old bead positions at step 0 - self.old_x = dstrip(self.beads.q[1:-1, self.stringgm.fixmask]).copy() + self.old_x = dstrip( + self.beads.q[1:-1, self.stringgm.fixatoms_mask] + ).copy() self.path_step_textbook2002(step) diff --git a/ipi/engine/motion/vscf.py b/ipi/engine/motion/vscf.py index effe76c27..4d49cd6fd 100644 --- a/ipi/engine/motion/vscf.py +++ b/ipi/engine/motion/vscf.py @@ -51,7 +51,7 @@ class NormalModeMover(Motion): def __init__( self, fixcom=False, - fixatoms=None, + fixatoms_dof=None, mode="imf", dynmat=np.zeros(0, float), prefix="", @@ -85,7 +85,7 @@ def __init__( refdynmatrix : A 3Nx3N array that stores the refined dynamic matrix. """ - super(NormalModeMover, self).__init__(fixcom=fixcom, fixatoms=fixatoms) + super(NormalModeMover, self).__init__(fixcom=fixcom, fixatoms_dof=fixatoms_dof) # Finite difference option. self.mode = mode diff --git a/ipi/engine/properties.py b/ipi/engine/properties.py index a3ab7edc7..6aeaccc07 100644 --- a/ipi/engine/properties.py +++ b/ipi/engine/properties.py @@ -1075,9 +1075,8 @@ def get_temp(self, atom="", bead="", nm=""): """ if self.ensemble.temp > 0 and ( - self.motion.fixcom or len(self.motion.fixatoms) > 0 + self.motion.fixcom or len(self.motion.fixatoms_dof) > 0 ): - dp = np.zeros_like(self.beads.p) # correction tempfactor = np.sqrt(Constants.kb * self.ensemble.temp * self.beads.nbeads) @@ -1090,10 +1089,10 @@ def get_temp(self, atom="", bead="", nm=""): dp += dstrip(self.beads.m3) * vcm - if len(self.motion.fixatoms) > 0: - for i in self.motion.fixatoms: - pi = self.beads.sm3[0, 3 * i] * tempfactor - dp[:, 3 * i : 3 * i + 3] = pi + if len(self.motion.fixatoms_dof) > 0: + for i in self.motion.fixatoms_dof: + pi = self.beads.sm3[0, i] * tempfactor + dp[:, i] = pi # we have to change p in place because the kinetic energy # can depend on nm masses diff --git a/ipi/inputs/motion/motion.py b/ipi/inputs/motion/motion.py index 97bb1bfcb..1bbf81187 100755 --- a/ipi/inputs/motion/motion.py +++ b/ipi/inputs/motion/motion.py @@ -83,6 +83,8 @@ class InputMotionBase(Input): fixcom: An optional boolean which decides whether the centre of mass motion will be constrained or not. fixatoms: A list of the indices of atoms that should not be moved. + fixatoms_dof: A list of indices of degrees of freedom that should be kept fixed. + Note that fixatoms is a 'short' way for to provide the fixatoms_dof, but only the latter is stored internally and written restart files. Example: [0,2,4] means (x-coordinate atom 1, z-coordinate atom 1, y-coordinate atom 2) """ @@ -130,7 +132,15 @@ class InputMotionBase(Input): { "dtype": int, "default": np.zeros(0, int), - "help": "Indices of the atmoms that should be held fixed.", + "help": "Indices of the atoms that should be held fixed.", + }, + ), + "fixatoms_dof": ( + InputArray, + { + "dtype": int, + "default": np.zeros(0, int), + "help": "Indices of the degrees of freedom that should be held fixed.", }, ), "optimizer": ( @@ -305,9 +315,9 @@ def store(self, sc): else: raise ValueError("Cannot store Mover calculator of type " + str(type(sc))) - if (sc.fixcom is True) and (len(sc.fixatoms) > 0): + if (sc.fixcom is True) and (len(sc.fixatoms_dof) > 0): warning( - "The flag fixcom is true by default but you have chosen to fix some atoms explicitly. Because the two cannot be used together, we are overriding the fixcom setting and making it False.", + "The flag fixcom is true by default but you have chosen to fix some atoms (or degree of freedom) explicitly. Because the two cannot be used together, we are overriding the fixcom setting and making it False.", verbosity.low, ) sc.fixcom = False @@ -316,7 +326,7 @@ def store(self, sc): self.file.store(sc.intraj) elif tsc > 0: self.fixcom.store(sc.fixcom) - self.fixatoms.store(sc.fixatoms) + self.fixatoms_dof.store(sc.fixatoms_dof) def fetch(self): """Creates a motion calculator object. @@ -328,16 +338,30 @@ def fetch(self): super(InputMotionBase, self).fetch() + fixatoms = self.fixatoms.fetch() + fixatoms_dof = self.fixatoms_dof.fetch() + if len(fixatoms) > 0: + if len(fixatoms_dof > 0): + softexit.trigger( + status="bad", + message=( + "Please specify either fixatoms or fixatoms_dof in your input file" + ), + ) + else: + fixatoms_dof = fixatoms[:, np.newaxis] * 3 + np.array([0, 1, 2]) + fixatoms_dof = np.sort(fixatoms_dof.flatten()) + if self.mode.fetch() == "replay": sc = Replay( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, intraj=self.file.fetch(), ) elif self.mode.fetch() == "minimize": sc = GeopMotion( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.optimizer.fetch() ) elif self.mode.fetch() == "neb": @@ -347,7 +371,7 @@ def fetch(self): # ) sc = NEBMover( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.neb_optimizer.fetch() ) elif self.mode.fetch() == "string": @@ -361,67 +385,67 @@ def fetch(self): ) sc = StringMover( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.string_optimizer.fetch() ) elif self.mode.fetch() == "driven_dynamics": sc = DrivenDynamics( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.driven_dynamics.fetch() ) elif self.mode.fetch() == "dynamics": sc = Dynamics( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.dynamics.fetch() ) elif self.mode.fetch() == "constrained_dynamics": sc = ConstrainedDynamics( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.constrained_dynamics.fetch() ) elif self.mode.fetch() == "vibrations": sc = DynMatrixMover( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.vibrations.fetch() ) elif self.mode.fetch() == "normalmodes": sc = NormalModeMover( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.normalmodes.fetch() ) elif self.mode.fetch() == "scp": sc = SCPhononsMover( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.scp.fetch() ) elif self.mode.fetch() == "alchemy": sc = AlchemyMC( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.alchemy.fetch() ) elif self.mode.fetch() == "atomswap": sc = AtomSwap( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.atomswap.fetch() ) elif self.mode.fetch() == "instanton": sc = InstantonMotion( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.instanton.fetch() ) elif self.mode.fetch() == "planetary": sc = Planetary( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.planetary.fetch() ) elif self.mode.fetch() == "t_ramp": @@ -431,7 +455,7 @@ def fetch(self): elif self.mode.fetch() == "al-kmc": sc = AlKMC( fixcom=self.fixcom.fetch(), - fixatoms=self.fixatoms.fetch(), + fixatoms_dof=fixatoms_dof, **self.al6xxx_kmc.fetch() ) else: diff --git a/ipi/utils/hesstools.py b/ipi/utils/hesstools.py index 01dde88fe..817e50c1f 100644 --- a/ipi/utils/hesstools.py +++ b/ipi/utils/hesstools.py @@ -176,7 +176,7 @@ def clean_hessian(h, q, natoms, nbeads, m, m3, asr, mofi=False): def get_hessian( - gm, x0, natoms, nbeads=1, fixatoms=[], d=0.001, new_disc=False, friction=False + gm, x0, natoms, nbeads=1, fixatoms_dof=[], d=0.001, new_disc=False, friction=False ): """Compute the physical hessian given a function to evaluate energy and forces (gm). The intermediate steps are written as a temporary files so the full hessian calculations is only ONE step. @@ -185,19 +185,16 @@ def get_hessian( x0 = position vector natoms = number of atoms nbeads = number of beads - fixatoms = indexes of fixed atoms + fixatoms_dof = indexes of fixed degrees of freedom d = displacement - OUT h = physical hessian ( (natoms-len(fixatoms) )*3 , nbeads*( natoms-len(fixatoms) )*3) + OUT h = physical hessian (3*natoms-len(fixatoms_dof) , nbeads*( 3*natoms-len(fixatoms_dof) )) """ info(" @get_hessian: Computing hessian", verbosity.low) - fixdofs = list() - for i in fixatoms: - fixdofs.extend([3 * i, 3 * i + 1, 3 * i + 2]) ii = natoms * 3 - activedof = np.delete(np.arange(ii), fixdofs) - ncalc = ii - len(fixdofs) + activedof = np.delete(np.arange(ii), fixatoms_dof) + ncalc = ii - len(fixatoms_dof) if x0.size != natoms * 3 * nbeads: raise ValueError( "The position vector is not consistent with the number of atoms/beads." @@ -250,7 +247,7 @@ def get_hessian( # Start calculation: for j in range(i0 + 1, ii): - if j in fixdofs: + if j in fixatoms_dof: continue else: ndone = len(activedof[activedof < j]) diff --git a/ipi/utils/instools.py b/ipi/utils/instools.py index 7c90f0298..929350730 100644 --- a/ipi/utils/instools.py +++ b/ipi/utils/instools.py @@ -4,6 +4,7 @@ from ipi.utils.messages import verbosity, info from ipi.utils import units import ipi.utils.mathtools as mt +from ipi.utils.softexit import softexit def banded_hessian(h, sm, masses=True, shift=0.001): @@ -307,14 +308,23 @@ def ms_pathway(pos, m3): class Fix(object): """Class that applies a fixatoms type constrain""" - def __init__(self, fixatoms, beads, nbeads=None): + def __init__(self, fixatoms_dof, beads, nbeads=None): self.natoms = beads.natoms if nbeads is None: self.nbeads = beads.nbeads else: self.nbeads = nbeads - self.fixatoms = fixatoms + self.fixatoms_dof = fixatoms_dof + if len(self.fixatoms_dof) > 0: + if np.mod(len(self.fixatoms_dof), 3) == 0: + self.fixatoms = np.unique(self.fixatoms_dof // 3) + else: + softexit.trigger( + message="fixatoms_dof is not yet implemented. please use fixatoms", + ) + else: + self.fixatoms = self.fixatoms_dof self.mask0 = np.delete(np.arange(self.natoms), self.fixatoms) self.nactive = len(self.mask0) @@ -327,7 +337,7 @@ def __init__(self, fixatoms, beads, nbeads=None): mask2 = np.tile(mask1, self.nbeads) self.mask2 = np.arange(3 * self.natoms * self.nbeads)[mask2] - self.fixbeads = Beads(beads.natoms - len(fixatoms), beads.nbeads) + self.fixbeads = Beads(beads.natoms - len(self.fixatoms), beads.nbeads) self.fixbeads.q[:] = self.get_active_vector(beads.clone().q, 1) self.fixbeads.m[:] = self.get_active_vector(beads.clone().m, 0) self.fixbeads.names[:] = self.get_active_vector(beads.clone().names, 0) diff --git a/ipi/utils/units.py b/ipi/utils/units.py index f6cb3eb9b..9cd4fa3a9 100644 --- a/ipi/utils/units.py +++ b/ipi/utils/units.py @@ -298,7 +298,6 @@ def mass(cls, label): # Conditionally includes "ase" units for each quantity if ase is not None: - # Conversion factors from atomic units to ASE units conversion_factors = { "undefined": {"ase": 1}, diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/RESTART b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/RESTART new file mode 100644 index 000000000..6a7d23d8b --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/RESTART @@ -0,0 +1,196 @@ + + + 123456 + [{"bit_generator": "MT19937", "state": {"key": [2147483648, 3937517930, 2150135538, 3482449142, 3600184337, 2193183394, 3870949520, 466887795, 1694788931, 382247763, 2565505168, 2564250736, 3547816048, 4128831427, 293226672, 881666154, 1369266778, 3204483163, 2325049, 2708179724, 1237571652, 1993078096, 4157003436, 2557478615, 3791609784, 133015286, 1322052982, 1897231026, 2257305484, 400786104, 776975173, 591145179, 1808533771, 2049898229, 3485570715, 1984709931, 1864373927, 3630755699, 2281311056, 3612254441, 217833916, 2802250141, 971383580, 3452932456, 627211621, 1298867632, 4262104640, 1625003068, 111332965, 339610725, 1438371105, 763220250, 266960750, 1777435498, 1158178530, 3496739019, 3329547059, 2531628286, 3158486648, 3760018874, 2702453011, 3212597543, 521210011, 3691282915, 2597305608, 3000553731, 2360713071, 322590301, 1703260930, 1754800259, 2140410046, 3012909618, 44044007, 3177763059, 3811329622, 572222652, 142270333, 2602722041, 2494373479, 2519584970, 1815784445, 3705713595, 74504042, 2979481072, 2069245649, 2339418347, 3465749753, 2516180318, 1557569169, 2660386697, 3260210920, 3289500086, 1639287986, 265421449, 654994688, 1632441514, 2366458826, 2961026214, 393536814, 321613388, 2667801220, 2069500993, 1016063269, 2547594878, 3338352572, 1124158874, 2661534041, 1377252528, 997224311, 3357731065, 2590164776, 257364400, 2546391809, 524728093, 2815922765, 73384504, 2315726464, 2306108399, 2827377772, 4111142828, 1310973796, 760944448, 1286894478, 3014167567, 1618857082, 452347053, 348755011, 1138394173, 4033969078, 657052914, 2099870195, 818855849, 1052460092, 4239752366, 2513349092, 2715202161, 2517309004, 2265227935, 1564212033, 2609431343, 1761665543, 3481566815, 1540668446, 1907769681, 2467834079, 1845465764, 505605688, 1783944243, 3122017169, 1273231480, 204667736, 800283924, 1502441418, 2812327611, 1950260612, 2498315086, 3375570996, 1875323548, 343662449, 4121832009, 3275258367, 2071932836, 2664735118, 3922341549, 1648053180, 826365530, 731040056, 2482427985, 2324727767, 4056758102, 2385993421, 1537403653, 304048664, 579877451, 599383539, 4011583484, 2310654334, 1831570800, 2463013972, 2010245046, 2868822649, 624738215, 3493282269, 3316293901, 3680677413, 2567170840, 3992049099, 1689857310, 91514227, 3500982007, 4207822660, 4026647014, 4251695788, 206382998, 3172621504, 2820829509, 405190305, 2642759070, 1799714415, 1131855569, 592398088, 1537705532, 2577582808, 1260104124, 1043249449, 2049932276, 1500694968, 1636793192, 1970825919, 1425826727, 1215170932, 2805755739, 4027848083, 928707777, 545011734, 2601289643, 3181047773, 3716781202, 1660110921, 3084899960, 1888648597, 1149587934, 3148792740, 3502283047, 2667159614, 80414736, 1818463289, 2854927181, 1304789058, 3147910330, 3931100645, 3092368886, 1718609704, 3935616015, 562625650, 2606866886, 3944793895, 3764144263, 24635965, 2536400329, 2034541955, 3518319086, 3911668413, 403604073, 2631925863, 1810940267, 3733259375, 1873305871, 731169491, 267750894, 4260333781, 580333872, 718436053, 2018303511, 248422468, 2597781808, 1353870197, 4029617140, 926076392, 174221573, 1828406908, 2432014574, 783729820, 1387853087, 296727016, 3961225600, 1570247138, 2774305275, 2646292156, 2968357174, 3499502940, 3924356367, 4276809005, 779927847, 2277562842, 2763601630, 365739083, 1585767711, 2083608923, 3821446497, 4053051347, 1996369893, 3859476912, 4142636364, 1806019234, 83282349, 1329147443, 2282421229, 3436254742, 2180105514, 3330902995, 961421865, 1069563463, 3709841924, 9621560, 304958858, 3323478879, 647833606, 698660702, 3023696030, 349463763, 1021746237, 1333353267, 1405259557, 335639750, 945743877, 1915891368, 3594564135, 4016969705, 3016200540, 225667737, 2207759152, 3596874532, 842631202, 2063678779, 4192298054, 3208068912, 2180292527, 4115742427, 3132489554, 4107889438, 3900175276, 1155433220, 2437299233, 3994689693, 4166219848, 3251286752, 1207473759, 501942700, 1882936736, 560801815, 2961802798, 813395836, 2195239683, 616618506, 2800764951, 3336505624, 778504508, 851543515, 2448870801, 1545109919, 1409886098, 2011863424, 2104479176, 1057224004, 1405338328, 1814641811, 4282698467, 4194893583, 2419053940, 3294902894, 1219204428, 3195826363, 1921607250, 3903868650, 602752650, 850939711, 1894897642, 1727490909, 566896749, 4104916459, 3386314572, 627158683, 1061466595, 1263339338, 3508373958, 3761844595, 3442428872, 571963088, 3346114346, 4114668762, 1244816469, 3040610747, 2212256071, 801441583, 1603583283, 425594905, 804249076, 2279687387, 419610277, 417869039, 2741138745, 4115841496, 1738262652, 2470707331, 2315788755, 3295816872, 4279896189, 1827827317, 3999684221, 1926578943, 1144668061, 4166647837, 7790061, 340135484, 4082906107, 4222441642, 3747165826, 1378564577, 2211584821, 1276149719, 2653153656, 4006939343, 3740530836, 2532448117, 3076283591, 917691864, 1741176175, 3084130707, 800122539, 56774360, 1086979950, 3284214470, 2975517697, 2474376305, 2781733418, 4154041694, 3395421881, 3936528888, 589073531, 4208712540, 4056837845, 3893296804, 4143301970, 647443408, 998524191, 3903368274, 172167908, 2874256214, 1050766970, 3384953736, 495152484, 3203728946, 1926687373, 2685690510, 3172468095, 2449891969, 768737098, 2989230022, 1279459556, 2984496292, 1048056931, 2404184950, 4274900842, 4079651629, 704875608, 1442854794, 3238189285, 3700855633, 885774096, 4172033398, 25116696, 4077335936, 3005332282, 396318389, 2946222652, 2717830585, 2201622177, 1729949798, 1024063406, 1001014445, 3133784850, 1756200039, 778808460, 1695695573, 3288132775, 805251813, 963938579, 3854899266, 2087946216, 1913474663, 3016898421, 3267766401, 2289731937, 845851856, 1729474226, 3016304334, 2522405635, 2295620830, 1869536905, 2875780527, 3031937132, 1607322519, 2845282544, 804354678, 3747213378, 1862864035, 3381728310, 3028594115, 2525730832, 7291285, 3638295164, 643916390, 430831990, 2640822829, 2488782512, 3976173624, 2822830107, 3765600232, 2705990445, 3677900735, 1210428094, 2477288770, 3618808085, 2119565074, 833227697, 550029810, 3580505805, 3820533695, 2133041528, 2379722589, 3904400223, 3714805420, 2987928003, 3047168890, 158876191, 3186663287, 2221982827, 2489879106, 3148559372, 3841739963, 2639182037, 3145100044, 2785718957, 1033113235, 4293037625, 2518607828, 3313805667, 3548411975, 631915249, 729381219, 360804326, 2977857785, 1565765320, 2056070119, 2821424780, 3859527756, 2207224468, 3401683323, 3628829676, 3471054819, 1571444977, 3901177229, 1096833671, 744541863, 3480515503, 247676825, 817279953, 4242007376, 1702429282, 2239447505, 2562563866, 676898079, 3386052424, 1209441004, 673809550, 2695387311, 3847699852, 208831544, 1568348572, 2504129926, 3408479090, 3937253943, 725378907, 1829666185, 2050760871, 458178725, 3065026071, 3590605635, 2500781845, 18656038, 3117202539, 2249887261, 1074468432, 2327692599, 1734855296, 3022263267, 1805629508, 600238108, 740079995, 3630665440, 2639144277, 3571020787, 1094547610, 331652995, 1890430262, 4276601757, 1424869962, 2870008855, 3616734793, 3134789651, 3743255034, 2709972545, 4219331622, 2109085356, 1082000409, 1119065908, 1898109625, 116597913, 333744963, 1132069181, 4153720463, 420793774, 842280851, 1071035089, 1879182681, 947042936, 2052636607, 2212881698, 3545571214, 1941633504, 509989634, 2173760535, 4108200901, 3255686055, 2706919679, 1397236239, 237924533, 1158433526, 343204563, 2560707750, 3475922933, 1579428718, 1162832808], "pos": 623}}] + + + [ step, potential{electronvolt} ] + x_centroid{angstrom} + + 18 + 400 + + + + + + + + + 1.00000000e+00 + -1.00000000e+00 + + [ -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, + -1.00000000e+00, -1.00000000e+00, -1.00000000e+00, -1.00000000e+00 ] + + [ 1.00000000e+00 ] + + + False + [ 15, 16, 17 ] + + 1.00000000e-03 + + [ 1.10121998e-04, 6.20723956e-05, 5.30603870e-05, -2.99891972e-05, -1.63566873e-05, + -1.39820783e-05, 5.44213521e-06, 5.25867636e-06, 4.56361859e-06, -6.27405220e-06, + -6.83805153e-06, -3.58412000e-06, -5.76548661e-06, -4.02963077e-06, -5.77365907e-06, + -2.82939271e-09, -6.25397001e-10, -5.33249133e-10, 6.20723502e-05, 7.02329835e-05, + 3.86844149e-05, -1.63568462e-05, -1.94790438e-05, -1.01932777e-05, -9.43210463e-06, + -5.16714180e-06, -4.32853579e-06, 9.09978467e-06, 5.88997838e-06, 5.77741900e-06, + -5.27609231e-06, -3.71499414e-06, -4.94632228e-06, -6.19354517e-10, 2.31124978e-10, + -1.04232833e-10, 5.30603372e-05, 3.86844118e-05, 5.80461712e-05, -1.39821995e-05, + -1.01932676e-05, -1.62676833e-05, -8.77110985e-06, -4.89472854e-06, -4.10260130e-06, + -5.87773480e-06, -5.82588576e-06, -3.44227422e-06, 9.85515398e-06, 7.22316163e-06, + 5.65397107e-06, -5.25696029e-10, -1.04232833e-10, 2.61337394e-10, -2.99891999e-05, + -1.63568619e-05, -1.39822166e-05, 2.53920002e-05, -1.41248865e-09, -1.22271164e-09, + -1.48500901e-05, 1.18257507e-05, 1.10152511e-05, -2.25429810e-05, 1.57260919e-05, + -1.31771503e-05, -2.02684900e-05, -1.11895889e-05, 1.61487786e-05, -1.62441354e-09, + -5.19007128e-10, -4.42862743e-10, -1.63566746e-05, -1.94790486e-05, -1.01932689e-05, + -1.42034849e-09, 2.53908301e-05, 1.84439934e-09, 1.18255503e-05, -2.67146298e-05, + -1.78477011e-05, 1.57256714e-05, -2.40527202e-05, 1.38239793e-05, -1.11891329e-05, + -1.74020372e-05, 1.42107512e-05, -5.12880568e-10, 9.23360067e-11, -1.22531194e-10, + -1.39820638e-05, -1.01932759e-05, -1.62676885e-05, -1.23171242e-09, 1.84097651e-09, + 2.53907260e-05, 1.10150957e-05, -1.78477541e-05, -2.41785549e-05, -1.31766816e-05, + 1.38238494e-05, -1.91384259e-05, 1.61483423e-05, 1.42109491e-05, -2.80634480e-05, + -4.40237075e-10, -1.23406417e-10, 1.31283422e-10, 5.44213521e-06, -9.43210916e-06, + -8.77111287e-06, -1.48500849e-05, 1.18255407e-05, 1.10150883e-05, 5.26689474e-05, + -4.48744207e-05, -4.17990264e-05, -3.56000898e-06, 6.25249262e-06, 7.40210373e-06, + -3.28879213e-06, 7.23277523e-06, 5.14443264e-06, -2.64358635e-10, -1.45019594e-10, + -1.28402766e-10, 5.25867636e-06, -5.16714029e-06, -4.89473458e-06, 1.18257616e-05, + -2.67146255e-05, -1.78477563e-05, -4.48744478e-05, 9.76895055e-05, 6.77308879e-05, + 3.33303217e-06, -6.09507536e-06, -7.92679973e-06, -4.53919941e-06, 5.79080763e-06, + 6.70062733e-06, -2.08465667e-10, -4.68292440e-11, -7.70416595e-11, 4.56361255e-06, + -4.32853730e-06, -4.10260432e-06, 1.10152585e-05, -1.78476976e-05, -2.41785510e-05, + -4.17990626e-05, 6.77308743e-05, 8.80651865e-05, -4.80713670e-06, 7.44745256e-06, + 5.82898102e-06, 4.01844462e-06, -9.24002466e-06, -6.32793453e-06, -1.87316976e-10, + -7.40204179e-11, -2.56805532e-11, -6.27405522e-06, 9.09978770e-06, -5.87772875e-06, + -2.25429766e-05, 1.57256705e-05, -1.31766847e-05, -3.56000898e-06, 3.33303066e-06, + -4.80714275e-06, 8.18629477e-05, -5.96778607e-05, 5.00047078e-05, 5.78893749e-06, + -7.03943389e-06, 6.16572407e-06, -1.73721389e-10, -3.02124155e-11, -5.28717271e-11, + -6.83804246e-06, 5.88997989e-06, -5.82588727e-06, 1.57260893e-05, -2.40527171e-05, + 1.38238586e-05, 6.25249262e-06, -6.09507385e-06, 7.44744501e-06, -5.96778668e-05, + 8.75895237e-05, -5.24629108e-05, 5.97741764e-06, -4.35522241e-06, 3.12182623e-06, + 3.77655194e-11, 2.56805532e-11, 7.55310387e-12, -3.58411396e-06, 5.77740843e-06, + -3.44227573e-06, -1.31771490e-05, 1.38239702e-05, -1.91384229e-05, 7.40210675e-06, + -7.92680728e-06, 5.82897951e-06, 5.00046912e-05, -5.24628912e-05, 6.89408921e-05, + -8.33550120e-06, 6.89238705e-06, -5.26235321e-06, -9.06372465e-11, -1.96380701e-11, + -1.35955870e-11, -5.76549114e-06, -5.27608777e-06, 9.85516002e-06, -2.02684869e-05, + -1.11891329e-05, 1.61483335e-05, -3.28878608e-06, -4.53920696e-06, 4.01844613e-06, + 5.78894202e-06, 5.97741160e-06, -8.33549818e-06, 7.32316881e-05, 4.24624789e-05, + -6.12816113e-05, -1.72210768e-10, -5.74035894e-11, -2.56805532e-11, -4.02962623e-06, + -3.71500169e-06, 7.22315861e-06, -1.11895863e-05, -1.74020337e-05, 1.42109346e-05, + 7.23277825e-06, 5.79080159e-06, -9.24002164e-06, -7.03943540e-06, -4.35522241e-06, + 6.89238403e-06, 4.24624729e-05, 6.23507169e-05, -5.39312070e-05, -8.91266257e-11, + -1.51062077e-11, -1.35955870e-11, -5.77366058e-06, -4.94632077e-06, 5.65397409e-06, + 1.61487878e-05, 1.42107635e-05, -2.80634458e-05, 5.14442811e-06, 6.70062582e-06, + -6.32793604e-06, 6.16572256e-06, 3.12182321e-06, -5.26236076e-06, -6.12816445e-05, + -5.39312508e-05, 1.02810418e-04, 5.13611063e-11, 1.20849662e-11, 2.56805532e-11, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00 ] + + + [ 1.10121998e-04, 6.20723956e-05, 5.30603870e-05, -2.99891972e-05, -1.63566873e-05, + -1.39820783e-05, 5.44213521e-06, 5.25867636e-06, 4.56361859e-06, -6.27405220e-06, + -6.83805153e-06, -3.58412000e-06, -5.76548661e-06, -4.02963077e-06, -5.77365907e-06, + -2.82939271e-09, -6.25397001e-10, -5.33249133e-10, 6.20723502e-05, 7.02329835e-05, + 3.86844149e-05, -1.63568462e-05, -1.94790438e-05, -1.01932777e-05, -9.43210463e-06, + -5.16714180e-06, -4.32853579e-06, 9.09978467e-06, 5.88997838e-06, 5.77741900e-06, + -5.27609231e-06, -3.71499414e-06, -4.94632228e-06, -6.19354517e-10, 2.31124978e-10, + -1.04232833e-10, 5.30603372e-05, 3.86844118e-05, 5.80461712e-05, -1.39821995e-05, + -1.01932676e-05, -1.62676833e-05, -8.77110985e-06, -4.89472854e-06, -4.10260130e-06, + -5.87773480e-06, -5.82588576e-06, -3.44227422e-06, 9.85515398e-06, 7.22316163e-06, + 5.65397107e-06, -5.25696029e-10, -1.04232833e-10, 2.61337394e-10, -2.99891999e-05, + -1.63568619e-05, -1.39822166e-05, 2.53920002e-05, -1.41248865e-09, -1.22271164e-09, + -1.48500901e-05, 1.18257507e-05, 1.10152511e-05, -2.25429810e-05, 1.57260919e-05, + -1.31771503e-05, -2.02684900e-05, -1.11895889e-05, 1.61487786e-05, -1.62441354e-09, + -5.19007128e-10, -4.42862743e-10, -1.63566746e-05, -1.94790486e-05, -1.01932689e-05, + -1.42034849e-09, 2.53908301e-05, 1.84439934e-09, 1.18255503e-05, -2.67146298e-05, + -1.78477011e-05, 1.57256714e-05, -2.40527202e-05, 1.38239793e-05, -1.11891329e-05, + -1.74020372e-05, 1.42107512e-05, -5.12880568e-10, 9.23360067e-11, -1.22531194e-10, + -1.39820638e-05, -1.01932759e-05, -1.62676885e-05, -1.23171242e-09, 1.84097651e-09, + 2.53907260e-05, 1.10150957e-05, -1.78477541e-05, -2.41785549e-05, -1.31766816e-05, + 1.38238494e-05, -1.91384259e-05, 1.61483423e-05, 1.42109491e-05, -2.80634480e-05, + -4.40237075e-10, -1.23406417e-10, 1.31283422e-10, 5.44213521e-06, -9.43210916e-06, + -8.77111287e-06, -1.48500849e-05, 1.18255407e-05, 1.10150883e-05, 5.26689474e-05, + -4.48744207e-05, -4.17990264e-05, -3.56000898e-06, 6.25249262e-06, 7.40210373e-06, + -3.28879213e-06, 7.23277523e-06, 5.14443264e-06, -2.64358635e-10, -1.45019594e-10, + -1.28402766e-10, 5.25867636e-06, -5.16714029e-06, -4.89473458e-06, 1.18257616e-05, + -2.67146255e-05, -1.78477563e-05, -4.48744478e-05, 9.76895055e-05, 6.77308879e-05, + 3.33303217e-06, -6.09507536e-06, -7.92679973e-06, -4.53919941e-06, 5.79080763e-06, + 6.70062733e-06, -2.08465667e-10, -4.68292440e-11, -7.70416595e-11, 4.56361255e-06, + -4.32853730e-06, -4.10260432e-06, 1.10152585e-05, -1.78476976e-05, -2.41785510e-05, + -4.17990626e-05, 6.77308743e-05, 8.80651865e-05, -4.80713670e-06, 7.44745256e-06, + 5.82898102e-06, 4.01844462e-06, -9.24002466e-06, -6.32793453e-06, -1.87316976e-10, + -7.40204179e-11, -2.56805532e-11, -6.27405522e-06, 9.09978770e-06, -5.87772875e-06, + -2.25429766e-05, 1.57256705e-05, -1.31766847e-05, -3.56000898e-06, 3.33303066e-06, + -4.80714275e-06, 8.18629477e-05, -5.96778607e-05, 5.00047078e-05, 5.78893749e-06, + -7.03943389e-06, 6.16572407e-06, -1.73721389e-10, -3.02124155e-11, -5.28717271e-11, + -6.83804246e-06, 5.88997989e-06, -5.82588727e-06, 1.57260893e-05, -2.40527171e-05, + 1.38238586e-05, 6.25249262e-06, -6.09507385e-06, 7.44744501e-06, -5.96778668e-05, + 8.75895237e-05, -5.24629108e-05, 5.97741764e-06, -4.35522241e-06, 3.12182623e-06, + 3.77655194e-11, 2.56805532e-11, 7.55310387e-12, -3.58411396e-06, 5.77740843e-06, + -3.44227573e-06, -1.31771490e-05, 1.38239702e-05, -1.91384229e-05, 7.40210675e-06, + -7.92680728e-06, 5.82897951e-06, 5.00046912e-05, -5.24628912e-05, 6.89408921e-05, + -8.33550120e-06, 6.89238705e-06, -5.26235321e-06, -9.06372465e-11, -1.96380701e-11, + -1.35955870e-11, -5.76549114e-06, -5.27608777e-06, 9.85516002e-06, -2.02684869e-05, + -1.11891329e-05, 1.61483335e-05, -3.28878608e-06, -4.53920696e-06, 4.01844613e-06, + 5.78894202e-06, 5.97741160e-06, -8.33549818e-06, 7.32316881e-05, 4.24624789e-05, + -6.12816113e-05, -1.72210768e-10, -5.74035894e-11, -2.56805532e-11, -4.02962623e-06, + -3.71500169e-06, 7.22315861e-06, -1.11895863e-05, -1.74020337e-05, 1.42109346e-05, + 7.23277825e-06, 5.79080159e-06, -9.24002164e-06, -7.03943540e-06, -4.35522241e-06, + 6.89238403e-06, 4.24624729e-05, 6.23507169e-05, -5.39312070e-05, -8.91266257e-11, + -1.51062077e-11, -1.35955870e-11, -5.77366058e-06, -4.94632077e-06, 5.65397409e-06, + 1.61487878e-05, 1.42107635e-05, -2.80634458e-05, 5.14442811e-06, 6.70062582e-06, + -6.32793604e-06, 6.16572256e-06, 3.12182321e-06, -5.26236076e-06, -6.12816445e-05, + -5.39312508e-05, 1.02810418e-04, 5.13611063e-11, 1.20849662e-11, 2.56805532e-11, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00 ] + + + + + + [ 3.08195430e+00, 2.57505417e+00, 2.17658652e+00, 1.59676375e+00, 1.49229969e+00, + 1.25102891e+00, 2.44371820e+00, 1.19985513e-01, -2.72464489e-02, 3.82756463e-01, + 2.76593540e+00, 1.83830665e-01, 4.78648724e-01, 5.08340100e-01, 2.67107115e+00, + 1.10153457e+01, 4.11835568e+00, 3.50096326e+00 ] + +

+ [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00 ] +

+ + [ 1.83736223e+03, 2.18941669e+04, 1.83736223e+03, 1.83736223e+03, 1.83736223e+03, + 1.83736223e+03 ] + + + [ H, C, H, H, H, + H ] + +
+ + [ 2.00000000e+02, 1.22464680e-14, 1.22464680e-14, 0.00000000e+00, 2.00000000e+02, + 1.22464680e-14, 0.00000000e+00, 0.00000000e+00, 2.00000000e+02 ] + +
+
diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/files_to_check.txt b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/files_to_check.txt new file mode 100644 index 000000000..d84e4fc2f --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/files_to_check.txt @@ -0,0 +1,8 @@ + filename format +---------------------------------------------------------- +ref_vib.xc.xyz xyz +ref_vib.out numpy +ref_vib.phonons.dynmat numpy all,1e-8,1e-8 +ref_vib.phonons.eigval numpy all,1e-8,1e-8 +ref_vib.phonons_full.hess numpy all,1e-8,1e-8 +ref_vib.phonons.hess numpy all,1e-8,1e-8 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/init.xyz b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/init.xyz new file mode 100644 index 000000000..dbca316e8 --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/init.xyz @@ -0,0 +1,8 @@ +6 +# CELL(abcABC): 130.18034 170.29206 240.21758 90.00000 90.00000 90.00000 cell{atomic_unit} Traj: x_centroid{angstrom} Step: 31 Bead: 0 + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/input.xml new file mode 100644 index 000000000..7daf71557 --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/input.xml @@ -0,0 +1,31 @@ + + + [ step, potential{electronvolt}] + x_centroid{angstrom} + + + 123456 + + 400 + +
localhost
+
+ + + init.xyz + [200.0, 200.0, 200.0 ] + + + + + + + 0.001 + phonons + none + + [5] + False + + +
diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.out b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.out new file mode 100644 index 000000000..4cfacf68d --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.out @@ -0,0 +1,21 @@ +# column 1 --> step : The current simulation time step. +# column 2 --> potential{electronvolt} : The physical system potential energy. + 0.00000000e+00 1.95280225e-04 + 1.00000000e+00 1.95280225e-04 + 2.00000000e+00 1.95280225e-04 + 3.00000000e+00 1.95280225e-04 + 4.00000000e+00 1.95280225e-04 + 5.00000000e+00 1.95280225e-04 + 6.00000000e+00 1.95280225e-04 + 7.00000000e+00 1.95280225e-04 + 8.00000000e+00 1.95280225e-04 + 9.00000000e+00 1.95280225e-04 + 1.00000000e+01 1.95280225e-04 + 1.10000000e+01 1.95280225e-04 + 1.20000000e+01 1.95280225e-04 + 1.30000000e+01 1.95280225e-04 + 1.40000000e+01 1.95280225e-04 + 1.50000000e+01 1.95280225e-04 + 1.60000000e+01 1.95280225e-04 + 1.70000000e+01 1.95280225e-04 + 1.80000000e+01 1.95280225e-04 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.dynmat b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.dynmat new file mode 100644 index 000000000..af973ddb1 --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.dynmat @@ -0,0 +1,16 @@ +# Dynamical matrix (atomic units) +0.0001101219975760934 6.207237290100471e-05 5.3060362091722285e-05 -2.9989198538358056e-05 -1.635668074439156e-05 -1.398207106391325e-05 5.44213521017396e-06 5.25867635962322e-06 4.563615571453957e-06 -6.274053708628827e-06 -6.838046995940226e-06 -3.5841169764577915e-06 -5.765488874076954e-06 -4.02962774458168e-06 -5.773659821844923e-06 +6.207237290100471e-05 7.023298349101703e-05 3.8684413356645466e-05 -1.6356854257314196e-05 -1.947904644361773e-05 -1.0193276800148814e-05 -9.432106893500162e-06 -5.167141049117342e-06 -4.328536543115602e-06 9.099786184681162e-06 5.889979132083694e-06 5.777413714468959e-06 -5.276090040598499e-06 -3.714997915650036e-06 -4.9463215255776125e-06 +5.3060362091722285e-05 3.8684413356645466e-05 5.804617124433905e-05 -1.3982208255089154e-05 -1.0193268704337794e-05 -1.626768590073058e-05 -8.771111359100843e-06 -4.894731560205483e-06 -4.102602812944615e-06 -5.8777317741563825e-06 -5.825886513873404e-06 -3.4422749729275175e-06 9.855156996641971e-06 7.2231608795780515e-06 5.653972582589943e-06 +-2.9989198538358056e-05 -1.6356854257314196e-05 -1.3982208255089154e-05 2.5392000229534728e-05 -1.4164185724508237e-09 -1.2272120281580773e-09 -1.4850087510863192e-05 1.1825756175314149e-05 1.1015254776700651e-05 -2.2542978548165433e-05 1.57260908035912e-05 -1.317714964834266e-05 -2.0268488449715702e-05 -1.1189587564305096e-05 1.6148783161916823e-05 +-1.635668074439156e-05 -1.947904644361773e-05 -1.0193268704337794e-05 -1.4164185724508237e-09 2.5390830128091632e-05 1.8426879226580996e-09 1.1825545465421972e-05 -2.6714627872291677e-05 -1.7847699606772132e-05 1.5725670915446764e-05 -2.405271864531717e-05 1.3823974753514476e-05 -1.1189133104859558e-05 -1.7402035712890755e-05 1.4210757376248656e-05 +-1.398207106391325e-05 -1.0193276800148814e-05 -1.626768590073058e-05 -1.2272120281580773e-09 1.8426879226580996e-09 2.5390726048645822e-05 1.1015091985257475e-05 -1.784775518342075e-05 -2.4178552930002482e-05 -1.3176683154583447e-05 1.3823853972766311e-05 -1.9138424384864035e-05 1.614833789231082e-05 1.421094182945645e-05 -2.8063446877416384e-05 +5.44213521017396e-06 -9.432106893500162e-06 -8.771111359100843e-06 -1.4850087510863192e-05 1.1825545465421972e-05 1.1015091985257475e-05 5.266894740883502e-05 -4.487443425284377e-05 -4.179904450267109e-05 -3.560008979521381e-06 6.2524926183178194e-06 7.402105239944917e-06 -3.2887891044692504e-06 7.232776736116601e-06 5.144430376397122e-06 +5.25867635962322e-06 -5.167141049117342e-06 -4.894731560205483e-06 1.1825756175314149e-05 -2.6714627872291677e-05 -1.784775518342075e-05 -4.487443425284377e-05 9.768950551979373e-05 6.773088112246937e-05 3.333031410395381e-06 -6.0950746039841555e-06 -7.926803504365884e-06 -4.539203184431533e-06 5.790804612322384e-06 6.700626579416211e-06 +4.563615571453957e-06 -4.328536543115602e-06 -4.102602812944615e-06 1.1015254776700651e-05 -1.7847699606772132e-05 -2.4178552930002482e-05 -4.179904450267109e-05 6.773088112246937e-05 8.806518648366636e-05 -4.80713972523081e-06 7.447448788415481e-06 5.828980265219088e-06 4.018445374300222e-06 -9.240023153638786e-06 -6.327935285715509e-06 +-6.274053708628827e-06 9.099786184681162e-06 -5.8777317741563825e-06 -2.2542978548165433e-05 1.5725670915446764e-05 -1.3176683154583447e-05 -3.560008979521381e-06 3.333031410395381e-06 -4.80713972523081e-06 8.186294768664584e-05 -5.967786374179331e-05 5.000469953824066e-05 5.788939750976561e-06 -7.039434649150267e-06 6.165723316354731e-06 +-6.838046995940226e-06 5.889979132083694e-06 -5.825886513873404e-06 1.57260908035912e-05 -2.405271864531717e-05 1.3823853972766311e-05 6.2524926183178194e-06 -6.0950746039841555e-06 7.447448788415481e-06 -5.967786374179331e-05 8.758952372488826e-05 -5.246290100115717e-05 5.977414617808231e-06 -4.3552216590928985e-06 3.1218247221526523e-06 +-3.5841169764577915e-06 5.777413714468959e-06 -3.4422749729275175e-06 -1.317714964834266e-05 1.3823974753514476e-05 -1.9138424384864035e-05 7.402105239944917e-06 -7.926803504365884e-06 5.828980265219088e-06 5.000469953824066e-05 -5.246290100115717e-05 6.89408921392033e-05 -8.335499688910675e-06 6.8923855358111205e-06 -5.262356987139703e-06 +-5.765488874076954e-06 -5.276090040598499e-06 9.855156996641971e-06 -2.0268488449715702e-05 -1.1189133104859558e-05 1.614833789231082e-05 -3.2887891044692504e-06 -4.539203184431533e-06 4.018445374300222e-06 5.788939750976561e-06 5.977414617808231e-06 -8.335499688910675e-06 7.323168808820519e-05 4.246247591306891e-05 -6.128162788237306e-05 +-4.02962774458168e-06 -3.714997915650036e-06 7.2231608795780515e-06 -1.1189587564305096e-05 -1.7402035712890755e-05 1.421094182945645e-05 7.232776736116601e-06 5.790804612322384e-06 -9.240023153638786e-06 -7.039434649150267e-06 -4.3552216590928985e-06 6.8923855358111205e-06 4.246247591306891e-05 6.235071686362824e-05 -5.393122892559988e-05 +-5.773659821844923e-06 -4.9463215255776125e-06 5.653972582589943e-06 1.6148783161916823e-05 1.4210757376248656e-05 -2.8063446877416384e-05 5.144430376397122e-06 6.700626579416211e-06 -6.327935285715509e-06 6.165723316354731e-06 3.1218247221526523e-06 -5.262356987139703e-06 -6.128162788237306e-05 -5.393122892559988e-05 0.00010281041779666677 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.eigval b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.eigval new file mode 100644 index 000000000..819aaee93 --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.eigval @@ -0,0 +1,16 @@ +# Eigenvalues (atomic units) +-2.4763115873088654e-09 +-5.26448939308928e-10 +-7.76963935107596e-11 +-7.171694690119285e-11 +6.718850205792285e-10 +1.689876552396044e-09 +3.976568907066896e-05 +3.9771038868769635e-05 +3.9772351908703205e-05 +4.9955417931153435e-05 +4.996111516618837e-05 +0.00018609221525559008 +0.00020814086696308373 +0.0002081495150672616 +0.00020817711461012942 \ No newline at end of file diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.hess b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.hess new file mode 100644 index 000000000..75120ef4f --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons.hess @@ -0,0 +1,16 @@ +# Hessian matrix (atomic units) +0.20233399955493778 0.11404943378590104 0.09749110546630745 -0.19020698627247867 -0.1037425173544548 -0.08868151629704002 0.009999173711250363 0.009662093347628797 0.008385014904632726 -0.011527709342651347 -0.01256396930937598 -0.006585321177254856 -0.010593291521754367 -0.007403885837753422 -0.010608304512604859 +0.11404943378590104 0.12904343149600098 0.07107728017263781 -0.10374361786302798 -0.12354617329179975 -0.06465102619923613 -0.017330196999676417 -0.009493909824964673 -0.007953089575796211 0.016719603479486974 0.010822025220402766 0.010615201773145344 -0.009694088587419714 -0.0068257968721674445 -0.009088184371730534 +0.09749110546630745 0.07107728017263781 0.10665184291269725 -0.08868238643433557 -0.06465097485142124 -0.10317806609094758 -0.016115708767472373 -0.008993394917666818 -0.0075379674724374 -0.010799522387472392 -0.010704263864180774 -0.006324706036675565 0.018107493282570886 0.013271563015226919 0.01038839569922345 +-0.19020698627247867 -0.10374361786302798 -0.08868238643433557 0.555936691126746 -3.1011304635342185e-05 -2.6868784974709566e-05 -0.09418692492602077 0.07500505355695351 0.0698644350705102 -0.14297921319128548 0.0997429902560576 -0.08357628894506419 -0.12855322223392918 -0.07097014365076147 0.10242392350923167 +-0.1037425173544548 -0.12354617329179975 -0.06465097485142124 -3.1011304635342185e-05 0.5559110727304528 4.034411693609741e-05 0.07500371712598763 -0.16943796782298293 -0.11319932907705164 0.09974032710857726 -0.15255476465414475 0.08767878784121662 -0.0709672612342338 -0.11037269848079845 0.09013196300422521 +-0.08868151629704002 -0.06465102619923613 -0.10317806609094758 -2.6868784974709566e-05 4.034411693609741e-05 0.5559087939976947 0.06986340256309731 -0.11319968157286199 -0.15335287067985703 -0.08357333020070357 0.08767802178732963 -0.12138577226705749 0.10242109937941278 0.0901331329017374 -0.17799287460595892 +0.009999173711250363 -0.017330196999676417 -0.016115708767472373 -0.09418692492602077 0.07500371712598763 0.06986340256309731 0.09677193490986723 -0.08245059079925454 -0.07679998581533454 -0.006541026054129873 0.011488093809575162 0.013600348625075755 -0.006042696898411747 0.013289230826885046 0.009452182092584136 +0.009662093347628797 -0.009493909824964673 -0.008993394917666818 0.07500505355695351 -0.16943796782298293 -0.11319968157286199 -0.08245059079925454 0.17949100816760935 0.12444616309670309 0.006123986040496021 -0.011198859894978598 -0.014564409400730227 -0.008340160506659087 0.010639805703149818 0.012311478225779384 +0.008385014904632726 -0.007953089575796211 -0.0075379674724374 0.0698644350705102 -0.11319932907705164 -0.15335287067985703 -0.07679998581533454 0.12444616309670309 0.16180764783602086 -0.008832456988017157 0.013683661148622406 0.010709948206066855 0.007383339772903952 -0.016977269590157107 -0.011626709317535955 +-0.011527709342651347 0.016719603479486974 -0.010799522387472392 -0.14297921319128548 0.09974032710857726 -0.08357333020070357 -0.006541026054129873 0.006123986040496021 -0.008832456988017157 0.1504118884998462 -0.1096498530861467 0.09187674648858389 0.01063637927734007 -0.012933991377916954 0.01132866717101777 +-0.01256396930937598 0.010822025220402766 -0.010704263864180774 0.0997429902560576 -0.15255476465414475 0.08767802178732963 0.011488093809575162 -0.011198859894978598 0.013683661148622406 -0.1096498530861467 0.16093368304659353 -0.09639335302180639 0.010982675879844807 -0.00800211980012122 0.005735922847804887 +-0.006585321177254856 0.010615201773145344 -0.006324706036675565 -0.08357628894506419 0.08767878784121662 -0.12138577226705749 0.013600348625075755 -0.014564409400730227 0.010709948206066855 0.09187674648858389 -0.09639335302180639 0.12666939164240887 -0.015315332335674723 0.012663808890422956 -0.009668855993627544 +-0.010593291521754367 -0.009694088587419714 0.018107493282570886 -0.12855322223392918 -0.0709672612342338 0.10242109937941278 -0.006042696898411747 -0.008340160506659087 0.007383339772903952 0.01063637927734007 0.010982675879844807 -0.015315332335674723 0.13455313807586577 0.07801894963410662 -0.112596548751398 +-0.007403885837753422 -0.0068257968721674445 0.013271563015226919 -0.07097014365076147 -0.11037269848079845 0.0901331329017374 0.013289230826885046 0.010639805703149818 -0.016977269590157107 -0.012933991377916954 -0.00800211980012122 0.012663808890422956 0.07801894963410662 0.11456085247107949 -0.09909120329831819 +-0.010608304512604859 -0.009088184371730534 0.01038839569922345 0.10242392350923167 0.09013196300422521 -0.17799287460595892 0.009452182092584136 0.012311478225779384 -0.011626709317535955 0.01132866717101777 0.005735922847804887 -0.009668855993627544 -0.112596548751398 -0.09909120329831819 0.18889997899229624 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons_full.hess b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons_full.hess new file mode 100644 index 000000000..943e68151 --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.phonons_full.hess @@ -0,0 +1,19 @@ +# Hessian matrix (atomic units) +0.20233399955493778 0.11404943378590104 0.09749110546630745 -0.19020698627247867 -0.1037425173544548 -0.08868151629704002 0.009999173711250363 0.009662093347628797 0.008385014904632726 -0.011527709342651347 -0.01256396930937598 -0.006585321177254856 -0.010593291521754367 -0.007403885837753422 -0.010608304512604859 -2.599309656403648e-06 -5.745404152435185e-07 -4.898859096158503e-07 +0.11404943378590104 0.12904343149600098 0.07107728017263781 -0.10374361786302798 -0.12354617329179975 -0.06465102619923613 -0.017330196999676417 -0.009493909824964673 -0.007953089575796211 0.016719603479486974 0.010822025220402766 0.010615201773145344 -0.009694088587419714 -0.0068257968721674445 -0.009088184371730534 -5.689893001203928e-07 2.123301534595612e-07 -9.575673587391975e-08 +0.09749110546630745 0.07107728017263781 0.10665184291269725 -0.08868238643433557 -0.06465097485142124 -0.10317806609094758 -0.016115708767472373 -0.008993394917666818 -0.0075379674724374 -0.010799522387472392 -0.010704263864180774 -0.006324706036675565 0.018107493282570886 0.013271563015226919 0.01038839569922345 -4.829470157119431e-07 -9.575673587391975e-08 2.400857290751901e-07 +-0.19020698627247867 -0.10374361786302798 -0.08868238643433557 0.555936691126746 -3.1011304635342185e-05 -2.6868784974709566e-05 -0.09418692492602077 0.07500505355695351 0.0698644350705102 -0.14297921319128548 0.0997429902560576 -0.08357628894506419 -0.12855322223392918 -0.07097014365076147 0.10242392350923167 -5.151434834260727e-06 -1.6459056340067946e-06 -1.4044321261508232e-06 +-0.1037425173544548 -0.12354617329179975 -0.06465097485142124 -3.1011304635342185e-05 0.5559110727304528 4.034411693609741e-05 0.07500371712598763 -0.16943796782298293 -0.11319932907705164 0.09974032710857726 -0.15255476465414475 0.08767878784121662 -0.0709672612342338 -0.11037269848079845 0.09013196300422521 -1.6264767310758545e-06 2.9282132274488504e-07 -3.885780586188048e-07 +-0.08868151629704002 -0.06465102619923613 -0.10317806609094758 -2.6868784974709566e-05 4.034411693609741e-05 0.5559087939976947 0.06986340256309731 -0.11319968157286199 -0.15335287067985703 -0.08357333020070357 0.08767802178732963 -0.12138577226705749 0.10242109937941278 0.0901331329017374 -0.17799287460595892 -1.3961054534661343e-06 -3.9135361618036773e-07 4.1633363423443365e-07 +0.009999173711250363 -0.017330196999676417 -0.016115708767472373 -0.09418692492602077 0.07500371712598763 0.06986340256309731 0.09677193490986723 -0.08245059079925454 -0.07679998581533454 -0.006541026054129873 0.011488093809575162 0.013600348625075755 -0.006042696898411747 0.013289230826885046 0.009452182092584136 -2.42861286636753e-07 -1.3322676295501878e-07 -1.179611963664229e-07 +0.009662093347628797 -0.009493909824964673 -0.008993394917666818 0.07500505355695351 -0.16943796782298293 -0.11319968157286199 -0.08245059079925454 0.17949100816760935 0.12444616309670309 0.006123986040496021 -0.011198859894978598 -0.014564409400730227 -0.008340160506659087 0.010639805703149818 0.012311478225779384 -1.915134717478395e-07 -4.3021142204224816e-08 -7.077671781985373e-08 +0.008385014904632726 -0.007953089575796211 -0.0075379674724374 0.0698644350705102 -0.11319932907705164 -0.15335287067985703 -0.07679998581533454 0.12444616309670309 0.16180764783602086 -0.008832456988017157 0.013683661148622406 0.010709948206066855 0.007383339772903952 -0.016977269590157107 -0.011626709317535955 -1.7208456881689926e-07 -6.800116025829084e-08 -2.359223927328458e-08 +-0.011527709342651347 0.016719603479486974 -0.010799522387472392 -0.14297921319128548 0.09974032710857726 -0.08357333020070357 -0.006541026054129873 0.006123986040496021 -0.008832456988017157 0.1504118884998462 -0.1096498530861467 0.09187674648858389 0.01063637927734007 -0.012933991377916954 0.01132866717101777 -1.5959455978986625e-07 -2.7755575615628917e-08 -4.85722573273506e-08 +-0.01256396930937598 0.010822025220402766 -0.010704263864180774 0.0997429902560576 -0.15255476465414475 0.08767802178732963 0.011488093809575162 -0.011198859894978598 0.013683661148622406 -0.1096498530861467 0.16093368304659353 -0.09639335302180639 0.010982675879844807 -0.00800211980012122 0.005735922847804887 3.469446951953615e-08 2.359223927328458e-08 6.938893903907229e-09 +-0.006585321177254856 0.010615201773145344 -0.006324706036675565 -0.08357628894506419 0.08767878784121662 -0.12138577226705749 0.013600348625075755 -0.014564409400730227 0.010709948206066855 0.09187674648858389 -0.09639335302180639 0.12666939164240887 -0.015315332335674723 0.012663808890422956 -0.009668855993627544 -8.326672684688674e-08 -1.8041124150158794e-08 -1.2490009027033011e-08 +-0.010593291521754367 -0.009694088587419714 0.018107493282570886 -0.12855322223392918 -0.0709672612342338 0.10242109937941278 -0.006042696898411747 -0.008340160506659087 0.007383339772903952 0.01063637927734007 0.010982675879844807 -0.015315332335674723 0.13455313807586577 0.07801894963410662 -0.112596548751398 -1.582067810090848e-07 -5.273559366969494e-08 -2.359223927328458e-08 +-0.007403885837753422 -0.0068257968721674445 0.013271563015226919 -0.07097014365076147 -0.11037269848079845 0.0901331329017374 0.013289230826885046 0.010639805703149818 -0.016977269590157107 -0.012933991377916954 -0.00800211980012122 0.012663808890422956 0.07801894963410662 0.11456085247107949 -0.09909120329831819 -8.049116928532385e-08 -1.3877787807814458e-08 -1.2490009027033011e-08 +-0.010608304512604859 -0.009088184371730534 0.01038839569922345 0.10242392350923167 0.09013196300422521 -0.17799287460595892 0.009452182092584136 0.012311478225779384 -0.011626709317535955 0.01132866717101777 0.005735922847804887 -0.009668855993627544 -0.112596548751398 -0.09909120329831819 0.18889997899229624 4.718447854656916e-08 1.1102230246251565e-08 2.359223927328458e-08 +-2.599309656403648e-06 -5.689893001203928e-07 -4.829470157119431e-07 -5.151434834260727e-06 -1.6264767310758545e-06 -1.3961054534661343e-06 -2.42861286636753e-07 -1.915134717478395e-07 -1.7208456881689926e-07 -1.5959455978986625e-07 3.469446951953615e-08 -8.326672684688674e-08 -1.582067810090848e-07 -8.049116928532385e-08 4.718447854656916e-08 0.0 0.0 0.0 +-5.745404152435185e-07 2.123301534595612e-07 -9.575673587391975e-08 -1.6459056340067946e-06 2.9282132274488504e-07 -3.9135361618036773e-07 -1.3322676295501878e-07 -4.3021142204224816e-08 -6.800116025829084e-08 -2.7755575615628917e-08 2.359223927328458e-08 -1.8041124150158794e-08 -5.273559366969494e-08 -1.3877787807814458e-08 1.1102230246251565e-08 0.0 0.0 0.0 +-4.898859096158503e-07 -9.575673587391975e-08 2.400857290751901e-07 -1.4044321261508232e-06 -3.885780586188048e-07 4.1633363423443365e-07 -1.179611963664229e-07 -7.077671781985373e-08 -2.359223927328458e-08 -4.85722573273506e-08 6.938893903907229e-09 -1.2490009027033011e-08 -2.359223927328458e-08 -1.2490009027033011e-08 2.359223927328458e-08 0.0 0.0 0.0 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.xc.xyz b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.xc.xyz new file mode 100644 index 000000000..ee3b02967 --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/ref_vib.xc.xyz @@ -0,0 +1,152 @@ +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 0 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 1 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 2 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 3 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 4 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 5 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 6 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 7 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 8 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 9 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 10 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 11 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 12 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 13 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 14 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 15 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 16 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 17 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 +6 +# CELL(abcABC): 200.00000 200.00000 200.00000 90.00000 90.00000 90.00000 Step: 18 Bead: 0 x_centroid{angstrom} cell{atomic_unit} + H 1.63090e+00 1.36266e+00 1.15180e+00 + C 8.44971e-01 7.89691e-01 6.62016e-01 + H 1.29316e+00 6.34936e-02 -1.44182e-02 + H 2.02546e-01 1.46367e+00 9.72790e-02 + H 2.53290e-01 2.69002e-01 1.41347e+00 + H 5.82907e+00 2.17934e+00 1.85263e+00 diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/test_settings.dat b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/test_settings.dat new file mode 100644 index 000000000..b2a2c6afc --- /dev/null +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixatoms/test_settings.dat @@ -0,0 +1,4 @@ +driver_model ch4hcbe +address localhost +port 32343 +socket_mode unix diff --git a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml index 7daf71557..29206ac00 100644 --- a/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml +++ b/ipi_tests/regression_tests/tests/PHONONS/fd_phonons/ch4hcbe-with_fixdofs/input.xml @@ -24,7 +24,7 @@ phonons none - [5] + [15,16,17] False diff --git a/tools/py/Instanton_postproc.py b/tools/py/Instanton_postproc.py index 5dd91b384..4445f9c66 100755 --- a/tools/py/Instanton_postproc.py +++ b/tools/py/Instanton_postproc.py @@ -204,7 +204,6 @@ def get_rp_freq(w0, nbeads, temp, mode="rate"): sys.exit() if mode == "rate": - for n in range(w0.size): for k in range(nbeads): if w0[n] == 0 and k == 0: From 76bd7b8aade084b6474f37256ec03c8f1f569d5d Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Tue, 12 Nov 2024 16:28:55 +0000 Subject: [PATCH 19/47] reworded the description of the MOOC --- docs/src/onlinereso.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index b2e996925..9f974ff9f 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -6,9 +6,9 @@ Tutorials, recipes, and on-line resources Massive Open Online Course (MOOC) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The theory behind many types of simulation that i-PI can do and examples -of simulations with i-PI can also be found in an online course freely -available to everyone, and accessible from this +The theory behind classical and path-integral methods for structure +and dynamics along with practical exercises can be found in an online +course freely available to everyone, and accessible from this `link `_. i-PI resources @@ -26,7 +26,8 @@ Examples and demos The `examples` and `demos` folders in the i-PI `source code `_ contain inputs for many different types of calculations based on i-PI. Examples are typically minimal use-cases of specific -features, while demos are more structured, tutorial-like examples that show how +features, examples of client codes, or setups for high performance computing, +while demos are more structured, tutorial-like examples that show how to realize more complex setups, and also provide a brief discussion of the underlying algorithms. From ce210488a4c5b284e672166e5e9a7a0cfab07a40 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Tue, 12 Nov 2024 16:34:36 +0000 Subject: [PATCH 20/47] reworded the barostat description to avoid confusion. --- ipi/inputs/barostats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipi/inputs/barostats.py b/ipi/inputs/barostats.py index f832be7a8..ff8833815 100644 --- a/ipi/inputs/barostats.py +++ b/ipi/inputs/barostats.py @@ -41,7 +41,7 @@ class InputBaro(Input): { "dtype": str, "default": "dummy", - "help": """The type of barostat. 'isotropic' implements the Bussi-Zykova-Parrinello barostat [doi:10.1063/1.3073889] that isotropically scales the volume while sampling the isothermal isobaric ensemble. The implementation details are given in [doi:10.1016/j.cpc.2013.10.027]. 'sc-isotropic' implements the same for Suzuki-Chin path integral molecular dynamics [10.1021/acs.jctc.8b01297]. This barostat is suitable for simulating liquids. 'flexible' implements the path integral version of the Martyna-Tuckerman-Tobias-Klein barostat which incorporates full cell fluctuations while sampling the isothermal isobaric ensemble [doi:10.1063/1.478193]. This is suitable for anisotropic systems such as molecular solids. 'anisotropic' implements the Raiteri-Gale-Bussi barostat which enables cell fluctuations at constant external stress [10.1088/0953-8984/23/33/334213]. It is suitable for simulating solids at given external (non-diagonal) stresses and requires specifying a reference cell for estimating strain. Note that this ensemble is valid only within the elastic limit of small strains. For diagonal stresses (or external pressures) the 'flexible' and the 'anisotropic' modes should give very similar results. 'dummy' barostat does not do anything.""", + "help": """The type of barostat. 'isotropic' implements the Bussi-Zykova-Parrinello barostat [doi:10.1063/1.3073889] that isotropically scales the volume while sampling the isothermal isobaric ensemble. The implementation details are given in [doi:10.1016/j.cpc.2013.10.027]. This barostat is suitable for simulating liquids. 'sc-isotropic' implements the same for Suzuki-Chin path integral molecular dynamics [10.1021/acs.jctc.8b01297] and should only be used with the Suzuki-Chin NPT ensemble. 'flexible' implements the path integral version of the Martyna-Tuckerman-Tobias-Klein barostat which incorporates full cell fluctuations while sampling the isothermal isobaric ensemble [doi:10.1063/1.478193]. This is suitable for anisotropic systems such as molecular solids. 'anisotropic' implements the Raiteri-Gale-Bussi barostat which enables cell fluctuations at constant external stress [10.1088/0953-8984/23/33/334213]. It is suitable for simulating solids at given external (non-diagonal) stresses and requires specifying a reference cell for estimating strain. Note that this ensemble is valid only within the elastic limit of small strains. For diagonal stresses (or external pressures) the 'flexible' and the 'anisotropic' modes should give very similar results. 'dummy' barostat does not do anything.""", "options": [ "dummy", "isotropic", From 139286c82ff6957560fec6e9046a12f76b0560f6 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Tue, 12 Nov 2024 16:48:58 +0000 Subject: [PATCH 21/47] added reference to docs in the README.md of the main i-PI dir and converted some of the READMEs into README.mds. --- README.md | 6 ++++- docs/{README => README.md} | 7 +++--- docs/latex/README | 46 -------------------------------------- docs/latex/README.md | 45 +++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 51 deletions(-) rename docs/{README => README.md} (57%) delete mode 100644 docs/latex/README create mode 100644 docs/latex/README.md diff --git a/README.md b/README.md index 000645b7d..d201fc302 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,10 @@ Last Release: pip install -U ipi ``` +## Documentation + +You can find the online documentation at [https://docs.ipi-code.org/#](https://docs.ipi-code.org/#). Alternatively, you can build it locally by following instructions in the `docs/README.md` file. + ## Source installation To develop i-PI or test it with the self-contained driver, follow these @@ -104,7 +108,7 @@ The monitoring can be interrupted with CTRL+C when the run has finished (5000 st ## Tutorials and online resources The i-PI [documentation](https://docs.ipi-code.org/onlinereso.html) has a list of -avaialble tutorials, recipes and other useful online resources. +available tutorials, recipes and other useful online resources. ## Run the automatic test suite diff --git a/docs/README b/docs/README.md similarity index 57% rename from docs/README rename to docs/README.md index f0bc71199..d130343b4 100644 --- a/docs/README +++ b/docs/README.md @@ -1,13 +1,12 @@ -i-PI documentation -================== +## i-PI documentation -This folder contains the files needed to build the documentation for i-PI. +This folder contains the files needed to locally build the documentation for i-PI. * `latex/` contains the "legacy" TeX manual, that includes also autogenerated input reference * `scripts/` contains automatic scripts to build the input reference * `src/` contains RST files that are compiled by sphynx into the HTML documentation. -To make the docs, make sure you have all the needed packages in `requirements.txt` installed, and type `make html`. The local documentation will be generated in `_build/html`. +To make the docs, make sure you have all the needed packages in `requirements.txt` installed, which can be achieved with `pip install -r requirements.txt`, and type `make html`. The local documentation will be generated in `_build/html`. To make the TeX docs follow the instructions in `latex`. diff --git a/docs/latex/README b/docs/latex/README deleted file mode 100644 index 59a8b0e0c..000000000 --- a/docs/latex/README +++ /dev/null @@ -1,46 +0,0 @@ - -- Documentation directory -- - - * This gives all the documentation for the program. - - * Directories: - - figures: Holds the figures used in the manual. - - input_docs: Generated by the Makefile to hold the automatically generated - input reference sections of the manual. - - * Files: - - ../scripts/create_man.py: python script which automatically generates latex help files - for all the classes, for use in the manual. - - ../scripts/help_list.py: python script which can generate custom help files for - the output classes, for use in the manual. - - ../scripts/help.py: python script which can generate custom help files for - each of the input classes, for use in the manual. - - Makefile: The makefile for the automatically generated manual. - - manual.tex: TeX file giving the manual template. - - mybib.bib: Bibliography file for the manual. - - elsarticle-num-names.bst: Bibliography style file. - - etoolbox.sty: LaTeX package which is used by manual.tex. - - * Some of the above files are used to automatically generate sections of the - user manual, and to create an xml showing the class hierarchy. The sections - of the user manual are created in a directory input_docs. - The user manual itself is created in two files, manual.pdf and manual.xml. - These are: - - manual.pdf: The user manual file. This explains how to run the code, - the input and output file syntax, and the design paradigm for ipi. - Also contains a tutorial which goes step by step through an example - calculation. - - manual.xml: This is an xml file that contains all the input names - along with a description of their purpose and what values are - expected for each of them. - - * To make the help files use: - -$ make - - * To remove the input reference sections and LaTeX compiled files, use: - -$ make clean - - * To remove all the generated files, use: - -$ make distclean diff --git a/docs/latex/README.md b/docs/latex/README.md new file mode 100644 index 000000000..de1b68f5f --- /dev/null +++ b/docs/latex/README.md @@ -0,0 +1,45 @@ + +## Documentation Directory + +This directory contains all the documentation for the program. + +### Directories + +- **figures**: Holds the figures used in the manual. +- **input_docs**: Generated by the Makefile to hold the automatically generated input reference sections of the manual. + +### Files + +- `../scripts/create_man.py`: Python script that automatically generates LaTeX help files for all the classes, used in the manual. +- `../scripts/help_list.py`: Python script to generate custom help files for the output classes, used in the manual. +- `../scripts/help.py`: Python script to generate custom help files for each of the input classes, used in the manual. +- `Makefile`: Makefile for generating the manual automatically. +- `manual.tex`: TeX file serving as the template for the manual. +- `mybib.bib`: Bibliography file for the manual. +- `elsarticle-num-names.bst`: Bibliography style file. +- `etoolbox.sty`: LaTeX package used by `manual.tex`. + +### Notes + +Some of the files listed above are used to automatically generate sections of the user manual and to create an XML file showing the class hierarchy. The sections of the user manual are generated in the `input_docs` directory. The user manual itself is created in two files: + +- **manual.pdf**: The main user manual file, explaining how to run the code, the syntax for input and output files, and the design paradigm for i-PI. It also contains a tutorial that goes step-by-step through an example calculation. +- **manual.xml**: An XML file that contains all the input names, along with descriptions of their purpose and the expected values for each. + +### Commands + +- **Generate Help Files**: + ```bash + make + ``` + +- **Clean Up (Remove Input Reference Sections and LaTeX Compiled Files)**: + ```bash + make clean + ``` + +- **Full Clean (Remove All Generated Files)**: + ```bash + make distclean + ``` + From e9c33287350f72fcad7fdb8ea5fe2a5682728af1 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Tue, 12 Nov 2024 16:50:51 +0000 Subject: [PATCH 22/47] edit to the docs link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d201fc302..f8363d368 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ pip install -U ipi ## Documentation -You can find the online documentation at [https://docs.ipi-code.org/#](https://docs.ipi-code.org/#). Alternatively, you can build it locally by following instructions in the `docs/README.md` file. +You can find the online documentation at [https://docs.ipi-code.org](https://docs.ipi-code.org/). Alternatively, you can build it locally by following instructions in the `docs/README.md` file. ## Source installation From 0e70ec235c4b2af707406923fc2a8923ed98967d Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Tue, 12 Nov 2024 22:04:41 +0100 Subject: [PATCH 23/47] A "direct" FF using the same PES interfaces as the python driver (#390) This is a major restructuring of the python driver and the forcefield block. All PES drivers have been moved to an ipi/pes folder, and their API streamlined with the possibility of providing both lists of arguments and named arguments. A new FFDirect forcefield makes it possible to call the PES from i-PI directly, avoiding the client/server setup that many find confusing. We converted most PES to the new interfaces, but several are possibly broken; these now trigger a warning so that users can check and possibly fix them. --------- Co-authored-by: Yair Litman Co-authored-by: Venkat Kapil --- docs/scripts/help.py | 1 + docs/src/contributing.rst | 8 +- docs/src/getting-started.rst | 26 +- docs/src/index.rst | 4 +- drivers/py/driver.py | 27 +- drivers/py/pes/mace.py | 40 -- drivers/py/pes/metatensor.py | 94 ----- drivers/py/pes/so3lr.py | 42 -- examples/clients/mace/RESTART | 365 ++++++++++++++++++ examples/clients/mace/getmodel.sh | 3 + examples/clients/mace/init.xyz | 1 + examples/clients/mace/input.xml | 37 ++ examples/clients/metatensor/README.md | 14 +- examples/clients/metatensor/create-model.py | 4 +- examples/clients/metatensor/input-direct.xml | 47 +++ examples/clients/metatensor/nickel-lj.pt | Bin 30459 -> 37924 bytes examples/clients/pes/README.md | 8 + examples/clients/pes/harmonic-direct/Makefile | 17 + examples/clients/pes/harmonic-direct/init.xyz | 3 + .../clients/pes/harmonic-direct/input.xml | 38 ++ .../pes/harmonic-direct/test_settings.dat | 0 examples/clients/xtb/config.json | 1 + examples/clients/xtb/run.sh | 2 +- .../implicit_bath_pos-dependent/run.sh | 9 +- examples/init_files/water_64mols.extxyz | 194 ++++++++++ ipi/__init__.py | 1 + ipi/engine/forcefields.py | 89 ++++- ipi/inputs/forcefields.py | 61 ++- ipi/inputs/simulation.py | 31 +- {drivers/py => ipi}/pes/__init__.py | 0 {drivers/py => ipi}/pes/ase.py | 51 ++- {drivers/py => ipi}/pes/bath.py | 27 +- {drivers/py => ipi}/pes/doubledoublewell.py | 66 ++-- {drivers/py => ipi}/pes/doublewell.py | 26 +- .../py => ipi}/pes/doublewell_with_bath.py | 57 +-- .../pes/doublewell_with_friction.py | 59 +-- {drivers/py => ipi}/pes/driverdipole.py | 24 +- {drivers/py => ipi}/pes/dummy.py | 21 +- {drivers/py => ipi}/pes/elphmod.py | 23 +- {drivers/py => ipi}/pes/harmonic.py | 36 +- ipi/pes/mace.py | 53 +++ ipi/pes/metatensor.py | 98 +++++ {drivers/py => ipi}/pes/pet.py | 91 ++--- {drivers/py => ipi}/pes/rascal.py | 52 +-- ipi/pes/so3lr.py | 37 ++ {drivers/py => ipi}/pes/spline.py | 20 +- {drivers/py => ipi}/pes/xtb.py | 48 +-- ipi/utils/io/inputs/__init__.py | 34 ++ ipi/utils/io/inputs/io_xml.py | 3 +- ipi_tests/README.md | 5 +- .../profiling/classical_md_direct/init.xyz | 10 + .../profiling/classical_md_direct/input.xml | 34 ++ ipi_tests/profiling/run_profiling.sh | 2 +- .../simulation.instanton_FINAL_15.ener | 33 -- .../100K_implicit_friction/test_settings.dat | 2 +- setup.py | 9 +- 56 files changed, 1533 insertions(+), 555 deletions(-) delete mode 100644 drivers/py/pes/mace.py delete mode 100644 drivers/py/pes/metatensor.py delete mode 100644 drivers/py/pes/so3lr.py create mode 100644 examples/clients/mace/RESTART create mode 100644 examples/clients/mace/getmodel.sh create mode 120000 examples/clients/mace/init.xyz create mode 100644 examples/clients/mace/input.xml create mode 100644 examples/clients/metatensor/input-direct.xml create mode 100644 examples/clients/pes/README.md create mode 100644 examples/clients/pes/harmonic-direct/Makefile create mode 100644 examples/clients/pes/harmonic-direct/init.xyz create mode 100644 examples/clients/pes/harmonic-direct/input.xml create mode 100644 examples/clients/pes/harmonic-direct/test_settings.dat create mode 100644 examples/clients/xtb/config.json create mode 100644 examples/init_files/water_64mols.extxyz rename {drivers/py => ipi}/pes/__init__.py (100%) rename {drivers/py => ipi}/pes/ase.py (70%) rename {drivers/py => ipi}/pes/bath.py (79%) rename {drivers/py => ipi}/pes/doubledoublewell.py (71%) rename {drivers/py => ipi}/pes/doublewell.py (73%) rename {drivers/py => ipi}/pes/doublewell_with_bath.py (65%) rename {drivers/py => ipi}/pes/doublewell_with_friction.py (71%) rename {drivers/py => ipi}/pes/driverdipole.py (95%) rename {drivers/py => ipi}/pes/dummy.py (71%) rename {drivers/py => ipi}/pes/elphmod.py (55%) rename {drivers/py => ipi}/pes/harmonic.py (60%) create mode 100644 ipi/pes/mace.py create mode 100644 ipi/pes/metatensor.py rename {drivers/py => ipi}/pes/pet.py (53%) rename {drivers/py => ipi}/pes/rascal.py (56%) create mode 100644 ipi/pes/so3lr.py rename {drivers/py => ipi}/pes/spline.py (84%) rename {drivers/py => ipi}/pes/xtb.py (74%) create mode 100644 ipi_tests/profiling/classical_md_direct/init.xyz create mode 100644 ipi_tests/profiling/classical_md_direct/input.xml delete mode 100644 ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/simulation.instanton_FINAL_15.ener diff --git a/docs/scripts/help.py b/docs/scripts/help.py index 541281e7e..3c646b862 100644 --- a/docs/scripts/help.py +++ b/docs/scripts/help.py @@ -87,6 +87,7 @@ "h0": cell.InputCell(), "forcefield": forcefields.InputForceField(), "ffsocket": forcefields.InputFFSocket(), + "ffdirect": forcefields.InputFFDirect(), "fflj": forcefields.InputFFLennardJones(), "ffdebye": forcefields.InputFFDebye(), "ffplumed": forcefields.InputFFPlumed(), diff --git a/docs/src/contributing.rst b/docs/src/contributing.rst index 7b2a9313d..32955b51c 100644 --- a/docs/src/contributing.rst +++ b/docs/src/contributing.rst @@ -1,3 +1,5 @@ +.. _contributing: + Contributing ============ @@ -89,7 +91,11 @@ If your new development in i-PI is directly related to a specific client code or We very much welcome new interfaces and we will be happy to answer your questions. If you want to enable the communication of a new client code with i-PI, it is not difficult: Please check an example of how it was done in ``fortran`` and ``python`` in the `drivers` folder in the repository. - +It is especially simple to add a new potential energy that is evaluated in Python: it is sufficient to add a file in the `ipi/pes` folder, specifying +`__DRIVER_NAME__` (a string that will be used to refer to the PES from the i-PI input or the command line) and `__DRIVER_CLASS__`, the name of the +actual class, that should provide, directly or through inheritance, a `__call__(self, cell, pos)` function and return a tuple with +`(potential, forces, virial, extras)`. See any of the existing PES files to use as templates - it is particularly simple to create a class that +piggybacs on an existing ASE-style calculator. Getting recognition for your contribution diff --git a/docs/src/getting-started.rst b/docs/src/getting-started.rst index fcc32010e..0d8c176ff 100644 --- a/docs/src/getting-started.rst +++ b/docs/src/getting-started.rst @@ -83,9 +83,29 @@ The built-in driver requires a FORTRAN compiler, and can be built as make cd ../.. +Python driver and PES +^^^^^^^^^^^^^^^^^^^^^ + +In addition to the FORTRAN drive, the i-PI distribution contains also a Python +driver, available in `drivers/py` and through the command-line command +`i-pi-py_driver`, which evaluates potential energy surfaces evaluated by simple +driver classes, that can be found in `ipi/pes`. + +These classes are particularly suitable to perform inference with machine-learning +potentials implemented in Python, and it is reasonably simple to add your own, +if you need to (see also the :ref:`contributing` section). + +These PES files can also be used directly, without the need to go through a +client-server interface, using a :ref:`ffdirect` forcefield, including in the +XML input a block similar to + +.. code-block:: + + + harmonic + { k1: 1.0} + -There is also a Python driver available in `drivers/py`, which however has limited -functionalities. Alternative installation using the setup.py module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -266,7 +286,7 @@ The flags do the following: -S: Optional parameter. If given, overwrite the default socket prefix used in the creation of files for the socket communication. - (default "/tmp/ipi_") + (default "/tmp/ipi\_") This code should be fairly simple to extend to other pair-wise interaction potentials, and examples of its use can be seen in the diff --git a/docs/src/index.rst b/docs/src/index.rst index 37b4c4f72..a0eeb385d 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -26,9 +26,8 @@ This documentation is structured as follows: :maxdepth: 2 introduction - onlinereso - features getting-started + features units input-files input-tags @@ -36,6 +35,7 @@ This documentation is structured as follows: output-tags distributed tutorials + onlinereso faq troubleshooting contributing diff --git a/drivers/py/driver.py b/drivers/py/driver.py index aeff7f8e4..98cab93f4 100755 --- a/drivers/py/driver.py +++ b/drivers/py/driver.py @@ -3,12 +3,8 @@ import argparse import numpy as np - -try: - from pes import * -except ImportError: - # when in an installed i-PI package - from ipi._driver.pes import * +from ipi.pes import * +from ipi.utils.io.inputs import read_args_kwargs description = """ Minimal example of a Python driver connecting to i-PI and exchanging energy, forces, etc. @@ -205,8 +201,8 @@ def run_driver( "--mode", type=str, default="dummy", + choices=list(__drivers__.keys()), help="""Type of potential to be used to compute the potential and its derivatives. - Currently implemented: [dummy, harmonic] """, ) parser.add_argument( @@ -227,10 +223,23 @@ def run_driver( args = parser.parse_args() + driver_args, driver_kwargs = read_args_kwargs(args.param) + if args.mode in __drivers__: - d_f = __drivers__[args.mode](args.param, args.verbose) + try: + d_f = __drivers__[args.mode]( + *driver_args, verbose=args.verbose, **driver_kwargs + ) + except ImportError: + # specific errors have already been triggered + raise + except Exception as err: + print(f"Error setting up PES mode {args.mode}") + print(__drivers__[args.mode].__doc__) + print("Error trace: ") + raise err elif args.mode == "dummy": - d_f = Dummy_driver(args.param, args.verbose) + d_f = Dummy_driver(verbose=args.verbose) else: raise ValueError("Unsupported driver mode ", args.mode) diff --git a/drivers/py/pes/mace.py b/drivers/py/pes/mace.py deleted file mode 100644 index 881f9e5cd..000000000 --- a/drivers/py/pes/mace.py +++ /dev/null @@ -1,40 +0,0 @@ -""" An interface for the [MACE](https://github.com/ACEsuit/mace) calculator """ - -import sys -from .ase import ASEDriver - -try: - from mace.calculators import MACECalculator -except: - MACECalculator = None - -__DRIVER_NAME__ = "mace" -__DRIVER_CLASS__ = "MACE_driver" - -ERROR_MSG = """ -MACE driver requires specification of a .json model, -and a template file that describes the chemical makeup of the structure. - -Example: python driver.py -m mace -u -o model.json,template.xyz -""" - - -class MACE_driver(ASEDriver): - def __init__(self, args=None, verbose=False): - if MACECalculator is None: - raise ImportError("Couldn't load mace bindings") - - super().__init__(args, verbose, ERROR_MSG) - - def check_arguments(self): - """Check the arguments requuired to run the driver - - This loads the potential and atoms template in MACE - """ - - super().check_arguments() - - if len(self.args) < 2: - sys.exit(self.error_msg) - - self.ase_calculator = MACECalculator(model_paths=self.args[1], device="cpu") diff --git a/drivers/py/pes/metatensor.py b/drivers/py/pes/metatensor.py deleted file mode 100644 index 271a0c04e..000000000 --- a/drivers/py/pes/metatensor.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Interface with metatensor -(https://lab-cosmo.github.io/metatensor/latest/atomistic/index.html), that can -be used to perform calculations based on different types of machine learning -potentials -""" - -import sys - -from ipi.utils.messages import warning - -from .ase import ASEDriver - -try: - import metatensor.torch - from metatensor.torch.atomistic.ase_calculator import MetatensorCalculator -except ImportError as e: - warning(f"Could not find or import metatensor.torch: {e}") - MetatensorCalculator = None - -__DRIVER_NAME__ = "metatensor" -__DRIVER_CLASS__ = "MetatensorDriver" - -ERROR_MSG = """ -The metatensor driver requires specification of a .pt TorchScript model and an -ASE-readable template file that describes the chemical makeup of the structure. - -Example: python driver.py -m metatensor -u -o template.xyz,model.pt,device=cpu,\ -extensions=path/to/extensions,check_consistency=False -""" - - -class MetatensorDriver(ASEDriver): - def __init__(self, args=None, verbose=False, error_msg=ERROR_MSG): - super().__init__(args, verbose, error_msg) - - def check_arguments(self): - """Check the arguments required to run the driver - - This loads the potential and atoms template in metatensor - """ - - if MetatensorCalculator is None: - raise ImportError("could not import metatensor.torch, is it installed?") - - metatensor_major, metatensor_minor, *_ = metatensor.torch.__version__.split(".") - metatensor_major = int(metatensor_major) - metatensor_minor = int(metatensor_minor) - - if metatensor_major != 0 or metatensor_minor != 5: - raise ImportError( - "this code is only compatible with metatensor-torch v0.5.x, " - f"found version v{metatensor.torch.__version__} " - f"at '{metatensor.torch.__file__}'" - ) - - super().check_arguments() - - if len(self.args) < 2: - sys.exit(self.error_msg) - self.model_path = self.args[1] - - device = None - extensions_directory = None - check_consistency = False - for arg in self.args[2:]: - if arg.startswith("device="): - device = arg[7:] - elif arg.startswith("extensions="): - extensions_directory = arg[11:] - elif arg.startswith("check_consistency="): - arg = arg[18:] - if arg == "True": - check_consistency = True - elif arg == "False": - check_consistency = False - else: - raise ValueError( - "invalid value for check_consistency, expected True or False, " - f"got {arg}" - ) - - else: - sys.exit(self.error_msg) - - self.ase_calculator = MetatensorCalculator( - self.model_path, - device=device, - extensions_directory=extensions_directory, - check_consistency=check_consistency, - ) - - # Show the model metadata to the users - print(self.ase_calculator.metadata()) diff --git a/drivers/py/pes/so3lr.py b/drivers/py/pes/so3lr.py deleted file mode 100644 index ee9599684..000000000 --- a/drivers/py/pes/so3lr.py +++ /dev/null @@ -1,42 +0,0 @@ -""" An interface for the [SO3LR](https://github.com/general-molecular-simulations/so3lr) calculator """ - -from .ase import ASEDriver - -try: - from so3lr import So3lrCalculator -except: - So3lrCalculator = None - -__DRIVER_NAME__ = "so3lr" -__DRIVER_CLASS__ = "SO3LR_driver" - -ERROR_MSG = """ -SO3LR driver requires a template file that describes the chemical makeup of the structure. - -Optionally, lr_cutoff and dispersion_energy_lr_cutoff_damping can be specified. - -Example: python driver.py -m so3lr -u -o template.xyz,lr_cutoff=12,dispersion_energy_lr_cutoff_damping=2 -""" - - -class SO3LR_driver(ASEDriver): - def __init__(self, args=None, verbose=False): - if So3lrCalculator is None: - raise ImportError("Couldn't load so3lr bindings") - - super().__init__(args, verbose, ERROR_MSG) - - def check_arguments(self): - super().check_arguments() - - args = self.args - - kwargs = {} - if len(args) >= 2: - _ = args[0] # template we don't need - - for arg in args[1:]: - key, value = arg.split("=") - kwargs[key] = float(value) - - self.ase_calculator = So3lrCalculator(**kwargs) diff --git a/examples/clients/mace/RESTART b/examples/clients/mace/RESTART new file mode 100644 index 000000000..3be060e83 --- /dev/null +++ b/examples/clients/mace/RESTART @@ -0,0 +1,365 @@ + + + 31415 + [{"bit_generator": "MT19937", "state": {"key": [795669418, 3354365008, 150463171, 3937589838, 937846891, 734296723, 764622735, 1183299804, 1272117760, 2010368631, 1241689493, 3626464784, 1162653305, 1289276628, 1367499306, 3247908752, 1963981358, 2105964165, 1030412370, 3753156803, 1150834373, 4031974639, 531307719, 4045118304, 2683788309, 116245922, 2731998769, 136843156, 2169419932, 2880162252, 4007512466, 488361195, 401722091, 2070790009, 1569274038, 815594016, 124972808, 474005227, 3249330448, 2100162826, 3174580426, 2683556907, 4048106153, 1785067589, 2389562067, 836361726, 50342815, 267551970, 3029837949, 3708063355, 717650658, 4006537337, 2479145810, 3256975969, 724976954, 2961068974, 1504794639, 1505207924, 2503985603, 311245764, 1337733744, 75442868, 165388908, 4036439509, 85007674, 1868694522, 2350085548, 3505596813, 47545258, 2074303192, 1070457701, 1029840107, 353040402, 1973126927, 1264732370, 2845086742, 2526982946, 711245124, 1767309883, 2553172272, 3804650134, 289756061, 1111550931, 4144472782, 3996394604, 1981950798, 844362391, 3764917697, 3438324015, 2851666299, 2537341468, 2679862414, 1922363332, 666882440, 3941252033, 757464743, 1045369080, 2905858236, 730860388, 1325996640, 3162113550, 2567309825, 1103202741, 3175399181, 2025511874, 2412947386, 3058427547, 227013550, 2159447082, 1067678484, 3425716523, 417688251, 808501564, 3029168553, 776434612, 115305601, 2788751616, 4246589453, 1253335687, 4141730143, 2414042400, 3419716119, 1633385319, 3247093955, 2994012100, 3972147166, 3745802163, 1304644993, 865244793, 3828379540, 692694198, 4224136046, 341321136, 3189881009, 3230663087, 2858154757, 1490950918, 2482160305, 2121120586, 3007482108, 822603820, 611698261, 2765298047, 345565265, 950359221, 1557230050, 709103228, 1186524570, 292929978, 1821072176, 738923492, 4274644, 779539689, 481731554, 1561808887, 4203195225, 1555517680, 3751871402, 1482431159, 2791267293, 3707069758, 3234075511, 2672838488, 1009278333, 1527771451, 3152681530, 2014224365, 148003440, 3882068492, 351078994, 1651963697, 1054663714, 2397065047, 1469924118, 1137039177, 3577753374, 686392654, 3017336343, 1040761223, 365471914, 2744241982, 2232067354, 4292242034, 3280899888, 2970074168, 4021665697, 4032550683, 2848764242, 134774596, 2698474524, 3951539303, 3050877350, 425236979, 3681969874, 536833020, 645868093, 3820567878, 818193000, 3703993042, 2811873296, 200223563, 2261193604, 4002620488, 573051517, 559569805, 1751201194, 3958517026, 3946914696, 843371176, 3401646834, 1276160980, 3113426010, 3652866953, 3777818492, 1153305286, 634988187, 4656920, 4017875503, 4244574051, 3891820314, 1921680474, 1139973881, 26053146, 3540936332, 1190218234, 3858351434, 4215348533, 1192366508, 3769660024, 3473641435, 798054066, 2265876112, 1057572646, 1880763545, 232212048, 1559861968, 2573998448, 879167696, 1381352741, 3800595158, 2698089866, 1949124578, 613088558, 733254358, 1014535932, 904484089, 2246187117, 4044798376, 2066284160, 3744977864, 800089136, 3114088148, 1106568495, 3832704901, 368290159, 1891318290, 2578953184, 623604879, 220664755, 4211596409, 3902639138, 3893193846, 444071368, 3037681030, 417202030, 3408758382, 1941104578, 4235778810, 1412270470, 3337251361, 3965657496, 565829799, 2074175501, 3575557, 105655240, 2090581125, 3306098583, 3395704630, 1923485982, 1800504879, 184025064, 3741358783, 1531109577, 3771712710, 1779168700, 3845470585, 54968271, 958679375, 643136974, 3568839812, 816610774, 269396381, 1071003538, 3955364110, 194687099, 350181071, 1806095246, 3847618589, 3093771598, 4091627518, 2587247322, 3899980915, 1407852399, 1825407665, 2573244759, 1807374193, 3505525555, 3863992055, 1480680373, 1898960191, 1705678055, 743066202, 1640873890, 1502514469, 62759855, 2132297488, 2382508606, 1130137488, 3409343240, 81886173, 218725541, 4201682764, 911613040, 1789780226, 2328217590, 3070595230, 1307451716, 917012100, 2466257247, 2759529868, 4189490536, 3495955071, 3707418358, 1380836129, 3581386770, 680470424, 4156278160, 3183533111, 2255433561, 31125173, 607214606, 3405607994, 2681426217, 4147600795, 3619039237, 763225706, 3096727002, 368528808, 3715678351, 3960812773, 1794416641, 24849552, 2330330218, 4198000056, 944776381, 4016144718, 4015476207, 2542135582, 891526613, 3275670597, 260289596, 1686366879, 811749559, 1930701239, 4106811535, 3486653570, 3757236663, 3058744443, 573883924, 1597973411, 2849367252, 837698365, 4068634250, 1668230932, 372720237, 2224907569, 4138179720, 2153761699, 1142555848, 642912525, 1775227279, 2202501344, 1576309174, 2020529413, 2759079887, 1476875451, 2490373885, 140951714, 3261701581, 2900952306, 2771780919, 3024978145, 3847035909, 2590213672, 3657015728, 2933466694, 2652199769, 779968378, 693587481, 3238084161, 1292859236, 3901198107, 1642771831, 2504839327, 2593018406, 3232082142, 2294577705, 3434756417, 1176324409, 2586064527, 3649392695, 4270213721, 369682239, 1833859305, 3004923589, 2157403691, 2909620342, 4038662021, 530878050, 3727607169, 2581922589, 3325028835, 3492366495, 2778152583, 1317623030, 985094443, 4200028354, 3818659668, 2290320879, 996660363, 4254245440, 3634630451, 2515846723, 3412149142, 713547821, 3915598384, 1722967802, 3031991720, 397851792, 2268486426, 1485982870, 1312405573, 1549720048, 3093342568, 2946875941, 763765622, 2904735136, 2576787606, 1307812616, 1922019727, 3895352419, 3130267707, 3041543726, 4156570049, 2040426037, 4185810248, 3336129979, 1543746434, 4114276353, 968506551, 831488510, 3910628170, 1588848655, 2295202084, 552508107, 2895382473, 3046575372, 1866870955, 705382541, 2784623343, 4182110533, 2827559551, 1027960460, 1950086097, 912710698, 3326002035, 3658909104, 1297039826, 714298744, 3314813781, 3390897113, 4117186502, 4249300284, 2177611878, 3519404052, 1215103020, 888161319, 3639110818, 2770087358, 4230724586, 1084939770, 1124825233, 2642336164, 3102293704, 2636412376, 3895111296, 4015894980, 1480524830, 2283627770, 2896169265, 1525361018, 4252128804, 3188301813, 578157311, 2825512587, 1353889048, 4109758585, 696181235, 715287672, 3344116697, 80143085, 1098959985, 3214960309, 2416526557, 607618034, 70832594, 1701217967, 2165635687, 970104148, 3879061619, 3523994229, 4192455772, 3014553164, 58296115, 3570431746, 2418920482, 3046097006, 366177630, 206133899, 3934812939, 3106058444, 3539689581, 219917426, 299931320, 1588386678, 2497199221, 1214539462, 1239314913, 3984725088, 2692578908, 750931547, 3585571140, 488681398, 1376038242, 560384883, 1332416451, 2912016916, 1884794666, 3769249332, 30846606, 1774556799, 411741744, 2798886417, 4156313896, 1075162039, 501151935, 605601098, 3840102651, 1767398917, 21611012, 2366766995, 3276021819, 379749019, 1353987593, 1364614484, 1303524118, 3975728117, 3671464016, 2958317770, 3854446205, 3411077042, 913017910, 1979049403, 1435107822, 2874429353, 2302569380, 3196830537, 3863113770, 410539094, 1769756413, 3673454397, 870551312, 3979217, 2679612570, 1291584258, 1565027228, 1877575392, 2372846756, 1697524416, 4175015869, 2274297454, 3741847250, 523408423, 4063843078, 2235754156, 3232533841, 2757177941, 2074155385, 386877545, 260349822, 4059210860, 3349159924, 531748356, 174724555, 3122595409, 3660832320, 579592266, 1350622822, 3279112166, 21688457, 2177358206, 3414507844, 3960313028, 2220533609, 3596959752, 808052420, 1362285260, 304161502, 2334325099, 4090228266, 526360154, 3527253401, 4177434316, 3382911628], "pos": 549}}] + + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, + potential{electronvolt}, pressure_md{megapascal} ] + + positions + 1 + + 1 + 20000 + +
driver
+
+ + + + + + + 9.50044560e-04 + 4.79612667e-04 + [ 1.00000000e+00 ] + + + + + + 1.08732992e-03 + 4.13413730e+03 + + 2.06706865e+01 + [ 1 ] + + + + + [ 2.11270674e+01, -1.36860295e+01, 1.21309109e+01, 2.13905728e+01, -1.48995535e+01, + 1.07839955e+01, 2.25466837e+01, -1.33494742e+01, 1.32355387e+01, 5.26292258e+00, + 3.03753005e+00, 2.95386440e+00, 4.63759498e+00, 3.75319475e+00, 4.79162448e+00, + 7.05549943e+00, 3.02660946e+00, 3.41089634e+00, 7.68280951e+00, 2.29463670e+00, + 1.15917368e+01, 8.54721344e+00, 1.59180645e+00, 1.01638082e+01, 7.05049810e+00, + 1.18156011e+00, 1.29580753e+01, -1.10555593e+01, -3.38025456e+00, -2.78541863e+00, + -1.11640441e+01, -4.97217119e+00, -4.00393338e+00, -1.28770002e+01, -2.98973666e+00, + -3.18922815e+00, -1.30773732e+00, 2.80916019e+00, 8.78308389e+00, -1.09035460e+00, + 3.24684786e+00, 1.05259695e+01, -2.21290761e+00, 4.33986686e+00, 8.10540613e+00, + 1.84994004e+01, -2.31212286e+00, 1.11324281e+01, 1.71343793e+01, -1.70545212e+00, + 1.00958713e+01, 1.99982592e+01, -1.89798731e+00, 1.02215215e+01, 3.38480627e+00, + -1.02059660e+01, -5.25221279e+00, 4.42576485e+00, -9.68664476e+00, -3.78241580e+00, + 1.68203597e+00, -9.68905088e+00, -5.09542299e+00, -5.21005973e+00, -1.63108694e+01, + -2.04708461e-01, -4.81781665e+00, -1.64227168e+01, -2.03623163e+00, -5.20969305e+00, + -1.45138746e+01, 2.22953104e-01, 1.86595134e+01, -7.56514257e+00, 1.32421462e+01, + 1.75798948e+01, -7.41248045e+00, 1.46026588e+01, 1.86576022e+01, -5.83205625e+00, + 1.25999077e+01, 2.57610855e+00, 5.13558558e+00, 6.81030022e+00, 1.73244179e+00, + 6.50463350e+00, 5.97680624e+00, 1.31691165e+00, 4.10234979e+00, 7.63449444e+00, + 1.39082898e+01, -9.96245939e+00, -3.25461663e+00, 1.51760632e+01, -1.15296706e+01, + -3.37732662e+00, 1.21007828e+01, -1.06523614e+01, -3.82444376e+00, 1.43524418e+01, + -7.39241448e+00, 3.56923216e+00, 1.27091775e+01, -7.73508523e+00, 2.69144356e+00, + 1.40691294e+01, -7.71022717e+00, 5.37580268e+00, -1.00675908e+00, -1.38432193e+01, + -2.97327593e+00, 1.70353123e-01, -1.27373430e+01, -3.84661160e+00, -1.73060924e+00, + -1.47524708e+01, -4.44555342e+00, 1.19729669e+01, 1.20733431e+01, -1.09025244e+01, + 9.99274183e+00, 1.17436895e+01, -1.04749088e+01, 1.18702114e+01, 1.38183802e+01, + -1.18703636e+01, 8.87350781e+00, -2.48453830e+00, 1.15231984e+01, 8.12254908e+00, + -2.17080193e+00, 9.66660045e+00, 7.63740978e+00, -2.25628963e+00, 1.27883558e+01, + 7.00672454e+00, -7.64976099e+00, 9.18220677e+00, 7.32437430e+00, -8.06738688e+00, + 7.37415484e+00, 6.43037804e+00, -9.16811693e+00, 1.00843559e+01, 8.03480627e+00, + -1.37102624e+01, 6.42921056e+00, 7.19894411e+00, -1.29335143e+01, 7.92774287e+00, + 8.66077412e+00, -1.54183582e+01, 6.97959522e+00, 5.38843050e+00, -4.28167030e-01, + -1.51443836e-01, 4.36031236e+00, 6.15179755e-01, 1.11561161e+00, 6.61865298e+00, + 9.53834535e-01, -5.84401180e-01, 1.35501597e+00, 1.42545868e+00, -1.95721393e+00, + 9.18335400e-01, 3.27806467e+00, -1.49220028e+00, -2.33137187e-01, 9.05564928e-01, + -2.84057752e+00, 7.29756827e+00, -1.10870354e+01, 1.57980278e+00, 5.71466230e+00, + -1.17390022e+01, 7.22268454e-01, 6.80927105e+00, -1.17038612e+01, 3.26405193e+00, + -5.01975383e+00, 3.03973079e+00, 5.01794918e+00, -5.32441308e+00, 2.66702778e+00, + 3.16062835e+00, -5.48883063e+00, 4.90714636e+00, 5.28519501e+00, 1.62103241e+01, + -1.76560529e+00, 6.97472841e+00, 1.60801190e+01, -3.24935234e+00, 5.82579474e+00, + 1.77963247e+01, -1.01672498e+00, 6.12825446e+00, 3.80024484e+00, -3.34448566e+00, + 3.35091101e+00, 3.23139426e+00, -4.33013813e+00, 4.76447241e+00, 5.45818342e+00, + -4.06170044e+00, 2.88609058e+00, -2.29106555e+00, 8.27699077e+00, 1.09064600e+00, + -3.59302905e+00, 9.60437448e+00, 8.14797198e-01, -2.46438985e+00, 7.44183939e+00, + -5.48883046e-01, 1.25077487e+01, -1.18739711e+01, 6.65675297e+00, 1.26707463e+01, + -1.01264862e+01, 7.68378868e+00, 1.07093093e+01, -1.23594150e+01, 6.65739810e+00, + 8.60509597e+00, -7.60304481e+00, 4.63854382e+00, 9.02578016e+00, -5.87949593e+00, + 4.07482932e+00, 7.12403922e+00, -8.13379120e+00, 3.51070503e+00, -3.00012077e+00, + -6.53179460e+00, 8.59007709e+00, -3.93905553e+00, -5.85750020e+00, 9.99816090e+00, + -1.75352091e+00, -7.63786023e+00, 9.17090076e+00, 1.20655910e+00, 1.10365477e+01, + -1.09830488e+00, 6.09246061e-01, 1.15808414e+01, 5.61555958e-01, 2.73453294e+00, + 1.20648566e+01, -1.25111478e+00, 2.62638436e+01, 7.27406319e+00, -8.75588526e+00, + 2.56834674e+01, 5.56426063e+00, -8.04139770e+00, 2.82412254e+01, 7.33859615e+00, + -8.38692536e+00, 2.74104908e+00, -1.86292973e+01, -9.19589353e+00, 4.43387362e+00, + -1.87846089e+01, -9.91418570e+00, 1.87855716e+00, -1.89783535e+01, -1.09205196e+01, + 3.97947941e+00, -5.47257104e+00, -6.83899148e+00, 2.77379545e+00, -4.71009592e+00, + -5.43207979e+00, 4.09371918e+00, -3.94218484e+00, -7.84955906e+00, 1.00356554e+01, + -1.76389816e+01, 4.22779892e+00, 1.15089292e+01, -1.81197327e+01, 5.10668667e+00, + 1.01129107e+01, -1.89069149e+01, 2.93228675e+00, 1.77493187e+01, -1.18696630e+01, + 6.15072403e+00, 1.69455996e+01, -1.15938719e+01, 7.68457144e+00, 1.65835561e+01, + -1.12666150e+01, 5.00737837e+00, 1.18087642e+01, -1.60388415e+01, -1.00042403e+01, + 1.28761001e+01, -1.76032488e+01, -1.02550343e+01, 1.22292183e+01, -1.49850429e+01, + -1.12468680e+01, -5.96314832e+00, -6.31887619e+00, 1.34500300e+01, -5.34715059e+00, + -7.72600390e+00, 1.44440780e+01, -6.88656998e+00, -7.10836674e+00, 1.20318716e+01, + 1.10557748e+01, -1.59085722e+01, -5.04387646e+00, 1.01204107e+01, -1.60028369e+01, + -3.54596491e+00, 1.01659085e+01, -1.68147828e+01, -6.31941602e+00, -8.45427460e+00, + -2.65667497e+00, 6.91745263e+00, -6.74375125e+00, -1.90126068e+00, 7.19132870e+00, + -8.96376344e+00, -2.19363418e+00, 5.14498758e+00, -3.89182857e-01, -1.56888753e+01, + 2.32879823e+00, -1.30089714e+00, -1.66343724e+01, 9.12257571e-01, -1.14188798e+00, + -1.46359268e+01, 3.51386876e+00, 9.37211806e+00, 8.54468618e+00, -2.89250979e+00, + 8.78141523e+00, 9.73701187e+00, -4.32302866e+00, 8.41517272e+00, 7.08433969e+00, + -3.31834175e+00, -2.22955499e+00, -7.91668250e-01, -2.38386476e+01, -1.83492868e+00, + -5.00991552e-01, -2.57437208e+01, -2.69880773e+00, -2.55960022e+00, -2.36353985e+01, + 8.27387771e+00, -7.33575688e+00, -5.87942330e+00, 6.35092941e+00, -7.08113274e+00, + -6.27991783e+00, 8.93763592e+00, -6.51719245e+00, -7.49966962e+00, 2.78840510e+00, + -9.64941990e+00, 3.87609500e+00, 2.92156758e+00, -9.98374738e+00, 5.82207066e+00, + 1.38506984e+00, -8.31553711e+00, 4.00615367e+00, 1.07803427e+00, 1.59229763e-01, + 5.61183782e+00, 2.53864873e+00, -5.23310319e-01, 4.94295750e+00, 7.65852377e-01, + 1.80102640e+00, 4.69045864e+00, 9.11194385e+00, 3.31117500e+00, -4.99694516e-01, + 7.69970540e+00, 4.29870451e+00, -9.81299344e-02, 1.04928491e+01, 4.20896687e+00, + 7.07434059e-01, 2.38843651e+00, -9.25719293e+00, -9.78855489e+00, 1.36723765e+00, + -1.07359219e+01, -9.52936754e+00, 3.35064685e+00, -9.18585996e+00, -8.32908184e+00, + -1.43231528e+01, -6.45597217e+00, -4.46118807e-01, -1.35679796e+01, -8.08771676e+00, + 3.00320855e-01, -1.28697145e+01, -5.48665674e+00, -1.07547594e+00, 1.18110613e+01, + -1.16531694e+01, -7.86500448e+00, 1.33622440e+01, -1.18955804e+01, -8.98089540e+00, + 1.20009816e+01, -1.32121475e+01, -6.74890856e+00, -3.45863064e+00, 2.95792643e+00, + -6.42658349e+00, -4.60614013e+00, 4.23189006e+00, -7.22285576e+00, -4.53339575e+00, + 1.42190834e+00, -6.19058161e+00, 3.24364788e+00, 7.02915419e+00, -5.39215348e-01, + 2.39708876e+00, 8.97617965e+00, -4.20126044e-01, 2.22196985e+00, 6.22895666e+00, + 5.56327805e-01, 1.59984204e+01, -5.84287574e+00, 1.86363441e+01, 1.47801353e+01, + -4.84559303e+00, 1.93533925e+01, 1.76828486e+01, -4.66931904e+00, 1.86230162e+01, + 6.08237008e+00, -1.47299814e+01, -3.78247837e+00, 4.78901045e+00, -1.39028545e+01, + -2.67742636e+00, 5.53381502e+00, -1.64397207e+01, -4.20231347e+00, -7.50143750e+00, + -9.10652021e-01, -1.65044874e+00, -8.92524410e+00, -1.77729527e+00, -2.40806154e+00, + -6.42215400e+00, 1.15848502e-01, -2.75045541e+00, 4.89505746e+00, 1.50494897e-01, + -4.99621539e+00, 3.58312493e+00, 7.36814991e-01, -6.02014838e+00, 3.76068453e+00, + -7.84227605e-02, -3.11714262e+00, -6.04596705e+00, -1.16496551e+00, -7.32403541e+00, + -5.59894261e+00, -2.87674427e+00, -6.45698238e+00, -7.57587741e+00, -1.76917601e+00, + -8.43410745e+00, 9.18653546e+00, -2.93498856e+00, 2.68500255e+00, 1.06367956e+01, + -3.65150207e+00, 1.61132687e+00, 8.38250023e+00, -1.93721739e+00, 1.16504700e+00, + 1.81626625e+00, -3.49676977e+00, -2.66477091e+00, 2.53150870e-01, -2.48620331e+00, + -2.85322051e+00, 2.40622962e+00, -3.44596743e+00, -9.93811065e-01, -2.94171379e+00, + -1.15802091e+01, 1.09161095e+01, -1.83503870e+00, -1.27216331e+01, 1.19853877e+01, + -2.68174694e+00, -9.95836912e+00, 1.17372362e+01, 1.20695200e+01, 6.92946961e+00, + 1.49151598e+00, 1.24390565e+01, 7.58521727e+00, 3.11596461e+00, 1.02554837e+01, + 7.32440427e+00, 1.21067003e+00, 1.43493276e+01, -1.57856515e+00, 2.03568985e+00, + 1.33636654e+01, -2.85087860e+00, 2.83623937e+00, 1.35985432e+01, -1.40251297e+00, + 3.14717634e-01, 6.55740268e+00, -8.17481875e-01, 6.81465394e+00, 5.85552908e+00, + -2.29389688e+00, 6.09518757e+00, 6.99006081e+00, 2.96832928e-01, 5.51556803e+00, + -6.87704245e-01, -6.34197738e+00, 3.27981758e+00, -2.52168336e+00, -6.66243631e+00, + 3.19109582e+00, -3.52920568e-01, -4.48559485e+00, 2.57382443e+00, 1.09885570e+01, + 1.20134297e+01, 2.00488702e+01, 9.53804230e+00, 1.09072164e+01, 2.00175146e+01, + 1.20661894e+01, 1.14325396e+01, 1.87478346e+01, 2.15889011e+00, -2.38560921e+01, + 7.86816975e+00, 3.35910665e+00, -2.52233478e+01, 8.24868855e+00, 4.78545613e-01, + -2.46866501e+01, 7.71853200e+00, -6.73627901e-01, -2.15188712e+01, 8.17319475e-01, + -1.90340564e+00, -2.08759741e+01, 1.93195444e+00, 7.31174686e-01, -2.03629864e+01, + 9.02513546e-01 ] + +

+ [ -4.02765830e+00, -3.16023137e+00, -6.88011833e+00, 6.46755190e-01, 1.53026954e+00, + -2.19506763e+00, -1.67835222e+00, -5.32155921e-01, -1.06085925e+00, -2.30471976e+00, + -3.52917704e+00, -3.94006174e+00, -7.34979987e-01, -2.10239481e-01, 7.18707512e-01, + 1.57005590e+00, 2.18516271e-01, 9.25232779e-01, 3.34019920e+00, -1.05455782e+01, + -6.37139586e+00, 1.26402730e-01, 1.25768619e-02, -3.09142555e-01, -8.39207249e-01, + -8.35248753e-01, -8.58037086e-01, 4.08421754e+00, 2.35572425e+00, -4.59257653e+00, + 3.17769176e-01, 2.33664714e+00, -1.33226716e+00, 6.13647976e-02, 9.14908453e-01, + 1.99621940e-01, -5.36433556e-01, 9.78577617e+00, 3.15100532e+00, -7.67098039e-02, + -2.68685188e-01, -2.21983725e+00, -4.40882737e-01, -1.71483915e-01, -7.17212520e-01, + 8.57637765e+00, 2.82256107e+00, 5.53177831e+00, 1.80559963e+00, 2.46786279e+00, + 1.51779938e+00, -2.02623211e+00, -5.78135941e-01, 1.49030327e+00, 1.07439175e+01, + 5.39180849e+00, -5.47784454e+00, 1.58381688e+00, 5.05886077e-01, 3.76803356e-01, + -1.38751615e+00, 2.95688436e-01, 1.58410366e+00, -2.80636045e+00, -4.90422672e+00, + -8.54444216e+00, -1.66361699e+00, 6.62247945e-01, 3.77915326e-01, -6.72869185e-01, + 1.70899114e+00, -1.39645304e+00, -8.89305852e+00, 8.87294193e-01, -6.25731915e+00, + -7.89802389e-01, -1.47434221e+00, 2.03450683e+00, 1.18483688e+00, -1.62130683e+00, + -9.66050236e-01, 1.79957758e+00, -1.91158836e+00, 1.52148414e+00, 1.02392868e+00, + 4.96524210e-01, -3.88683893e-01, 2.97483850e-01, -1.81675060e-01, -5.40274010e-01, + 7.56174836e+00, -4.17216519e+00, -2.04695415e-01, -1.07181836e+00, 4.49563846e-01, + 8.76759186e-01, -3.84162916e-01, -3.88527314e+00, -1.62530511e+00, 5.65454856e+00, + 2.91730118e+00, -3.90989881e+00, 1.54231359e+00, -2.21972512e-01, -4.51045558e-02, + 3.99416478e-01, -1.00950555e+00, 3.39184284e-01, 5.90140476e+00, -3.22770125e+00, + 7.82044643e+00, 2.09317553e-01, 2.68579455e-01, 6.63090432e-01, 1.44255027e+00, + -2.32917987e+00, 2.01606232e-01, -3.12618017e+00, 4.30261848e+00, -2.71378848e+00, + 1.85882366e+00, -1.61633781e-01, 2.64130322e-01, -4.46744495e-01, 1.31080074e+00, + 6.60114040e-01, -8.30310641e+00, 9.25745314e-01, 7.64332400e+00, -2.01002448e+00, + 2.30174903e-01, -1.23201926e+00, 2.66401112e-01, 6.12873234e-01, 1.13792494e+00, + -9.92961866e-01, 1.40104874e+00, -1.54976667e+00, -2.09460862e+00, -1.11318979e+00, + -6.77879296e-01, -1.48922489e+00, 5.77486551e-01, 8.95837254e-02, 7.19296755e-01, + -2.14225094e-01, 5.13432993e+00, 8.13091174e-02, 3.19785272e-01, 2.05804267e+00, + -7.06147577e-01, 1.19400637e+00, -1.09844364e+00, -9.70764522e-01, -9.63044853e+00, + 9.95372411e+00, 1.10906246e+00, -5.38801179e-01, 2.52658243e+00, 4.24814703e-01, + 3.51643210e-01, 2.65609594e-01, 3.20325937e+00, -3.83370547e-01, 5.46853459e+00, + -3.80891311e-01, -5.78597893e-01, 1.00601378e+00, -1.94028707e+00, 8.53963967e-01, + -1.04905411e-01, -2.10817786e-01, 4.75283908e+00, -2.80392819e+00, -5.34639991e-01, + -1.04298964e+00, -2.56306844e-02, -6.25008824e-01, -1.09859980e+00, 5.12861463e-01, + 7.24710437e+00, -6.36295046e+00, -4.66028066e+00, 1.51129191e-01, -3.51535018e-01, + 1.01099172e+00, -5.30210104e-01, -5.26844762e-01, -1.07618887e-01, -1.32849603e+01, + -7.81488092e+00, -1.18072980e+00, -9.30213958e-01, -1.94013976e-01, 6.33616430e-01, + 1.19898755e+00, -2.30617292e+00, 2.61701779e+00, 7.71101489e+00, 1.60726495e+00, + -2.40983274e+00, -1.16338678e+00, 1.88871931e-01, 1.71770472e+00, -4.64385501e-02, + 1.39155166e+00, -1.74835047e+00, -1.41568360e+00, -2.86578718e+00, 5.52999030e+00, + -2.24926040e+00, -3.61432769e-01, -1.12630561e+00, 1.68660194e+00, -2.49880250e+00, + -7.77272175e-01, -3.01543784e+00, 6.03277807e+00, 2.86043016e+00, -2.12976635e-01, + 2.01492967e+00, -1.78760816e+00, -6.61890776e-01, -1.30111518e+00, 9.38199658e-01, + 4.99052574e+00, -3.20148706e+00, -4.28580193e+00, -1.76106567e+00, -2.18336915e+00, + -5.12765262e-01, 1.10394817e+00, -7.30500839e-01, 2.46295960e+00, 1.16724054e+00, + -3.43835368e+00, 3.35366912e+00, -9.52601684e-01, -1.21651126e+00, 1.85209383e+00, + 2.44758034e+00, -1.24989641e+00, -1.42092175e-01, 9.30070829e-02, -1.00986313e+01, + 3.71453120e+00, -1.57124704e+00, -1.57842572e-01, 2.80923890e-01, 9.74670118e-01, + -6.44852652e-01, -8.06646424e-01, -2.64682957e+00, -1.04039827e+01, -1.28501080e+01, + 1.68550729e+00, 6.62379774e-01, -1.08806618e+00, -5.42781546e-02, -2.12338052e+00, + -7.09371750e-01, -2.86715414e+00, -2.89936794e+00, 1.39691277e+00, -7.03065772e-01, + -4.01449140e-01, -4.40156839e-01, -1.39532149e+00, -1.55399108e+00, 2.18289212e-01, + 3.92577101e+00, -6.97357837e+00, 7.06725283e+00, -4.66206715e-01, -1.69782685e+00, + -1.08672806e+00, -2.30218438e+00, 1.65965573e+00, 2.07218951e+00, 4.66525729e+00, + 1.26098992e+01, -4.00067984e+00, -7.35377098e-01, 1.50851886e+00, -1.64387393e+00, + -1.62093913e+00, 1.29255558e+00, 2.57817323e+00, 4.40735433e+00, -1.51360322e+00, + 9.76654291e+00, -2.55092007e+00, 1.55729978e+00, 1.22987852e+00, -1.41074169e+00, + 1.68281967e+00, -4.22655643e+00, -7.24433989e+00, -4.51111007e+00, 3.50913442e-01, + 3.92032331e-01, 1.68475390e+00, -1.38236289e+00, 2.16342139e-01, 4.02620945e-01, + 1.58645468e+00, -2.42720323e+00, -2.88063493e+00, -2.43603217e+00, 6.39552310e-01, + -1.23633810e+00, -1.75135112e+00, -1.61746470e+00, 5.66089197e-01, -1.19265022e+00, + -4.45566252e+00, 1.46674521e+00, -1.62711333e+00, -9.79802117e-01, -2.69954658e+00, + 1.00992706e+00, 4.79890537e-01, -2.24175980e+00, 9.71855533e-01, 5.76489712e+00, + -6.64159634e+00, -1.21802309e+01, -1.07858699e-01, 6.62944859e-01, -1.81036037e+00, + -6.50039954e-01, 7.18291481e-01, 9.49026400e-01, 5.46607017e+00, 8.67055746e+00, + 6.89907713e-01, -8.89380803e-01, 7.82411332e-01, 2.33811329e-01, 1.90045957e+00, + -1.43146248e+00, -1.20403128e+00, 5.34999992e+00, -5.37143672e-01, -7.42224616e-01, + 1.14401389e+00, -2.02676171e+00, 7.25767787e-01, 1.38819101e+00, -1.07684631e+00, + 2.11049922e+00, 4.94613560e+00, -2.47629465e+00, -4.81220995e+00, -3.62407656e+00, + -6.21428478e-01, 2.48121999e+00, 4.89964677e-01, 1.94082430e+00, 1.75503578e-01, + 4.64198784e+00, -5.28542267e+00, 1.87467637e+00, -8.36058746e-01, 2.89787801e-01, + -1.50441306e-01, -1.57859573e+00, -4.54015547e-01, -6.22336881e-01, 7.79080554e+00, + 3.85125618e+00, -2.88449914e+00, 4.03841820e-01, 5.42378712e-01, 1.73163636e+00, + -8.49431866e-01, 4.23521295e-01, 3.47485965e-01, -3.84957440e+00, 4.57855459e+00, + 7.17096730e+00, 1.88463955e+00, 1.71916155e+00, 1.69169705e+00, 1.02318947e+00, + -2.43890026e-01, 3.02909344e-01, 5.14240978e+00, -1.23371036e+00, 1.14767194e+00, + -8.54565063e-01, 1.50345811e+00, -5.15548466e-01, 3.10364515e-02, -7.48013507e-01, + 4.36977353e-01, -7.47807746e+00, 6.27566212e+00, 1.87739418e+00, 1.26082206e+00, + -6.17876533e-02, -6.51088895e-01, -1.28752643e+00, 9.40911536e-02, 2.24710031e-01, + -8.60913146e+00, 3.13634246e+00, -5.22275443e+00, -2.00695888e+00, 3.89703254e-01, + 4.69470837e-02, -1.42436128e+00, 1.09837492e+00, -6.95885886e-01, 2.63575791e+00, + 5.20132739e+00, -2.48589051e+00, -1.06453295e+00, -2.03802874e+00, -8.44154407e-01, + -1.90732616e+00, -4.50714573e-01, 8.73494630e-01, -3.09347871e+00, -2.49271916e+00, + 2.55373723e+00, 2.18455516e+00, -2.15960624e+00, -1.35163423e+00, 1.55154456e+00, + -6.16741959e-02, 5.97961238e-01, -1.29709652e-02, 4.03233615e+00, -2.89978788e+00, + -9.23892726e-01, -9.99338701e-02, -8.88772142e-01, -5.08559082e-01, 1.12082844e+00, + 1.23042350e+00, -5.65678688e+00, 3.90278929e+00, 1.58369961e+00, 1.54060894e+00, + 1.20331859e+00, 3.02411668e+00, 1.97412122e+00, -3.35319919e-01, 1.09255916e-01, + 4.76458711e+00, 3.15184088e+00, -1.21439625e+01, 9.39418898e-01, 1.43614538e-01, + -8.71666677e-01, 6.68427271e-02, 1.02012295e+00, 1.82573777e-01, 5.88240113e-01, + 6.44210105e+00, -5.67351310e-01, -1.85489322e+00, -5.02684523e-01, 6.05553861e-02, + 1.76710710e-01, -2.02505386e+00, -1.41940272e+00, 4.15874511e+00, 1.30142366e+01, + 1.40701259e+00, 1.98563976e+00, 1.23602998e+00, -5.64438487e-01, -1.09987142e+00, + -1.95882860e-01, -1.73178964e+00, -5.59174795e+00, 1.36496200e+01, 3.56245544e+00, + -1.66428666e+00, -2.21370979e-01, 6.37547650e-01, 1.27997883e-01, 4.08643296e-01, + -1.21172144e+00, -4.01016350e-01, -5.57590252e+00, -8.90880408e+00, -2.37565308e+00, + -1.80892597e-01, 2.29027900e+00, 1.00249387e+00, 1.82021769e+00, 3.58229650e-01, + 2.07814011e-01, -6.04090738e+00, -4.42046679e+00, 8.80624118e-01, -1.67505974e-01, + 1.26718922e+00, -1.19360672e-01, 2.28569512e+00, 2.55251102e+00, 5.92740372e+00, + 1.76594769e+01, -5.29238134e-01, -2.21418228e+00, 1.96654873e+00, -1.46373470e+00, + 2.73622576e-02, 3.19472484e+00, 1.81582156e+00, 4.49426744e+00, -4.55970942e+00, + 9.33984742e+00, -6.49580638e-01, -2.29683261e-01, 1.31664350e+00, 2.26546880e-01, + 5.56581079e-01, 2.65156828e-01, -2.09260328e+00, -1.05341376e+00, 3.26833856e+00, + 1.04515423e-01, 1.89093396e+00, 7.92865605e-01, -4.98700350e-02, 1.57796084e+00, + -1.28357407e+00, -4.42784886e+00, -2.42557309e+00, 4.26836218e+00, 1.09690039e+00, + 1.18463101e+00, 1.75466877e+00, -1.14322099e+00, 2.43708040e+00, -1.44543158e+00, + -1.60552469e+00, 4.55175566e-01, -9.25674731e-01, -9.22299171e-01, -1.76795613e+00, + -9.32968169e-01, -1.57739533e+00, -1.20199857e-01, -5.55904036e-01, -1.73947725e+00, + -4.24156667e+00, 5.90537105e+00, -2.62989661e-01, -6.26245215e-01, 4.91116432e-01, + 1.09954587e+00, 1.99217319e+00, 9.78589205e-01, 4.23093659e+00, -4.87338632e+00, + -7.01468491e-01, -8.39465960e-01, 5.88624039e-01, 8.01985241e-02, 2.71379766e+00, + -1.00809113e+00, -2.81042990e-01, -1.20095635e+01, -2.29213926e+00, 3.19024062e+00, + -1.58003258e+00, -2.43456480e+00, 9.72091106e-01, 8.17191111e-01, 1.18797677e+00, + 1.71905046e+00 ] +

+ + [ 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, + 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, + 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, + 1.83747161e+03, 1.83747161e+03 ] + + + [ O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H, O, H, H, + O, H, H, O, H, + H, O, H, H, O, + H, H ] + +
+ + [ 1.96756566e+01, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.96756566e+01, + 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.96756566e+01 ] + +
+
diff --git a/examples/clients/mace/getmodel.sh b/examples/clients/mace/getmodel.sh new file mode 100644 index 000000000..31ee1ca0d --- /dev/null +++ b/examples/clients/mace/getmodel.sh @@ -0,0 +1,3 @@ +wget wget https://github.com/ACEsuit/mace-mp/releases/download/mace_mp_0c/mace-small-density-agnesi-stress.model +mv mace-small-density-agnesi-stress.model mace.model + diff --git a/examples/clients/mace/init.xyz b/examples/clients/mace/init.xyz new file mode 120000 index 000000000..0db27c06d --- /dev/null +++ b/examples/clients/mace/init.xyz @@ -0,0 +1 @@ +../../init_files/water_64mols.extxyz \ No newline at end of file diff --git a/examples/clients/mace/input.xml b/examples/clients/mace/input.xml new file mode 100644 index 000000000..72103e52f --- /dev/null +++ b/examples/clients/mace/input.xml @@ -0,0 +1,37 @@ + + + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{megapascal} ] + positions + + + 20000 + + 31415 + + +
driver
+
+ + + init.xyz + 300 + + + + + + + + + 100 + + + 0.50 + + + + 300 + + +
diff --git a/examples/clients/metatensor/README.md b/examples/clients/metatensor/README.md index a5b0f23c2..c36c2a1b0 100644 --- a/examples/clients/metatensor/README.md +++ b/examples/clients/metatensor/README.md @@ -10,14 +10,14 @@ machine learning potentials. ## Installation -The code is compatible with metatensor-torch v0.5, which you can install with +The code is compatible with metatensor-torch v0.6, which you can install with ```bash # install all metatensor packages simultaneously pip install "metatensor[torch]" # install packages individually, with explicit control over the installed versions -pip install "metatensor-torch ==0.5.*" "metatensor-operations ==0.2.*" +pip install "metatensor-torch ==0.6.*" "metatensor-operations ==0.2.*" ``` ## Running the example @@ -42,3 +42,13 @@ The options (after `-o`) are as follow: - `check_consistency` controls whether we should run some extra internal consistency checks about data given to the model and data returned by the model. + +## Running with FFDirect + +It is also possible to run the metatensor PES directly, without the need for an external +driver. To do so, you need to use a `` clause in the input, and specify +the appropriate options as a dictionary. Then, you can simply run + +```bash +i-pi input-direct.xml +``` diff --git a/examples/clients/metatensor/create-model.py b/examples/clients/metatensor/create-model.py index f821b73b2..9b442be83 100644 --- a/examples/clients/metatensor/create-model.py +++ b/examples/clients/metatensor/create-model.py @@ -13,7 +13,7 @@ with_extension=False, ) -model.export("nickel-lj.pt") +model.save("nickel-lj.pt") model = metatensor_lj_test.lennard_jones_model( @@ -25,4 +25,4 @@ energy_unit="kcal/mol", with_extension=True, ) -model.export("nickel-lj-extensions.pt", collect_extensions="collected-extensions/") +model.save("nickel-lj-extensions.pt", collect_extensions="collected-extensions/") diff --git a/examples/clients/metatensor/input-direct.xml b/examples/clients/metatensor/input-direct.xml new file mode 100644 index 000000000..9422cd787 --- /dev/null +++ b/examples/clients/metatensor/input-direct.xml @@ -0,0 +1,47 @@ + + + + [step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, + kinetic_md{electronvolt}, potential{electronvolt}, pressure_md{bar}, + volume{angstrom3}, ensemble_temperature{kelvin}, cell_abcABC] + + x_centroid{angstrom} + + + 1000 +12345 + + + metatensor + {template:nickel.xyz,model:nickel-lj.pt,device:cpu } + + + + + nickel.xyz + 250.0 + + + + + + + + 0.5 + + [ + 4.49e-3, 6.59e-6, 2.79e-4, -8.81e-4, 5.61e-3, + -6.73e-6, 2.08e-9, 1.75e-5, -4.80e-6, 1.03e-5, + -3.59e-4, -1.75e-5, 3.29e-5, 1.24e-4, -2.42e-4, + -2.51e-4, 4.80e-6, -1.24e-4, 6.45e-4, 2.78e-4, + 5.27e-3, -1.03e-5, 2.42e-4, -2.78e-4, 7.49e-3 + ] + + + + + + 250.0 + + + diff --git a/examples/clients/metatensor/nickel-lj.pt b/examples/clients/metatensor/nickel-lj.pt index 9491841ca0bd70e87d0c78be7152f2cf24a0c84a..c9765a0ebbe5dfbe319e8245b90dc8c662ebaca6 100644 GIT binary patch delta 29961 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 I_` clause in the input diff --git a/examples/clients/pes/harmonic-direct/Makefile b/examples/clients/pes/harmonic-direct/Makefile new file mode 100644 index 000000000..7bc94106b --- /dev/null +++ b/examples/clients/pes/harmonic-direct/Makefile @@ -0,0 +1,17 @@ +# Makefile for the "direct" harmonic oscillator example +# +# This file is part of i-PI. +# i-PI Copyright (C) 2014-2015 i-PI developers +# See the "licenses" directory for full license information. + +.PHONY: all clean harmonic +all: harmonic + +IPI:=i-pi + + +harmonic: + $(IPI) input.xml + +clean: + rm -f *simulation.* RESTART EXIT diff --git a/examples/clients/pes/harmonic-direct/init.xyz b/examples/clients/pes/harmonic-direct/init.xyz new file mode 100644 index 000000000..8efa9e7ef --- /dev/null +++ b/examples/clients/pes/harmonic-direct/init.xyz @@ -0,0 +1,3 @@ +1 + +H 0.108 0.000 0.000 diff --git a/examples/clients/pes/harmonic-direct/input.xml b/examples/clients/pes/harmonic-direct/input.xml new file mode 100644 index 000000000..b3b5ba4b6 --- /dev/null +++ b/examples/clients/pes/harmonic-direct/input.xml @@ -0,0 +1,38 @@ + + + [ step, time{picosecond}, conserved{kelvin}, temperature{kelvin}, kinetic_cv{kelvin}, potential{kelvin}, pressure_cv{megapascal}] + positions{angstrom} + forces{piconewton} + + 100 + + 3348 + + + harmonic + { k1:1.0 } + + + + + [ 15., 15.0, 15.0 ] + + init.xyz + 3683.412077 + + + + + + 3683.412077 + + + + + 25 + + 0.003 + + + + diff --git a/examples/clients/pes/harmonic-direct/test_settings.dat b/examples/clients/pes/harmonic-direct/test_settings.dat new file mode 100644 index 000000000..e69de29bb diff --git a/examples/clients/xtb/config.json b/examples/clients/xtb/config.json new file mode 100644 index 000000000..f299cd2e4 --- /dev/null +++ b/examples/clients/xtb/config.json @@ -0,0 +1 @@ +{"method": "GFN2-xTB", "numbers": [6,1,1,1,1], "periodic": false} diff --git a/examples/clients/xtb/run.sh b/examples/clients/xtb/run.sh index 3726ce141..98eea7e55 100644 --- a/examples/clients/xtb/run.sh +++ b/examples/clients/xtb/run.sh @@ -3,5 +3,5 @@ echo "Running i-PI" i-pi input.xml &> log.ipi & sleep 1 echo "Running driver" -i-pi-py_driver -m xtb -o '{"method": "GFN2-xTB", "numbers": [6,1,1,1,1], "periodic": false}' -u -a xtb &> log.xtb +i-pi-py_driver -m xtb -o config.json -u -a xtb &> log.xtb diff --git a/examples/features/ring_polymer_instanton/rates_1D_double_well_with_friction/implicit_bath_pos-dependent/run.sh b/examples/features/ring_polymer_instanton/rates_1D_double_well_with_friction/implicit_bath_pos-dependent/run.sh index 8bc25bc1e..3ee1793d9 100755 --- a/examples/features/ring_polymer_instanton/rates_1D_double_well_with_friction/implicit_bath_pos-dependent/run.sh +++ b/examples/features/ring_polymer_instanton/rates_1D_double_well_with_friction/implicit_bath_pos-dependent/run.sh @@ -5,9 +5,9 @@ wc=500 V0=2085 mass=1837.36223469 - x0=0 epsilon=-1.0 delta=0 + epsilon2=0 deltaQ=1 address=localhost @@ -19,4 +19,9 @@ sleep 3 #Launch driver - i-pi-driver-py -m ${model} -o ${wb},${V0},${mass},${x0},${eta},${epsilon},${delta},${deltaQ} -u -a ${address} + #i-pi-driver-py -m ${model} -o ${wb},${V0},${mass},${x0},${eta},${epsilon},${delta},${deltaQ} -u -a ${address} + arg="w_b=${wb},v0=${V0},m=${mass},delta=${delta},eta0=${eta},eps1=${epsilon},eps2=${epsilon2},deltaQ=${deltaQ}" + + echo ${arg} +# def __init__(self,w_b=None,v0=None,m=None,eta0=None,eps1=None,eps2=None,delta=None,deltaQ=None, *args, **kwargs): + i-pi-driver-py -m ${model} -o ${arg} -u -a ${address} diff --git a/examples/init_files/water_64mols.extxyz b/examples/init_files/water_64mols.extxyz new file mode 100644 index 000000000..7e35fe97f --- /dev/null +++ b/examples/init_files/water_64mols.extxyz @@ -0,0 +1,194 @@ +192 +Lattice="10.4119090601988 0 0 0 10.4119090601988 0 0 0 10.4119090601988" +O 11.18136 -7.24116 6.42199 +H 11.31672 -7.89411 5.71998 +H 11.94205 -7.06097 7.01033 +O 2.78582 1.60883 1.56485 +H 2.45814 1.98676 2.52844 +H 3.72449 1.60021 1.79886 +O 4.06425 1.21834 6.13650 +H 4.52259 0.84151 5.38020 +H 3.73582 0.62974 6.86168 +O -5.85212 -1.78980 -1.47238 +H -5.90795 -2.64483 -2.11048 +H -6.81342 -1.58626 -1.68821 +O -0.69190 1.48298 4.64653 +H -0.57700 1.71944 5.58467 +H -1.16810 2.29631 4.29351 +O 9.78623 -1.22461 5.88911 +H 9.05533 -0.91721 5.33231 +H 10.59603 -1.00085 5.39957 +O 1.78731 -5.40285 -2.77723 +H 2.33162 -5.12910 -2.00467 +H 0.89681 -5.12748 -2.70535 +O -2.75590 -8.62956 -0.10520 +H -2.53979 -8.69428 -1.07891 +H -2.75324 -7.69016 0.12631 +O 9.87767 -4.00367 7.00969 +H 9.30537 -3.91345 7.71858 +H 9.86640 -3.07612 6.67277 +O 1.36270 2.71836 3.60327 +H 0.90987 3.43987 3.16458 +H 0.69390 2.17126 4.04330 +O 7.35720 -5.27057 -1.72224 +H 8.03476 -6.10104 -1.79227 +H 6.40744 -5.61367 -2.01308 +O 7.59285 -3.91299 1.89032 +H 6.71605 -4.09193 1.42394 +H 7.44293 -4.07392 2.84248 +O -0.53502 -7.32429 -1.57639 +H 0.08940 -6.74166 -2.03905 +H -0.92479 -7.79351 -2.35343 +O 6.33684 6.38743 -5.76835 +H 5.27875 6.21603 -5.54541 +H 6.28403 7.30291 -6.28440 +O 4.69882 -1.31516 6.09464 +H 4.31123 -1.15051 5.12558 +H 4.03848 -1.19721 6.76146 +O 3.70821 -4.04859 4.85959 +H 3.88830 -4.26209 3.90588 +H 3.41156 -4.85543 5.33543 +O 4.25159 -7.25513 3.40025 +H 3.80863 -6.84649 4.18355 +H 4.58665 -8.16468 3.69969 +O 2.85185 -0.22288 -0.08384 +H 2.30198 0.32795 0.57462 +H 3.49964 0.50183 -0.31096 +O 0.71578 0.75467 -1.03772 +H 0.48930 1.73621 -0.79676 +H -0.11147 0.47379 -1.50236 +O 3.86173 -5.86884 0.83708 +H 3.02686 -6.20624 0.38164 +H 3.60762 -6.18672 1.72461 +O -2.65909 1.61105 2.65709 +H -2.81796 1.41394 1.66795 +H -2.90099 2.59787 2.79689 +O 8.58320 -0.93140 3.69116 +H 8.51457 -1.71811 3.08024 +H 9.40919 -0.52395 3.22850 +O 2.00819 -1.77043 1.77406 +H 1.71599 -2.29317 2.51221 +H 2.88786 -2.15737 1.53734 +O -1.21196 4.38114 0.57505 +H -1.88725 5.08448 0.43844 +H -1.31330 3.95262 -0.28572 +O 6.62006 -6.28562 3.52156 +H 6.70557 -5.37221 4.07543 +H 5.67024 -6.53243 3.51712 +O 4.55162 -4.02218 2.45618 +H 4.78639 -3.09848 2.15965 +H 3.76492 -4.29938 1.84435 +O -1.58811 -3.45511 4.54425 +H -2.07874 -3.09246 5.28050 +H -0.94080 -4.03592 4.85498 +O 0.63844 5.84407 -0.58258 +H 0.33058 6.12957 0.29606 +H 1.44170 6.38939 -0.65771 +O 13.89937 3.85311 -4.62853 +H 13.58234 2.94223 -4.24959 +H 14.94280 3.89592 -4.43418 +O 1.45155 -9.85714 -4.86694 +H 2.35131 -9.93790 -5.24325 +H 1.00248 -10.03331 -5.77904 +O 2.10425 -2.89321 -3.62158 +H 1.47224 -2.48362 -2.86866 +H 2.18045 -2.09609 -4.16680 +O 5.30876 -9.33887 2.23872 +H 6.09707 -9.59732 2.71391 +H 5.36099 -10.01325 1.53512 +O 9.39110 -6.28070 3.25110 +H 8.98146 -6.14406 4.06255 +H 8.78207 -5.97081 2.67205 +O 6.25165 -8.48610 -5.29389 +H 6.81062 -9.32378 -5.41835 +H 6.47210 -7.92782 -5.96594 +O -3.15468 -3.34260 7.11828 +H -2.83364 -4.08200 7.65508 +H -3.63428 -3.76480 6.37405 +O 5.85238 -8.41894 -2.66855 +H 5.35988 -8.45234 -1.87962 +H 5.37565 -8.88515 -3.35133 +O -4.47590 -1.40335 3.66515 +H -3.56824 -1.01032 3.81598 +H -4.73962 -1.16543 2.71828 +O -0.20781 -8.30570 1.23188 +H -0.68347 -8.80535 0.48392 +H -0.61830 -7.73467 1.86794 +O 4.95749 4.52203 -1.53048 +H 4.64077 5.16432 -2.29082 +H 4.44398 3.75315 -1.76902 +O -1.18170 -0.41798 -12.61310 +H -0.94931 -0.26291 -13.63669 +H -1.43151 -1.36626 -12.50848 +O 4.37654 -3.87984 -3.11203 +H 3.36699 -3.74856 -3.32174 +H 4.73860 -3.44669 -3.96314 +O 1.47263 -5.10769 2.05248 +H 1.54376 -5.28591 3.06801 +H 0.73852 -4.40355 2.11733 +O 0.57171 0.08269 2.96703 +H 1.33511 -0.28899 2.60400 +H 0.39918 0.95384 2.48030 +O 4.82014 1.75266 -0.26475 +H 4.07740 2.26716 -0.04860 +H 5.55096 2.23000 0.36991 +O 1.26659 -4.90102 -5.18088 +H 0.71571 -5.68172 -5.03880 +H 1.78228 -4.86123 -4.40607 +O -7.57618 -3.41768 -0.23405 +H -7.16860 -4.28058 0.15792 +H -6.80151 -2.90991 -0.56491 +O 6.24921 -6.16862 -4.16104 +H 7.07600 -6.28218 -4.74638 +H 6.36108 -6.98816 -3.57694 +O -1.82911 1.56633 -3.40176 +H -2.45012 2.25119 -3.81374 +H -2.40852 0.75307 -3.27997 +O 1.71669 3.71840 -0.28443 +H 1.27373 4.74944 -0.21805 +H 1.17547 3.28611 0.29122 +O 8.46853 -3.09340 9.86116 +H 7.80954 -2.56880 10.22497 +H 9.34209 -2.47122 9.85476 +O 3.21682 -7.79589 -1.99707 +H 2.52837 -7.35831 -1.41162 +H 2.92784 -8.70634 -2.22468 +O -3.96971 -0.48422 -0.87321 +H -4.71266 -0.93801 -1.27585 +H -3.40046 0.07288 -1.44726 +O 2.58880 0.07464 -2.64410 +H 1.88211 0.38311 -3.18472 +H 1.99881 -0.03955 -1.64188 +O -3.19736 -0.62180 -3.87710 +H -2.95370 -1.51924 -3.42177 +H -4.00833 -0.93762 -4.45389 +O 4.86152 -1.55101 1.42393 +H 5.64113 -1.93118 0.83995 +H 4.42948 -1.03684 0.61612 +O 0.96100 -1.84820 -1.40869 +H 0.12950 -1.31463 -1.51719 +H 1.27479 -1.83709 -0.53915 +O -1.55890 -6.13475 5.77682 +H -0.95828 -6.74283 6.34991 +H -1.41913 -5.28777 6.20053 +O 6.38516 3.66860 0.78566 +H 6.58667 4.01604 1.64321 +H 5.42592 3.87325 0.63911 +O 7.59422 -0.83492 1.07614 +H 7.07118 -1.52087 1.49718 +H 7.19591 -0.75122 0.17345 +O 3.47168 -0.43168 3.60482 +H 3.09120 -1.22210 3.21392 +H 3.70663 0.14389 2.92538 +O -0.36322 -3.35602 1.73591 +H -1.32945 -3.51529 1.69406 +H -0.17779 -2.37533 1.36604 +O 5.81550 6.35896 10.60725 +H 5.04874 5.77496 10.58989 +H 6.38013 6.03712 9.91339 +O 1.14085 -12.62231 4.16390 +H 1.78212 -13.35146 4.36508 +H 0.23752 -13.05745 4.08631 +O -0.35190 -11.38652 0.43131 +H -1.00022 -11.03186 1.01782 +H 0.38267 -10.78230 0.46692 diff --git a/ipi/__init__.py b/ipi/__init__.py index 1b337369a..196aa6995 100644 --- a/ipi/__init__.py +++ b/ipi/__init__.py @@ -12,6 +12,7 @@ "inputs", "interfaces", "utils", + "pes", "ipi_global_settings", "install_driver", "read_output", diff --git a/ipi/engine/forcefields.py b/ipi/engine/forcefields.py index 827d92b6a..d764902b6 100644 --- a/ipi/engine/forcefields.py +++ b/ipi/engine/forcefields.py @@ -23,11 +23,9 @@ from ipi.utils.io import read_file from ipi.utils.units import unit_to_internal from ipi.utils.distance import vector_separation +from ipi.pes import __drivers__ -try: - import plumed -except ImportError: - plumed = None +plumed = None class ForceRequest(dict): @@ -391,6 +389,58 @@ def evaluate(self, request): request["status"] = "Done" +class FFDirect(FFEval): + def __init__( + self, + latency=1.0, + offset=0.0, + name="", + pars=None, + dopbc=False, + active=np.array([-1]), + threaded=False, + pes="dummy", + ): + """Initialises FFDirect. + + Args: + latency: The number of seconds the socket will wait before updating + the client list. + offset: A constant offset subtracted from the energy value given by the + client. + name: The name of the forcefield. + pars: A dictionary used to initialize the forcefield, if required. + Of the form {'name1': value1, 'name2': value2, ... }. + dopbc: Decides whether or not to apply the periodic boundary conditions + before sending the positions to the client code. + active: Indexes of active atoms in this forcefield + + """ + + super().__init__(latency, offset, name, pars, dopbc, active, threaded) + + self.pes = pes + try: + self.driver = __drivers__[self.pes](verbose=verbosity.high, **pars) + except ImportError: + # specific errors have already been triggered + raise + except Exception as err: + print(f"Error setting up PES mode {self.pes}") + print(__drivers__[self.pes].__doc__) + print("Error trace: ") + raise err + + def evaluate(self, request): + results = list(self.driver(request["cell"][0], request["pos"].reshape(-1, 3))) + + # ensure forces and virial have the correct shape to fit the results + results[1] = results[1].reshape(-1) + results[2] = results[2].reshape(3, 3) + request["result"] = results + request["status"] = "Done" + + class FFLennardJones(FFEval): """Basic fully pythonic force provider. @@ -409,12 +459,14 @@ class FFLennardJones(FFEval): def __init__( self, - latency=1.0e-3, + latency=1.0, offset=0.0, name="", pars=None, - dopbc=False, - threaded=False, + dopbc=True, + active=np.array([-1]), + threaded=True, + interface=None, ): """Initialises FFLennardJones. @@ -430,7 +482,7 @@ def __init__( # a socket to the communication library is created or linked super(FFLennardJones, self).__init__( - latency, offset, name, pars, dopbc=dopbc, threaded=threaded + latency, offset, name, pars, dopbc=dopbc, threaded=threaded, active=active ) self.epsfour = float(self.pars["eps"]) * 4 self.sixepsfour = 6 * self.epsfour @@ -678,8 +730,11 @@ def __init__( pars: Optional dictionary, giving the parameters needed by the driver. """ + global plumed # a socket to the communication library is created or linked - if plumed is None: + try: + import plumed + except ImportError: raise ImportError( "Cannot find plumed libraries to link to a FFPlumed object/" ) @@ -863,6 +918,14 @@ def __init__( """ + warning( + """ + is deprecated and might be removed in a future release of i-PI. + If you are interested in using it, please help port it to the PES + infrastructure. + """ + ) + from yaff import System, ForceField, log import codecs import locale @@ -955,6 +1018,14 @@ def __init__( """ + warning( + """ + is deprecated and might be removed in a future release of i-PI. + If you are interested in using it, please help port it to the PES + infrastructure. + """ + ) + # a socket to the communication library is created or linked super(FFsGDML, self).__init__( latency, offset, name, pars, dopbc, threaded=threaded diff --git a/ipi/inputs/forcefields.py b/ipi/inputs/forcefields.py index a8fcd6467..f3b8e0757 100644 --- a/ipi/inputs/forcefields.py +++ b/ipi/inputs/forcefields.py @@ -11,6 +11,7 @@ from ipi.engine.forcefields import ( ForceField, FFSocket, + FFDirect, FFLennardJones, FFDebye, FFPlumed, @@ -21,6 +22,7 @@ FFCavPhSocket, ) from ipi.interfaces.sockets import InterfaceSocket +from ipi.pes import __drivers__ import ipi.engine.initializer from ipi.inputs.initializer import * from ipi.utils.inputvalue import * @@ -28,6 +30,7 @@ __all__ = [ "InputFFSocket", + "InputFFDirect", "InputFFLennardJones", "InputFFDebye", "InputFFPlumed", @@ -135,6 +138,8 @@ def store(self, ff): self.activelist.store(ff.active) self.threaded.store(ff.threaded) + _FFCLASS = ForceField + def fetch(self): """Creates a ForceField object. @@ -144,7 +149,7 @@ def fetch(self): super(InputForceField, self).fetch() - return ForceField( + return self._FFCLASS( pars=self.parameters.fetch(), name=self.name.fetch(), latency=self.latency.fetch(), @@ -336,37 +341,58 @@ def check(self): raise ValueError("Negative timeout parameter specified.") -class InputFFLennardJones(InputForceField): +class InputFFDirect(InputForceField): + fields = { + "pes": ( + InputValue, + { + "dtype": str, + "default": "dummy", + "options": list(__drivers__.keys()), + "help": "Type of PES that should be used to evaluate the forcefield", + }, + ), + } + fields.update(InputForceField.fields) + attribs = {} attribs.update(InputForceField.attribs) - default_help = """Simple, internal LJ evaluator without cutoff, neighbour lists or minimal image convention. - Expects standard LJ parameters, e.g. { eps: 0.1, sigma: 1.0 }. """ - default_label = "FFLJ" + default_help = """ Direct potential that evaluates forces through a Python + call, using PES providers from a list of possible external codes. The available + PES interfaces are listed into the `ipi/pes` folder, and are the same available + for the Python driver. The `` field should contain a dictionary + of the specific option of the chosen PES. + """ + default_label = "FFDirect" def store(self, ff): - super(InputFFLennardJones, self).store(ff) + super().store(ff) + self.pes.store(ff.pes) def fetch(self): - super(InputFFLennardJones, self).fetch() + super().fetch() - return FFLennardJones( + return FFDirect( pars=self.parameters.fetch(), name=self.name.fetch(), latency=self.latency.fetch(), offset=self.offset.fetch(), dopbc=self.pbc.fetch(), threaded=self.threaded.fetch(), + pes=self.pes.fetch(), ) - if self.slots.fetch() < 1 or self.slots.fetch() > 5: - raise ValueError( - "Slot number " + str(self.slots.fetch()) + " out of acceptable range." - ) - if self.latency.fetch() < 0: - raise ValueError("Negative latency parameter specified.") - if self.timeout.fetch() < 0.0: - raise ValueError("Negative timeout parameter specified.") + +class InputFFLennardJones(InputForceField): + attribs = {} + attribs.update(InputForceField.attribs) + + default_help = """Simple, internal LJ evaluator without cutoff, neighbour lists or minimal image convention. + Expects standard LJ parameters, e.g. { eps: 0.1, sigma: 1.0 }. """ + default_label = "FFLJ" + + _FFCLASS = FFLennardJones class InputFFdmd(InputForceField): @@ -445,7 +471,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. " - "Implemented options are: 'atomic_unit', 'ev/ang\^2'", + r"Implemented options are: 'atomic_unit', 'ev/ang^2'", "dimension": "hessian", }, ), @@ -747,6 +773,7 @@ class InputFFCommittee(InputForceField): dynamic = { "ffsocket": (InputFFSocket, {"help": InputFFSocket.default_help}), + "ffdirect": (InputFFDirect, {"help": InputFFDirect.default_help}), "fflj": (InputFFLennardJones, {"help": InputFFLennardJones.default_help}), "ffdebye": (InputFFDebye, {"help": InputFFDebye.default_help}), "ffplumed": (InputFFPlumed, {"help": InputFFPlumed.default_help}), diff --git a/ipi/inputs/simulation.py b/ipi/inputs/simulation.py index 56b8666a3..796316d59 100644 --- a/ipi/inputs/simulation.py +++ b/ipi/inputs/simulation.py @@ -159,6 +159,10 @@ class InputSimulation(Input): iforcefields.InputFFSocket, {"help": iforcefields.InputFFSocket.default_help}, ), + "ffdirect": ( + iforcefields.InputFFDirect, + {"help": iforcefields.InputFFDirect.default_help}, + ), "fflj": ( iforcefields.InputFFLennardJones, {"help": iforcefields.InputFFLennardJones.default_help}, @@ -246,6 +250,10 @@ def store(self, simul): _iobj = iforcefields.InputFFSocket() _iobj.store(_obj) self.extra[_ii] = ("ffsocket", _iobj) + elif isinstance(_obj, eforcefields.FFDirect): + _iobj = iforcefields.InputFFDirect() + _iobj.store(_obj) + self.extra[_ii] = ("ffdirect", _iobj) elif isinstance(_obj, eforcefields.FFLennardJones): _iobj = iforcefields.InputFFLennardJones() _iobj.store(_obj) @@ -322,17 +330,18 @@ def fetch(self): # of system objects with the desired properties set # automatically to many values. syslist += v.fetch() - elif ( - k == "ffsocket" - or k == "fflj" - or k == "ffdebye" - or k == "ffdmd" - or k == "ffplumed" - or k == "ffsgdml" - or k == "ffyaff" - or k == "ffcommittee" - or k == "ffcavphsocket" - ): + elif k in [ + "ffsocket", + "ffdirect", + "fflj", + "ffdebye", + "ffdmd", + "ffplumed", + "ffsgdml", + "ffyaff", + "ffcommittee", + "ffcavphsocket", + ]: new_ff = v.fetch() if k == "ffsocket": # overrides ffsocket prefix diff --git a/drivers/py/pes/__init__.py b/ipi/pes/__init__.py similarity index 100% rename from drivers/py/pes/__init__.py rename to ipi/pes/__init__.py diff --git a/drivers/py/pes/ase.py b/ipi/pes/ase.py similarity index 70% rename from drivers/py/pes/ase.py rename to ipi/pes/ase.py index 7d5597a52..567c4e4e7 100644 --- a/drivers/py/pes/ase.py +++ b/ipi/pes/ase.py @@ -1,48 +1,45 @@ """Interface with ASE calculators""" -import sys import numpy as np from .dummy import Dummy_driver from ipi.utils.units import unit_to_internal, unit_to_user from ipi.utils.messages import warning -try: - from ase.io import read -except ImportError: - warning("Could not find or import the ASE module") - MetatensorCalculator = None + +read = None __DRIVER_NAME__ = "ase" __DRIVER_CLASS__ = "ASEDriver" -ERROR_MSG = """ -This ASE driver requires specification of and ASE calculator -and an ASE-readable template file that describes the chemical makeup of the structure. - -Example: python driver.py -m ase -u -o template.xyz,model_parameters -""" - class ASEDriver(Dummy_driver): - """Abstract base class using an arbitrary ASE calculator as i-pi driver""" - - def __init__(self, args=None, verbose=False, error_msg=ERROR_MSG): - super().__init__(args, verbose, error_msg=error_msg) - - def check_arguments(self): + """ + Base class using an arbitrary ASE calculator as i-pi driver. + Should not be called directly as it does not set a calculator. + + Parameters: + :param verbose: bool, whether to print verbose output + :param template: string, ASE-readable filename where to get the structure data from + """ + + def __init__(self, template, *args, **kwargs): + global read + try: + from ase.io import read + except ImportError: + warning("Could not find or import the ASE module") + + self.template = template + super().__init__(*args, **kwargs) + + def check_parameters(self): """Check the arguments required to run the driver This loads the potential and atoms template in metatensor """ - if len(self.args) >= 1: - self.template = self.args[0] - else: - sys.exit(self.error_msg) - self.template_ase = read(self.template) - self.ase_calculator = None def __call__(self, cell, pos): @@ -63,7 +60,9 @@ def __call__(self, cell, pos): structure.calc = self.ase_calculator # Do the actual calculation - properties = structure.get_properties(["energy", "forces", "stress"]) + self.ase_calculator.calculate(atoms=structure) + properties = self.ase_calculator.results + pot = properties["energy"] force = properties["forces"] stress = properties["stress"] diff --git a/drivers/py/pes/bath.py b/ipi/pes/bath.py similarity index 79% rename from drivers/py/pes/bath.py rename to ipi/pes/bath.py index f4d62d95e..c49c63de6 100644 --- a/drivers/py/pes/bath.py +++ b/ipi/pes/bath.py @@ -2,22 +2,29 @@ import numpy as np -__DRIVER_NAME__ = None -__DRIVER_CLASS__ = "driver_tools" +from ipi.utils.messages import verbosity, warning + +__DRIVER_NAME__ = "bath" +__DRIVER_CLASS__ = "Harmonic_Bath_explicit" class Harmonic_Bath_explicit(object): """Explicit description of an Harmonic bath""" - def __init__(self, nbath, parameters): + def __init__(self, nbath, m, eta0, eps1, eps2, deltaQ, w_c, *args, **kwargs): + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) + super().__init__(*args, **kwargs) + self.nbath = nbath - self.m = parameters["m"] - # self.delta = parameters["delta"] - self.eta0 = parameters["eta0"] - self.eps1 = parameters["eps1"] - self.eps2 = parameters["eps2"] - self.deltaQ = parameters["deltaQ"] - self.w_c = parameters["w_c"] + self.m = m + self.eta0 = eta0 + self.eps1 = eps1 + self.eps2 = eps2 + self.deltaQ = deltaQ + self.w_c = w_c self.set_ci_and_wi() diff --git a/drivers/py/pes/doubledoublewell.py b/ipi/pes/doubledoublewell.py similarity index 71% rename from drivers/py/pes/doubledoublewell.py rename to ipi/pes/doubledoublewell.py index 94b5c90e5..e4f633639 100644 --- a/drivers/py/pes/doubledoublewell.py +++ b/ipi/pes/doubledoublewell.py @@ -28,7 +28,7 @@ class DDW_with_explicit_bath_driver(Dummy_driver): - """Adds to a double-double well (DDW) potential coupled to two (explicit) harmonic baths. + r"""Adds to a double-double well (DDW) potential coupled to two (explicit) harmonic baths. pos[0:2] = DDW pos[2:n//2+1] = bath1 pos[n//2+1:] = bath2 @@ -47,49 +47,61 @@ class DDW_with_explicit_bath_driver(Dummy_driver): ! and ! ! DDW(q1,q2) = DW(q1) + DW(q2) + C(q1q2)^2 - """ - def __init__(self, args=None, verbose=None): - self.error_msg = """\nDW+explicit_bath driver expects 11 arguments.\n - Example: python driver.py -m DoubleWell_with_explicit_bath -o wb1 (cm^-1) V1 (cm^-1) wb2 (cm^-1) V2 (cm^-1) coupling(au) mass delta(\AA) eta0 eps1 eps2 deltaQ omega_c(cm^-1) \n - python driver.py -m DoubleWell -o 500,2085,500,2085,0.1,1837,0.00,1,0,0,1,500\n""" - super(DDW_with_explicit_bath_driver, self).__init__( - args, error_msg=self.error_msg - ) - self.init = False + DW+explicit_bath driver expects 11 arguments.\n + Example: + i-pi-py_driver.py -m DoubleWell_with_explicit_bath -o wb1 (cm^-1) V1 (cm^-1) wb2 (cm^-1) V2 (cm^-1) coupling(au) mass delta(\AA) eta0 eps1 eps2 deltaQ omega_c(cm^-1) \n + i-pi-py_driver.py -m DoubleWell -o 500,2085,500,2085,0.1,1837,0.00,1,0,0,1,500 + """ - def check_arguments(self): - """Function that checks the arguments required to run the driver""" + def __init__( + self, + wb1=None, + v1=None, + wb2=None, + v2=None, + C=None, + m=None, + delta=None, + eta0=None, + eps1=None, + eps2=None, + deltaQ=None, + w_c=None, + *args, + **kwargs + ): + self.init = False try: - param = list(map(float, self.args)) - assert len(param) == 12 - wb1 = param[0] * invcm2au - v1 = param[1] * invcm2au - wb2 = param[2] * invcm2au - v2 = param[3] * invcm2au - self.C = param[4] - self.m = param[5] - self.delta = param[6] * A2au + wb1 = wb1 * invcm2au + v1 = v1 * invcm2au + wb2 = wb2 * invcm2au + v2 = v2 * invcm2au + self.C = C + self.m = m + self.delta = delta * A2au self.bath_parameters = {} self.bath_parameters["m"] = self.m + self.bath_parameters["eta0"] = eta0 + self.bath_parameters["eps1"] = eps1 + self.bath_parameters["eps2"] = eps2 + self.bath_parameters["deltaQ"] = deltaQ + self.bath_parameters["w_c"] = w_c * invcm2au self.bath_parameters["delta"] = self.delta - self.bath_parameters["eta0"] = param[7] - self.bath_parameters["eps1"] = param[8] - self.bath_parameters["eps2"] = param[9] - self.bath_parameters["deltaQ"] = param[10] - self.bath_parameters["w_c"] = param[11] * invcm2au + # def __init__(self, nbath, m, eta0, eps1, eps2, deltaQ, w_c, *args, **kwargs): except: print("Received arguments:") - sys.exit(self.error_msg) + sys.exit(self.__doc__) self.A1 = -0.5 * self.m * (wb1) ** 2 self.B1 = ((self.m**2) * (wb1) ** 4) / (16 * v1) self.A2 = -0.5 * self.m * (wb2) ** 2 self.B2 = ((self.m**2) * (wb2) ** 4) / (16 * v2) + super().__init__(*args, **kwargs) def __call__(self, cell, pos): """DoubleWell potential""" diff --git a/drivers/py/pes/doublewell.py b/ipi/pes/doublewell.py similarity index 73% rename from drivers/py/pes/doublewell.py rename to ipi/pes/doublewell.py index b75dad204..10987414f 100644 --- a/drivers/py/pes/doublewell.py +++ b/ipi/pes/doublewell.py @@ -28,15 +28,14 @@ class DoubleWell_driver(Dummy_driver): - def __init__(self, args=None, verbose=None): - self.error_msg = """\nDW driver accepts 0 or 4 arguments.\nExample: python driver.py -m DoubleWell -o omega_b (cm^-1) V0 (cm^-1) mass(a.u) delta(angs) \n + """ + DW driver accepts 0 or 4 arguments.\nExample: python driver.py -m DoubleWell -o omega_b (cm^-1) V0 (cm^-1) mass(a.u) delta(angs) \n python driver.py -m DoubleWell -o 500,2085,1837,0.00 \n""" - super(DoubleWell_driver, self).__init__(args, error_msg=self.error_msg) - def check_arguments(self): - """Function that checks the arguments required to run the driver""" - self.k = 1837.36223469 * (3800.0 / 219323.0) ** 2 - if self.args == "": + def __init__(self, w_b=None, v0=None, m=None, delta=None, *args, **kwargs): + + if w_b == None or v0 == None or m == None or delta == None: + print("using default values from Craig-JCP-2005") # We used Craig's values (J. Chem. Phys. 122, 084106, 2005) w_b = 500 * invcm2au # Tc = 115K v0 = 2085 * invcm2au @@ -44,17 +43,16 @@ def check_arguments(self): self.delta = 00 else: try: - param = list(map(float, self.args)) - assert len(param) == 4 - w_b = param[0] * invcm2au - v0 = param[1] * invcm2au - m = param[2] - self.delta = param[3] * A2au + w_b = w_b * invcm2au + v0 = v0 * invcm2au + self.delta = delta * A2au except: - sys.exit(self.error_msg) + sys.exit(self.__doc__) + self.k = 1837.36223469 * (3800.0 / 219323.0) ** 2 self.A = -0.5 * m * (w_b) ** 2 self.B = ((m**2) * (w_b) ** 4) / (16 * v0) + super().__init__(*args, **kwargs) def __call__(self, cell, pos): """DoubleWell potential l""" diff --git a/drivers/py/pes/doublewell_with_bath.py b/ipi/pes/doublewell_with_bath.py similarity index 65% rename from drivers/py/pes/doublewell_with_bath.py rename to ipi/pes/doublewell_with_bath.py index d5b8567f2..a79354f8e 100644 --- a/drivers/py/pes/doublewell_with_bath.py +++ b/ipi/pes/doublewell_with_bath.py @@ -30,50 +30,57 @@ class DoubleWell_with_explicit_bath_driver(Dummy_driver): - """Adds to the double well potential an explicit harmonic bath. First dof correpond to the DW, the rest to the bath discretization + r"""Adds to the double well potential an explicit harmonic bath. First dof correpond to the DW, the rest to the bath discretization ! V(q,x1,..,xn) = DW(q) + ! sum_2^(3*N) [ 0.5 m w_i^2(q - (c_i s(q))/(m w_i)^2)^2 ] ! s(q) = q *sd(q) ! sd(q) = [1+eps1*exp( q^2 / (2 deltaQ^2) ) ] + eps2 tanh(q/deltaQ) ! If eps1=eps2=0 then sd(q) =1 and s(q) = q --->Spatially independent bath - """ - def __init__(self, args=None, verbose=None): - self.error_msg = """\nDW+explicit_bath driver expects 9 arguments.\n + DW+explicit_bath driver expects 9 arguments. Example: python driver.py -m DoubleWell_with_explicit_bath -o omega_b (cm^-1) V0 (cm^-1) mass delta(\AA) eta0 eps1 eps2 deltaQ omega_c(cm^-1) \n - python driver.py -m DoubleWell -o 500,2085,1837,0.00,1,0,0,1,500\n""" - super(DoubleWell_with_explicit_bath_driver, self).__init__( - args, error_msg=self.error_msg - ) + python driver.py -m DoubleWell -o 500,2085,1837,0.00,1,0,0,1,500 + """ - self.init = False + def __init__( + self, + w_b=None, + v0=None, + m=None, + delta=None, + eta0=None, + eps1=None, + eps2=None, + deltaQ=None, + w_c=None, + *args, + **kwargs + ): - def check_arguments(self): - """Function that checks the arguments required to run the driver""" + self.init = False try: - param = list(map(float, self.args)) - assert len(param) == 9 - w_b = param[0] * invcm2au - v0 = param[1] * invcm2au - self.m = param[2] - self.delta = param[3] * A2au + w_b = w_b * invcm2au + v0 = v0 * invcm2au + self.m = m + self.delta = delta * A2au self.bath_parameters = {} - self.bath_parameters["m"] = param[2] + self.bath_parameters["m"] = self.m - self.bath_parameters["eta0"] = param[4] - self.bath_parameters["eps1"] = param[5] - self.bath_parameters["eps2"] = param[6] - self.bath_parameters["deltaQ"] = param[7] - self.bath_parameters["w_c"] = param[8] * invcm2au + self.bath_parameters["eta0"] = eta0 + self.bath_parameters["eps1"] = eps1 + self.bath_parameters["eps2"] = eps2 + self.bath_parameters["deltaQ"] = deltaQ + self.bath_parameters["w_c"] = w_c * invcm2au except: - sys.exit(self.error_msg) + sys.exit(self.__doc__) self.A = -0.5 * self.m * (w_b) ** 2 self.B = ((self.m**2) * (w_b) ** 4) / (16 * v0) + super().__init__(*args, **kwargs) def __call__(self, cell, pos): """DoubleWell potential""" @@ -85,7 +92,7 @@ def __call__(self, cell, pos): if not self.init: self.nbath = np.size(x) - self.bath = Harmonic_Bath_explicit(self.nbath, self.bath_parameters) + self.bath = Harmonic_Bath_explicit(self.nbath, **self.bath_parameters) # Harmonic bath pot, fq, fx = self.bath(q, x) diff --git a/drivers/py/pes/doublewell_with_friction.py b/ipi/pes/doublewell_with_friction.py similarity index 71% rename from drivers/py/pes/doublewell_with_friction.py rename to ipi/pes/doublewell_with_friction.py index dfacdb7b8..d456cfb43 100644 --- a/drivers/py/pes/doublewell_with_friction.py +++ b/ipi/pes/doublewell_with_friction.py @@ -1,7 +1,5 @@ """ Harmonic potential """ -import sys - try: from .doublewell import DoubleWell_driver except: @@ -10,6 +8,7 @@ import numpy as np from ipi.utils import units import json +import sys __DRIVER_NAME__ = "DW_friction" @@ -29,42 +28,48 @@ class DoubleWell_with_friction_driver(DoubleWell_driver): - """Adds to the double well potential the calculation of the friction tensor. + r"""Adds to the double well potential the calculation of the friction tensor. friction(q) = eta0 [\partial sd(q) \partial q ]^2 with q = position, and sd(q) = [1+eps1 exp( (q-0)^2 / (2deltaQ^2) ) ] + eps2 tanh(q/deltaQ) - """ - def __init__(self, args=None, verbose=None): - self.error_msg = """\nDW+fric driver expects 8 arguments.\n - Example: python driver.py -m DoubleWell_with_fric -o omega_b (cm^-1) V0 (cm^-1) mass delta(\AA) eta0 eps1 eps2 deltaQ \n - python driver.py -m DoubleWell -o 500,2085,1837,0.00,1,0,0,1\n""" - self.args = args.split(",") - self.verbose = verbose - self.check_arguments() + DW+fric driver expects 8 arguments. + Example: python driver.py -m DoubleWell_with_fric -o omega_b (cm^-1) V0 (cm^-1) mass delta(\AA) eta0 eps1 eps2 deltaQ + python driver.py -m DoubleWell -o 500,2085,1837,0.00,1,0,0,1 + """ - def check_arguments(self): - """Function that checks the arguments required to run the driver""" + def __init__( + self, + w_b=None, + v0=None, + m=None, + eta0=None, + eps1=None, + eps2=None, + delta=None, + deltaQ=None, + *args, + **kwargs + ): - self.k = 1837.36223469 * (3800.0 / 219323.0) ** 2 try: - param = list(map(float, self.args)) - assert len(param) == 8 - w_b = param[0] * invcm2au - v0 = param[1] * invcm2au - m = param[2] - self.delta = param[3] * A2au - self.eta0 = param[4] - self.eps1 = param[5] - self.eps2 = param[6] - self.deltaQ = param[7] + w_b = w_b * invcm2au + v0 = v0 * invcm2au + self.delta = delta * A2au + self.eta0 = eta0 + self.eps1 = eps1 + self.eps2 = eps2 + self.deltaQ = deltaQ + self.k = 1837.36223469 * (3800.0 / 219323.0) ** 2 + self.A = -0.5 * m * (w_b) ** 2 + self.B = ((m**2) * (w_b) ** 4) / (16 * v0) + except: - sys.exit(self.error_msg) + sys.exit(self.__doc__) - self.A = -0.5 * m * (w_b) ** 2 - self.B = ((m**2) * (w_b) ** 4) / (16 * v0) + super().__init__(*args, **kwargs) def check_dimensions(self, pos): """Functions that checks dimensions of the received position""" diff --git a/drivers/py/pes/driverdipole.py b/ipi/pes/driverdipole.py similarity index 95% rename from drivers/py/pes/driverdipole.py rename to ipi/pes/driverdipole.py index be0929042..2a87b9242 100644 --- a/drivers/py/pes/driverdipole.py +++ b/ipi/pes/driverdipole.py @@ -4,6 +4,9 @@ import json import numpy as np import warnings + +from ipi.utils.messages import verbosity, warning + import importlib from .dummy import Dummy_driver @@ -118,6 +121,9 @@ def get_model(instructions, parameters: str): class driverdipole_driver(Dummy_driver): + """The parameters of 'driverdipole_driver' are not correctly formatted. \ + They should be two or three strings, separated by a comma.""" + opts_default = { "dipole": { "send": True, # whether to send the dipole to i-PI @@ -131,19 +137,21 @@ class driverdipole_driver(Dummy_driver): "restart": False, # whether remove the files (if already existing) where the dipole and BEC will be saved. } - def __init__(self, args=None): - self.error_msg = """The parameters of 'driverdipole_driver' are not correctly formatted. \ - They should be two or three strings, separated by a comma.""" + def __init__(self, *args, **kwargs): + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) self.opts = dict() self.count = 0 - super().__init__(args) + super().__init__(*args, **kwargs) - def check_arguments(self): + def check_parameters(self): """Check the arguments required to run the driver.""" try: - arglist = self.args.split(",") + arglist = self.args except ValueError: - sys.exit(self.error_msg) + sys.exit(self.__doc__) if len(arglist) >= 2: info_file = arglist[0] # json file to properly allocate a 'model' object @@ -154,7 +162,7 @@ def check_arguments(self): print("\tNo options file provided: using the default values") opts_file = None else: - sys.exit(self.error_msg) # to be modified + sys.exit(self._error_msg) # to be modified print("\n\tThe driver is 'driverdipole_driver'") print("\tLoading model ...") diff --git a/drivers/py/pes/dummy.py b/ipi/pes/dummy.py similarity index 71% rename from drivers/py/pes/dummy.py rename to ipi/pes/dummy.py index 457c624a3..83430a93c 100644 --- a/drivers/py/pes/dummy.py +++ b/ipi/pes/dummy.py @@ -6,18 +6,23 @@ class Dummy_driver(object): - """Base class providing the structure of a PES for the python driver.""" + """Base class providing the structure of a PES for the python driver. - def __init__( - self, args="", verbose=False, error_msg="Invalid arguments for the PES" - ): + Command line: + i-pi-py_driver -m dummy [...] + Init arguments: + :param verbose: bool to determine whether the PES should output verbose info. + """ + + def __init__(self, verbose=False, *args, **kwargs): """Initialized dummy drivers""" - self.error_msg = error_msg - self.args = args.split(",") self.verbose = verbose - self.check_arguments() + self.args = args + self.kwargs = kwargs + + self.check_parameters() - def check_arguments(self): + def check_parameters(self): """Dummy function that checks the arguments required to run the driver""" pass diff --git a/drivers/py/pes/elphmod.py b/ipi/pes/elphmod.py similarity index 55% rename from drivers/py/pes/elphmod.py rename to ipi/pes/elphmod.py index efa863131..f4068d1c4 100644 --- a/drivers/py/pes/elphmod.py +++ b/ipi/pes/elphmod.py @@ -3,26 +3,29 @@ import sys from .dummy import Dummy_driver +from ipi.utils.messages import verbosity, warning + __DRIVER_NAME__ = "elphmod" __DRIVER_CLASS__ = "ModelIIIDriver" -ERROR_MSG = """ -A pickled driver instance is required (see elphmod.md.Driver.save). - -Example: python3 driver.py -u -m elphmod -o driver.pickle -""" - class ModelIIIDriver(Dummy_driver): - """Wrapper around elphmod MD driver.""" + """Wrapper around elphmod MD driver. + A pickled driver instance is required (see elphmod.md.Driver.save). - def check_arguments(self): - """Check arguments and load driver instance.""" + Example: python3 driver.py -u -m elphmod -o driver.pickle + """ + def check_parameters(self): + """Check arguments and load driver instance.""" + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) import elphmod if len(self.args) != 1: - sys.exit(ERROR_MSG) + sys.exit(self.__doc__) self.driver = elphmod.md.Driver.load(self.args[0]) diff --git a/drivers/py/pes/harmonic.py b/ipi/pes/harmonic.py similarity index 60% rename from drivers/py/pes/harmonic.py rename to ipi/pes/harmonic.py index d92f7bac9..df3974815 100644 --- a/drivers/py/pes/harmonic.py +++ b/ipi/pes/harmonic.py @@ -1,33 +1,37 @@ """ Harmonic potential """ -import sys from .dummy import Dummy_driver import numpy as np __DRIVER_NAME__ = "harmonic" __DRIVER_CLASS__ = "Harmonic_driver" -ERROR_MSG = """ -Harmonic driver requires specification of force constant. -Example: python driver.py -m harmonic -u -o 1.3 -""" - class Harmonic_driver(Dummy_driver): - def __init__(self, args=None, verbose=False): - super(Harmonic_driver, self).__init__(args, verbose, error_msg=ERROR_MSG) + """ + Harmonic driver, generating either an isotropic or 3D confining + potential for each atom. + + Command-line: + i-pi-py_driver -m harmonic -u -o 1.3 [...] + i-pi-py_driver -m harmonic -u -o 1.3,2.1,2.3 [...] + + Init parameters: + :param k1: float, spring constant of the oscillator (in a.u.) + :param k2: float, spring constant of the oscillator along y (in a.u.), optional + :param k3: float, spring constant of the oscillator along z (in a.u.), optional + """ - def check_arguments(self): - """Function that checks the arguments required to run the driver""" + def __init__(self, k1, k2=None, k3=None, *args, **kwargs): - if len(self.args) == 1: - self.k = float(self.args[0]) + if k2 == None or k3 == None: + self.k = k1 self.type = "isotropic" - elif len(self.args) == 3: - self.k = np.asarray(list(map(float, self.args))) - self.type = "non-isotropic" else: - sys.exit(self.error_msg) + self.k = np.asarray([k1, k2, k3]) + self.type = "non-isotropic" + + super().__init__(*args, **kwargs) def __call__(self, cell, pos): """Silly harmonic potential""" diff --git a/ipi/pes/mace.py b/ipi/pes/mace.py new file mode 100644 index 000000000..0aea548bb --- /dev/null +++ b/ipi/pes/mace.py @@ -0,0 +1,53 @@ +""" An interface for the [MACE](https://github.com/ACEsuit/mace) calculator """ + +from .ase import ASEDriver + +from ipi.utils.messages import verbosity, warning + +MACECalculator = None + +__DRIVER_NAME__ = "mace" +__DRIVER_CLASS__ = "MACE_driver" + + +class MACE_driver(ASEDriver): + """ + Driver for the MACE MLIPs. + The driver requires specification of a .json model, + and a template file that describes the chemical makeup + of the structure. + + Command-line: + i-pi-py_driver.py -m mace -u -o template=template.xyz,model=model.json + + Parameters: + :param template: string, filename of an ASE-readable structure file + to initialize atomic number and types + :param model: string, filename of the json-formatted model file + """ + + def __init__(self, template, model, device="cpu", *args, **kwargs): + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) + global MACECalculator + + try: + from mace.calculators import MACECalculator + except: + raise ImportError("Couldn't load mace bindings") + + self.model = model + self.device = device + super().__init__(template, *args, **kwargs) + + def check_parameters(self): + """Check the arguments requuired to run the driver + + This loads the potential and atoms template in MACE + """ + + super().check_parameters() + + self.ase_calculator = MACECalculator(model_paths=self.model, device=self.device) diff --git a/ipi/pes/metatensor.py b/ipi/pes/metatensor.py new file mode 100644 index 000000000..d857c68ad --- /dev/null +++ b/ipi/pes/metatensor.py @@ -0,0 +1,98 @@ +""" +Interface with metatensor +(https://lab-cosmo.github.io/metatensor/latest/atomistic/index.html), that can +be used to perform calculations based on different types of machine learning +potentials +""" + +from ipi.utils.messages import warning + +from .ase import ASEDriver + +MetatensorCalculator = None +mtt = None + +__DRIVER_NAME__ = "metatensor" +__DRIVER_CLASS__ = "MetatensorDriver" + + +class MetatensorDriver(ASEDriver): + """ + Driver for `metatensor` MLIPs + The driver requires specification of a torchscript model, + and a template file that describes the chemical makeup + of the structure. Requires the metatensor-torch library + + Command-line: + i-pi-py_driver -m metatensor -o template=template.xyz,model=model.json [...] + + Parameters: + :param template: string, filename of an ASE-readable structure file + to initialize atomic number and types + :param model: string, filename of the torchscript model file + :param device: string, optional, ["cpu" | "cuda"] + """ + + def __init__( + self, + template, + model, + device="cpu", + extensions="", + check_consistency=False, + *args, + **kwargs, + ): + global MetatensorCalculator, mtt + if MetatensorCalculator is None: + try: + import metatensor.torch as mtt + from metatensor.torch.atomistic.ase_calculator import ( + MetatensorCalculator, + ) + except ImportError as e: + warning(f"Could not find or import metatensor.torch: {e}") + + self.model = model + self.device = device + self.extensions = extensions + self.check_consistency = check_consistency + super().__init__(template, *args, **kwargs) + + def check_parameters(self): + """Check the arguments required to run the driver + + This loads the potential and atoms template in metatensor + """ + + if MetatensorCalculator is None: + raise ImportError("could not import metatensor.torch, is it installed?") + + metatensor_major, metatensor_minor, *_ = mtt.__version__.split(".") + metatensor_major = int(metatensor_major) + metatensor_minor = int(metatensor_minor) + + if metatensor_major != 0 or metatensor_minor < 5: + raise ImportError( + "this code is only compatible with metatensor-torch >= v0.5, " + f"found version v{mtt.__version__} " + f"at '{mtt.__file__}'" + ) + + super().check_parameters() + + self.model_path = self.model + + device = self.device + extensions_directory = self.extensions + check_consistency = self.check_consistency + + self.ase_calculator = MetatensorCalculator( + self.model_path, + device=device, + extensions_directory=extensions_directory, + check_consistency=check_consistency, + ) + + # Show the model metadata to the users + print(self.ase_calculator.metadata()) diff --git a/drivers/py/pes/pet.py b/ipi/pes/pet.py similarity index 53% rename from drivers/py/pes/pet.py rename to ipi/pes/pet.py index f072336e2..7e54c37e3 100644 --- a/drivers/py/pes/pet.py +++ b/ipi/pes/pet.py @@ -1,78 +1,65 @@ """Interface with [PET](https://github.com/serfg/pet) models to run machine learning potentials""" -import sys import numpy as np from .dummy import Dummy_driver from ipi.utils.units import unit_to_internal, unit_to_user from ipi.utils.messages import warning -try: - from pet import SingleStructCalculator as PETCalc - - try: - from ase.io import read - except ImportError: - warning("The PET driver has an ASE dependency") - raise -except ImportError: - warning("Could not find or import the PET module") - PETCalc = None +PETCalc = None +read = None __DRIVER_NAME__ = "pet" __DRIVER_CLASS__ = "PET_driver" class PET_driver(Dummy_driver): - def __init__(self, args=None, verbose=False): - self.error_msg = """ -The PET driver requires (a) a path to the results/experiment_name folder emitted by pet_train - (b) a path to an ase.io.read-able file with a prototype structure - -Other arguments to the pet.SingleStructCalculator class can be optionally -supplied in key=value form after the required arguments. - -Example: python driver.py -m pet -u -o "path/to/results/name,template.xyz,device=cuda" -""" - - super().__init__(args, verbose) - - if PETCalc is None: - raise ImportError("Couldn't load PET bindings") - - def check_arguments(self): + """ + Driver for `PET` MLIPs + The driver requires specification of the folder containing the + outputs from a PET model training, a template file that describes the chemical makeup + of the structure, and optional parameters specific for the PET architecture. + Requires the pet library + + Command-line: + i-pi-py_driver -m pet -o model_path=path_to_results/prefix,template=template.xyz,device=cuda [...] + + Parameters: + :param template: string, filename of an ASE-readable structure file + to initialize atomic number and types + :param model: string, filename of the torchscript model file + :param device: string, optional, ["cpu" | "cuda"] + """ + + def __init__(self, model_path, template, *args, **kwargs): + global PETCalc, read + + try: + from pet import SingleStructCalculator as PETCalc + + try: + from ase.io import read + except ImportError: + warning("The PET driver has an ASE dependency") + raise + except ImportError: + raise ImportError("Could not find or import the PET module") + + self.model_path = model_path + self.template = template + super().__init__(*args, **kwargs) + + def check_parameters(self): """Check the arguments required to run the driver This loads the potential and atoms template in PET """ - args = self.args - - if len(args) >= 2: - self.model_path = args[0] - self.template = args[1] - kwargs = {} - if len(args) > 2: - for arg in args[2:]: - key, value = arg.split("=") - lookup = { - "None": None, - "False": False, - "True": True, - } - - if value in lookup: - value = lookup[value] - - kwargs[key] = value - - else: - sys.exit(self.error_msg) self.template_ase = read(self.template) self.template_ase.arrays["forces"] = np.zeros_like(self.template_ase.positions) self.pet_calc = PETCalc( self.model_path, - **kwargs, + **self.kwargs, ) def __call__(self, cell, pos): diff --git a/drivers/py/pes/rascal.py b/ipi/pes/rascal.py similarity index 56% rename from drivers/py/pes/rascal.py rename to ipi/pes/rascal.py index c7ac7da31..7bef90025 100644 --- a/drivers/py/pes/rascal.py +++ b/ipi/pes/rascal.py @@ -1,45 +1,53 @@ """Interface with librascal to run machine learning potentials""" -import sys from .dummy import Dummy_driver from ipi.utils.mathtools import det_ut3x3 from ipi.utils.units import unit_to_internal, unit_to_user +from ipi.utils.messages import verbosity, warning -try: - from rascal.models.genericmd import GenericMDCalculator as RascalCalc -except: - RascalCalc = None +RascalCalc = None __DRIVER_NAME__ = "rascal" __DRIVER_CLASS__ = "Rascal_driver" -ERROR_MSG = """ -Rascal driver requires specification of a .json model file fitted with librascal, -and a template file that describes the chemical makeup of the structure. -Example: python driver.py -m rascal -u -o model.json,template.xyz -""" - class Rascal_driver(Dummy_driver): - def __init__(self, args=None, verbose=False): - super().__init__(args, verbose, error_msg=ERROR_MSG) + """ + Driver for `librascal` MLIPs + The driver requires specification of the model JSON-formated definition, + and a template file that describes the chemical makeup + of the structure. Requires the librascal library + + Command-line: + i-pi-py_driver -m rascal -o model=model.json,template=template.xyz [...] + + Parameters: + :param template: string, filename of an ASE-readable structure file + to initialize atomic number and types + :param model: string, filename of the torchscript model file + """ - if RascalCalc is None: + def __init__(self, model, template, *args, **kwargs): + global RascalCalc + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) + try: + from rascal.models.genericmd import GenericMDCalculator as RascalCalc + except: raise ImportError("Couldn't load librascal bindings") + self.model = model + self.template = template - def check_arguments(self): + super().__init__(*args, **kwargs) + + def check_parameters(self): """Check the arguments required to run the driver This loads the potential and atoms template in librascal """ - arglist = self.args - - if len(arglist) == 2: - self.model = arglist[0] - self.template = arglist[1] - else: - sys.exit(self.error_msg) self.rascal_calc = RascalCalc(self.model, True, self.template) diff --git a/ipi/pes/so3lr.py b/ipi/pes/so3lr.py new file mode 100644 index 000000000..c0ee083c5 --- /dev/null +++ b/ipi/pes/so3lr.py @@ -0,0 +1,37 @@ +""" An interface for the [SO3LR](https://github.com/general-molecular-simulations/so3lr) calculator """ + +from .ase import ASEDriver +from ipi.utils.messages import verbosity, warning + +So3lrCalculator = None + +__DRIVER_NAME__ = "so3lr" +__DRIVER_CLASS__ = "SO3LR_driver" + + +class SO3LR_driver(ASEDriver): + """ + SO3LR driver requires a template file that describes the chemical makeup of the structure. + + Optionally, lr_cutoff and dispersion_energy_lr_cutoff_damping can be specified. + + Example: python driver.py -m so3lr -u -o template.xyz,lr_cutoff=12,dispersion_energy_lr_cutoff_damping=2 + """ + + def __init__(self, *args, **kwargs): + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) + global So3lrCalculator + try: + from so3lr import So3lrCalculator + except: + raise ImportError("Couldn't load so3lr bindings") + + super().__init__(*args, **kwargs) + + def check_parameters(self): + super().check_parameters() + + self.ase_calculator = So3lrCalculator(**self.kwargs) diff --git a/drivers/py/pes/spline.py b/ipi/pes/spline.py similarity index 84% rename from drivers/py/pes/spline.py rename to ipi/pes/spline.py index eb7de4ea4..3adbd0821 100644 --- a/drivers/py/pes/spline.py +++ b/ipi/pes/spline.py @@ -6,6 +6,8 @@ from scipy import interpolate import json +from ipi.utils.messages import verbosity, warning + """Spline driver. This is not a serious interpolation, use it if you know what you are doing. """ factor_coord = 5 mass = 1836 @@ -18,21 +20,27 @@ class Spline_driver(Dummy_driver): - def __init__(self, args=None, verbose=None): - self.error_msg = """\nspline driver requires specification of filename that contains 5 columns (pos, f1,f2,f3,e) to perform 3x1D spline.\nExample: python driver.py -m spline -u -o \n""" - super(Spline_driver, self).__init__(args) + """\nspline driver requires specification of filename that contains 5 columns (pos, f1,f2,f3,e) to perform 3x1D spline.\nExample: python driver.py -m spline -u -o \n""" + + def __init__(self, data_file, *args, **kwargs): + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) + self.data_file = data_file + super().__init__(*args, **kwargs) self.get_spline() if friction and not SI: self.get_spline_fric() self.k = 1836 * (3800.0 / 219323.0) ** 2 - def check_arguments(self): + def check_parameters(self): """Function that checks the arguments required to run the driver""" try: - data = np.loadtxt(self.args[0]).reshape(-1, 5) + data = np.loadtxt(self.data_file).reshape(-1, 5) except ValueError: - sys.exit(self.error_msg) + sys.exit(self._error_msg) self.data = data def get_spline(self): diff --git a/drivers/py/pes/xtb.py b/ipi/pes/xtb.py similarity index 74% rename from drivers/py/pes/xtb.py rename to ipi/pes/xtb.py index 144a07c67..687c8768b 100644 --- a/drivers/py/pes/xtb.py +++ b/ipi/pes/xtb.py @@ -1,42 +1,40 @@ -""" -Interface with tblite to provide GFN1-xTB and GFN2-xTB calculators. - -Example:: - - python driver.py -m xtb -u -o '{"method": "GFN2-xTB", "numbers": [8,1,1], "periodic": false}' -""" - import numpy as np import json from ipi.utils.units import unit_to_internal, unit_to_user +from ipi.utils.messages import verbosity, warning +from .dummy import Dummy_driver -try: - import tblite.interface as tb -except ImportError: - tb = None - +tb = None __DRIVER_NAME__ = "xtb" __DRIVER_CLASS__ = "TBLiteDriver" -class TBLiteDriver(object): - """Base class providing the structure of a PES for the python driver.""" +class TBLiteDriver(Dummy_driver): + """ + Interface with tblite to provide GFN1-xTB and GFN2-xTB calculators. + + Example:: - def __init__( - self, - args="", - verbose=False, - ): - """Initialized dummy drivers""" + python driver.py -m xtb -u -o config.json + """ - if tb is None: + def __init__(self, json_input, *args, **kwargs): + warning( + "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", + verbosity.low, + ) + config = json.load(open(json_input)) + + global tb + try: + import tblite.interface as tb + except ImportError: raise ModuleNotFoundError( "Could not find tblite for xtb driver. Please install tblite-python with mamba" ) - config = json.loads(args) try: self.method = config["method"] self.numbers = np.asarray(config["numbers"]) @@ -45,7 +43,9 @@ def __init__( self.charge = config.get("charge") self.uhf = config.get("uhf") self.periodic = config.get("periodic") - self.verbosity = 1 if verbose else 0 + self.verbosity = 1 if self.verbose else 0 + + super().__init__(*args, **kwargs) def __call__(self, cell, pos): """ diff --git a/ipi/utils/io/inputs/__init__.py b/ipi/utils/io/inputs/__init__.py index e766bce28..aad0bbbf8 100644 --- a/ipi/utils/io/inputs/__init__.py +++ b/ipi/utils/io/inputs/__init__.py @@ -8,3 +8,37 @@ __all__ = ["io_xml"] + + +def read_value(s): + """Attempt to parse a string to int or float; fallback to string.""" + s = s.strip() + for cast in (int, float): + try: + return cast(s) + except ValueError: + continue + return s + + +def read_args_kwargs(input_str): + """ + Parses a string into positional arguments and keyword arguments. + + Args: + input_str (str): The input string containing comma-separated values and key-value pairs. + + Returns: + tuple: A tuple containing a list of positional arguments and a dictionary of keyword arguments. + """ + args = [] + kwargs = {} + tokens = input_str.split(",") + for token in tokens: + token = token.strip() + if "=" in token: + key, value = token.split("=", 1) + kwargs[key.strip()] = read_value(value) + elif len(token) > 0: + args.append(read_value(token)) + return args, kwargs diff --git a/ipi/utils/io/inputs/io_xml.py b/ipi/utils/io/inputs/io_xml.py index 7ecb2ac68..8fbc0a261 100644 --- a/ipi/utils/io/inputs/io_xml.py +++ b/ipi/utils/io/inputs/io_xml.py @@ -12,6 +12,7 @@ import numpy as np from ipi import ipi_global_settings +from . import read_value __all__ = [ "xml_node", @@ -448,7 +449,7 @@ def mystrip(data): rtuple = list(map(mystrip, s.split(key_split))) if not len(rtuple) == 2: raise ValueError("Format for a key:value format is wrong for item " + s) - rdict[rtuple[0]] = rtuple[1] + rdict[rtuple[0]] = read_value(rtuple[1]) return rdict diff --git a/ipi_tests/README.md b/ipi_tests/README.md index 97b667f3e..152d4a5ac 100644 --- a/ipi_tests/README.md +++ b/ipi_tests/README.md @@ -14,7 +14,10 @@ * To run the unitary, example and regression tests, please use i-pi/bin/i-pi-tests. For details of usage call it with "-h" option. - * In some situations it is desirable to perform regresion/examples tests only for a selected set. + * The tests can be customized to an extent by including a `test_settings.dat` file that specifies how to run the test, + mostly by describing the driver that should be used. See some of the existing files as examples. + + * In some situations it is desirable to perform regression/examples tests only for a selected set. For these cases, we also provide more flexible scripts for performing the regresion tests and testing the provided examples. See i-pi/ipi_tests/regression_tests/test_run.py and i-pi/ipi_tests/examples/test_examples.py, respectively. For details of usage call them with "-h" option. diff --git a/ipi_tests/profiling/classical_md_direct/init.xyz b/ipi_tests/profiling/classical_md_direct/init.xyz new file mode 100644 index 000000000..f2f3870f8 --- /dev/null +++ b/ipi_tests/profiling/classical_md_direct/init.xyz @@ -0,0 +1,10 @@ +8 +# CELL(abcABC): 50.0 50.0 50.0 90.00000 90.00000 90.00000 +H 0 0 0 +H 0 0 1 +H 0 0 2 +H 0 0 3 +H 0 0 4 +H 0 0 5 +H 0 0 6 +H 0 0 7 diff --git a/ipi_tests/profiling/classical_md_direct/input.xml b/ipi_tests/profiling/classical_md_direct/input.xml new file mode 100644 index 000000000..21d038b66 --- /dev/null +++ b/ipi_tests/profiling/classical_md_direct/input.xml @@ -0,0 +1,34 @@ + + + dummy + 1.00000000e-04 + + 10000 + + positions + [ step, time, conserved, temperature, kinetic_md, potential, pressure_md, volume ] + + + 18885 + + + + + + + init.xyz + [10.0, 0, 0, 0, 10.0, 0, 0, 0, 10.0] + [1.0] + 1 + + + 1 + + + False + + 0.01 + + + + diff --git a/ipi_tests/profiling/run_profiling.sh b/ipi_tests/profiling/run_profiling.sh index c475445c0..b8ae0bfb8 100755 --- a/ipi_tests/profiling/run_profiling.sh +++ b/ipi_tests/profiling/run_profiling.sh @@ -1,5 +1,5 @@ #!/bin/bash -# usage: run_profile.sh [-p] natoms [ndriver] +# usage: run_profiling.sh [-p] natoms [ndriver] # run a mock simulation using an natoms box, -p activates yappi profiling # Default value for natoms diff --git a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/simulation.instanton_FINAL_15.ener b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/simulation.instanton_FINAL_15.ener deleted file mode 100644 index 6a2a6e394..000000000 --- a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/simulation.instanton_FINAL_15.ener +++ /dev/null @@ -1,33 +0,0 @@ -#Bead Energy (eV) -0 -0.11866259790715851 -1 -0.11691012681205774 -2 -0.11342166079444242 -3 -0.1082351949410836 -4 -0.10141984639090063 -5 -0.09308898239047224 -6 -0.08341517679588735 -7 -0.0726445585426023 -8 -0.06110741669327686 -9 -0.049221487325502286 -10 -0.03748445701371601 -11 -0.026453159043353814 -12 -0.016708861462551 -13 -0.008810819030011201 -14 -0.0032433701350644724 -15 -0.0003644451312916968 -16 -0.0003644451319317277 -17 -0.0032433701369415356 -18 -0.008810819032999921 -19 -0.016708861466452396 -20 -0.026453159047914718 -21 -0.03748445701864777 -22 -0.04922148733051311 -23 -0.06110741669809458 -24 -0.07264455854700659 -25 -0.0834151767997177 -26 -0.09308898239364362 -27 -0.10141984639339816 -28 -0.10823519494296141 -29 -0.11342166079580748 -30 -0.11691012681305872 -31 -0.11866259790797011 diff --git a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/test_settings.dat b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/test_settings.dat index 42ec12ec1..0d6ab5051 100644 --- a/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/test_settings.dat +++ b/ipi_tests/regression_tests/tests/INSTANTON/100K_implicit_friction/test_settings.dat @@ -1,6 +1,6 @@ driver_model DW_friction driver_code python -flags -o 500,2085,1837.36223469,0,1.5,-1.0,0,1 +flags -o 'w_b=500,v0=2085,m=1837.36223469,delta=0,eta0=1.5,eps1=-1.0,eps2=0,deltaQ=1' address localhost port 33335 socket_mode unix diff --git a/setup.py b/setup.py index bf8364962..e865e9c79 100644 --- a/setup.py +++ b/setup.py @@ -6,13 +6,6 @@ scripts = [str(p) for p in Path("bin").iterdir() if p.name != "i-pi-driver"] setup( - packages=[ - *find_packages(exclude=["ipi_tests*"]), - "ipi._driver", - "ipi._driver.pes", - ], - package_dir={ - "ipi._driver": "drivers/py", - }, + packages=[*find_packages(exclude=["ipi_tests*"])], scripts=scripts, ) From 2b41f4fe670f2fa715deae003e92e5d62279521c Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Tue, 12 Nov 2024 22:59:17 +0100 Subject: [PATCH 24/47] Restyling --- docs/_static/custom_styles.css | 8 ++++++++ docs/src/distributed.rst | 1 + docs/src/getting-started.rst | 1 + docs/src/introduction.rst | 3 +++ 4 files changed, 13 insertions(+) create mode 100644 docs/_static/custom_styles.css diff --git a/docs/_static/custom_styles.css b/docs/_static/custom_styles.css new file mode 100644 index 000000000..13c727374 --- /dev/null +++ b/docs/_static/custom_styles.css @@ -0,0 +1,8 @@ +figcaption { + font-style: italic; /* makes text italic */ + font-size: 0.9em; /* reduces font size to 90% of the surrounding text */ +} + +img.white-background { + background-color: white; +} diff --git a/docs/src/distributed.rst b/docs/src/distributed.rst index 449bee7a1..f8e30a879 100644 --- a/docs/src/distributed.rst +++ b/docs/src/distributed.rst @@ -213,6 +213,7 @@ example above. .. _fig-network: .. figure:: ../figures/ipi-network.* + :class: white-background :width: 90.0% A schematic representation of the network layout one diff --git a/docs/src/getting-started.rst b/docs/src/getting-started.rst index 0d8c176ff..e1f6d2e06 100644 --- a/docs/src/getting-started.rst +++ b/docs/src/getting-started.rst @@ -435,6 +435,7 @@ nodes, and to queue and manage computational jobs. .. _fig-running: .. figure:: ../figures/ipi-running.* + :class: white-background :width: 90.0% Different approaches to run i-PI and a number of diff --git a/docs/src/introduction.rst b/docs/src/introduction.rst index 21e3934b2..d198457a8 100644 --- a/docs/src/introduction.rst +++ b/docs/src/introduction.rst @@ -27,6 +27,7 @@ A schematic representation of the code structure and the server-client communica .. figure:: ../figures/ipi-structure-v3.* :width: 90.0% + :class: white-background Figure 1. Schematic representation of the i-PI code structure and the server-client communication. @@ -81,6 +82,7 @@ machinery in i-PI might appear complicated at first, and deserves a brief discussion. .. figure:: ../figures/ipi-forces.* + :class: white-background :width: 90.0% Schematic representation of the different objects that @@ -146,6 +148,7 @@ a “depend” object class, which is given the parameters on which it depends and a function used to calculate its value. .. figure:: ../figures/ipi-depend.* + :class: white-background :width: 90.0% Schematic overview of the functioning of the From dcc5ebbd027986f66279579f7ef77a86134f5c60 Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Tue, 12 Nov 2024 23:08:08 +0100 Subject: [PATCH 25/47] Added further configuration stuff --- docs/_static/favicon-ipi.png | Bin 0 -> 1002 bytes docs/requirements.txt | 4 ++-- docs/src/conf.py | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 docs/_static/favicon-ipi.png diff --git a/docs/_static/favicon-ipi.png b/docs/_static/favicon-ipi.png new file mode 100644 index 0000000000000000000000000000000000000000..beaf016d9b90bfef984d352217bcbc7ed90d1963 GIT binary patch literal 1002 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U~&ua3327%0;w^ya|}$+@k`Fo zG%;slW@cq$*R`|>NX-J0nkHtfY-~Wbb8r+;B_kt~cWjEGts}b`Cxb5o2>CE@Tk;2` z=K{4eW-~J6Ffe8_X&9Tuv{iFxb2E4_Ft{@?xH0hR3Ierj8Cw8JAh7ZBxA6)9GF(EU zSQ*&a&AEVjIdyn|Hh|?pgsh61v4gX$sybW*3&RIwI0rK~x3vIc4im4wFbe}4ubvRl z4M0~hGBJ6^CR=$2*mwtc$E5(dx)#x*FOzDyVDgSXlFL@Qc~W zN|?&CFt9Q>FfimYFr+asm@`1RK;MTlFaVtov@r){DbTgDs%k(#8rV8I2S)-!5)uf& z;0jF7oqP1c#(Qrz+xqthGGVW5(b7MhO8yM43!M5`D|CdYjsIZ*JbP-nSvWbItZu zS0CBf*c28P=I7@Z6ck*(eEIzO^JmVSY0FD7j%RQUXKSr2PwZ_9>Bygc@XYC@8?I?d z-89!dyyryQnr&Tcx39hZtn1*O13oV6QllrGI=SNV{Yi%pi4`bV#4u_mFsfIX&pLiK zwzrzOh=rkvfwxdFxx0n2n3188fjOHcv9~d}BcGv~fuWpX&e03gb|3%$|G&iIOW?#& z666=m;PC7QFx(gzlf2zs7&=&GfhmB2v%n(~=sUabAk3J*EbbLhkiEpy*OmPtGqbpc zjL4f0D}j1sJzX3_EKc`M-q?4@fT!*4^#wWGl{an`ICZEX{}6Y>71{4DXFZ~;vhO!G zHdb#dmb$++X7QK0(3A6D1V7qg#;|}R#IFD5!x=C2(iYk8n_YVS_0c&UMMb|}?DN}H z8q{!(^}N!>KZh2bzVk~`JpC6Vm+iN=U%Q%2I_CU!ELx|dD==+;e(+|NmpuqTX0+&g@>t(~E=wt9h|@EgY2{|yTE7eC-~sI##UP-$RwI?qy9S7;FE z@VkDgRovR%n@e6EoAFgkj=Ax^ZKy%8s<}?o7g1fg<){7`+_iXk?X%gN)%@H4o6l%v Wepow|XALmy7(8A5T-G@yGywom6IAQ~ literal 0 HcmV?d00001 diff --git a/docs/requirements.txt b/docs/requirements.txt index f469284bd..a05ac6e3f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,6 +1,6 @@ sphinx >= 3.2 -jinja2 < 3.1 +jinja2 sphinxcontrib-bibtex==2.1.4 numpy pathlib -furo==2023.5.20 \ No newline at end of file +furo diff --git a/docs/src/conf.py b/docs/src/conf.py index e94b835b8..a6ebf7cb5 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -54,11 +54,12 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # +html_title = "i-PI documentation pages" html_theme = "furo" html_theme_options = { - "rightsidebar": "false", + "top_of_page_buttons": [], } - +html_favicon = "../_static/favicon-ipi.png" html_logo = "../figures/ipi-logo.svg" html_css_files = [ From 4b26f7b503a6ab56c3615b0c04313f0cdd5be006 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 10:16:50 +0000 Subject: [PATCH 26/47] added info on MLIP examples --- docs/src/onlinereso.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/src/onlinereso.rst b/docs/src/onlinereso.rst index 9f974ff9f..8ca372b5b 100644 --- a/docs/src/onlinereso.rst +++ b/docs/src/onlinereso.rst @@ -58,6 +58,9 @@ Flagship school, are available here: Tutorials from the 2023 CECAM Flagship school are available here: `i-PI 2023 tutorials `_. +Tutorial from one of our developers on using machine learning interatomic potentials with i-PI are available here: +`MLIPs-with-i-PI `_. + Note that these examples use some features (such as qTIP4P/F water and the Zundel cation potentials in the driver code, and optionally also CP2K). Instructions on how to install and run these codes From ae304a443f7fdba44d84c1a94ac6338939868e60 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 10:22:01 +0000 Subject: [PATCH 27/47] removing restart file from example --- examples/clients/mace/RESTART | 365 ---------------------------------- 1 file changed, 365 deletions(-) delete mode 100644 examples/clients/mace/RESTART diff --git a/examples/clients/mace/RESTART b/examples/clients/mace/RESTART deleted file mode 100644 index 3be060e83..000000000 --- a/examples/clients/mace/RESTART +++ /dev/null @@ -1,365 +0,0 @@ - - - 31415 - [{"bit_generator": "MT19937", "state": {"key": [795669418, 3354365008, 150463171, 3937589838, 937846891, 734296723, 764622735, 1183299804, 1272117760, 2010368631, 1241689493, 3626464784, 1162653305, 1289276628, 1367499306, 3247908752, 1963981358, 2105964165, 1030412370, 3753156803, 1150834373, 4031974639, 531307719, 4045118304, 2683788309, 116245922, 2731998769, 136843156, 2169419932, 2880162252, 4007512466, 488361195, 401722091, 2070790009, 1569274038, 815594016, 124972808, 474005227, 3249330448, 2100162826, 3174580426, 2683556907, 4048106153, 1785067589, 2389562067, 836361726, 50342815, 267551970, 3029837949, 3708063355, 717650658, 4006537337, 2479145810, 3256975969, 724976954, 2961068974, 1504794639, 1505207924, 2503985603, 311245764, 1337733744, 75442868, 165388908, 4036439509, 85007674, 1868694522, 2350085548, 3505596813, 47545258, 2074303192, 1070457701, 1029840107, 353040402, 1973126927, 1264732370, 2845086742, 2526982946, 711245124, 1767309883, 2553172272, 3804650134, 289756061, 1111550931, 4144472782, 3996394604, 1981950798, 844362391, 3764917697, 3438324015, 2851666299, 2537341468, 2679862414, 1922363332, 666882440, 3941252033, 757464743, 1045369080, 2905858236, 730860388, 1325996640, 3162113550, 2567309825, 1103202741, 3175399181, 2025511874, 2412947386, 3058427547, 227013550, 2159447082, 1067678484, 3425716523, 417688251, 808501564, 3029168553, 776434612, 115305601, 2788751616, 4246589453, 1253335687, 4141730143, 2414042400, 3419716119, 1633385319, 3247093955, 2994012100, 3972147166, 3745802163, 1304644993, 865244793, 3828379540, 692694198, 4224136046, 341321136, 3189881009, 3230663087, 2858154757, 1490950918, 2482160305, 2121120586, 3007482108, 822603820, 611698261, 2765298047, 345565265, 950359221, 1557230050, 709103228, 1186524570, 292929978, 1821072176, 738923492, 4274644, 779539689, 481731554, 1561808887, 4203195225, 1555517680, 3751871402, 1482431159, 2791267293, 3707069758, 3234075511, 2672838488, 1009278333, 1527771451, 3152681530, 2014224365, 148003440, 3882068492, 351078994, 1651963697, 1054663714, 2397065047, 1469924118, 1137039177, 3577753374, 686392654, 3017336343, 1040761223, 365471914, 2744241982, 2232067354, 4292242034, 3280899888, 2970074168, 4021665697, 4032550683, 2848764242, 134774596, 2698474524, 3951539303, 3050877350, 425236979, 3681969874, 536833020, 645868093, 3820567878, 818193000, 3703993042, 2811873296, 200223563, 2261193604, 4002620488, 573051517, 559569805, 1751201194, 3958517026, 3946914696, 843371176, 3401646834, 1276160980, 3113426010, 3652866953, 3777818492, 1153305286, 634988187, 4656920, 4017875503, 4244574051, 3891820314, 1921680474, 1139973881, 26053146, 3540936332, 1190218234, 3858351434, 4215348533, 1192366508, 3769660024, 3473641435, 798054066, 2265876112, 1057572646, 1880763545, 232212048, 1559861968, 2573998448, 879167696, 1381352741, 3800595158, 2698089866, 1949124578, 613088558, 733254358, 1014535932, 904484089, 2246187117, 4044798376, 2066284160, 3744977864, 800089136, 3114088148, 1106568495, 3832704901, 368290159, 1891318290, 2578953184, 623604879, 220664755, 4211596409, 3902639138, 3893193846, 444071368, 3037681030, 417202030, 3408758382, 1941104578, 4235778810, 1412270470, 3337251361, 3965657496, 565829799, 2074175501, 3575557, 105655240, 2090581125, 3306098583, 3395704630, 1923485982, 1800504879, 184025064, 3741358783, 1531109577, 3771712710, 1779168700, 3845470585, 54968271, 958679375, 643136974, 3568839812, 816610774, 269396381, 1071003538, 3955364110, 194687099, 350181071, 1806095246, 3847618589, 3093771598, 4091627518, 2587247322, 3899980915, 1407852399, 1825407665, 2573244759, 1807374193, 3505525555, 3863992055, 1480680373, 1898960191, 1705678055, 743066202, 1640873890, 1502514469, 62759855, 2132297488, 2382508606, 1130137488, 3409343240, 81886173, 218725541, 4201682764, 911613040, 1789780226, 2328217590, 3070595230, 1307451716, 917012100, 2466257247, 2759529868, 4189490536, 3495955071, 3707418358, 1380836129, 3581386770, 680470424, 4156278160, 3183533111, 2255433561, 31125173, 607214606, 3405607994, 2681426217, 4147600795, 3619039237, 763225706, 3096727002, 368528808, 3715678351, 3960812773, 1794416641, 24849552, 2330330218, 4198000056, 944776381, 4016144718, 4015476207, 2542135582, 891526613, 3275670597, 260289596, 1686366879, 811749559, 1930701239, 4106811535, 3486653570, 3757236663, 3058744443, 573883924, 1597973411, 2849367252, 837698365, 4068634250, 1668230932, 372720237, 2224907569, 4138179720, 2153761699, 1142555848, 642912525, 1775227279, 2202501344, 1576309174, 2020529413, 2759079887, 1476875451, 2490373885, 140951714, 3261701581, 2900952306, 2771780919, 3024978145, 3847035909, 2590213672, 3657015728, 2933466694, 2652199769, 779968378, 693587481, 3238084161, 1292859236, 3901198107, 1642771831, 2504839327, 2593018406, 3232082142, 2294577705, 3434756417, 1176324409, 2586064527, 3649392695, 4270213721, 369682239, 1833859305, 3004923589, 2157403691, 2909620342, 4038662021, 530878050, 3727607169, 2581922589, 3325028835, 3492366495, 2778152583, 1317623030, 985094443, 4200028354, 3818659668, 2290320879, 996660363, 4254245440, 3634630451, 2515846723, 3412149142, 713547821, 3915598384, 1722967802, 3031991720, 397851792, 2268486426, 1485982870, 1312405573, 1549720048, 3093342568, 2946875941, 763765622, 2904735136, 2576787606, 1307812616, 1922019727, 3895352419, 3130267707, 3041543726, 4156570049, 2040426037, 4185810248, 3336129979, 1543746434, 4114276353, 968506551, 831488510, 3910628170, 1588848655, 2295202084, 552508107, 2895382473, 3046575372, 1866870955, 705382541, 2784623343, 4182110533, 2827559551, 1027960460, 1950086097, 912710698, 3326002035, 3658909104, 1297039826, 714298744, 3314813781, 3390897113, 4117186502, 4249300284, 2177611878, 3519404052, 1215103020, 888161319, 3639110818, 2770087358, 4230724586, 1084939770, 1124825233, 2642336164, 3102293704, 2636412376, 3895111296, 4015894980, 1480524830, 2283627770, 2896169265, 1525361018, 4252128804, 3188301813, 578157311, 2825512587, 1353889048, 4109758585, 696181235, 715287672, 3344116697, 80143085, 1098959985, 3214960309, 2416526557, 607618034, 70832594, 1701217967, 2165635687, 970104148, 3879061619, 3523994229, 4192455772, 3014553164, 58296115, 3570431746, 2418920482, 3046097006, 366177630, 206133899, 3934812939, 3106058444, 3539689581, 219917426, 299931320, 1588386678, 2497199221, 1214539462, 1239314913, 3984725088, 2692578908, 750931547, 3585571140, 488681398, 1376038242, 560384883, 1332416451, 2912016916, 1884794666, 3769249332, 30846606, 1774556799, 411741744, 2798886417, 4156313896, 1075162039, 501151935, 605601098, 3840102651, 1767398917, 21611012, 2366766995, 3276021819, 379749019, 1353987593, 1364614484, 1303524118, 3975728117, 3671464016, 2958317770, 3854446205, 3411077042, 913017910, 1979049403, 1435107822, 2874429353, 2302569380, 3196830537, 3863113770, 410539094, 1769756413, 3673454397, 870551312, 3979217, 2679612570, 1291584258, 1565027228, 1877575392, 2372846756, 1697524416, 4175015869, 2274297454, 3741847250, 523408423, 4063843078, 2235754156, 3232533841, 2757177941, 2074155385, 386877545, 260349822, 4059210860, 3349159924, 531748356, 174724555, 3122595409, 3660832320, 579592266, 1350622822, 3279112166, 21688457, 2177358206, 3414507844, 3960313028, 2220533609, 3596959752, 808052420, 1362285260, 304161502, 2334325099, 4090228266, 526360154, 3527253401, 4177434316, 3382911628], "pos": 549}}] - - - - [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, kinetic_md{electronvolt}, - potential{electronvolt}, pressure_md{megapascal} ] - - positions - 1 - - 1 - 20000 - -
driver
-
- - - - - - - 9.50044560e-04 - 4.79612667e-04 - [ 1.00000000e+00 ] - - - - - - 1.08732992e-03 - 4.13413730e+03 - - 2.06706865e+01 - [ 1 ] - - - - - [ 2.11270674e+01, -1.36860295e+01, 1.21309109e+01, 2.13905728e+01, -1.48995535e+01, - 1.07839955e+01, 2.25466837e+01, -1.33494742e+01, 1.32355387e+01, 5.26292258e+00, - 3.03753005e+00, 2.95386440e+00, 4.63759498e+00, 3.75319475e+00, 4.79162448e+00, - 7.05549943e+00, 3.02660946e+00, 3.41089634e+00, 7.68280951e+00, 2.29463670e+00, - 1.15917368e+01, 8.54721344e+00, 1.59180645e+00, 1.01638082e+01, 7.05049810e+00, - 1.18156011e+00, 1.29580753e+01, -1.10555593e+01, -3.38025456e+00, -2.78541863e+00, - -1.11640441e+01, -4.97217119e+00, -4.00393338e+00, -1.28770002e+01, -2.98973666e+00, - -3.18922815e+00, -1.30773732e+00, 2.80916019e+00, 8.78308389e+00, -1.09035460e+00, - 3.24684786e+00, 1.05259695e+01, -2.21290761e+00, 4.33986686e+00, 8.10540613e+00, - 1.84994004e+01, -2.31212286e+00, 1.11324281e+01, 1.71343793e+01, -1.70545212e+00, - 1.00958713e+01, 1.99982592e+01, -1.89798731e+00, 1.02215215e+01, 3.38480627e+00, - -1.02059660e+01, -5.25221279e+00, 4.42576485e+00, -9.68664476e+00, -3.78241580e+00, - 1.68203597e+00, -9.68905088e+00, -5.09542299e+00, -5.21005973e+00, -1.63108694e+01, - -2.04708461e-01, -4.81781665e+00, -1.64227168e+01, -2.03623163e+00, -5.20969305e+00, - -1.45138746e+01, 2.22953104e-01, 1.86595134e+01, -7.56514257e+00, 1.32421462e+01, - 1.75798948e+01, -7.41248045e+00, 1.46026588e+01, 1.86576022e+01, -5.83205625e+00, - 1.25999077e+01, 2.57610855e+00, 5.13558558e+00, 6.81030022e+00, 1.73244179e+00, - 6.50463350e+00, 5.97680624e+00, 1.31691165e+00, 4.10234979e+00, 7.63449444e+00, - 1.39082898e+01, -9.96245939e+00, -3.25461663e+00, 1.51760632e+01, -1.15296706e+01, - -3.37732662e+00, 1.21007828e+01, -1.06523614e+01, -3.82444376e+00, 1.43524418e+01, - -7.39241448e+00, 3.56923216e+00, 1.27091775e+01, -7.73508523e+00, 2.69144356e+00, - 1.40691294e+01, -7.71022717e+00, 5.37580268e+00, -1.00675908e+00, -1.38432193e+01, - -2.97327593e+00, 1.70353123e-01, -1.27373430e+01, -3.84661160e+00, -1.73060924e+00, - -1.47524708e+01, -4.44555342e+00, 1.19729669e+01, 1.20733431e+01, -1.09025244e+01, - 9.99274183e+00, 1.17436895e+01, -1.04749088e+01, 1.18702114e+01, 1.38183802e+01, - -1.18703636e+01, 8.87350781e+00, -2.48453830e+00, 1.15231984e+01, 8.12254908e+00, - -2.17080193e+00, 9.66660045e+00, 7.63740978e+00, -2.25628963e+00, 1.27883558e+01, - 7.00672454e+00, -7.64976099e+00, 9.18220677e+00, 7.32437430e+00, -8.06738688e+00, - 7.37415484e+00, 6.43037804e+00, -9.16811693e+00, 1.00843559e+01, 8.03480627e+00, - -1.37102624e+01, 6.42921056e+00, 7.19894411e+00, -1.29335143e+01, 7.92774287e+00, - 8.66077412e+00, -1.54183582e+01, 6.97959522e+00, 5.38843050e+00, -4.28167030e-01, - -1.51443836e-01, 4.36031236e+00, 6.15179755e-01, 1.11561161e+00, 6.61865298e+00, - 9.53834535e-01, -5.84401180e-01, 1.35501597e+00, 1.42545868e+00, -1.95721393e+00, - 9.18335400e-01, 3.27806467e+00, -1.49220028e+00, -2.33137187e-01, 9.05564928e-01, - -2.84057752e+00, 7.29756827e+00, -1.10870354e+01, 1.57980278e+00, 5.71466230e+00, - -1.17390022e+01, 7.22268454e-01, 6.80927105e+00, -1.17038612e+01, 3.26405193e+00, - -5.01975383e+00, 3.03973079e+00, 5.01794918e+00, -5.32441308e+00, 2.66702778e+00, - 3.16062835e+00, -5.48883063e+00, 4.90714636e+00, 5.28519501e+00, 1.62103241e+01, - -1.76560529e+00, 6.97472841e+00, 1.60801190e+01, -3.24935234e+00, 5.82579474e+00, - 1.77963247e+01, -1.01672498e+00, 6.12825446e+00, 3.80024484e+00, -3.34448566e+00, - 3.35091101e+00, 3.23139426e+00, -4.33013813e+00, 4.76447241e+00, 5.45818342e+00, - -4.06170044e+00, 2.88609058e+00, -2.29106555e+00, 8.27699077e+00, 1.09064600e+00, - -3.59302905e+00, 9.60437448e+00, 8.14797198e-01, -2.46438985e+00, 7.44183939e+00, - -5.48883046e-01, 1.25077487e+01, -1.18739711e+01, 6.65675297e+00, 1.26707463e+01, - -1.01264862e+01, 7.68378868e+00, 1.07093093e+01, -1.23594150e+01, 6.65739810e+00, - 8.60509597e+00, -7.60304481e+00, 4.63854382e+00, 9.02578016e+00, -5.87949593e+00, - 4.07482932e+00, 7.12403922e+00, -8.13379120e+00, 3.51070503e+00, -3.00012077e+00, - -6.53179460e+00, 8.59007709e+00, -3.93905553e+00, -5.85750020e+00, 9.99816090e+00, - -1.75352091e+00, -7.63786023e+00, 9.17090076e+00, 1.20655910e+00, 1.10365477e+01, - -1.09830488e+00, 6.09246061e-01, 1.15808414e+01, 5.61555958e-01, 2.73453294e+00, - 1.20648566e+01, -1.25111478e+00, 2.62638436e+01, 7.27406319e+00, -8.75588526e+00, - 2.56834674e+01, 5.56426063e+00, -8.04139770e+00, 2.82412254e+01, 7.33859615e+00, - -8.38692536e+00, 2.74104908e+00, -1.86292973e+01, -9.19589353e+00, 4.43387362e+00, - -1.87846089e+01, -9.91418570e+00, 1.87855716e+00, -1.89783535e+01, -1.09205196e+01, - 3.97947941e+00, -5.47257104e+00, -6.83899148e+00, 2.77379545e+00, -4.71009592e+00, - -5.43207979e+00, 4.09371918e+00, -3.94218484e+00, -7.84955906e+00, 1.00356554e+01, - -1.76389816e+01, 4.22779892e+00, 1.15089292e+01, -1.81197327e+01, 5.10668667e+00, - 1.01129107e+01, -1.89069149e+01, 2.93228675e+00, 1.77493187e+01, -1.18696630e+01, - 6.15072403e+00, 1.69455996e+01, -1.15938719e+01, 7.68457144e+00, 1.65835561e+01, - -1.12666150e+01, 5.00737837e+00, 1.18087642e+01, -1.60388415e+01, -1.00042403e+01, - 1.28761001e+01, -1.76032488e+01, -1.02550343e+01, 1.22292183e+01, -1.49850429e+01, - -1.12468680e+01, -5.96314832e+00, -6.31887619e+00, 1.34500300e+01, -5.34715059e+00, - -7.72600390e+00, 1.44440780e+01, -6.88656998e+00, -7.10836674e+00, 1.20318716e+01, - 1.10557748e+01, -1.59085722e+01, -5.04387646e+00, 1.01204107e+01, -1.60028369e+01, - -3.54596491e+00, 1.01659085e+01, -1.68147828e+01, -6.31941602e+00, -8.45427460e+00, - -2.65667497e+00, 6.91745263e+00, -6.74375125e+00, -1.90126068e+00, 7.19132870e+00, - -8.96376344e+00, -2.19363418e+00, 5.14498758e+00, -3.89182857e-01, -1.56888753e+01, - 2.32879823e+00, -1.30089714e+00, -1.66343724e+01, 9.12257571e-01, -1.14188798e+00, - -1.46359268e+01, 3.51386876e+00, 9.37211806e+00, 8.54468618e+00, -2.89250979e+00, - 8.78141523e+00, 9.73701187e+00, -4.32302866e+00, 8.41517272e+00, 7.08433969e+00, - -3.31834175e+00, -2.22955499e+00, -7.91668250e-01, -2.38386476e+01, -1.83492868e+00, - -5.00991552e-01, -2.57437208e+01, -2.69880773e+00, -2.55960022e+00, -2.36353985e+01, - 8.27387771e+00, -7.33575688e+00, -5.87942330e+00, 6.35092941e+00, -7.08113274e+00, - -6.27991783e+00, 8.93763592e+00, -6.51719245e+00, -7.49966962e+00, 2.78840510e+00, - -9.64941990e+00, 3.87609500e+00, 2.92156758e+00, -9.98374738e+00, 5.82207066e+00, - 1.38506984e+00, -8.31553711e+00, 4.00615367e+00, 1.07803427e+00, 1.59229763e-01, - 5.61183782e+00, 2.53864873e+00, -5.23310319e-01, 4.94295750e+00, 7.65852377e-01, - 1.80102640e+00, 4.69045864e+00, 9.11194385e+00, 3.31117500e+00, -4.99694516e-01, - 7.69970540e+00, 4.29870451e+00, -9.81299344e-02, 1.04928491e+01, 4.20896687e+00, - 7.07434059e-01, 2.38843651e+00, -9.25719293e+00, -9.78855489e+00, 1.36723765e+00, - -1.07359219e+01, -9.52936754e+00, 3.35064685e+00, -9.18585996e+00, -8.32908184e+00, - -1.43231528e+01, -6.45597217e+00, -4.46118807e-01, -1.35679796e+01, -8.08771676e+00, - 3.00320855e-01, -1.28697145e+01, -5.48665674e+00, -1.07547594e+00, 1.18110613e+01, - -1.16531694e+01, -7.86500448e+00, 1.33622440e+01, -1.18955804e+01, -8.98089540e+00, - 1.20009816e+01, -1.32121475e+01, -6.74890856e+00, -3.45863064e+00, 2.95792643e+00, - -6.42658349e+00, -4.60614013e+00, 4.23189006e+00, -7.22285576e+00, -4.53339575e+00, - 1.42190834e+00, -6.19058161e+00, 3.24364788e+00, 7.02915419e+00, -5.39215348e-01, - 2.39708876e+00, 8.97617965e+00, -4.20126044e-01, 2.22196985e+00, 6.22895666e+00, - 5.56327805e-01, 1.59984204e+01, -5.84287574e+00, 1.86363441e+01, 1.47801353e+01, - -4.84559303e+00, 1.93533925e+01, 1.76828486e+01, -4.66931904e+00, 1.86230162e+01, - 6.08237008e+00, -1.47299814e+01, -3.78247837e+00, 4.78901045e+00, -1.39028545e+01, - -2.67742636e+00, 5.53381502e+00, -1.64397207e+01, -4.20231347e+00, -7.50143750e+00, - -9.10652021e-01, -1.65044874e+00, -8.92524410e+00, -1.77729527e+00, -2.40806154e+00, - -6.42215400e+00, 1.15848502e-01, -2.75045541e+00, 4.89505746e+00, 1.50494897e-01, - -4.99621539e+00, 3.58312493e+00, 7.36814991e-01, -6.02014838e+00, 3.76068453e+00, - -7.84227605e-02, -3.11714262e+00, -6.04596705e+00, -1.16496551e+00, -7.32403541e+00, - -5.59894261e+00, -2.87674427e+00, -6.45698238e+00, -7.57587741e+00, -1.76917601e+00, - -8.43410745e+00, 9.18653546e+00, -2.93498856e+00, 2.68500255e+00, 1.06367956e+01, - -3.65150207e+00, 1.61132687e+00, 8.38250023e+00, -1.93721739e+00, 1.16504700e+00, - 1.81626625e+00, -3.49676977e+00, -2.66477091e+00, 2.53150870e-01, -2.48620331e+00, - -2.85322051e+00, 2.40622962e+00, -3.44596743e+00, -9.93811065e-01, -2.94171379e+00, - -1.15802091e+01, 1.09161095e+01, -1.83503870e+00, -1.27216331e+01, 1.19853877e+01, - -2.68174694e+00, -9.95836912e+00, 1.17372362e+01, 1.20695200e+01, 6.92946961e+00, - 1.49151598e+00, 1.24390565e+01, 7.58521727e+00, 3.11596461e+00, 1.02554837e+01, - 7.32440427e+00, 1.21067003e+00, 1.43493276e+01, -1.57856515e+00, 2.03568985e+00, - 1.33636654e+01, -2.85087860e+00, 2.83623937e+00, 1.35985432e+01, -1.40251297e+00, - 3.14717634e-01, 6.55740268e+00, -8.17481875e-01, 6.81465394e+00, 5.85552908e+00, - -2.29389688e+00, 6.09518757e+00, 6.99006081e+00, 2.96832928e-01, 5.51556803e+00, - -6.87704245e-01, -6.34197738e+00, 3.27981758e+00, -2.52168336e+00, -6.66243631e+00, - 3.19109582e+00, -3.52920568e-01, -4.48559485e+00, 2.57382443e+00, 1.09885570e+01, - 1.20134297e+01, 2.00488702e+01, 9.53804230e+00, 1.09072164e+01, 2.00175146e+01, - 1.20661894e+01, 1.14325396e+01, 1.87478346e+01, 2.15889011e+00, -2.38560921e+01, - 7.86816975e+00, 3.35910665e+00, -2.52233478e+01, 8.24868855e+00, 4.78545613e-01, - -2.46866501e+01, 7.71853200e+00, -6.73627901e-01, -2.15188712e+01, 8.17319475e-01, - -1.90340564e+00, -2.08759741e+01, 1.93195444e+00, 7.31174686e-01, -2.03629864e+01, - 9.02513546e-01 ] - -

- [ -4.02765830e+00, -3.16023137e+00, -6.88011833e+00, 6.46755190e-01, 1.53026954e+00, - -2.19506763e+00, -1.67835222e+00, -5.32155921e-01, -1.06085925e+00, -2.30471976e+00, - -3.52917704e+00, -3.94006174e+00, -7.34979987e-01, -2.10239481e-01, 7.18707512e-01, - 1.57005590e+00, 2.18516271e-01, 9.25232779e-01, 3.34019920e+00, -1.05455782e+01, - -6.37139586e+00, 1.26402730e-01, 1.25768619e-02, -3.09142555e-01, -8.39207249e-01, - -8.35248753e-01, -8.58037086e-01, 4.08421754e+00, 2.35572425e+00, -4.59257653e+00, - 3.17769176e-01, 2.33664714e+00, -1.33226716e+00, 6.13647976e-02, 9.14908453e-01, - 1.99621940e-01, -5.36433556e-01, 9.78577617e+00, 3.15100532e+00, -7.67098039e-02, - -2.68685188e-01, -2.21983725e+00, -4.40882737e-01, -1.71483915e-01, -7.17212520e-01, - 8.57637765e+00, 2.82256107e+00, 5.53177831e+00, 1.80559963e+00, 2.46786279e+00, - 1.51779938e+00, -2.02623211e+00, -5.78135941e-01, 1.49030327e+00, 1.07439175e+01, - 5.39180849e+00, -5.47784454e+00, 1.58381688e+00, 5.05886077e-01, 3.76803356e-01, - -1.38751615e+00, 2.95688436e-01, 1.58410366e+00, -2.80636045e+00, -4.90422672e+00, - -8.54444216e+00, -1.66361699e+00, 6.62247945e-01, 3.77915326e-01, -6.72869185e-01, - 1.70899114e+00, -1.39645304e+00, -8.89305852e+00, 8.87294193e-01, -6.25731915e+00, - -7.89802389e-01, -1.47434221e+00, 2.03450683e+00, 1.18483688e+00, -1.62130683e+00, - -9.66050236e-01, 1.79957758e+00, -1.91158836e+00, 1.52148414e+00, 1.02392868e+00, - 4.96524210e-01, -3.88683893e-01, 2.97483850e-01, -1.81675060e-01, -5.40274010e-01, - 7.56174836e+00, -4.17216519e+00, -2.04695415e-01, -1.07181836e+00, 4.49563846e-01, - 8.76759186e-01, -3.84162916e-01, -3.88527314e+00, -1.62530511e+00, 5.65454856e+00, - 2.91730118e+00, -3.90989881e+00, 1.54231359e+00, -2.21972512e-01, -4.51045558e-02, - 3.99416478e-01, -1.00950555e+00, 3.39184284e-01, 5.90140476e+00, -3.22770125e+00, - 7.82044643e+00, 2.09317553e-01, 2.68579455e-01, 6.63090432e-01, 1.44255027e+00, - -2.32917987e+00, 2.01606232e-01, -3.12618017e+00, 4.30261848e+00, -2.71378848e+00, - 1.85882366e+00, -1.61633781e-01, 2.64130322e-01, -4.46744495e-01, 1.31080074e+00, - 6.60114040e-01, -8.30310641e+00, 9.25745314e-01, 7.64332400e+00, -2.01002448e+00, - 2.30174903e-01, -1.23201926e+00, 2.66401112e-01, 6.12873234e-01, 1.13792494e+00, - -9.92961866e-01, 1.40104874e+00, -1.54976667e+00, -2.09460862e+00, -1.11318979e+00, - -6.77879296e-01, -1.48922489e+00, 5.77486551e-01, 8.95837254e-02, 7.19296755e-01, - -2.14225094e-01, 5.13432993e+00, 8.13091174e-02, 3.19785272e-01, 2.05804267e+00, - -7.06147577e-01, 1.19400637e+00, -1.09844364e+00, -9.70764522e-01, -9.63044853e+00, - 9.95372411e+00, 1.10906246e+00, -5.38801179e-01, 2.52658243e+00, 4.24814703e-01, - 3.51643210e-01, 2.65609594e-01, 3.20325937e+00, -3.83370547e-01, 5.46853459e+00, - -3.80891311e-01, -5.78597893e-01, 1.00601378e+00, -1.94028707e+00, 8.53963967e-01, - -1.04905411e-01, -2.10817786e-01, 4.75283908e+00, -2.80392819e+00, -5.34639991e-01, - -1.04298964e+00, -2.56306844e-02, -6.25008824e-01, -1.09859980e+00, 5.12861463e-01, - 7.24710437e+00, -6.36295046e+00, -4.66028066e+00, 1.51129191e-01, -3.51535018e-01, - 1.01099172e+00, -5.30210104e-01, -5.26844762e-01, -1.07618887e-01, -1.32849603e+01, - -7.81488092e+00, -1.18072980e+00, -9.30213958e-01, -1.94013976e-01, 6.33616430e-01, - 1.19898755e+00, -2.30617292e+00, 2.61701779e+00, 7.71101489e+00, 1.60726495e+00, - -2.40983274e+00, -1.16338678e+00, 1.88871931e-01, 1.71770472e+00, -4.64385501e-02, - 1.39155166e+00, -1.74835047e+00, -1.41568360e+00, -2.86578718e+00, 5.52999030e+00, - -2.24926040e+00, -3.61432769e-01, -1.12630561e+00, 1.68660194e+00, -2.49880250e+00, - -7.77272175e-01, -3.01543784e+00, 6.03277807e+00, 2.86043016e+00, -2.12976635e-01, - 2.01492967e+00, -1.78760816e+00, -6.61890776e-01, -1.30111518e+00, 9.38199658e-01, - 4.99052574e+00, -3.20148706e+00, -4.28580193e+00, -1.76106567e+00, -2.18336915e+00, - -5.12765262e-01, 1.10394817e+00, -7.30500839e-01, 2.46295960e+00, 1.16724054e+00, - -3.43835368e+00, 3.35366912e+00, -9.52601684e-01, -1.21651126e+00, 1.85209383e+00, - 2.44758034e+00, -1.24989641e+00, -1.42092175e-01, 9.30070829e-02, -1.00986313e+01, - 3.71453120e+00, -1.57124704e+00, -1.57842572e-01, 2.80923890e-01, 9.74670118e-01, - -6.44852652e-01, -8.06646424e-01, -2.64682957e+00, -1.04039827e+01, -1.28501080e+01, - 1.68550729e+00, 6.62379774e-01, -1.08806618e+00, -5.42781546e-02, -2.12338052e+00, - -7.09371750e-01, -2.86715414e+00, -2.89936794e+00, 1.39691277e+00, -7.03065772e-01, - -4.01449140e-01, -4.40156839e-01, -1.39532149e+00, -1.55399108e+00, 2.18289212e-01, - 3.92577101e+00, -6.97357837e+00, 7.06725283e+00, -4.66206715e-01, -1.69782685e+00, - -1.08672806e+00, -2.30218438e+00, 1.65965573e+00, 2.07218951e+00, 4.66525729e+00, - 1.26098992e+01, -4.00067984e+00, -7.35377098e-01, 1.50851886e+00, -1.64387393e+00, - -1.62093913e+00, 1.29255558e+00, 2.57817323e+00, 4.40735433e+00, -1.51360322e+00, - 9.76654291e+00, -2.55092007e+00, 1.55729978e+00, 1.22987852e+00, -1.41074169e+00, - 1.68281967e+00, -4.22655643e+00, -7.24433989e+00, -4.51111007e+00, 3.50913442e-01, - 3.92032331e-01, 1.68475390e+00, -1.38236289e+00, 2.16342139e-01, 4.02620945e-01, - 1.58645468e+00, -2.42720323e+00, -2.88063493e+00, -2.43603217e+00, 6.39552310e-01, - -1.23633810e+00, -1.75135112e+00, -1.61746470e+00, 5.66089197e-01, -1.19265022e+00, - -4.45566252e+00, 1.46674521e+00, -1.62711333e+00, -9.79802117e-01, -2.69954658e+00, - 1.00992706e+00, 4.79890537e-01, -2.24175980e+00, 9.71855533e-01, 5.76489712e+00, - -6.64159634e+00, -1.21802309e+01, -1.07858699e-01, 6.62944859e-01, -1.81036037e+00, - -6.50039954e-01, 7.18291481e-01, 9.49026400e-01, 5.46607017e+00, 8.67055746e+00, - 6.89907713e-01, -8.89380803e-01, 7.82411332e-01, 2.33811329e-01, 1.90045957e+00, - -1.43146248e+00, -1.20403128e+00, 5.34999992e+00, -5.37143672e-01, -7.42224616e-01, - 1.14401389e+00, -2.02676171e+00, 7.25767787e-01, 1.38819101e+00, -1.07684631e+00, - 2.11049922e+00, 4.94613560e+00, -2.47629465e+00, -4.81220995e+00, -3.62407656e+00, - -6.21428478e-01, 2.48121999e+00, 4.89964677e-01, 1.94082430e+00, 1.75503578e-01, - 4.64198784e+00, -5.28542267e+00, 1.87467637e+00, -8.36058746e-01, 2.89787801e-01, - -1.50441306e-01, -1.57859573e+00, -4.54015547e-01, -6.22336881e-01, 7.79080554e+00, - 3.85125618e+00, -2.88449914e+00, 4.03841820e-01, 5.42378712e-01, 1.73163636e+00, - -8.49431866e-01, 4.23521295e-01, 3.47485965e-01, -3.84957440e+00, 4.57855459e+00, - 7.17096730e+00, 1.88463955e+00, 1.71916155e+00, 1.69169705e+00, 1.02318947e+00, - -2.43890026e-01, 3.02909344e-01, 5.14240978e+00, -1.23371036e+00, 1.14767194e+00, - -8.54565063e-01, 1.50345811e+00, -5.15548466e-01, 3.10364515e-02, -7.48013507e-01, - 4.36977353e-01, -7.47807746e+00, 6.27566212e+00, 1.87739418e+00, 1.26082206e+00, - -6.17876533e-02, -6.51088895e-01, -1.28752643e+00, 9.40911536e-02, 2.24710031e-01, - -8.60913146e+00, 3.13634246e+00, -5.22275443e+00, -2.00695888e+00, 3.89703254e-01, - 4.69470837e-02, -1.42436128e+00, 1.09837492e+00, -6.95885886e-01, 2.63575791e+00, - 5.20132739e+00, -2.48589051e+00, -1.06453295e+00, -2.03802874e+00, -8.44154407e-01, - -1.90732616e+00, -4.50714573e-01, 8.73494630e-01, -3.09347871e+00, -2.49271916e+00, - 2.55373723e+00, 2.18455516e+00, -2.15960624e+00, -1.35163423e+00, 1.55154456e+00, - -6.16741959e-02, 5.97961238e-01, -1.29709652e-02, 4.03233615e+00, -2.89978788e+00, - -9.23892726e-01, -9.99338701e-02, -8.88772142e-01, -5.08559082e-01, 1.12082844e+00, - 1.23042350e+00, -5.65678688e+00, 3.90278929e+00, 1.58369961e+00, 1.54060894e+00, - 1.20331859e+00, 3.02411668e+00, 1.97412122e+00, -3.35319919e-01, 1.09255916e-01, - 4.76458711e+00, 3.15184088e+00, -1.21439625e+01, 9.39418898e-01, 1.43614538e-01, - -8.71666677e-01, 6.68427271e-02, 1.02012295e+00, 1.82573777e-01, 5.88240113e-01, - 6.44210105e+00, -5.67351310e-01, -1.85489322e+00, -5.02684523e-01, 6.05553861e-02, - 1.76710710e-01, -2.02505386e+00, -1.41940272e+00, 4.15874511e+00, 1.30142366e+01, - 1.40701259e+00, 1.98563976e+00, 1.23602998e+00, -5.64438487e-01, -1.09987142e+00, - -1.95882860e-01, -1.73178964e+00, -5.59174795e+00, 1.36496200e+01, 3.56245544e+00, - -1.66428666e+00, -2.21370979e-01, 6.37547650e-01, 1.27997883e-01, 4.08643296e-01, - -1.21172144e+00, -4.01016350e-01, -5.57590252e+00, -8.90880408e+00, -2.37565308e+00, - -1.80892597e-01, 2.29027900e+00, 1.00249387e+00, 1.82021769e+00, 3.58229650e-01, - 2.07814011e-01, -6.04090738e+00, -4.42046679e+00, 8.80624118e-01, -1.67505974e-01, - 1.26718922e+00, -1.19360672e-01, 2.28569512e+00, 2.55251102e+00, 5.92740372e+00, - 1.76594769e+01, -5.29238134e-01, -2.21418228e+00, 1.96654873e+00, -1.46373470e+00, - 2.73622576e-02, 3.19472484e+00, 1.81582156e+00, 4.49426744e+00, -4.55970942e+00, - 9.33984742e+00, -6.49580638e-01, -2.29683261e-01, 1.31664350e+00, 2.26546880e-01, - 5.56581079e-01, 2.65156828e-01, -2.09260328e+00, -1.05341376e+00, 3.26833856e+00, - 1.04515423e-01, 1.89093396e+00, 7.92865605e-01, -4.98700350e-02, 1.57796084e+00, - -1.28357407e+00, -4.42784886e+00, -2.42557309e+00, 4.26836218e+00, 1.09690039e+00, - 1.18463101e+00, 1.75466877e+00, -1.14322099e+00, 2.43708040e+00, -1.44543158e+00, - -1.60552469e+00, 4.55175566e-01, -9.25674731e-01, -9.22299171e-01, -1.76795613e+00, - -9.32968169e-01, -1.57739533e+00, -1.20199857e-01, -5.55904036e-01, -1.73947725e+00, - -4.24156667e+00, 5.90537105e+00, -2.62989661e-01, -6.26245215e-01, 4.91116432e-01, - 1.09954587e+00, 1.99217319e+00, 9.78589205e-01, 4.23093659e+00, -4.87338632e+00, - -7.01468491e-01, -8.39465960e-01, 5.88624039e-01, 8.01985241e-02, 2.71379766e+00, - -1.00809113e+00, -2.81042990e-01, -1.20095635e+01, -2.29213926e+00, 3.19024062e+00, - -1.58003258e+00, -2.43456480e+00, 9.72091106e-01, 8.17191111e-01, 1.18797677e+00, - 1.71905046e+00 ] -

- - [ 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, - 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, - 1.83747161e+03, 2.91643931e+04, 1.83747161e+03, 1.83747161e+03, 2.91643931e+04, - 1.83747161e+03, 1.83747161e+03 ] - - - [ O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H, O, H, H, - O, H, H, O, H, - H, O, H, H, O, - H, H ] - -
- - [ 1.96756566e+01, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.96756566e+01, - 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.96756566e+01 ] - -
-
From 7a0fdd5d2b49906cebf2d596e99db53adf68bf42 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 10:23:52 +0000 Subject: [PATCH 28/47] added REAMDE for mace example --- examples/clients/mace/README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 examples/clients/mace/README.md diff --git a/examples/clients/mace/README.md b/examples/clients/mace/README.md new file mode 100644 index 000000000..3b8f24ef3 --- /dev/null +++ b/examples/clients/mace/README.md @@ -0,0 +1,28 @@ +# MACE Example + +Runs an example of the pretrained [MACE model](https://github.com/ACEsuit/mace-mp/releases/download/mace_mp_0c/mace-small-density-agnesi-stress.model) for simple molecular dynamics of liquid water at 300 K. + +## Installation + +To be able to run MACE, check out the installation instructions at [https://github.com/ACEsuit/mace/tree/main?tab=readme-ov-file#installation](https://github.com/ACEsuit/mace/tree/main?tab=readme-ov-file#installation). + +## Running the Example + +To download the pretrained [MACE model](https://github.com/ACEsuit/mace-mp/releases/download/mace_mp_0c/mace-small-density-agnesi-stress.model): + +```bash +bash getmodel.sh +``` + +Then, run the following to start the i-PI simulation: + +```bash +i-pi input.xml & sleep 10 +i-pi-py_driver -a driver -u -m mace -o init.xyz,mace.model +``` + +### Options (after `-o`) + +- Path to a template file, used to retrieve the types for all atoms in the system. +- Path to the model file. + From bbf7428ed1f0893921f1c681776242b91fc15160 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 12:30:42 +0000 Subject: [PATCH 29/47] removed debug print statement --- ipi/inputs/motion/dynamics.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ipi/inputs/motion/dynamics.py b/ipi/inputs/motion/dynamics.py index 2a9ae7931..e4571c74d 100644 --- a/ipi/inputs/motion/dynamics.py +++ b/ipi/inputs/motion/dynamics.py @@ -144,5 +144,4 @@ def fetch(self): rv = super(InputDynamics, self).fetch() rv["mode"] = self.mode.fetch() rv["splitting"] = self.splitting.fetch() - print(self) return rv From a7bdf7519a179d0c0722f5f23dffd95e8410c820 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 13:39:09 +0000 Subject: [PATCH 30/47] streamlining the output of i-PI --- ipi/engine/initializer.py | 10 +++++----- ipi/engine/simulation.py | 14 +++++++------- ipi/engine/system.py | 4 ++-- ipi/interfaces/sockets.py | 18 +++++++++--------- ipi/utils/io/__init__.py | 2 +- ipi/utils/io/io_units.py | 2 +- ipi/utils/prng.py | 2 +- ipi/utils/softexit.py | 8 ++++---- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ipi/engine/initializer.py b/ipi/engine/initializer.py index 03ee134ad..e609502b7 100644 --- a/ipi/engine/initializer.py +++ b/ipi/engine/initializer.py @@ -123,7 +123,7 @@ def init_file( ratoms = [] info( - " # Initializing from file %s. Dimension: %s, units: %s, cell_units: %s" + " @init_file: Initializing from file %s. Dimension: %s, units: %s, cell_units: %s" % (filename, dimension, units, cell_units), verbosity.low, ) @@ -283,7 +283,7 @@ def set_vector(iif, dq, rq): res = nm_rescale(nbeads, dbeads) # path rescaler if nbeads != dbeads: info( - " # Initialize is rescaling from %5d beads to %5d beads" + " @set_vector: Initialize is rescaling from %5d beads to %5d beads" % (nbeads, dbeads), verbosity.low, ) @@ -368,7 +368,7 @@ def init_stage1(self, simul): for k, v in self.queue: info( - " # Initializer (stage 1) parsing " + str(k) + " object.", + " @initializer: Initializer (stage 1) parsing " + str(k) + " object.", verbosity.high, ) @@ -491,7 +491,7 @@ def init_stage1(self, simul): rtemp = simul.ensemble.temp else: info( - " # Resampling velocities at temperature %s %s" + " @initializer: Resampling velocities at temperature %s %s" % (v.value, v.units), verbosity.low, ) @@ -615,7 +615,7 @@ def init_stage2(self, simul): for k, v in self.queue: info( - " # Initializer (stage 2) parsing " + str(k) + " object.", + " @initializer: Initializer (stage 2) parsing " + str(k) + " object.", verbosity.high, ) diff --git a/ipi/engine/simulation.py b/ipi/engine/simulation.py index ce896971f..e9e7f49c4 100644 --- a/ipi/engine/simulation.py +++ b/ipi/engine/simulation.py @@ -108,8 +108,8 @@ def load_from_xml( # echo the input file if verbose enough if verbosity.low: - print(" # i-PI loaded input file: ", fn_input) - elif verbosity.medium: + print(" @simulation: i-PI loaded input file: ", fn_input) + if verbosity.medium: print(" --- begin input file content ---") ifile = open(fn_input, "r") for line in ifile.readlines(): @@ -151,7 +151,7 @@ def __init__( cumulative total. """ - info(" # Initializing simulation object ", verbosity.low) + info(" @simulation: Initializing simulation object ", verbosity.low) self.prng = prng self.mode = mode self.threading = threads @@ -268,7 +268,7 @@ def softexit(self): if self.step < self.tsteps: self.step += 1 if not self.rollback: - info("SOFTEXIT: Saving the latest status at the end of the step") + info(" @simulation.softexit: Saving the latest status at the end of the step") self.chk.store() self.chk.write(store=False) @@ -377,7 +377,7 @@ def run(self): or (verbosity.low and self.step % 1000 == 0) ): info( - " # Average timings at MD step % 7d. t/step: %10.5e" + " @simulation.run: Average timings at MD step % 7d. t/step: %10.5e" % (self.step, ttot / cstep) ) cstep = 0 @@ -396,11 +396,11 @@ def run(self): info(line) if os.path.exists("EXIT"): - info(" # EXIT file detected! Bye bye!", verbosity.low) + info(" @simulation.run: EXIT file detected! Bye bye!", verbosity.low) break if (self.ttime > 0) and (time.time() - simtime > self.ttime): - info(" # Wall clock time expired! Bye bye!", verbosity.low) + info(" @simulation.run: Wall clock time expired! Bye bye!", verbosity.low) break self.rollback = False diff --git a/ipi/engine/system.py b/ipi/engine/system.py index 7f5c2e65a..dd7c99d83 100644 --- a/ipi/engine/system.py +++ b/ipi/engine/system.py @@ -61,7 +61,7 @@ def __init__( systems. """ - info(" # Initializing system object ", verbosity.low) + info(" @system: Initializing system object ", verbosity.low) self.prefix = prefix self.init = init self.ensemble = ensemble @@ -82,7 +82,7 @@ def bind(self, simul): self.simul = simul # keeps a handle to the parent simulation object # binds important computation engines - info(" # Binding the forces ", verbosity.low) + info(" @system.bind: Binding the forces ", verbosity.low) self.forces.bind( self.beads, self.cell, diff --git a/ipi/interfaces/sockets.py b/ipi/interfaces/sockets.py index 8c9c17810..e6ccb134b 100644 --- a/ipi/interfaces/sockets.py +++ b/ipi/interfaces/sockets.py @@ -486,11 +486,11 @@ def getforce(self): if mxtra: try: mxtradict = json.loads(mxtra) - info("Extra string JSON has been loaded.", verbosity.debug) + info("@driver.getforce: Extra string JSON has been loaded.", verbosity.debug) except: # if we can't parse it as a dict, issue a warning and carry on info( - "Extra string could not be loaded as a dictionary. Extra=" + mxtra, + "@driver.getforce: Extra string could not be loaded as a dictionary. Extra=" + mxtra, verbosity.debug, ) mxtradict = {} @@ -654,7 +654,7 @@ def open(self): try: self.server.bind(self.sockets_prefix + self.address) info( - "Created unix socket with address " + self.address, verbosity.medium + " @interfacesocket.open: Created unix socket with address " + self.address, verbosity.medium ) except socket.error: raise RuntimeError( @@ -676,7 +676,7 @@ def open(self): self.server.bind((self.address, self.port)) info( - "Created inet socket with address " + " @interfacesocket.open: Created inet socket with address " + self.address + " and port number " + str(self.port), @@ -700,7 +700,7 @@ def open(self): def close(self): """Closes down the socket.""" - info(" @SOCKET: Shutting down the driver interface.", verbosity.low) + info(" @interfacesocket.close: Shutting down the driver interface.", verbosity.low) for c in self.clients: try: @@ -718,7 +718,7 @@ def close(self): self.server.close() except: info( - " @SOCKET: Problem shutting down the server socket. Will just continue and hope for the best.", + " @interfacesocket.close: Problem shutting down the server socket. Will just continue and hope for the best.", verbosity.low, ) if self.mode == "unix": @@ -795,7 +795,7 @@ def pool_update(self): client.settimeout(TIMEOUT) driver = Driver(client) info( - " @SOCKET: Client asked for connection from " + " @interfacesocket.pool_update: Client asked for connection from " + str(address) + ". Now hand-shaking.", verbosity.low, @@ -805,7 +805,7 @@ def pool_update(self): driver.exit_on_disconnect = self.exit_on_disconnect self.clients.append(driver) info( - " @SOCKET: Handshaking was successful. Added to the client list.", + " @interfacesocket.pool_update: Handshaking was successful. Added to the client list.", verbosity.low, ) self.poll_iter = UPDATEFREQ # if a new client was found, will try again harder next time @@ -948,7 +948,7 @@ def dispatch_free_client(self, fc, match_ids="any", send_threads=[]): r["status"] = "Running" self.prlist.remove(r) info( - " @SOCKET: %s Assigning [%5s] request id %4s to client with last-id %4s (% 3d/% 3d : %s)" + " @interfacesocket.dispatch_free_client: %s Assigning [%5s] request id %4s to client with last-id %4s (% 3d/% 3d : %s)" % ( time.strftime("%y/%m/%d-%H:%M:%S"), match_ids, diff --git a/ipi/utils/io/__init__.py b/ipi/utils/io/__init__.py index bd0a076b7..df9c62bd3 100644 --- a/ipi/utils/io/__init__.py +++ b/ipi/utils/io/__init__.py @@ -456,7 +456,7 @@ def open_backup(filename, mode="r", buffering=-1): if fn_backup != filename: os.rename(filename, fn_backup) info( - "Backup performed: {0:s} -> {1:s}".format(filename, fn_backup), + " @open_backup: Backup performed: {0:s} -> {1:s}".format(filename, fn_backup), verbosity.low, ) diff --git a/ipi/utils/io/io_units.py b/ipi/utils/io/io_units.py index 059b61e21..64ef7fe68 100755 --- a/ipi/utils/io/io_units.py +++ b/ipi/utils/io/io_units.py @@ -113,7 +113,7 @@ def process_units( ) info( - " # Interpreting input with dimension %s, units %s and cell units %s" + " @process_units: Interpreting input with dimension %s, units %s and cell units %s" % (dimension, units, cell_units), verbosity.high, ) diff --git a/ipi/utils/prng.py b/ipi/utils/prng.py index c73bfb307..f5fbcbcfe 100644 --- a/ipi/utils/prng.py +++ b/ipi/utils/prng.py @@ -60,7 +60,7 @@ def __init__(self, seed=-1, state=None, n_threads=1): if threading.current_thread() == threading.main_thread(): info( - "@ RANDOM SEED: The seed used in this calculation was " + " @random: The seed used in this calculation was " + str(self.seed), verbosity.low, ) diff --git a/ipi/utils/softexit.py b/ipi/utils/softexit.py index a49924785..a60e0db3a 100644 --- a/ipi/utils/softexit.py +++ b/ipi/utils/softexit.py @@ -77,17 +77,17 @@ def trigger(self, status="restartable", message=""): message: The message to output to standard output. """ - print("SOFTEXIT CALLED FROM THREAD", threading.currentThread(), message) + print(" @softexit.trigger: SOFTEXIT CALLED FROM THREAD", threading.currentThread(), message) if not self.triggered: # avoid double calls from different threads self.exiting = True self.triggered = True if status == "restartable": - message += "\nRestartable as is: YES." + message += " Restartable as is: YES." elif status == "success": - message += "\nI-PI reports success. Restartable as is: NO." + message += " I-PI reports success. Restartable as is: NO." elif status == "bad": - message += "\nI-PI reports a problem. Restartable as is: NO." + message += " I-PI reports a problem. Restartable as is: NO." else: raise ValueError("Unknown option for softexit status.") From b71e2ee202e2e74899a96c188a5a944bace21964 Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 13:44:55 +0000 Subject: [PATCH 31/47] another print statement that shows up in remd --- ipi/inputs/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipi/inputs/system.py b/ipi/inputs/system.py index 2d69bc82f..82fe28969 100644 --- a/ipi/inputs/system.py +++ b/ipi/inputs/system.py @@ -90,7 +90,7 @@ def fetch(self): for label, to_insert in sorted(zip(labels, ins), reverse=True): # sort from longest to smallest label, to avoid replacing 'string' in 'string1' sys = sys.replace(label, to_insert) - print("Generating system from template: \n", sys) + print(" @inputsystemplate.fetch: Generating system from template:", sys) xsys = xml_parse_string(sys) # parses the string to an XML object isys = InputSystem() isys.parse( From 521a03f93159eb075d7749427cc727acbaefabde Mon Sep 17 00:00:00 2001 From: Venkat Kapil Date: Wed, 13 Nov 2024 13:48:57 +0000 Subject: [PATCH 32/47] style --- ipi/engine/simulation.py | 8 ++++++-- ipi/interfaces/sockets.py | 17 +++++++++++++---- ipi/utils/io/__init__.py | 4 +++- ipi/utils/prng.py | 3 +-- ipi/utils/softexit.py | 6 +++++- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/ipi/engine/simulation.py b/ipi/engine/simulation.py index e9e7f49c4..7031c8b8e 100644 --- a/ipi/engine/simulation.py +++ b/ipi/engine/simulation.py @@ -268,7 +268,9 @@ def softexit(self): if self.step < self.tsteps: self.step += 1 if not self.rollback: - info(" @simulation.softexit: Saving the latest status at the end of the step") + info( + " @simulation.softexit: Saving the latest status at the end of the step" + ) self.chk.store() self.chk.write(store=False) @@ -400,7 +402,9 @@ def run(self): break if (self.ttime > 0) and (time.time() - simtime > self.ttime): - info(" @simulation.run: Wall clock time expired! Bye bye!", verbosity.low) + info( + " @simulation.run: Wall clock time expired! Bye bye!", verbosity.low + ) break self.rollback = False diff --git a/ipi/interfaces/sockets.py b/ipi/interfaces/sockets.py index e6ccb134b..8aecbb35a 100644 --- a/ipi/interfaces/sockets.py +++ b/ipi/interfaces/sockets.py @@ -486,11 +486,15 @@ def getforce(self): if mxtra: try: mxtradict = json.loads(mxtra) - info("@driver.getforce: Extra string JSON has been loaded.", verbosity.debug) + info( + "@driver.getforce: Extra string JSON has been loaded.", + verbosity.debug, + ) except: # if we can't parse it as a dict, issue a warning and carry on info( - "@driver.getforce: Extra string could not be loaded as a dictionary. Extra=" + mxtra, + "@driver.getforce: Extra string could not be loaded as a dictionary. Extra=" + + mxtra, verbosity.debug, ) mxtradict = {} @@ -654,7 +658,9 @@ def open(self): try: self.server.bind(self.sockets_prefix + self.address) info( - " @interfacesocket.open: Created unix socket with address " + self.address, verbosity.medium + " @interfacesocket.open: Created unix socket with address " + + self.address, + verbosity.medium, ) except socket.error: raise RuntimeError( @@ -700,7 +706,10 @@ def open(self): def close(self): """Closes down the socket.""" - info(" @interfacesocket.close: Shutting down the driver interface.", verbosity.low) + info( + " @interfacesocket.close: Shutting down the driver interface.", + verbosity.low, + ) for c in self.clients: try: diff --git a/ipi/utils/io/__init__.py b/ipi/utils/io/__init__.py index df9c62bd3..b6efb5609 100644 --- a/ipi/utils/io/__init__.py +++ b/ipi/utils/io/__init__.py @@ -456,7 +456,9 @@ def open_backup(filename, mode="r", buffering=-1): if fn_backup != filename: os.rename(filename, fn_backup) info( - " @open_backup: Backup performed: {0:s} -> {1:s}".format(filename, fn_backup), + " @open_backup: Backup performed: {0:s} -> {1:s}".format( + filename, fn_backup + ), verbosity.low, ) diff --git a/ipi/utils/prng.py b/ipi/utils/prng.py index f5fbcbcfe..4904bc25c 100644 --- a/ipi/utils/prng.py +++ b/ipi/utils/prng.py @@ -60,8 +60,7 @@ def __init__(self, seed=-1, state=None, n_threads=1): if threading.current_thread() == threading.main_thread(): info( - " @random: The seed used in this calculation was " - + str(self.seed), + " @random: The seed used in this calculation was " + str(self.seed), verbosity.low, ) diff --git a/ipi/utils/softexit.py b/ipi/utils/softexit.py index a60e0db3a..70b675c40 100644 --- a/ipi/utils/softexit.py +++ b/ipi/utils/softexit.py @@ -77,7 +77,11 @@ def trigger(self, status="restartable", message=""): message: The message to output to standard output. """ - print(" @softexit.trigger: SOFTEXIT CALLED FROM THREAD", threading.currentThread(), message) + print( + " @softexit.trigger: SOFTEXIT CALLED FROM THREAD", + threading.currentThread(), + message, + ) if not self.triggered: # avoid double calls from different threads self.exiting = True self.triggered = True From 3fdc4f1899ce427d6b8f4fdbeec29054bc1e6284 Mon Sep 17 00:00:00 2001 From: EliaStocco Date: Wed, 13 Nov 2024 16:18:19 +0100 Subject: [PATCH 33/47] fixing bug visible only when using debugpy --- drivers/py/driver.py | 4 ++-- ipi/pes/elphmod.py | 30 ++++++++++++++++++------------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/py/driver.py b/drivers/py/driver.py index 98cab93f4..1877613e1 100755 --- a/drivers/py/driver.py +++ b/drivers/py/driver.py @@ -115,8 +115,8 @@ def run_driver( nat = recv_data(sock, np.int32()) if len(pos) == 0: # shapes up the position array - pos.resize((nat, 3)) - force.resize((nat, 3)) + pos.resize((nat, 3), refcheck=False) + force.resize((nat, 3), refcheck=False) else: if len(pos) != nat: raise RuntimeError("Atom number changed during i-PI run") diff --git a/ipi/pes/elphmod.py b/ipi/pes/elphmod.py index f4068d1c4..4fa55484f 100644 --- a/ipi/pes/elphmod.py +++ b/ipi/pes/elphmod.py @@ -1,6 +1,7 @@ """Interface with [elphmod](https://github.com/janberges/elphmod) MD driver.""" import sys +import os from .dummy import Dummy_driver from ipi.utils.messages import verbosity, warning @@ -13,21 +14,26 @@ class ModelIIIDriver(Dummy_driver): """Wrapper around elphmod MD driver. A pickled driver instance is required (see elphmod.md.Driver.save). - Example: python3 driver.py -u -m elphmod -o driver.pickle + Example: python3 driver.py -u -m elphmod -o driver=driver.pickle """ - def check_parameters(self): - """Check arguments and load driver instance.""" - warning( - "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", - verbosity.low, - ) + def __init__(self, *args, **kwargs): import elphmod - - if len(self.args) != 1: - sys.exit(self.__doc__) - - self.driver = elphmod.md.Driver.load(self.args[0]) + from icecream import ic + + ic(args) + ic(kwargs) + filename = kwargs["driver"] + if not os.path.exists(filename): + raise ValueError(f"File '{filename}' does not exist.") + self.driver = elphmod.md.Driver.load(filename) + if self.driver is None: + raise ValueError( + f"Some error occured within `ModelIIIDriver.__init__` when trying to load the driver from file '{filename}'." + ) + del kwargs["driver"] + super().__init__(*args, **kwargs) + pass def __call__(self, cell, pos): """Calculate energy and forces for given structure.""" From 5fb46489cb7a4078cae2cfc36811426071fcd181 Mon Sep 17 00:00:00 2001 From: EliaStocco Date: Wed, 13 Nov 2024 16:18:58 +0100 Subject: [PATCH 34/47] modified Makefile --- examples/clients/elphmod/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/clients/elphmod/Makefile b/examples/clients/elphmod/Makefile index 1561650d4..60e3ecf40 100644 --- a/examples/clients/elphmod/Makefile +++ b/examples/clients/elphmod/Makefile @@ -22,7 +22,7 @@ driver $(DRIVER): driver.py $(MODEL) run $(RUN): input.xml $(DRIVER) $(IPI) $< & sleep 5 - i-pi-driver-py -u -m elphmod -o $(word 2,$^) + i-pi-driver-py -u -m elphmod -o driver=driver.pickle wait run2: input.xml run.py $(DRIVER) From 4eb57307ab8e54139bb4c9a6c79921ac53e7197b Mon Sep 17 00:00:00 2001 From: EliaStocco Date: Wed, 13 Nov 2024 16:22:03 +0100 Subject: [PATCH 35/47] preparing PR --- ipi/pes/elphmod.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ipi/pes/elphmod.py b/ipi/pes/elphmod.py index 4fa55484f..79b4161a4 100644 --- a/ipi/pes/elphmod.py +++ b/ipi/pes/elphmod.py @@ -1,11 +1,8 @@ """Interface with [elphmod](https://github.com/janberges/elphmod) MD driver.""" -import sys import os from .dummy import Dummy_driver -from ipi.utils.messages import verbosity, warning - __DRIVER_NAME__ = "elphmod" __DRIVER_CLASS__ = "ModelIIIDriver" @@ -19,10 +16,7 @@ class ModelIIIDriver(Dummy_driver): def __init__(self, *args, **kwargs): import elphmod - from icecream import ic - ic(args) - ic(kwargs) filename = kwargs["driver"] if not os.path.exists(filename): raise ValueError(f"File '{filename}' does not exist.") From c908ff82682fc249c94ab5926a7d2963d6bfc4e6 Mon Sep 17 00:00:00 2001 From: Mariana Rossi 2 Date: Wed, 13 Nov 2024 18:24:58 +0100 Subject: [PATCH 36/47] This fixes the multiple outputs of random seed to standard output. It also fixes a small syntax warning. --- ipi/engine/simulation.py | 7 +++++++ ipi/inputs/forcefields.py | 2 +- ipi/inputs/prng.py | 1 - ipi/inputs/simulation.py | 2 +- ipi/utils/prng.py | 9 --------- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ipi/engine/simulation.py b/ipi/engine/simulation.py index ce896971f..a90e3f470 100644 --- a/ipi/engine/simulation.py +++ b/ipi/engine/simulation.py @@ -21,6 +21,7 @@ from ipi.utils.softexit import softexit import ipi.engine.outputs as eoutputs import ipi.inputs.simulation as isimulation +import threading from concurrent.futures import ThreadPoolExecutor @@ -161,6 +162,12 @@ def __init__( self.syslist = syslist for s in syslist: s.prng = self.prng # bind the system's prng to self prng + if threading.current_thread() == threading.main_thread(): + info( + "@ RANDOM SEED: The seed used in this calculation was " + + str(self.prng.seed), + verbosity.low, + ) s.init.init_stage1(s) # TODO - does this have any meaning now that we introduce the smotion class? diff --git a/ipi/inputs/forcefields.py b/ipi/inputs/forcefields.py index a8fcd6467..2da101e44 100644 --- a/ipi/inputs/forcefields.py +++ b/ipi/inputs/forcefields.py @@ -445,7 +445,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. " - "Implemented options are: 'atomic_unit', 'ev/ang\^2'", + r"Implemented options are: 'atomic_unit', 'ev/ang\^2'", "dimension": "hessian", }, ), diff --git a/ipi/inputs/prng.py b/ipi/inputs/prng.py index 2fa5ca34b..78e386aae 100644 --- a/ipi/inputs/prng.py +++ b/ipi/inputs/prng.py @@ -51,7 +51,6 @@ class InputRandom(Input): InputValue, { "dtype": int, - # "default": 123456, "default": -1, "help": "This specifies the seed number used to generate the initial state of the random number generator. Previously, the default seed was fixed as 123456. Currently, the default seed is random and given by the system time (down to ms). This is done in utils/prng.py.", }, diff --git a/ipi/inputs/simulation.py b/ipi/inputs/simulation.py index 56b8666a3..febc226f0 100644 --- a/ipi/inputs/simulation.py +++ b/ipi/inputs/simulation.py @@ -57,7 +57,7 @@ class InputSimulation(Input): InputRandom, { "help": InputRandom.default_help, - "default": input_default(factory=Random), + "default": input_default(factory=(lambda: Random())), }, ), "output": ( diff --git a/ipi/utils/prng.py b/ipi/utils/prng.py index c73bfb307..890907fe6 100644 --- a/ipi/utils/prng.py +++ b/ipi/utils/prng.py @@ -15,8 +15,6 @@ import numpy as np import concurrent.futures import time -from ipi.utils.messages import verbosity, info -import threading __all__ = ["Random"] @@ -58,13 +56,6 @@ def __init__(self, seed=-1, state=None, n_threads=1): self.seed = seed - if threading.current_thread() == threading.main_thread(): - info( - "@ RANDOM SEED: The seed used in this calculation was " - + str(self.seed), - verbosity.low, - ) - self.rng = [ np.random.Generator(np.random.MT19937(s)) for s in np.random.SeedSequence(seed).spawn(n_threads) From 448b44e956e3b3e0c8aedee3c0e3728331e5e154 Mon Sep 17 00:00:00 2001 From: Mariana Rossi 2 Date: Wed, 13 Nov 2024 19:08:31 +0100 Subject: [PATCH 37/47] Removing forgotten test --- ipi/inputs/simulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipi/inputs/simulation.py b/ipi/inputs/simulation.py index d55b02da9..ca24853dc 100644 --- a/ipi/inputs/simulation.py +++ b/ipi/inputs/simulation.py @@ -57,7 +57,7 @@ class InputSimulation(Input): InputRandom, { "help": InputRandom.default_help, - "default": input_default(factory=(lambda: Random())), + "default": input_default(factory=(Random())), }, ), "output": ( From 803a44d4af457662d01e94fa38dea3610877bfd6 Mon Sep 17 00:00:00 2001 From: Mariana Rossi 2 Date: Wed, 13 Nov 2024 19:59:47 +0100 Subject: [PATCH 38/47] Always good to call things in the correct way.... --- ipi/inputs/simulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipi/inputs/simulation.py b/ipi/inputs/simulation.py index ca24853dc..796316d59 100644 --- a/ipi/inputs/simulation.py +++ b/ipi/inputs/simulation.py @@ -57,7 +57,7 @@ class InputSimulation(Input): InputRandom, { "help": InputRandom.default_help, - "default": input_default(factory=(Random())), + "default": input_default(factory=Random), }, ), "output": ( From 5d44b0113e765c9542ed030ac48909b9cc1644f4 Mon Sep 17 00:00:00 2001 From: Mariana Rossi 2 Date: Wed, 13 Nov 2024 20:17:53 +0100 Subject: [PATCH 39/47] encapsulating scipy import in a try statement --- ipi/pes/spline.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ipi/pes/spline.py b/ipi/pes/spline.py index 3adbd0821..f76c4057b 100644 --- a/ipi/pes/spline.py +++ b/ipi/pes/spline.py @@ -3,10 +3,14 @@ import numpy as np import sys from .dummy import Dummy_driver -from scipy import interpolate import json - from ipi.utils.messages import verbosity, warning +try: + from scipy import interpolate +except ImportError: + raise ImportError( + "Could not import scipy. Please install to use this." + ) """Spline driver. This is not a serious interpolation, use it if you know what you are doing. """ factor_coord = 5 From 41a4ca6e5b9bfc50a41ee9a470785062bbb3d9ac Mon Sep 17 00:00:00 2001 From: Mariana Rossi 2 Date: Wed, 13 Nov 2024 20:21:09 +0100 Subject: [PATCH 40/47] lint --- ipi/pes/spline.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ipi/pes/spline.py b/ipi/pes/spline.py index f76c4057b..354890721 100644 --- a/ipi/pes/spline.py +++ b/ipi/pes/spline.py @@ -5,12 +5,11 @@ from .dummy import Dummy_driver import json from ipi.utils.messages import verbosity, warning + try: from scipy import interpolate except ImportError: - raise ImportError( - "Could not import scipy. Please install to use this." - ) + raise ImportError("Could not import scipy. Please install to use this.") """Spline driver. This is not a serious interpolation, use it if you know what you are doing. """ factor_coord = 5 From a966ca73c4b644e2053dd76e4f6485fc340c3fdb Mon Sep 17 00:00:00 2001 From: EliaStocco Date: Thu, 14 Nov 2024 13:13:59 +0100 Subject: [PATCH 41/47] tidied up --- ipi/pes/elphmod.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ipi/pes/elphmod.py b/ipi/pes/elphmod.py index 79b4161a4..5e776b254 100644 --- a/ipi/pes/elphmod.py +++ b/ipi/pes/elphmod.py @@ -14,18 +14,16 @@ class ModelIIIDriver(Dummy_driver): Example: python3 driver.py -u -m elphmod -o driver=driver.pickle """ - def __init__(self, *args, **kwargs): + def __init__(self, driver, *args, **kwargs): import elphmod - filename = kwargs["driver"] - if not os.path.exists(filename): - raise ValueError(f"File '{filename}' does not exist.") - self.driver = elphmod.md.Driver.load(filename) + if not os.path.exists(driver): + raise ValueError(f"File '{driver}' does not exist.") + self.driver = elphmod.md.Driver.load(driver) if self.driver is None: raise ValueError( - f"Some error occured within `ModelIIIDriver.__init__` when trying to load the driver from file '{filename}'." + f"Some error occured within `ModelIIIDriver.__init__` when trying to load the driver from file '{driver}'." ) - del kwargs["driver"] super().__init__(*args, **kwargs) pass From 36662decd484eff3fb2f8b2002a079b563ab43c5 Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Mon, 18 Nov 2024 13:25:22 +0100 Subject: [PATCH 42/47] A rudimentary scripting interface for i-PI (#397) This PR introduces a rudimentary API to run i-PI from a Python script. While quite limited in scope, it might simplify setting up simulations for those who are uncomfortable with XML, and might also help to set up active learning schemes, as one can run a segment of trajectory and then modify the calculator. The simulation set up is achieved by helper functions that create XML strings, so it will take some time to reach feature-parity on that front, but one can still just manually edit the XML to realize exactly any simulation setup that is available from the command line. --------- Co-authored-by: Venkat Kapil --- bin/i-pi | 2 +- demos/2D-IR-Raman/noneqm-traj.py | 2 +- docs/scripts/help.py | 2 + docs/src/index.rst | 1 + docs/src/python.rst | 71 +++++ examples/clients/metatensor/README.md | 9 + examples/clients/metatensor/create-model.py | 2 +- examples/clients/metatensor/input.xml | 2 +- examples/clients/metatensor/nickel-lj.pt | Bin 37924 -> 37988 bytes examples/clients/metatensor/run.py | 47 ++++ examples/features/scripting-api/run.py | 63 +++++ examples/features/scripting-api/water-64.xyz | 194 +++++++++++++ ipi/__init__.py | 7 + ipi/engine/properties.py | 4 +- ipi/engine/simulation.py | 116 ++++---- ipi/pes/ase.py | 36 ++- ipi/pes/metatensor.py | 1 + ipi/utils/io/inputs/__init__.py | 4 + ipi/utils/io/inputs/io_xml.py | 38 ++- ipi/utils/scripting.py | 279 +++++++++++++++++++ ipi/utils/units.py | 63 ++--- tools/py/Instanton_interpolation.py | 2 +- tools/py/Instanton_postproc.py | 2 +- tools/py/committee-reweight.py | 2 +- tools/py/neb_interpolate.py | 5 +- 25 files changed, 846 insertions(+), 108 deletions(-) create mode 100644 docs/src/python.rst create mode 100644 examples/clients/metatensor/run.py create mode 100644 examples/features/scripting-api/run.py create mode 100644 examples/features/scripting-api/water-64.xyz create mode 100644 ipi/utils/scripting.py diff --git a/bin/i-pi b/bin/i-pi index d26d8c92b..554567dd4 100755 --- a/bin/i-pi +++ b/bin/i-pi @@ -58,7 +58,7 @@ def main(fn_input, options): raise ImportError('Profiling requires the `yappi` package.') # construct simulation based on input file - simulation = Simulation.load_from_xml(fn_input, request_banner=True, custom_verbosity=options.verbosity, sockets_prefix=options.sockets_prefix) + simulation = Simulation.load_from_xml(open(fn_input), request_banner=True, custom_verbosity=options.verbosity, sockets_prefix=options.sockets_prefix) # run the simulation simulation.run() diff --git a/demos/2D-IR-Raman/noneqm-traj.py b/demos/2D-IR-Raman/noneqm-traj.py index 658c945c7..86277f1ab 100755 --- a/demos/2D-IR-Raman/noneqm-traj.py +++ b/demos/2D-IR-Raman/noneqm-traj.py @@ -175,7 +175,7 @@ def main(fn_input, options): tree.write(fn_input_noneqm) simulation = Simulation.load_from_xml( - fn_input_noneqm, request_banner=False, custom_verbosity=options.verbosity + open(fn_input_noneqm), request_banner=False, custom_verbosity=options.verbosity ) spec.run(simulation, options.tfirst, options.tlast) softexit.trigger(status="success", message=" @ SIMULATION: Exiting cleanly.") diff --git a/docs/scripts/help.py b/docs/scripts/help.py index 3c646b862..7a6a74f80 100644 --- a/docs/scripts/help.py +++ b/docs/scripts/help.py @@ -68,6 +68,8 @@ "dynamics": motion.dynamics.InputDynamics(), "constrained_dynamics": motion.constrained_dynamics.InputConstrainedDynamics(), "driven_dynamics": motion.driven_dynamics.InputDrivenDynamics(), + "bec": motion.driven_dynamics.InputBEC(), + "efield": motion.driven_dynamics.InputElectricField(), "csolver": motion.constrained_dynamics.InputConstraintSolver(), "constraint": motion.constrained_dynamics.InputConstraint(), "t_ramp": motion.ramp.InputTemperatureRamp(), diff --git a/docs/src/index.rst b/docs/src/index.rst index a0eeb385d..1c2ecd10a 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -33,6 +33,7 @@ This documentation is structured as follows: input-tags output-files output-tags + python distributed tutorials onlinereso diff --git a/docs/src/python.rst b/docs/src/python.rst new file mode 100644 index 000000000..422bb2185 --- /dev/null +++ b/docs/src/python.rst @@ -0,0 +1,71 @@ +Tools and python utilities +========================== + +Post-processing tools +~~~~~~~~~~~~~~~~~~~~~ +Some observables (such as autocorrelation functions, isotope fractionation ratios, particle +momentum distributions) require post-processing the raw outputs of a simulation. +The folder ``tools`` contains several post-processing scripts, that can +be used to this end - each (tersely) self-documented with a help string and in +the code. +Some of these tools are also accessible as python functions, so that they can +be invoked from custom post-processing workflows. They can be found in +the ``ipi/utils/tools`` folder, and accessed by importing the module, e.g. + +.. code-block:: python + + from ipi.utils.tools import isra_deconvolute + +is a routine to correct the correlation spectrum computed from a thermostatted simulation, +see this `example `_. + +Parsing +~~~~~~~ + +i-PI trajectories can be output in +`extended xyz format `_, +and can be read by `ASE `_, while the property +outputs can be simply read with ``np.loadtxt``. However, more reliable parsing can be +achieved using the ``ipi.read_output`` and ``ipi.read_trajectory`` functions, that +can also read the native i-PI trajectory formats, and that parse the header of the +output file to provide metadata on the type and units of the properties it contains. + +Scripting i-PI +~~~~~~~~~~~~~~ + +If one wants to run an i-PI simulation within a Python script, it is also possible +to use a (somewhat primitive) scripting API, defined in the ``ipi.utils.scripting`` +module. The core component is the ``InteractiveSimulation`` class, that can be +initialized from an *XML* input, advanced for a given number of steps using the +``run`` method. The calculation requires also the use of a driver, that can +communicate through sockets (in which case it must be launched after +initialization, and before running) or directly using a Python API +using an :ref:`ffdirect` block. + +Properties can be accessed using the ``properties`` method, and a snapshot +of the configuration by calling ``get_structures``. +It is also possible to call ``set_structures`` to change positions, cell +and (if available) velocities to those that can be found in an Atoms structure +(or a list of structures in case there are multiple systems and/or multiple +beads). +Several utility functions, also available within the module, facilitate +building on the fly an *XML* string to initialize the simulation. +An example of usage of this interface goes as follows: + +.. code-block:: python + + from ipi.utils.scripting import InteractiveSimulation, simulation_xml, motion_nvt_xml, forcefield_xml + + data = ase.io.read("init.xyz") + input_xml = simulation_xml( + structures=data, + forcefield=forcefield_xml(name="dummy", mode="direct"), + motion=motion_nvt_xml(timestep=2.0 * ase.units.fs), + temperature=300, + prefix="example", + ) + + sim = InteractiveSimulation(input_xml) + sim.run(100) + potential = sim.properties("potential") + ase.io.write("final_structure.xyz", sim.get_structures()) diff --git a/examples/clients/metatensor/README.md b/examples/clients/metatensor/README.md index c36c2a1b0..b85f96bdf 100644 --- a/examples/clients/metatensor/README.md +++ b/examples/clients/metatensor/README.md @@ -52,3 +52,12 @@ the appropriate options as a dictionary. Then, you can simply run ```bash i-pi input-direct.xml ``` + +## Running with a scripting interface + +To see how to run the metatensor calculator through the interactive Python interface, +check the `run.py` script + +```bash +python run.py +``` diff --git a/examples/clients/metatensor/create-model.py b/examples/clients/metatensor/create-model.py index 9b442be83..b93ad10d6 100644 --- a/examples/clients/metatensor/create-model.py +++ b/examples/clients/metatensor/create-model.py @@ -1,4 +1,4 @@ -# Use https://github.com/Luthaf/metatensor-lj-test/ to define a basic LJ model, +# Use https://github.com/metatensor/lj-test/ to define a basic LJ model, # with and without a custom TorchScript extension import metatensor_lj_test diff --git a/examples/clients/metatensor/input.xml b/examples/clients/metatensor/input.xml index ad58b0a8c..0af3796b7 100644 --- a/examples/clients/metatensor/input.xml +++ b/examples/clients/metatensor/input.xml @@ -27,7 +27,7 @@ - 0.5 + 2 [ 4.49e-3, 6.59e-6, 2.79e-4, -8.81e-4, 5.61e-3, diff --git a/examples/clients/metatensor/nickel-lj.pt b/examples/clients/metatensor/nickel-lj.pt index c9765a0ebbe5dfbe319e8245b90dc8c662ebaca6..17b7ccea5ada9bfddb52389d93f551334e94a6c4 100644 GIT binary patch delta 22010 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 DN0)%` diff --git a/examples/clients/metatensor/run.py b/examples/clients/metatensor/run.py new file mode 100644 index 000000000..8943415f5 --- /dev/null +++ b/examples/clients/metatensor/run.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +from ipi.utils.scripting import ( + simulation_xml, + forcefield_xml, + motion_nvt_xml, + InteractiveSimulation, +) +import ase, ase.io + +# There are utilities to quickly set up XML inputs for commonly-used simulations +data = ase.io.read("nickel.xyz") +input_xml = simulation_xml( + structures=data, + forcefield=forcefield_xml( + name="lj-mtt", + mode="direct", + pes="metatensor", + parameters={"model": "nickel-lj.pt", "template": "nickel.xyz"}, + ), + motion=motion_nvt_xml(timestep=2 * ase.units.fs), + temperature=250, + prefix="script", +) + +print("Running with XML input:\n\n", input_xml) + +# The main object for scripting is `InteractiveSimulation`, that is initialized from +# and XML input and acts as a wrapper around an i-PI simulation object +sim = InteractiveSimulation(input_xml) + +# `properties` accesses the (well) properties of the simulation object +print( + sim.properties("time") / ase.units.fs, + sim.properties("potential"), + sim.properties("temperature"), +) +# `run` advances the interactive simulation by one (or the prescribed number) of steps +sim.run(100) +print( + sim.properties("time") / ase.units.fs, + sim.properties("potential"), + sim.properties("temperature"), +) + +# `get_structures` dumps the state of the system as ASE Atoms objects, possibly listing +# all systems and beads +ase.io.write("final_positions.xyz", sim.get_structures()) diff --git a/examples/features/scripting-api/run.py b/examples/features/scripting-api/run.py new file mode 100644 index 000000000..869b40dca --- /dev/null +++ b/examples/features/scripting-api/run.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +from ipi.utils.scripting import ( + simulation_xml, + forcefield_xml, + motion_nvt_xml, + InteractiveSimulation, +) +import ase, ase.io + +# There are utilities to quickly set up XML inputs for commonly-used simulations +data = ase.io.read("water-64.xyz") +input_xml = simulation_xml( + structures=data, + forcefield=forcefield_xml( + name="harmonic", mode="direct", pes="harmonic", parameters="{k1:1e-3}" + ), + motion=motion_nvt_xml(timestep=0.5 * ase.units.fs), + temperature=400, + prefix="script", +) + +print("Running with XML input:\n\n", input_xml) + +# The main object for scripting is `InteractiveSimulation`, that is initialized from +# and XML input and acts as a wrapper around an i-PI simulation object +sim = InteractiveSimulation(input_xml) + +# `properties` accesses the (well) properties of the simulation object +print( + sim.properties("time") / ase.units.fs, + sim.properties("potential"), + sim.properties("temperature"), +) +# `run` advances the interactive simulation by one (or the prescribed number) of steps +sim.run(10) +print( + sim.properties("time") / ase.units.fs, + sim.properties("potential"), + sim.properties("temperature"), +) +sim.run(10, write_outputs=False) # we can suppress the outputs +print( + sim.properties("time") / ase.units.fs, + sim.properties("potential"), + sim.properties("temperature"), +) +sim.run(10) +print( + sim.properties("time") / ase.units.fs, + sim.properties("potential"), + sim.properties("temperature"), +) + +# `get_structures` dumps the state of the system as ASE Atoms objects, possibly listing +# all systems and beads +ase.io.write("final_positions.xyz", sim.get_structures()) + +# we can also set the simulation state +structure = sim.get_structures() +structure.positions[:] = data.positions +structure.arrays["ipi_velocities"][:] = 0 +sim.set_structures(structure) +print(sim.properties("potential"), sim.properties("kinetic_md")) diff --git a/examples/features/scripting-api/water-64.xyz b/examples/features/scripting-api/water-64.xyz new file mode 100644 index 000000000..c6d078e3f --- /dev/null +++ b/examples/features/scripting-api/water-64.xyz @@ -0,0 +1,194 @@ +192 +Lattice="12.4244 0.0 0.0 0.0 12.4244 0.0 0.0 0.0 12.4244" Properties=species:S:1:pos:R:3 ipi_comment="Step: 1900 Bead: 0 positions{ase} cell{ase}" pbc="T T T" +O 2.21387327 12.40725068 2.23031948 +H 2.06694404 11.67860309 1.64454197 +H 1.31318334 12.80514770 2.28237999 +O -0.75321508 -0.59448153 -1.04435843 +H -0.43690708 0.32900852 -1.04657525 +H -0.57971040 -0.98114653 -1.94412965 +O 5.74154040 -0.87984718 0.72588630 +H 6.39142623 -1.27091020 0.15466910 +H 4.95746147 -0.84286870 0.17858963 +O 11.99198992 13.45036196 2.41825677 +H 11.37275732 12.74729899 2.49935612 +H 11.89932759 14.00247471 1.54806628 +O 11.93044048 1.05488399 -3.73314299 +H 11.32455922 0.93150585 -4.46539255 +H 12.65005178 0.53170032 -3.90569743 +O 14.73647355 5.99191632 -7.05710376 +H 14.64143925 5.03360348 -7.27737786 +H 14.06733122 6.17072192 -6.37654095 +O -2.73217835 10.36158893 0.16191577 +H -2.06962320 10.93427055 -0.33139183 +H -2.51616800 9.45621753 -0.12184826 +O 6.23846578 1.75374492 0.35639039 +H 5.96089981 0.77730520 0.46453180 +H 5.39628380 2.29054891 0.26418202 +O 8.80269662 8.43566538 5.05023611 +H 9.72832216 8.80499254 4.93842353 +H 8.41177392 8.34800960 4.16677335 +O 5.89328910 5.88414156 -1.14225059 +H 6.07707839 5.68838338 -2.06445181 +H 5.43934590 6.71987929 -1.04508996 +O 7.84016011 2.70671541 2.39204316 +H 7.20788308 3.26556062 2.89380271 +H 7.32436176 2.27545437 1.68427297 +O 11.00517380 5.32928124 3.72557263 +H 10.29738407 5.10122268 2.99805211 +H 10.47093006 5.51304477 4.52225686 +O 2.68516096 2.41177930 -0.66463660 +H 3.12947415 1.66826602 -1.03006854 +H 3.27709683 2.85722501 -0.03548707 +O 0.86065791 8.02193473 -3.37520070 +H 1.11321946 7.81534106 -2.41395316 +H 0.22218987 8.78231178 -3.28348522 +O 5.85747567 0.46065763 -7.43414667 +H 5.53128874 0.87653800 -6.61624733 +H 6.70168137 0.85902635 -7.62984359 +O 0.35921371 7.78272581 0.92779636 +H 0.33955254 7.65595272 1.95023127 +H -0.57003051 7.61892999 0.59896908 +O 9.66377080 4.68256823 1.55730430 +H 8.94312649 3.99347302 1.59425106 +H 9.12089025 5.41769479 1.22888925 +O 7.65457008 9.64069496 -5.18343076 +H 6.71889770 10.06399282 -5.36783785 +H 7.86674566 9.22701576 -6.04725986 +O 7.19321761 7.29823464 -3.80100596 +H 6.56015700 6.73992439 -4.20133887 +H 7.11414012 8.15417328 -4.27363292 +O 3.83577940 1.78813133 -9.06883411 +H 4.53247690 1.32915811 -8.51485276 +H 3.49007109 1.14218766 -9.67998028 +O 5.41832971 4.07076363 -9.29354261 +H 5.48908171 4.86701095 -8.71798047 +H 4.68397254 3.57778432 -8.93660697 +O 5.43789885 9.40228872 -2.55111439 +H 5.53478981 8.57938118 -3.03901209 +H 6.35730989 9.67858848 -2.30146709 +O -0.45742934 2.92384837 4.23795020 +H -0.65542588 3.78038584 3.80834483 +H -0.37808374 2.22326659 3.64590428 +O 11.29795954 -2.96162904 4.75239636 +H 11.63370731 -2.27574515 5.29218659 +H 11.98621823 -3.65051989 4.71422796 +O 4.99707156 -1.79914799 -5.28772929 +H 4.51880831 -2.52931828 -4.83665169 +H 4.55020604 -1.70717848 -6.16555670 +O 2.45689908 4.45686228 -2.67399317 +H 1.51398216 4.27108297 -2.80060549 +H 2.66694593 3.70962297 -2.01741030 +O 3.73283820 -4.15860576 2.96998886 +H 4.08732955 -3.25525927 3.11614931 +H 3.82660862 -4.19314289 2.00934888 +O 3.79953928 3.53561128 -5.00221400 +H 3.17434628 3.25755097 -5.65336138 +H 3.29406548 3.75250667 -4.22005070 +O 2.15476289 2.61062944 -7.02913464 +H 2.47557818 2.36463061 -7.99045139 +H 1.25468277 2.75698642 -7.25518955 +O 4.88286219 6.36826713 -5.16303301 +H 4.34394281 7.02331963 -4.75813168 +H 4.30506585 5.73206177 -5.44919722 +O 7.54258972 -1.74845549 -1.20128842 +H 7.58173346 -0.96340903 -1.81213879 +H 8.41599553 -1.70098336 -0.75529423 +O 8.66587253 3.99443202 -4.83379584 +H 9.05848307 4.73782323 -5.32398176 +H 9.08641306 3.24755764 -5.24853036 +O 15.39832523 -0.98662008 -7.24558405 +H 14.81412921 -0.61721460 -7.92182780 +H 14.88249533 -0.75285373 -6.45380899 +O 8.73211726 0.85742774 4.18921288 +H 8.71727739 1.55957315 3.54206134 +H 8.81252752 0.01593544 3.72986823 +O 3.32413086 8.59329072 -4.72268559 +H 2.51972443 8.61143412 -4.19067201 +H 3.00530797 8.60420808 -5.62979986 +O 9.88683349 6.02693741 5.99064857 +H 10.66843185 6.47446641 6.38238368 +H 9.45847853 6.79275119 5.61687708 +O 5.48734339 -1.80547540 3.21362128 +H 5.37614757 -1.28745938 4.05714107 +H 5.55205282 -1.14821437 2.49504858 +O -0.17451136 1.95380021 -0.42983176 +H 0.74756628 2.13576872 -0.57275419 +H -0.83764648 2.59865739 -0.79248245 +O 12.26425852 4.05272251 -3.21409599 +H 12.35662902 3.10992710 -3.53322869 +H 11.49147736 4.13940388 -2.66280329 +O -0.98576882 10.01726713 -3.28890861 +H -1.54050933 9.23169822 -3.08255339 +H -1.55693518 10.58711799 -3.82222753 +O 10.32526061 7.73843560 -0.33229257 +H 10.23281998 7.39655498 -1.22803525 +H 9.60467759 7.22752309 0.25198323 +O 0.09191373 6.28553276 -5.26909244 +H 0.30345729 5.42888899 -4.86584086 +H 0.24416340 6.99184601 -4.61102483 +O -2.18445141 11.11099414 2.66233241 +H -1.77931618 10.42404589 3.27279560 +H -2.45449419 10.70582712 1.83155514 +O 11.83691986 11.62521338 6.29252911 +H 10.90703270 11.66245027 6.65664727 +H 11.98152631 12.58003326 6.01283684 +O 9.76700302 7.21345169 -3.05782750 +H 8.81888709 7.11975811 -3.43799470 +H 10.29610713 6.47686190 -3.37256470 +O 2.22433993 8.82465394 5.46407496 +H 2.53017747 9.68322136 5.08696224 +H 2.62159591 8.18963464 4.84191210 +O 2.58549224 10.22788385 -2.23574588 +H 3.28576690 9.54599998 -2.29861530 +H 2.05697668 10.04802514 -1.46372318 +O 1.28564872 10.23409319 0.08375371 +H 0.51315024 10.65646336 -0.17658479 +H 0.89435872 9.38464929 0.35596781 +O 6.46338348 4.56083691 -3.42884523 +H 7.25243635 4.40444161 -3.91165357 +H 5.65045951 4.36919349 -3.97438205 +O 5.12851460 6.42128330 4.49193755 +H 5.20109935 6.63813806 5.44949628 +H 4.39732180 7.02007805 4.19101922 +O 0.31002319 7.34990480 3.60793458 +H 1.09376589 7.03127626 4.00071569 +H -0.23051772 6.49087082 3.49320068 +O 7.85467960 2.94434063 -1.52839549 +H 7.18762033 3.47881011 -2.01180042 +H 7.32398761 2.43871845 -0.89548889 +O 7.99176053 6.67379648 0.76234189 +H 7.36968188 6.48516030 0.02147414 +H 7.39906311 7.03701090 1.43547078 +O 10.45810792 4.19159838 -1.06465671 +H 9.71439511 3.54579561 -1.27241836 +H 10.25866575 4.52896421 -0.14439244 +O 2.16580171 7.02507248 -1.05936971 +H 1.56300413 7.11891493 -0.25941855 +H 2.07623629 6.16423927 -1.48299475 +O 4.68508075 3.85099647 0.53238242 +H 5.13098521 4.42762464 -0.12485212 +H 5.02723072 4.13401269 1.40990289 +O 7.41492214 0.57564648 -2.89288637 +H 7.63746561 1.40778149 -2.49914757 +H 6.59782147 0.64798185 -3.36395253 +O 1.71626830 11.66007035 -4.47546514 +H 0.99756996 11.32581387 -5.05282264 +H 2.00055363 10.90357627 -3.92540839 +O 4.85017126 1.03969846 -4.52787580 +H 4.08444178 1.63223795 -4.64862906 +H 4.50350826 0.17230808 -4.81974036 +O 9.41760438 -0.98890426 7.68151902 +H 8.76346603 -1.69362425 7.48031621 +H 9.01846782 -0.30634124 8.18571242 +O 10.17759636 1.75304672 6.41252838 +H 10.73383750 2.36059625 5.95314219 +H 9.67149853 1.27545072 5.73203121 +O 4.28513592 8.22630015 0.13948157 +H 4.92185001 8.72436720 -0.37998991 +H 3.61827294 8.05475284 -0.47628170 +O 3.86459479 0.29107940 -1.75734214 +H 3.35482860 -0.52822670 -1.97160082 +H 4.17943753 0.58968815 -2.64543229 +O 6.90060092 8.00151268 3.01115132 +H 6.30143375 7.46163097 3.57494518 +H 6.55125677 8.87622169 3.02492108 diff --git a/ipi/__init__.py b/ipi/__init__.py index 196aa6995..b611ab7a1 100644 --- a/ipi/__init__.py +++ b/ipi/__init__.py @@ -20,3 +20,10 @@ ] ipi_global_settings = {"floatformat": "%16.8e"} + +from ipi.engine.simulation import Simulation + + +class IPI: + def __init__(self, xml_data): + self._simulation = Simulation.load_from_xml(xml_data) diff --git a/ipi/engine/properties.py b/ipi/engine/properties.py index 6aeaccc07..6bc259c30 100644 --- a/ipi/engine/properties.py +++ b/ipi/engine/properties.py @@ -998,14 +998,14 @@ def __getitem__(self, key): pkey = self.property_dict[key] # pkey["func"](*arglist,**kwarglist) gives the value of the property - # in atomic units. unit_to_user() returns the value in the user + # in atomic units. use unit_to_user() to convert the value in the user # specified units. with self._threadlock: value = pkey["func"](*arglist, **kwarglist) if "dimension" in pkey: dimension = pkey["dimension"] else: - dimension = "" + dimension = "undefined" return value, dimension, unit def tensor2vec(self, tensor): diff --git a/ipi/engine/simulation.py b/ipi/engine/simulation.py index 2d6a6013a..122b012f3 100644 --- a/ipi/engine/simulation.py +++ b/ipi/engine/simulation.py @@ -16,7 +16,7 @@ from copy import deepcopy from ipi.utils.depend import depend_value, dpipe, dproperties -from ipi.utils.io.inputs.io_xml import xml_parse_file +from ipi.utils.io.inputs.io_xml import xml_parse_file, xml_parse_string, xml_write from ipi.utils.messages import verbosity, info, warning, banner from ipi.utils.softexit import softexit import ipi.engine.outputs as eoutputs @@ -60,7 +60,7 @@ class Simulation: @staticmethod def load_from_xml( - fn_input, + xml_input, custom_verbosity=None, sockets_prefix=None, request_banner=False, @@ -69,7 +69,7 @@ def load_from_xml( """Load an XML input file and return a `Simulation` object. Arguments: - fn_input (str): Name of the input file. + xml_input (str | file): XML-formatted string, or open file handle custom_verbosity (str): If not `None`, overrides the verbosity specified by the input file. request_banner (bool): Whether to print the i-PI banner, @@ -78,7 +78,10 @@ def load_from_xml( """ # parse the file - xmlrestart = xml_parse_file(open(fn_input)) + if type(xml_input) is str: + xmlrestart = xml_parse_string(xml_input) + else: + xmlrestart = xml_parse_file(xml_input) # prepare the simulation input object input_simulation = isimulation.InputSimulation() @@ -104,19 +107,14 @@ def load_from_xml( # create the simulation object simulation = input_simulation.fetch() - # pipe between the components of the simulation - simulation.bind(read_only) - # echo the input file if verbose enough - if verbosity.low: - print(" @simulation: i-PI loaded input file: ", fn_input) if verbosity.medium: print(" --- begin input file content ---") - ifile = open(fn_input, "r") - for line in ifile.readlines(): - print(line, end=" ") + print(xml_write(xmlrestart)) print(" --- end input file content ---") - ifile.close() + + # pipe between the components of the simulation + simulation.bind(read_only) return simulation @@ -265,6 +263,14 @@ def bind(self, read_only=False): if self.smotion is not None: self.smotion.bind(self.syslist, self.prng, self.output_maker) + # registers the softexit routine + softexit.register_function(self.softexit) + softexit.start(self.ttime) + + # starts tracemalloc to debug memory leaks + if verbosity.debug: + tracemalloc.start(10) + def softexit(self): """Deals with a soft exit request. @@ -282,7 +288,7 @@ def softexit(self): self.chk.write(store=False) - def run(self): + def run(self, write_outputs=True): """Runs the simulation. Does all the simulation steps, and outputs data to the appropriate files @@ -290,16 +296,8 @@ def run(self): in the communication between the driver and the PIMD code. """ - # registers the softexit routine - softexit.register_function(self.softexit) - softexit.start(self.ttime) - - # starts tracemalloc to debug memory leaks - if verbosity.debug: - tracemalloc.start(10) - # prints inital configuration -- only if we are not restarting - if self.step == 0: + if self.step == 0 and write_outputs: self.step = -1 # must use multi-threading to avoid blocking in multi-system runs with WTE if self.threading: @@ -337,44 +335,25 @@ def run(self): if self.step % self.safe_stride == 0: self.chk.store() - if len(self.syslist) > 0 and self.threading: - stepthreads = [] - # steps through all the systems - for s in self.syslist: - # creates separate threads for the different systems - st = self.executor.submit(s.motion.step, step=self.step) - stepthreads.append(st) - - for st in stepthreads: - st.result() - else: - for s in self.syslist: - s.motion.step(step=self.step) - - if softexit.triggered: - # Don't continue if we are about to exit. - break - - # does the "super motion" step - if self.smotion is not None: - self.smotion.step(self.step) + self.run_step(self.step) if softexit.triggered: # Don't write if we are about to exit. break - if self.threading: - stepthreads = [] - for o in self.outputs: - if o.active(): # don't start a thread if it's not needed - st = self.executor.submit(o.write) - stepthreads.append(st) + if write_outputs: + if self.threading: + stepthreads = [] + for o in self.outputs: + if o.active(): # don't start a thread if it's not needed + st = self.executor.submit(o.write) + stepthreads.append(st) - for st in stepthreads: - st.result() - else: - for o in self.outputs: - o.write() + for st in stepthreads: + st.result() + else: + for o in self.outputs: + o.write() steptime += time.time() ttot += steptime @@ -416,5 +395,32 @@ def run(self): self.rollback = False + def run_step(self, step): + if len(self.syslist) > 0 and self.threading: + stepthreads = [] + # steps through all the systems + for s in self.syslist: + # creates separate threads for the different systems + st = self.executor.submit(s.motion.step, step=step) + stepthreads.append(st) + + for st in stepthreads: + if softexit.triggered: + return + st.result() + else: + for s in self.syslist: + s.motion.step(step=step) + if softexit.triggered: + return + + # does the "super motion" step + if self.smotion is not None: + self.smotion.step(step) + + def stop(self): + for k, f in self.fflist.items(): + f.stop() + dproperties(Simulation, ["step"]) diff --git a/ipi/pes/ase.py b/ipi/pes/ase.py index 567c4e4e7..ee8ef677b 100644 --- a/ipi/pes/ase.py +++ b/ipi/pes/ase.py @@ -21,16 +21,37 @@ class ASEDriver(Dummy_driver): Parameters: :param verbose: bool, whether to print verbose output :param template: string, ASE-readable filename where to get the structure data from + :param has_energy: bool, whether the model can compute energy + :param has_forces: bool, whether the model can compute forces + :param has_stress: bool, whether the model can compute stress """ - def __init__(self, template, *args, **kwargs): + def __init__( + self, + template, + has_energy=True, + has_forces=True, + has_stress=True, + *args, + **kwargs + ): global read try: from ase.io import read except ImportError: warning("Could not find or import the ASE module") + global all_changes + from ase.calculators.calculator import all_changes + self.template = template + self.capabilities = [] + if has_energy: + self.capabilities.append("energy") + if has_forces: + self.capabilities.append("forces") + if has_stress: + self.capabilities.append("stress") super().__init__(*args, **kwargs) def check_parameters(self): @@ -60,12 +81,15 @@ def __call__(self, cell, pos): structure.calc = self.ase_calculator # Do the actual calculation - self.ase_calculator.calculate(atoms=structure) - properties = self.ase_calculator.results + properties = structure.get_properties(self.capabilities) - pot = properties["energy"] - force = properties["forces"] - stress = properties["stress"] + pot = properties["energy"] if "energy" in self.capabilities else 0.0 + force = ( + properties["forces"] + if "forces" in self.capabilities + else np.zeros_like(pos) + ) + stress = properties["stress"] if "stress" in self.capabilities else np.zeros(9) if len(stress) == 6: # converts from voight notation stress = np.array(stress[[0, 5, 4, 5, 1, 3, 4, 3, 2]]) diff --git a/ipi/pes/metatensor.py b/ipi/pes/metatensor.py index d857c68ad..4e3dc133d 100644 --- a/ipi/pes/metatensor.py +++ b/ipi/pes/metatensor.py @@ -57,6 +57,7 @@ def __init__( self.device = device self.extensions = extensions self.check_consistency = check_consistency + print("ARGS ", kwargs) super().__init__(template, *args, **kwargs) def check_parameters(self): diff --git a/ipi/utils/io/inputs/__init__.py b/ipi/utils/io/inputs/__init__.py index aad0bbbf8..ca18a14e2 100644 --- a/ipi/utils/io/inputs/__init__.py +++ b/ipi/utils/io/inputs/__init__.py @@ -18,6 +18,10 @@ def read_value(s): return cast(s) except ValueError: continue + if s.lower() == "false": + return False + if s.lower() == "true": + return True return s diff --git a/ipi/utils/io/inputs/io_xml.py b/ipi/utils/io/inputs/io_xml.py index 8fbc0a261..c2a508792 100644 --- a/ipi/utils/io/inputs/io_xml.py +++ b/ipi/utils/io/inputs/io_xml.py @@ -19,6 +19,7 @@ "xml_handler", "xml_parse_string", "xml_parse_file", + "xml_edit", "xml_write", "read_type", "read_float", @@ -56,9 +57,10 @@ def __init__(self, attribs=None, name="", fields=None): Args: attribs: An optional dictionary giving attribute data. Defaults to {}. - fields: An optional dictionary holding all the data between the start + fields: An optional list holding all the data between the start and end tags, including information about other nodes. - Defaults to {}. + This is stored as a list of tuples [(key, value)] to allow for + duplicated entries. name: An optional string giving the tag name. Defaults to ''. """ @@ -244,6 +246,38 @@ def xml_write(xml, name="", indent="", text=""): return rstr +def xml_edit(root, path, node, full_path=False, mode="add"): + """Edits an xml_node, "add"-ing, "remove"-ing + or "replace"-ing the node at the desired location(s)""" + + n_edited = 0 + + for idx in range(len(root.fields) - 1, -1, -1): + # iterate backwards to avoid index errors as we are editing the list in place + name, field = root.fields[idx] + if name == "_text": # reached a dead end + continue + print(name, field) + if name == path[0]: + if len(path) == 1: + if mode == "add": + field.fields.append((node.name, node)) + elif mode == "remove": + root.fields.pop(idx) + elif mode == "replace": + root.fields[idx] = (node.name, node) + else: + raise ValueError(f"Invalid editing mode {mode}") + n_edited += 1 + else: + n_edited += xml_edit(field, path[1:], node, full_path, mode) + elif not full_path: + # see if the path is to be found somewhere >>within<< + n_edited += xml_edit(field, path, node, full_path, mode) + + return n_edited + + def read_type(type, data): """Reads a string and outputs data of a specified type. diff --git a/ipi/utils/scripting.py b/ipi/utils/scripting.py new file mode 100644 index 000000000..2549bf1b3 --- /dev/null +++ b/ipi/utils/scripting.py @@ -0,0 +1,279 @@ +import numpy as np +from ipi.utils.depend import dstrip +from ipi.utils.units import Elements, unit_to_internal, unit_to_user +from ipi.inputs.beads import InputBeads +from ipi.inputs.cell import InputCell +from ipi.engine.beads import Beads +from ipi.engine.cell import Cell +from ipi.engine.simulation import Simulation +from ipi.utils.io.inputs.io_xml import xml_parse_string, xml_write, write_dict +from ipi.pes import __drivers__ + +from ipi.utils.io.backends.io_ase import ase, _asecheck + +__all__ = [ + "simulation_xml", + "motion_nvt_xml", + "forcefield_xml", + "InteractiveSimulation", +] + + +DEFAULT_OUTPUTS = """ + + [ step, time{picosecond}, conserved{electronvolt}, temperature{kelvin}, potential{electronvolt} ] + positions{angstrom} + + +""" + + +def simulation_xml( + structures, + forcefield, + motion, + temperature=None, + output=None, + verbosity="quiet", + safe_stride=20, + prefix=None, +): + """ + A helper function to generate an XML string for an i-PI simulation input. + """ + + if type(structures) is list: + nbeads = len(structures) + natoms = len(structures[0]) + q = np.vstack([frame.positions.reshape(1, -1) for frame in structures]) + structure = structures[0] + else: + structure = structures + nbeads = 1 + natoms = len(structure) + q = structure.positions.flatten() + + beads = Beads(nbeads=nbeads, natoms=natoms) + beads.q = q * unit_to_internal("length", "ase", 1.0) + beads.names = np.array(structure.symbols) + if "mass" in structure.arrays: + beads.m = structure.arrays["mass"] * unit_to_internal("mass", "ase", 1.0) + else: + beads.m = np.array([Elements.mass(n) for n in beads.names]) + + input_beads = InputBeads() + input_beads.store(beads) + + cell = Cell(h=np.array(structure.cell) * unit_to_internal("length", "ase", 1.0)) + input_cell = InputCell() + input_cell.store(cell) + + # gets ff name + xml_ff = xml_parse_string(forcefield).fields[0][1] + ff_name = xml_ff.attribs["name"] + + # parses the outputs and overrides prefix + if output is None: + output = DEFAULT_OUTPUTS + if prefix is not None: + xml_output = xml_parse_string(output) + if xml_output.fields[0][0] != "output": + raise ValueError("the output parameter should be a valid 'output' block") + xml_output.fields[0][1].attribs["prefix"] = prefix + output = xml_write(xml_output) + + return f""" + +{forcefield} +{output} + +{input_beads.write("beads")} +{input_cell.write("cell")} +{( + f"" + f" {temperature} " + "" + f"" + f" {temperature} " + "" + if temperature is not None else "" +)} + + + +{motion} + + +""" + + +def forcefield_xml( + name, mode="direct", parameters=None, pes=None, address=None, port=None +): + """ + A helper function to generate an XML string for a forcefield block. + """ + + if mode == "direct": + if pes is None: + raise ValueError(f"Must specify 'pes' for {mode} forcefields") + elif pes not in __drivers__.keys(): + raise ValueError(f"Invalid value {pes} for 'pes'") + if parameters is None: + parameters = "" + elif type(parameters) is dict: + parameters = f"{write_dict(parameters)}" + else: + parameters = f"{parameters}" + + xml_ff = f""" + +{"dummy" if pes is None else pes} +{parameters} + +""" + elif mode == "unix" or mode == "inet": + if address is None: + raise ValueError("Must specify address for {mode} forcefields") + if mode == "inet" and port is None: + raise ValueError("Must specify port for {mode} forcefields") + xml_ff = f""" + +
{address}
+{f"{port}" if mode=="inet" else ""} + 1e-4 +
+""" + else: + raise ValueError( + "Invalid forcefield mode, use ['direct', 'unix', 'inet'] or set up manually" + ) + + return xml_ff + + +def motion_nvt_xml(timestep, thermostat=None, path_integrals=False): + """ + A helper function to generate an XML string for a MD simulation input. + """ + + # sets up thermostat + if thermostat is None: + if path_integrals: + # defaults to pile_g + xml_thermostat = f""" + + {10*timestep} + 0.5 + +""" + else: + # defaults to svr + xml_thermostat = f""" + + {10*timestep} + +""" + + return f""" + + + {timestep} +{xml_thermostat} + + +""" + + +class InteractiveSimulation: + """A wrapper to `Simulation` that allows accessing + properties and configurations in a "safe" way from Python. + The object is initialized from an XML input, and supports + a minimalistic API to step through the simulation, extract + properties and structures, and set configurations interactively. + + :param xml_input: An open XML file, or an XML-formatted string + containing the i-PI simulation that should be run. + """ + + def __init__(self, xml_input): + self.simulation = Simulation.load_from_xml(xml_input) + + def run(self, steps=1, write_outputs=True): + """Stepper through the simulation. + Run the simulation interactively for the specified number of steps. + + :param steps: int, number of steps the simulation should be advanced by + """ + + print(self.simulation.step) + self.simulation.tsteps = self.simulation.step + steps + self.simulation.run(write_outputs=write_outputs) + # saves the RESTART file + self.simulation.chk.write(store=True) + self.simulation.step += 1 + + def run_step(self, step): + self.simulation.run_step(step) + + def properties(self, property): + """Fetches properties from the simulation state. + + :param property: the name of a property to be fetched from the simulation + """ + props = [] + for system in self.simulation.syslist: + value, dimension, unit = system.properties[property] + props.append(value * unit_to_user(dimension, "ase", 1.0)) + if len(props) == 1: + return props[0] + else: + return props + + def get_structures(self): + _asecheck() + + sys_structures = [] + for system in self.simulation.syslist: + structures = [] + for b in range(system.beads.nbeads): + struc = ase.Atoms( + positions=dstrip(system.beads.q[b]).reshape(-1, 3) + * unit_to_user("length", "ase", 1.0), + symbols=dstrip(system.beads.names), + cell=dstrip(system.cell.h) * unit_to_user("length", "ase", 1.0), + ) + struc.arrays["ipi_velocities"] = dstrip(system.beads.p[b]).reshape( + -1, 3 + ) * unit_to_user("velocity", "ase", 1.0) + struc.arrays["ipi_forces"] = dstrip(system.forces.f[b]).reshape( + -1, 3 + ) * unit_to_user("force", "ase", 1.0) + struc.info["ipi_potential"] = dstrip( + system.forces.pots[b] + ) * unit_to_user("energy", "ase", 1.0) + structures.append(struc) + if len(structures) == 1: # flatten the structure if there's just one beads + structures = structures[0] + sys_structures.append(structures) + if len(sys_structures) == 1: # flatten the structure if there's just one system + sys_structures = sys_structures[0] + return sys_structures + + def set_structures(self, sys_structures): + _asecheck() + + if len(self.simulation.syslist) == 1: + sys_structures = [sys_structures] + for system, structures in zip(self.simulation.syslist, sys_structures): + if system.beads.nbeads == 1: + structures = [structures] + for b, struc in enumerate(structures): + system.beads.q[b] = struc.positions.flatten() * unit_to_internal( + "length", "ase", 1.0 + ) + system.cell.h = struc.cell * unit_to_internal("length", "ase", 1.0) + if "ipi_velocities" in struc.arrays: + system.beads.p[b] = struc.arrays[ + "ipi_velocities" + ].flatten() * unit_to_internal("velocity", "ase", 1.0) diff --git a/ipi/utils/units.py b/ipi/utils/units.py index 9cd4fa3a9..4841a1950 100644 --- a/ipi/utils/units.py +++ b/ipi/utils/units.py @@ -13,7 +13,7 @@ try: import ase - from ase.units import Bohr, Hartree, eV, Angstrom, Pascal, kB, Debye, _amu + from ase.units import Bohr, Hartree, eV, Angstrom, kB except ImportError: ase = None @@ -299,41 +299,34 @@ def mass(cls, label): # Conditionally includes "ase" units for each quantity if ase is not None: # Conversion factors from atomic units to ASE units - conversion_factors = { - "undefined": {"ase": 1}, - "energy": {"ase": 1 / (Hartree / eV)}, - "temperature": {"ase": kB}, - "time": { - "ase": 1 - / ((Bohr / Angstrom) * (1 / (Hartree / eV)) ** 0.5 * (_amu / 1) ** 0.5) - }, - "frequency": { - "ase": (Bohr / Angstrom) * (1 / (Hartree / eV)) ** 0.5 * (_amu / 1) ** 0.5 - }, - "electric-field": {"ase": 1 / (Hartree / (Bohr * eV / Angstrom))}, - "electric-dipole": {"ase": 1 / (Bohr / Debye)}, - "length": {"ase": 1 / (Bohr / Angstrom)}, - "volume": {"ase": 1 / ((Bohr**3) / (Angstrom**3))}, - "velocity": { - "ase": 1 / ((Hartree / eV) ** 0.5 * (Bohr / Angstrom) / (_amu / 1) ** 0.5) - }, - "momentum": {"ase": 1 / ((Bohr / Angstrom) * (Hartree / eV) ** 0.5)}, - "mass": {"ase": 1}, # Atomic unit of mass to amu - "pressure": {"ase": 1 / (Hartree / (Bohr**3 * Pascal))}, - "density": { - "ase": 1 / (_amu / (Angstrom**3)) - }, # Atomic unit of density to g/cm^3 - "force": {"ase": 1 / (Hartree / Bohr)}, # Atomic unit of force to N - "hessian": { - "ase": 1 / (Hartree / (Bohr**2)) - }, # Atomic unit of Hessian to eV/Å^2 - } - - # Update UnitMap with ASE conversion factors - for quantity, factors in conversion_factors.items(): - if quantity in UnitMap: - UnitMap[quantity].update(factors) + UnitMap["undefined"]["ase"] = 1.0 + UnitMap["energy"]["ase"] = eV / Hartree + UnitMap["length"]["ase"] = Angstrom / Bohr + UnitMap["temperature"]["ase"] = kB * eV / Hartree + UnitMap["time"]["ase"] = (Angstrom / Bohr) * (Constants.amu / (eV / Hartree)) ** 0.5 + UnitMap["velocity"]["ase"] = UnitMap["length"]["ase"] / UnitMap["time"]["ase"] + UnitMap["force"]["ase"] = UnitMap["energy"]["ase"] / UnitMap["length"]["ase"] + UnitMap["volume"]["ase"] = UnitMap["length"]["ase"] ** 3 + UnitMap["frequency"]["ase"] = 1 / UnitMap["time"]["ase"] + UnitMap["mass"]["ase"] = ( + UnitMap["energy"]["ase"] / UnitMap["velocity"]["ase"] ** 2 + ) # to check + UnitMap["pressure"]["ase"] = ( + UnitMap["energy"]["ase"] / UnitMap["volume"]["ase"] + ) # to check + UnitMap["momentum"]["ase"] = ( + UnitMap["mass"]["ase"] * UnitMap["velocity"]["ase"] + ) # to check + UnitMap["density"]["ase"] = ( + UnitMap["mass"]["ase"] / UnitMap["volume"]["ase"] + ) # to check + UnitMap["hessian"]["ase"] = ( + UnitMap["energy"]["ase"] / UnitMap["length"]["ase"] ** 2 + ) # to check + # since ASe handles charges in atomic_units, dipole and electric field should have the same units as lenth and force, respectively + UnitMap["electric-dipole"]["ase"] = UnitMap["length"]["ase"] + UnitMap["electric-field"]["ase"] = UnitMap["force"]["ase"] # a list of magnitude prefixes UnitPrefix = { diff --git a/tools/py/Instanton_interpolation.py b/tools/py/Instanton_interpolation.py index befe7fd25..0b5ac63fd 100755 --- a/tools/py/Instanton_interpolation.py +++ b/tools/py/Instanton_interpolation.py @@ -122,7 +122,7 @@ if os.path.exists(chk): simulation = Simulation.load_from_xml( - chk, custom_verbosity="low", request_banner=False, read_only=True + open(chk), custom_verbosity="low", request_banner=False, read_only=True ) else: print("We can't find {}".format(chk)) diff --git a/tools/py/Instanton_postproc.py b/tools/py/Instanton_postproc.py index 4445f9c66..2737e0741 100755 --- a/tools/py/Instanton_postproc.py +++ b/tools/py/Instanton_postproc.py @@ -258,7 +258,7 @@ def save_frequencies(d, nzeros, filename="freq.dat"): print("\nWe are ready to start. Reading {} ... (This can take a while)".format(inputt)) simulation = Simulation.load_from_xml( - inputt, custom_verbosity="quiet", request_banner=False, read_only=True + open(inputt), custom_verbosity="quiet", request_banner=False, read_only=True ) diff --git a/tools/py/committee-reweight.py b/tools/py/committee-reweight.py index 724b52474..fc3cfffa7 100755 --- a/tools/py/committee-reweight.py +++ b/tools/py/committee-reweight.py @@ -262,7 +262,7 @@ def commitee_reweight( # Load kbT from i-PI, we could make it into a small function if args.input != "": simul = Simulation.load_from_xml( - args.input, custom_verbosity="quiet", read_only=True + open(args.input), custom_verbosity="quiet", read_only=True ) kt = float(simul.syslist[0].ensemble.temp) else: diff --git a/tools/py/neb_interpolate.py b/tools/py/neb_interpolate.py index aaaa9a45b..d524affe9 100755 --- a/tools/py/neb_interpolate.py +++ b/tools/py/neb_interpolate.py @@ -352,7 +352,10 @@ def spline_resample(q, nbeads_old, nbeads_new, k=3): input_chk = args.chk if os.path.exists(input_chk): simulation = Simulation.load_from_xml( - input_chk, custom_verbosity="low", request_banner=False, read_only=True + open(input_chk), + custom_verbosity="low", + request_banner=False, + read_only=True, ) else: print("Error: cannot find {}.".format(input_chk)) From 1f7606c6e491c64c119fe8f6f70e02230a2b3467 Mon Sep 17 00:00:00 2001 From: Vahideh Alizadeh <82591913+V-Alizade@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:16:05 +0100 Subject: [PATCH 43/47] update xtb client (#407) * update xtb: allow reading .xyz format * update tblite for version 0.4 --------- Co-authored-by: Michele Ceriotti --- examples/clients/xtb/README.md | 2 +- examples/clients/xtb/config.json | 1 - examples/clients/xtb/run.sh | 2 +- ipi/pes/xtb.py | 56 +++++++++++++++----------------- 4 files changed, 29 insertions(+), 32 deletions(-) delete mode 100644 examples/clients/xtb/config.json mode change 100644 => 100755 examples/clients/xtb/run.sh diff --git a/examples/clients/xtb/README.md b/examples/clients/xtb/README.md index c3b2b0c57..ccb6475e6 100644 --- a/examples/clients/xtb/README.md +++ b/examples/clients/xtb/README.md @@ -15,5 +15,5 @@ the example can be run as usual ```bash i-pi input.xml &> log.ipi & -i-pi-py_driver -m xtb -o '{"method": "GFN2-xTB", "numbers": [6,1,1,1,1], "periodic": false}' -u -a xtb &> log.xtb & +i-pi-py_driver -m xtb -o template=ch4.xyz,method=GFN2-xTB -u -a xtb &> log.xtb ``` diff --git a/examples/clients/xtb/config.json b/examples/clients/xtb/config.json deleted file mode 100644 index f299cd2e4..000000000 --- a/examples/clients/xtb/config.json +++ /dev/null @@ -1 +0,0 @@ -{"method": "GFN2-xTB", "numbers": [6,1,1,1,1], "periodic": false} diff --git a/examples/clients/xtb/run.sh b/examples/clients/xtb/run.sh old mode 100644 new mode 100755 index 98eea7e55..a93bebf5c --- a/examples/clients/xtb/run.sh +++ b/examples/clients/xtb/run.sh @@ -3,5 +3,5 @@ echo "Running i-PI" i-pi input.xml &> log.ipi & sleep 1 echo "Running driver" -i-pi-py_driver -m xtb -o config.json -u -a xtb &> log.xtb +i-pi-py_driver -m xtb -o template=ch4.xyz,method=GFN2-xTB -u -a xtb &> log.xtb diff --git a/ipi/pes/xtb.py b/ipi/pes/xtb.py index 687c8768b..7c0d0e14b 100644 --- a/ipi/pes/xtb.py +++ b/ipi/pes/xtb.py @@ -1,8 +1,7 @@ import numpy as np -import json from ipi.utils.units import unit_to_internal, unit_to_user -from ipi.utils.messages import verbosity, warning +from ipi.utils.io import read_file_name from .dummy import Dummy_driver tb = None @@ -17,15 +16,14 @@ class TBLiteDriver(Dummy_driver): Example:: - python driver.py -m xtb -u -o config.json + i-pi-py_driver -m xtb -u -o template=input.xyz,method=GFN2-xTB """ - def __init__(self, json_input, *args, **kwargs): - warning( - "THIS PES HAS NOT BEEN TESTED FOLLOWING CONVERSION TO THE NEW PES API.", - verbosity.low, - ) - config = json.load(open(json_input)) + def __init__( + self, template, method, charge=None, uhf=None, periodic=None, *args, **kwargs + ): + + super().__init__(*args, **kwargs) global tb try: @@ -35,17 +33,26 @@ def __init__(self, json_input, *args, **kwargs): "Could not find tblite for xtb driver. Please install tblite-python with mamba" ) - try: - self.method = config["method"] - self.numbers = np.asarray(config["numbers"]) - except KeyError as e: - raise ValueError(f"Required key {str(e)} not found.") - self.charge = config.get("charge") - self.uhf = config.get("uhf") - self.periodic = config.get("periodic") + input_data = read_file_name(template) + atoms = input_data["atoms"] + symbols = atoms.names[:] + numbers = np.asarray(tb.symbols_to_numbers(symbols)) + self.periodic = periodic self.verbosity = 1 if self.verbose else 0 - super().__init__(*args, **kwargs) + pos = unit_to_user("length", "atomic_unit", atoms.q[:]) + cell = unit_to_user("length", "atomic_unit", input_data["cell"].h.T) + + self.calc = tb.Calculator( + method, + numbers, + np.asarray(pos), + charge, + uhf, # unpaired electrons + np.asarray(cell) if self.periodic else None, + np.repeat(self.periodic, 3) if self.periodic else None, + ) + self.calc.set("verbosity", self.verbosity) def __call__(self, cell, pos): """ @@ -58,19 +65,10 @@ def __call__(self, cell, pos): pos = unit_to_user("length", "atomic_unit", pos) cell = unit_to_user("length", "atomic_unit", cell.T) - calc = tb.Calculator( - self.method, - self.numbers, - np.asarray(pos), - self.charge, - self.uhf, # unpaired electrons - np.asarray(cell) if self.periodic else None, - np.repeat(self.periodic, 3) if self.periodic else None, - ) - calc.set("verbosity", self.verbosity) + self.calc.update(np.asarray(pos), np.asarray(cell) if self.periodic else None) # Do the actual calculation - results = calc.singlepoint() + results = self.calc.singlepoint() pot = results.get("energy") grad = results.get("gradient") vir = results.get("virial") From ab08e91634ff2bce6d7239d444991eab04ea635f Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Thu, 21 Nov 2024 01:05:21 +0100 Subject: [PATCH 44/47] Fix traj parsing --- ipi/utils/parsing.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ipi/utils/parsing.py b/ipi/utils/parsing.py index ef9455bb1..1313323e8 100644 --- a/ipi/utils/parsing.py +++ b/ipi/utils/parsing.py @@ -139,7 +139,7 @@ def read_trajectory( file_handle = open(filename, "r") bohr2angstrom = unit_to_user("length", "angstrom", 1.0) - comment_regex = re.compile(r"([^)]+)\{([^}]+)\}") + comment_regex = re.compile(r"(\w+)\{([^}]+)\}") step_regex = re.compile(r"Step:\s+(\d+)") frames = [] @@ -207,10 +207,10 @@ def read_trajectory( # parse comment to get the property matches = comment_regex.findall(ret["comment"]) - + print("MATCHES ", matches) # get what we have found - if len(matches) >= 2: - what = matches[-2][0] + if len(matches) == 2: + what = matches[0][0] else: # defaults to reading positions what = "positions" @@ -219,13 +219,14 @@ def read_trajectory( if len(matches) >= 1: frame.info["step"] = int(matches[-1][0]) - # if we have forces, set positions to zero (that data is missing!) and set forces instead + # if we have forces, set positions to zero (that data is missing!) + # and set forces instead if what == "forces": # set forces and convert to eV/angstrom frame.positions *= 0 frame.arrays["forces"] = ret["atoms"].q.reshape( (-1, 3) - ) * unit_to_user("force", "ev/ang", 1.0) + ) * unit_to_user("force", "ase", 1.0) frames.append(frame) From 16dadfbb1619606e4fd6ca3d6f194a655886d1cc Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Thu, 21 Nov 2024 01:07:13 +0100 Subject: [PATCH 45/47] Remove debug print --- ipi/utils/parsing.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ipi/utils/parsing.py b/ipi/utils/parsing.py index 1313323e8..225713604 100644 --- a/ipi/utils/parsing.py +++ b/ipi/utils/parsing.py @@ -207,7 +207,6 @@ def read_trajectory( # parse comment to get the property matches = comment_regex.findall(ret["comment"]) - print("MATCHES ", matches) # get what we have found if len(matches) == 2: what = matches[0][0] From fda7aec239de1434d94878d1507c189b70e20606 Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Thu, 28 Nov 2024 13:27:10 +0100 Subject: [PATCH 46/47] Improved handling of other trajectory types --- ipi/utils/parsing.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ipi/utils/parsing.py b/ipi/utils/parsing.py index 225713604..2b1bd4f9e 100644 --- a/ipi/utils/parsing.py +++ b/ipi/utils/parsing.py @@ -9,6 +9,7 @@ import re import numpy as np from ipi.utils.units import unit_to_user +from ipi.utils.messages import warning, verbosity try: import ase @@ -220,12 +221,35 @@ def read_trajectory( # if we have forces, set positions to zero (that data is missing!) # and set forces instead - if what == "forces": - # set forces and convert to eV/angstrom - frame.positions *= 0 - frame.arrays["forces"] = ret["atoms"].q.reshape( - (-1, 3) - ) * unit_to_user("force", "ase", 1.0) + if what in [ + "positions", + "x_centroid", + "x_centroid_even", + "x_centroid_odd", + ]: + pass # nothing to do here, positions is the right place to store + else: + frame.positions *= 0.0 # trajectory does NOT contain position data! + frame.arrays[what] = ret["atoms"].q.reshape((-1, 3)) + if what in [ + "forces", + "forces_spring", + "forces_component", + "forces_sc", + "Eforces", + "f_centroid", + "forces_component_raw", + ]: + frame.arrays[what] *= unit_to_user("force", "ase", 1.0) + elif what in ["velocities", "v_centroid"]: + frame.arrays[what] *= unit_to_user("velocity", "ase", 1.0) + elif what in ["momenta", "p_centroid"]: + frame.arrays[what] *= unit_to_user("momentum", "ase", 1.0) + else: + warning( + f"No units conversion implemented for trajectory type {what}", + verbosity.low, + ) frames.append(frame) From 3d89bacef8c7fa1c4247dde2d0a2dfa7d978f02f Mon Sep 17 00:00:00 2001 From: Michele Ceriotti Date: Fri, 29 Nov 2024 00:38:14 +0100 Subject: [PATCH 47/47] Fixed units conversion in parser in a smarter way --- ipi/utils/parsing.py | 54 +++++++++++++++++--------------------------- ipi/utils/units.py | 6 ++--- 2 files changed, 24 insertions(+), 36 deletions(-) diff --git a/ipi/utils/parsing.py b/ipi/utils/parsing.py index 2b1bd4f9e..ef4ea1a42 100644 --- a/ipi/utils/parsing.py +++ b/ipi/utils/parsing.py @@ -139,7 +139,6 @@ def read_trajectory( raise ValueError(f"Unrecognized file format: {format}") file_handle = open(filename, "r") - bohr2angstrom = unit_to_user("length", "angstrom", 1.0) comment_regex = re.compile(r"(\w+)\{([^}]+)\}") step_regex = re.compile(r"Step:\s+(\d+)") @@ -201,8 +200,9 @@ def read_trajectory( frame = ase.Atoms( ret["atoms"].names, - positions=ret["atoms"].q.reshape((-1, 3)) * bohr2angstrom, - cell=ret["cell"].h.T * bohr2angstrom, + # will apply conversion later! + positions=ret["atoms"].q.reshape((-1, 3)), + cell=ret["cell"].h.T * unit_to_user("length", "ase"), pbc=True, ) @@ -219,37 +219,25 @@ def read_trajectory( if len(matches) >= 1: frame.info["step"] = int(matches[-1][0]) - # if we have forces, set positions to zero (that data is missing!) - # and set forces instead - if what in [ - "positions", - "x_centroid", - "x_centroid_even", - "x_centroid_odd", - ]: - pass # nothing to do here, positions is the right place to store + # fetch the list of known traj types, cf. `engine/properties.py`` + from ipi.engine.properties import Trajectories # avoids circular import + + traj_types = Trajectories().traj_dict + if not what in traj_types: + warning( + f"{what} is not a known trajectory type. Will apply no units conversion", + verbosity.low, + ) + elif traj_types[what]["dimension"] == "length": + # positions is the right place to store, and we just need to convert + frame.positions *= unit_to_user("length", "ase") else: - frame.positions *= 0.0 # trajectory does NOT contain position data! - frame.arrays[what] = ret["atoms"].q.reshape((-1, 3)) - if what in [ - "forces", - "forces_spring", - "forces_component", - "forces_sc", - "Eforces", - "f_centroid", - "forces_component_raw", - ]: - frame.arrays[what] *= unit_to_user("force", "ase", 1.0) - elif what in ["velocities", "v_centroid"]: - frame.arrays[what] *= unit_to_user("velocity", "ase", 1.0) - elif what in ["momenta", "p_centroid"]: - frame.arrays[what] *= unit_to_user("momentum", "ase", 1.0) - else: - warning( - f"No units conversion implemented for trajectory type {what}", - verbosity.low, - ) + # if we have another type of value, set positions to zero + # (that data is missing!) and set an array instead + frame.positions *= 0.0 + frame.arrays[what] = ret["atoms"].q.reshape((-1, 3)) * unit_to_user( + traj_types[what]["dimension"], "ase" + ) frames.append(frame) diff --git a/ipi/utils/units.py b/ipi/utils/units.py index 4841a1950..6f621bbf2 100644 --- a/ipi/utils/units.py +++ b/ipi/utils/units.py @@ -365,7 +365,7 @@ def mass(cls, label): # -def unit_to_internal(family, unit, number): +def unit_to_internal(family, unit, number=1.0): """Converts a number of given dimensions and units into internal units. Args: @@ -411,7 +411,7 @@ def unit_to_internal(family, unit, number): return number * UnitMap[family][base.lower()] * UnitPrefix[prefix] -def unit_to_user(family, unit, number): +def unit_to_user(family, unit, number=1.0): """Converts a number of given dimensions from internal to user units. Args: @@ -423,4 +423,4 @@ def unit_to_user(family, unit, number): The number in the user specified units """ - return number / unit_to_internal(family, unit, 1.0) + return number / unit_to_internal(family, unit)