Sockets provide a convenient interface to communicate small amount of information between independent processes. They can be used to exchange atomic coordinates and forces, separating the task of evaluating electronic structure properties from that of moving the position of the nuclei, e.g. in a molecular dynamics simulation.
Here we will discuss briefly how an interface based on sockets, and a minimal communication protocol can be used to exchange information between a server that deals with nuclear motion, and a client that computes energy, forces and possibly further properties. This communication protocol is implemented and used by i-PI, but it could similarly be used by any code that wants to realize a similar decoupling of energy calculation and nuclear evolution.
The server application starts first and listens on a specified UNIX socket or TCP/IP port and network interface. Subsequently, the client - having been given the address and port on which the server is listening - establishes a connection.
The client then enters a listening loop waiting for signals from the server. Communication is built arountd the exchange of short synchronization messages, that are 12 characters strings, that announce the status of the two parties, and the transfer of data in both directions.
The figure shows a typical complete exchange as one might need to realize in order to advance the server by one molecular dynamics step. First, the server sends a STATUS request. The client might either respond with NEEDINIT, to signal that it wants some initialization data from the server. In that case, the server sends an integer (4 bytes) containing the unique ID of the replica it is about to dispatch. This is useful when the server is performing a simulation that entails multiple atomic configurations (path integrals, parallel tempering, NEB, ...) so that the client can ascertain whether it is about to receive a brand new configuration or data from the same replica it processed at a previous step. The server then sends an initialization string, which is preceded by an integer that contains the string length, and another STATUS request.
After processing this preliminary exchange - which is not mandatory - the client responds READY, to signal it is available to perform a calculation. The server might continue sending STATUS requests, up to the point when a force evaluation is needed. It then sends a POSDATA request, so that the client can prepare to receive data. The server sends the cell parameters as a matrix (9*8 bytes), the inverse of the cell matrix (9*8 bytes), the number of atoms (a 4-bytes integer), the atomic coordinates (3* 8-bytes doubles) ordered as x y z x y z ...
The client has then enough information to start a new energy calculation. The internal information on the atomic structure should be updated, and energy, forces, stress tensor, and possibly other observables that depend on the nuclear coordinates can be computed. Meanwhile, the server can send one more STATUS request, that will stay pending while the calculation completes. At that point, the client can sed a HAVEDATA string to signal that it is ready to return energy data.
A FORCEREADY header precedes the actual information, that is returned as the energy first (an 8-bytes double), the number of atoms (a 4-bytes integer), the force (3* 8-bytes doubles), the stress tensor (9*8 bytes). Since different clients may compute different properties in addition to energy and forces, the mechanism to return extra information is extremely general: the additional data is returned as a string, preceded by an integer that indicates the number of characters the string contains. This makes it possible to return completely arbitrary information, that can be then processed later in a way that is specific to the format used by a particular client.
Having returned the results of the calculation, the client can then prepare to receive a new batch of nuclear coordinates, to continue the calculation.