seamm_mdi package#

Submodules#

seamm_mdi.mdi_engine module#

Driver-side MDI engine facility for SEAMM.

MDIEngine launches an MDI engine once and drives it for many energy/force evaluations. The driver is the MDI listener: it binds a TCP port and the engine connects back to it (the direction that works both locally and, later, from a compute node dialing back to the JobServer). Unit conversions are handled here, in one place, via seamm_util.Q_.

Local mode only for now: the engine is launched as a subprocess on the same host and dials back to 127.0.0.1 (LOCAL_HOST). Remote/queue launching through the SEAMM executor is planned.

seamm_mdi.mdi_engine.LOCAL_HOST = '127.0.0.1'#

the loopback address itself, not “localhost”, whose lookup can fail for a while when the resolver hiccups (macOS, 2026-10-29: “[Errno 8] nodename nor servname provided, or not known” for about 2.5 minutes, so that engines could not be started)

Type:

The address a local engine dials back to

class seamm_mdi.mdi_engine.MDIEngine(build_argv, elements, *, name='SEAMM', hostname='127.0.0.1', timeout=60.0, logger=<Logger seamm_mdi.mdi_engine (WARNING)>)[source]#

Bases: object

Drive an MDI engine for repeated energy/force evaluations.

Parameters:
  • build_argv (callable(hostname, port) -> list[str]) – Builds the argv that launches the engine wrapper, pointed at the driver’s hostname/port (e.g. from a program step’s get_mdi_engine_command). The engine must be -role ENGINE so it connects back to the driver.

  • elements (sequence[int]) – Atomic numbers of the atoms, in coordinate order. Fixed for the session.

  • name (str) – The MDI driver name.

  • hostname (str) – The host the engine should dial: by default the loopback address 127.0.0.1, which needs no name lookup.

  • timeout (float) – Seconds to wait for the engine to connect before giving up.

  • logger (logging.Logger)

Notes

One active engine per process (MDI keeps global state). Use as a context manager, or call start() / close() explicitly.

close()[source]#

Tell the engine to exit and reap the process.

energy(units='hartree')[source]#

Return the total energy in units (default MDI-native hartree).

fingerprints()[source]#

The fingerprints of the settings of the engine’s last calculations, or None if the engine does not give them.

Via the engine’s custom <FINGERPRINT_LENGTH and <FINGERPRINT commands, which return JSON: {"energy": record, "hessian": record}, each the record of the last energy/gradient or analytic-Hessian run (None until there has been one), as from seamm_util.fingerprint.calculation_record(). A step stores them with the results with Node.store_calculation_record(). An engine that runs where seamm_util is not installed may send a record without its fingerprints (program, version and the hashed files only); it is completed here (complete_records()), so every code hashes the same way.

forces(units='hartree/bohr')[source]#

Return the forces as an (n, 3) array in units (default hartree/bohr).

hessian(units='hartree/bohr**2')[source]#

Return the analytic Cartesian Hessian as a (3n, 3n) array in units (default hartree/bohr^2), via the engine’s custom <HESSIAN command.

Raises NotImplementedError if the engine does not support <HESSIAN – the caller should then finite-difference forces() instead.

set_cell(vectors, units='bohr')[source]#

Send the periodic cell (lattice) vectors to the engine (>CELL).

Parameters:
  • vectors ((3, 3) array-like) – The three cell vectors as rows, in units.

  • units (str) – The units of vectors (default MDI-native bohr).

Notes

Not every engine understands >CELL; check supports() first when a molecular-only engine is a possibility. The MDI convention is that the engine treats the system as fully periodic once a cell is set.

set_coordinates(xyz, units='bohr')[source]#

Send the atomic coordinates to the engine.

Parameters:
  • xyz ((n, 3) or (3n,) array-like) – The coordinates, in units.

  • units (str) – The units of xyz (default MDI-native bohr).

start()[source]#

Listen, launch the engine, accept its connection, send the topology.

Starting is tried up to start_attempts times, waiting start_retry_waits (2, 10 and 30 s) between them: an engine has occasionally failed to start when engines were started one after another (the first command, >NATOMS, failed on a connection that had just been accepted), and the next attempt, on a new port, succeeds; the longer waits ride out a short outage of the machine’s networking. The error of the last attempt is raised if none does.

stress(units='hartree/bohr**3')[source]#

Return the stress tensor as a (3, 3) array in units (default hartree/bohr^3), via <STRESS.

The engine returns the MDI pressure-sign convention; a non-periodic engine typically returns zeros.

supports(command, node='@DEFAULT')[source]#

Whether the engine supports an MDI command (e.g. "<HESSIAN").

Lets a driver discover an optional capability at runtime rather than being told in advance – e.g. use the analytic Hessian if the engine offers one, else finite-difference the forces.

seamm_mdi.mdi_engine.complete_records(records)[source]#

Engine records with their fingerprints: a record that has “files” but no “fingerprint” (from an engine without seamm_util, e.g. xTB’s tblite engine in its own environment) gets them from seamm_util.fingerprint.calculation_record(); others are unchanged.

Module contents#

seamm_mdi – a reusable MDI driver facility for SEAMM.