diff --git a/drivers/py/driver.py b/drivers/py/driver.py index 327de30e6..669778e8d 100755 --- a/drivers/py/driver.py +++ b/drivers/py/driver.py @@ -9,6 +9,7 @@ Minimal example of a Python driver connecting to i-PI and exchanging energy, forces, etc. """ + def recv_data(sock, data): """Fetches binary data from i-PI socket.""" blen = data.itemsize * data.size diff --git a/ipi/engine/forcefields.py b/ipi/engine/forcefields.py index d2ff5fb4a..6edabebea 100644 --- a/ipi/engine/forcefields.py +++ b/ipi/engine/forcefields.py @@ -23,6 +23,7 @@ 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 @@ -392,7 +393,42 @@ def evaluate(self, request): class FFDirect(FFEval): - pass + 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 + # TODO sanitize the handling of pars + self.driver = __drivers__[self.pes]("", verbosity.high) + + def evaluate(self, request): + request["result"] = list(self.driver(request["cell"][0], request["pos"])) + request["status"] = "Done" class FFLennardJones(FFEval): diff --git a/ipi/inputs/forcefields.py b/ipi/inputs/forcefields.py index 68f0ed3b9..ec4e8af5d 100644 --- a/ipi/inputs/forcefields.py +++ b/ipi/inputs/forcefields.py @@ -22,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 * @@ -341,6 +342,19 @@ def check(self): 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) @@ -348,7 +362,22 @@ class InputFFDirect(InputForceField): call, using PES providers from a list of possible external codes. """ default_label = "FFDirect" - _FFCLASS = FFDirect + def store(self, ff): + super().store(ff) + self.pes.store(ff.pes) + + def fetch(self): + super().fetch() + + 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(), + ) class InputFFLennardJones(InputForceField): @@ -438,7 +467,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_tests/profiling/classical_md_direct/input.xml b/ipi_tests/profiling/classical_md_direct/input.xml index a3620476e..21d038b66 100644 --- a/ipi_tests/profiling/classical_md_direct/input.xml +++ b/ipi_tests/profiling/classical_md_direct/input.xml @@ -1,5 +1,6 @@ - + + dummy 1.00000000e-04 10000