Thermodynamic Integration#

class directupsampling.ti.ThermoInt(atoms: Atoms, calc0: Calculator, calc1: Calculator, vt_grid: Grid | Iterable[tuple[float]], lambdas: Grid | Iterable[float] = (0.0, 0.25, 0.5, 0.75, 1.0), eos0: Any | None = None, eos1: Any | None = None, sampling_setting: SamplingSetting | dict[str, Any] | None = None)[source]#

Bases: object

Class for thermodynamic integration from calc0 to calc1 on vt_grid.

Integrates over provided lambdas (from 0 to 1, corresponding to the repsective calculators).

extract_free_energy_difference(vtp: tuple) None[source]#
property free_energy_differences: DataFrame#
static get_avg_and_err(data) tuple[float, float][source]#
classmethod read(filename: str | Path, atoms: Atoms = None) ThermoInt[source]#

Return a ThermoInt instance corresponding to .db file.

Parameters#

filenamestr or Path

Path to file from which to read the snapshots for the thermodynamic integration. The .db file must contain indices over volume, temperature and lambda.

atomsASE Atoms (optional)

Will be assigend to returned ThermoInt instance. This is not needed if the .db file contains sampled atoms.

Returns#

A new ThermoInt instance.

run_sampling(nsnapshots: int = 150, sample_atoms: bool = False, **kwargs: dict) None[source]#

Sample nsnapshots (default 150) snapshots over vt_grid*lambdas.

Parameters#

nsnapshots: int

The number of snapshots to sample.

sample_atoms: bool

Whether or not to sample atoms objects. Note that the default (False) differs from that of SnapshotSamplers sample_snapshots and Dynamics.

kwargs: dict

Keyword arguments for Dynamics.

write_folders(**kwargs: dict) None[source]#
directupsampling.ti.check_if_empty(snapshot_container: SnapshotContainer, vt_point: NamedTuple) bool[source]#
class directupsampling.tifit.RawData(lambda_: ndarray, energy: ndarray, error: ndarray)[source]#

Bases: object

Container for raw data used in thermodynamic integration fitting.

energy: ndarray#
error: ndarray#
lambda_: ndarray#
class directupsampling.tifit.ThermoIntFit(lambdas: ndarray, energies: ndarray, errors=[])[source]#

Bases: object

property best_fit#
check_raw_data() tuple[source]#
fit() None[source]#
fit_types = ('linear', 'cubic', 'tan', 'tan2', 'glogit')#
directupsampling.tifit.glogit(x, a0, a1, a2, a3, a4, a5)[source]#

Generalized logit function

directupsampling.tifit.logit(x, a0, a1, a2, a3, a4)[source]#

Logit function

a0: y shift a1: slope a2: higher x shift (x of y = inf) a3: lower x shift (-x of y = -inf) a4: y span

directupsampling.tifit.tan(x, a0, a1, a2, a3)[source]#

Cotangens

directupsampling.tifit.tan2(x, a0, a1, a2_over_a3_a4, a3, a4)[source]#

Cotangens(x**2 + …)

class directupsampling.thermo.Thermo(fes: FreeEnergySurface, tmax=1000, pressure=0.0001, temperatures=None, pressure_unit: str = 'GPa')[source]#

Bases: object

calculate_properties(veps=0.0001)[source]#

At the moment without defects

property properties#
class directupsampling.debye.Debye(atoms: Atoms, eos: EOS, gamma=0.6666666666666666)[source]#

Bases: object

calculate_debye_temperature(volume)[source]#
property free_energy_surface#
get_free_energy(volume, temperature)[source]#

Calculates vibrational free energies in the Debye-Gueneisen approximation as function of temperature at given volume.

According to Moruzzi, PRB 37 (1988) 790. Arguments include eos parameters and effective mass (a.u.). Fqhs are created for the low T gamma=1 and for high T gamma=2/3.

directupsampling.debye.debye_function(x)[source]#
directupsampling.debye.fdebye(t, t_debye)[source]#

Debye free energy.

Corresponds to Eq. (19) from Moruzzi, but NOTE that there is an error in Moruzzi, the 3ln term must be positive in the end (i.e., when the brackets are eliminated) so inside the brackets the 3ln term should be negative to cancel the minus in front of the brackets.

class directupsampling.eos.EOS(eq_energy: float, eq_volume: float, eq_bulk_modulus: float, eq_bulk_modulus_derivative: float, bulk_modulus_unit: Literal['eV_per_Angstrom3', 'GPa'] = 'eV_per_Angstrom3', name: str = 'EOS')[source]#

Bases: object

asarray() ndarray[source]#

Return the four EOS parameters as a 1-D array in internal units.

Returns#

np.ndarray

