Socket-Communication#
[Input: recipes/interfaces/ase/sockets/]
For calculations that heavily rely on file-IO, it is better to use communication between Fortnet and ASE with the i-PI protocol. In these cases, the reduction of the wallclock time can be significant.
Below, an exemplary geometry optimization, controlled by ASE via socket communication, is performed. A water molecule is used for demonstration.
Geometry Optimization by ASE#
Providing the input for Fortnet#
To establish a connection via socket communication, Fortnet is called with the
appropriate Socket{}
driver option, specifying, among others, the expected
atom elements and boundary conditions:
Driver = Socket {
File = 'fortnet'
Protocol = i-PI {
# Non-periodic water molecule (H2O)
Periodic = No
AtomicNumbers = 8 1 1
}
MaxSteps = -1
Verbosity = 0
}
It instructs Fortnet to read geometry driving commands via a named temporary
communication file (stored in /tmp/). The code is asked to continue running
until told to stop (MaxSteps = -1
).
Additionally, a network initialization file (NetstatFile
) must be specified
and read. Operating in socket mode always requires force analysis, which is
assumed (and overwritten) even if not requested by the user:
Data {
NetstatFile = 'fortnet.hdf5'
}
Options {
ReadNetStats = Yes
Mode = 'predict'
}
Analysis {
Forces = Analytical {}
}
Main Script#
The geometry used is a simple, unoptimized water molecule, whose file location is specified in the main script (GEO_IN):
3
O 0.0000000000E+00 -1.0000000000E+00 0.0000000000E+00
H 0.0000000000E+00 0.0000000000E+00 7.8306400000E-01
H 0.0000000000E+00 0.0000000000E+00 -7.8306400000E-01
Following the necessary imports, the main script defines the type of socket to
be used (UNIX socket) as well as the path to the Fortnet executable
(FNET) and the geometry (GEO_IN). The main method then first reads in
the geometry to optimize. Subsequently, the ASE driver BFGS()
for geometry
optimization is specified and where to write the trajectory and the logfile.
Finally, the last trajectory image that contains the optimized water molecule is extracted and the geometry written to disk:
import sys
from subprocess import Popen
from ase.io import read, write
from ase.optimize import BFGS
from ase.io.trajectory import Trajectory
from ase.calculators.socketio import SocketIOCalculator
UNIXSOCKET = 'fortnet'
FNET = 'fnet'
GEO_IN = './H2O_unoptimized.xyz'
GEO_OUT = './H2O_optimized.xyz'
TRAJECTORY = 'opt.traj'
def main():
'''Main driver routine.'''
system = read(GEO_IN, format='xyz')
opt = BFGS(system, trajectory=TRAJECTORY, logfile='opt.log')
with SocketIOCalculator(log=sys.stdout, unixsocket=UNIXSOCKET) as calc:
Popen(FNET)
system.set_calculator(calc)
opt.run(fmax=1E-04)
traj = Trajectory(TRAJECTORY)
atoms = traj[-1]
write(GEO_OUT, atoms, format='xyz')
if __name__ == "__main__":
main()
You may also consider inspecting the trajectory of the run by invoking:
ase gui opt.traj
Note
To correctly close sockets on the ASE side, call calc.close() at the end
or, more elegantly, enclose the class SocketIOCalculator
using the
with statement as done in the example shown here. Nevertheless, in the
current state of ASE, the socket gets closed without warning missing the
‘EXIT’ string of the i-PI protocol, which always leads to an error message
issued by Fortnet at the end of a calculation driven by
socket-communication.