HookFunctions¶
- class HookFunctions(pre_step_hooks=None, post_step_hooks=None, measurement_hooks=None)¶
Class to store and manage all hook functions for a dynamics calculation (MD or TS-FBMC).
- Parameters:
pre_step_hooks (callable | list of callable | None) – A user-defined function or a list of functions which will be called just before the forces evaluation. The signature of the function requires the arguments
step, time, configuration
. The return status is ignored. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
Default:None
.post_step_hooks (callable | list of callable | None) – A user-defined function or a list of functions which will be called just after the forces evaluation. The signature of the function requires the arguments
step, time, configuration
. Optional arguments include, forces, local_forces (for distributed MD), stress, trajectory (the MD trajectory), temperature, pressure, potential_energy, and/or kinetic_energy. The return status is ignored. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
Default:None
.measurement_hooks (callable | list of callable | None) – A user-defined function or a list of functions which will be called at the end of each MD step after all constraints have been applied. The signature of the function requires the arguments
step, time, configuration
. Optional arguments include forces, local_forces (for distributed MD), stress, trajectory (the MD trajectory), temperature, pressure, potential_energy, and/or kinetic_energy. The return value should be a dictionary that maps string keys to values. The values may be numbers, numpy arrays, or PhysicalQuantities. These values are stored on the MDTrajectory and can be accessed using the measurement method. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
Default:None
.
- addMeasurementHooks(hook_functions)¶
Add a measurement hook function or functions.
- Parameters:
hook_functions (callable | list of callable) – A user-defined function or a list of functions which will be called at the end of each MD step after all constraints have been applied. The signature of the function requires the arguments
step, time, configuration
. Optional arguments include forces, local_forces (for distributed MD), stress, trajectory (the MD trajectory), temperature, pressure, potential_energy, and/or kinetic_energy. The return value should be a dictionary that maps string keys to values. The values may be numbers, numpy arrays, or PhysicalQuantities. These values are stored on the MDTrajectory and can be accessed using the measurement method. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
- addPostStepHooks(hook_functions)¶
Add a post step hook function or functions.
- Parameters:
hook_functions (callable | list of callable) – A user-defined function or a list of functions which will be called just after the forces evaluation. The signature of the function requires the arguments
step, time, configuration
. Optional arguments include, forces, local_forces (for distributed MD), stress, trajectory (the MD trajectory), temperature, pressure, potential_energy, and/or kinetic_energy. The return status is ignored. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
- addPreStepHooks(hook_functions)¶
Add a pre-step hook function or functions.
- Parameters:
hook_functions (callable | list of callable) – A user-defined function or a list of functions which will be called just before the forces evaluation. The signature of the function requires the arguments
step, time, configuration
. The return status is ignored. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
- allHooks()¶
- Returns:
All hook functions separated by hook types.
- Return type:
dict
- anyMeasurementHooksRequireStress()¶
Check if any of the measurement hooks requires stress.
- Returns:
True, if any measurement hook requires stress.
- Return type:
bool
- callAllHookFunctions(hook_type, step, time, configuration, local_forces, stress, trajectory, md_quantities=None)¶
Run through all hook functions, gather their required arguments and call them in the given order.
- Parameters:
hook_type (str) – The hook type.
step (int) – The current MD step number.
time (PhysicalQuantity of type time) – The current simulation time.
configuration (DistributedConfiguration |
MoleculeConfiguration
|BulkConfiguration
|DeviceConfiguration
|SurfaceConfiguration
) – The current configuration.local_forces (PhysicalQuantity of type energy/length) – The local forces vector. For serial simulation this will be the same as the global vector.
stress (PhysicalQuantity of type energy/length**3 | None) – The stress tensor or None if no stress calculation is carried out.
trajectory (MDTrajectory) – The trajectory calculated so far.
md_quantities (MDQuantities) – Optional, the MDQuantities object.
Default: None.
- Returns:
Measurement values.
- Return type:
dict
- hasMeasurementHooks()¶
- Returns:
True, if there are measurement hooks in the store.
- Return type:
bool
- hasPostStepHooks()¶
- Returns:
True, if there are post-step hooks in the store.
- Return type:
bool
- hasPreStepHooks()¶
- Returns:
True, if there are pre-step hooks in the store.
- Return type:
bool
- measurementHooks()¶
- Returns:
The measurement hooks.
- Return type:
list of HookFunctionCall
- metatext()¶
- Returns:
The metatext of the object or None if no metatext is present.
- Return type:
str | None
- nlinfo()¶
Create NLInfo.
- Returns:
The nlinfo.
- Return type:
dict
- postStepHooks()¶
- Returns:
The post-step hooks.
- Return type:
list of HookFunctionCall
- preStepHooks()¶
- Returns:
The pre-step hooks.
- Return type:
list of HookFunctionCall
- removeMeasurementHook(index)¶
Remove a measurement hook function.
- Parameters:
index (int) – The index of the hook function to remove.
- Returns:
The removed hook function.
- Return type:
HookFunctionCall | None
- removePostStepHook(index)¶
Remove a post-step hook function.
- Parameters:
index (int) – The index of the hook function to remove.
- Returns:
The removed hook function.
- Return type:
HookFunctionCall | None
- removePreStepHook(index)¶
Remove a pre-step hook function.
- Parameters:
index (int) – The index of the hook function to remove.
- Returns:
The removed hook function.
- Return type:
HookFunctionCall | None
- setHookFunctions(pre_step_hooks=None, post_step_hooks=None, measurement_hooks=None)¶
Set hook functions.
Note! This replaces any currently set hook functions.
- Parameters:
pre_step_hooks (callable | list of callable | None) – A user-defined function or a list of functions which will be called just before the forces evaluation. The signature of the function requires the arguments
step, time, configuration
. The return status is ignored. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
Default:None
.post_step_hooks (callable | list of callable | None) – A user-defined function or a list of functions which will be called just after the forces evaluation. The signature of the function requires the arguments
step, time, configuration
. Optional arguments include, forces, local_forces (for distributed MD), stress, trajectory (the MD trajectory), temperature, pressure, potential_energy, and/or kinetic_energy. The return status is ignored. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
Default:None
.measurement_hooks (callable | list of callable | None) – A user-defined function or a list of functions which will be called at the end of each MD step after all constraints have been applied. The signature of the function requires the arguments
step, time, configuration
. Optional arguments include forces, local_forces (for distributed MD), stress, trajectory (the MD trajectory), temperature, pressure, potential_energy, and/or kinetic_energy. The return value should be a dictionary that maps string keys to values. The values may be numbers, numpy arrays, or PhysicalQuantities. These values are stored on the MDTrajectory and can be accessed using the measurement method. Unhandled exceptions will terminate a Molecular Dynamics evaluation. If a list is given, the functions will be called in the given order.
Default:None
.
- setMetatext(metatext)¶
Set a given metatext string on the object.
- Parameters:
metatext (str | None) – The metatext string that should be set. A value of “None” can be given to remove the current metatext.
- uniqueString()¶
Return a unique string representing the state of the object.
Usage Examples¶
Set up a HookFunctions object with a StrainConfigurationHook as a pre-step hook, a custom hook function as a post-step hook and a measurement hook to measure the uniaxial stress and strain in all three Cartesian directions:
# -*- coding: utf-8 -*-
from .hook_functions_configuration import silver
# %% HookFunctions
# Pre-step hook functions
strain_configuration_hook = StrainConfigurationHook(
strain_direction='xx', strain_rate=5.0 * 1 / ps, call_interval=10, strain_interval=1
)
# Post-step hook functions
def custom_hook(step, time, configuration, forces):
call_interval = 10
if step % call_interval != 0:
return
print(forces)
# Measurement hooks
md_measurement = MDMeasurement(
measurements=[
'strain_xx',
'strain_yy',
'strain_zz',
'stress_xx',
'stress_yy',
'stress_zz',
],
call_interval=10
)
pre_step_hooks = [
strain_configuration_hook,
]
post_step_hooks = [
custom_hook,
]
measurement_hooks = [
md_measurement,
]
hook_functions = HookFunctions(
pre_step_hooks=pre_step_hooks,
post_step_hooks=post_step_hooks,
measurement_hooks=measurement_hooks,
)
nlsave('HookFunctions_results.hdf5', hook_functions)
# %% MolecularDynamics
method = NVEVelocityVerlet(
initial_velocity=MaxwellBoltzmannDistribution(
temperature=300.0 * Kelvin,
remove_center_of_mass_momentum=False,
random_seed=None,
enforce_temperature=True,
),
time_step=1.0 * fs,
)
md_trajectory = MolecularDynamics(
configuration=silver,
constraints=[],
trajectory_filename='HookFunctions_results.hdf5',
steps=5000,
log_interval=100,
method=method,
hook_functions=hook_functions,
)
last_image = md_trajectory.lastImage()
# %% TimeStampedForceBiasMonteCarlo
monte_carlo_method = ForceBiasMonteCarlo(
temperature=300.0 * Kelvin,
max_atom_displacement=0.1 * Angstrom,
heating_rate=0.0 * Kelvin,
random_seed=None,
max_random_attempts=500,
)
tfmc_trajectory = TimeStampedForceBiasMonteCarlo(
configuration=last_image,
constraints=[],
trajectory_filename='HookFunctions_results.hdf5',
steps=5000,
log_interval=100,
method=monte_carlo_method,
hook_functions=hook_functions,
)
last_image_1 = tfmc_trajectory.lastImage()
hook_functions_configuration.py
hook_functions.py
For sake of clarity, the configuration and calculator are defined in a separate file. In the example, both a MolecularDynamics and a TimeStampedForceBiasMonteCarlo are instantiated to illustrate how the HookFunctions is passed to them respectively.
General¶
The HookFunctions class can be used to organize sets of pre-, post- and measurement hook functions, that can then be passed to a MolecularDynamics or TimeStampedForceBiasMonteCarlo function to be used in a dynamics simulation.
The pre-step hook is invoked immediately before each forces calculation during the MD loop, whereas the post-step hook is invoked immediately after the forces calculation. The measurement hook is invoked at the end of each MD step (see also the reference manual notes MolecularDynamics).
Each category of hook functions can consist of a list of functions. For instance, the pre-step hook can consist of a StrainConfigurationHook and two CustomHooks. The functions within each category are then called in the order they are given in the list.
A HookFunctions object can be saved to disk, and so can be created once and used/reused in different dynamics simulations.
The HookFunctions object is also supported in NanoLab, in the form of a
Workflow Builder Block with the icon . It can be found
under the Optimization and Dynamics category. The block requires an input
configuration and provides a HookFunctions object.
Available hook functions¶
The following classes are available for use in scripting, though not all of them may be available in NanoLab:
Custom hook functions¶
In principle, any callable object can be used as a custom hook function.
Python generator
objects are not allowed as hook functions. Examples of
valid hook functions are:
Function
def customHookFunction(step, time, configuration):
call_interval = 10
if step % call_interval != 0:
return
...
hook_functions = HookFunctions(pre_step_hooks=[customHookFunction])
For functions, the call interval can be included as part of the function body, if the hook should not be called at each step.
Callable class
class CustomHookCallable:
def __call__(self, step, time, configuration):
...
def callInterval(self):
return 10
hook_functions = HookFunctions(pre_step_hooks=[CustomHookCallable])
For callable classes, the call interval can be provided by defining a
callInterval
method on the class that returns an integer, if the hook
should not be called at each step.
Class method
class CustomHookClass:
def hookMethod(self, step, time, configuration):
...
def callInterval(self):
return 10
hook_functions = HookFunctions(pre_step_hooks=[CustomHookClass.hookMethod])
For class methods, there can also be a callInterval
method on the class
that returns the call interval as an integer.
Warning
It is not recommended to use class methods as these cannot be
reconstructed when a saved HookFunctions object is read from disk. They
can, however, be safely used if the custom hook class and HookFunctions
are defined within the same script. If possible, opt to re-write the
custom hook class with a __call__
method instead.
Note! Any modification to the configuration, forces, or stress, must be made in-place, e.g:
def customHookFunction(step, time, configuration, forces):
# Add a small constant forces to the forces vector of the first atom.
forces[0] += [0.1, 0.1, 0.1] * eV / Ang
Because the pre-step hook is invoked immediately before each forces calculation during the MD loop, any modification to the forces or stress, e.g. adding an external force, should be made in a post-step hook, which is invoked after the forces calculation. If a modification is done in a pre-step hook, it would be overwritten by the calculated forces, and have no effect.
In contrast, any modification to the configuration, e.g. straining the cell, should be made in a pre-step-hook, so that the following forces calculation will be carried out on the modified configuration.
Input arguments¶
A custom hook function must take at least the following arguments:
step
time
configuration
It may optionally take the following arguments:
forces
local_forces (for MPI-distributed MD simulations)
stress
trajectory
If it is to be used as a measurement hook, it may also optionally take the following arguments:
temperature
pressure
potential_energy
kinetic_energy
md_quantities
md_quantities
contains all of the other measurement types, and additionally
has the methods reservoirTemperature
, reservoirPressure
and
timeStep
.
Any arguments not listed above (excluding self
, cls
for
callable classes and class methods) will raise an exception when the
HookFunctions object is instantiated.
Return value¶
In general, a hook function does not return a value. For pre- and post-step hooks any return value is simply neglected.
For measurement hooks, a dict
can be returned, for which each entry
in the dictionary is then stored as a separate measurement on the
MDTrajectory, and would be automatically available as a plot when
visualized in the MovieTool. In this way, custom measurement quantities can
be introduced in a dynamics simulation.
Notes¶
The keyword arguments
pre_step_hook
andpost_step_hook
for MolecularDynamics and a TimeStampedForceBiasMonteCarlo andmeasurement_hook
for MolecularDynamics are also available for convenience of use. However, if ahook_functions
is given, these keyword arguments will be ignored.A HookFunctions object must be saved explicitly. The MolecularDynamics and TimeStampedForceBiasMonteCarlo functions do not save the hook functions they use, irrespective of which keyword(s) were used to pass the functions.