[eq_energy, eq_volume, eq_bulk_mod, eq_bulk_mod_deriv] in eV and ų.

classmethod fit(volumes: np.ndarray, energies: np.ndarray) Self[source]#

Fit an EOS to energy-volume data and return the optimised instance.

Parameters#

volumesnp.ndarray

Volumes in ų/atom.

energiesnp.ndarray

DFT total energies in eV/atom, same length as volumes.

Returns#

Self

Fitted EOS instance with raw_data and volume_bounds set.

classmethod fromdict(dct: dict) Self[source]#

Reconstruct an EOS instance from a dict produced by todict.

Parameters#

dctdict

Dictionary as returned by todict().

Returns#

Self

New instance with parameters restored from dct.

abstractmethod get_bulk_modulus(volume: float, unit: str) float[source]#
abstractmethod get_energy(volume: float) float[source]#
abstractmethod get_pressure(volume: float, unit: str) float[source]#
get_volume(pressure: float, unit: str = 'eV_per_Angstrom3') float[source]#

Find the volume at the given pressure by scalar optimisation.

Parameters#

pressurefloat

Target pressure.

unit{“eV_per_Angstrom3”, “GPa”}

Unit of pressure. Default is eV/ų.

Returns#

float

Volume in ų at which the EOS pressure equals pressure.

classmethod read(filename: str | pathlib.Path) Self[source]#

Read EOS parameters from a legacy text file written by write().

Parameters#

filenamestr or pathlib.Path

Path to the file to read.

Returns#

Self

New instance constructed from the file contents.

set_bounds_from_raw_data() None[source]#

Set volume_bounds from the volume range in raw_data.

todict() dict[source]#

Return a JSON-serialisable dict of the EOS parameters.

Returns#

dict

Dictionary of EOS parameters suitable for write_json.

write(filename: str | pathlib.Path) None[source]#

Write the EOS parameters to a text file in the legacy format.

Parameters#

filenamestr or pathlib.Path

Output file path.

class directupsampling.eos.RawData(volume: ndarray, energy: ndarray)[source]#

Bases: object

Container for raw data used in EOS fitting.

energy: ndarray#
volume: ndarray#
class directupsampling.eos.Vinet(eq_energy: float, eq_volume: float, eq_bulk_modulus: float, eq_bulk_modulus_derivative: float, bulk_modulus_unit: Literal['eV_per_Angstrom3', 'GPa'] = 'eV_per_Angstrom3', name: str = 'EOS')[source]#

Bases: EOS

directupsampling_objtype = 'vinet'#
get_bulk_modulus(volume: float, unit: Literal['eV_per_Angstrom3', 'GPa'] = 'eV_per_Angstrom3') float[source]#

Get the analytical bulk modulus at the specified volume.

Parameters#

volumefloat

The volume at which to calculate the bulk modulus.

unit{“eV_per_Angstrom3”, “GPa”}

Specifies the unit of the returned bulk modulus. The default is eV/ų.

Returns#

float

Bulk modulus in the requested unit.

get_energy(volume: float) float[source]#

Return the Vinet energy at the given volume.

Parameters#

volumefloat

Volume in ų.

Returns#

float

Energy in eV.

get_pressure(volume: float, unit: Literal['eV_per_Angstrom3', 'GPa'] = 'eV_per_Angstrom3') float[source]#

Get the analytical pressure at the specified volume.

Parameters#

volumefloat

The volume at which to calculate the pressure.

unit{“eV_per_Angstrom3”, “GPa”}

Specifies the unit of the returned pressure. The default is eV/ų.

Returns#

float

Pressure in the requested unit.

directupsampling.eos.check_pressure_unit(unit: str) float[source]#

Return the conversion factor from the given pressure unit to eV/ų.

Parameters#

unitstr

Pressure unit string. Accepted values (case-insensitive, spaces and underscores ignored): "eV_per_Angstrom3" and "GPa".

Returns#

float

Multiplicative factor to convert a value in unit to eV/ų.

Raises#

ValueError

If unit is not recognised.

directupsampling.eos.get_eos_from_folders(paths: list[pathlib.Path]) EOS[source]#

Fit a Vinet EOS from a list of completed VASP calculation directories.

Parameters#

pathslist of pathlib.Path

Directories each containing a vasprun.xml file. Each directory represents one volume point.

Returns#

EOS

Fitted Vinet EOS instance.

directupsampling.eos.read_eos(file: pathlib.Path) EOS[source]#

Read an EOS from a file, dispatching on the filename.

Parameters#

filepathlib.Path

Path to the EOS file. The filename must contain "vinet" (case-insensitive) to be recognised as a Vinet EOS.

Returns#

EOS

Parsed EOS instance.

Raises#

RuntimeError

If the filename does not match any known EOS type.