from __future__ import annotations
from pathlib import Path
from typing import Iterable, Literal, Sequence
from scm.pisa.block import DriverBlock,EngineBlock,FixedBlock,FreeBlock,InputBlock
from scm.pisa.key import BoolKey,FloatKey,FloatListKey,IntKey,IntListKey,MultipleChoiceKey,PathStringKey,StringKey,BoolType
[docs]class SimpleActiveLearning(DriverBlock):
r"""
:ivar RNGSeed: Initial seed for the (pseudo)random number generator. This should be omitted in most calculations to avoid introducing bias into the results. If this is unset, the generator will be seeded randomly from external sources of entropy. If you want to exactly reproduce an older calculation, set this to the numbers printed in its output.
:vartype RNGSeed: Iterable[int] | IntListKey
:ivar Task: The task to perform.
:vartype Task: Literal["MolecularDynamics"]
:ivar ActiveLearning: Settings for Active Learning
:vartype ActiveLearning: SimpleActiveLearning._ActiveLearning
:ivar Constraints: The Constraints block allows geometry optimizations and potential energy surface scans with constraints. The constraints do not have to be satisfied at the start of the calculation.
:vartype Constraints: SimpleActiveLearning._Constraints
:ivar Engine: The reference engine settings.
:vartype Engine: EngineBlock
:ivar LoadSystem: Block that controls reading the chemical system from a KF file instead of the [System] block.
:vartype LoadSystem: SimpleActiveLearning._LoadSystem
:ivar MachineLearning: Options for Task MachineLearning.
:vartype MachineLearning: SimpleActiveLearning._MachineLearning
:ivar MolecularDynamics: Settings for Molecular Dynamics
:vartype MolecularDynamics: SimpleActiveLearning._MolecularDynamics
:ivar ParallelLevels: Distribution of threads/processes between the parallelization levels.
:vartype ParallelLevels: SimpleActiveLearning._ParallelLevels
:ivar System: Specification of the chemical system. For some applications more than one system may be present in the input. In this case, all systems except one must have a non-empty string ID specified after the System keyword. The system without an ID is considered the main one.
:vartype System: SimpleActiveLearning._System
"""
[docs] class _ActiveLearning(FixedBlock):
r"""
Settings for Active Learning
:ivar JobPrefix: Jobs added to the job collection will receive this prefix. Example: set to ``water_`` to get jobs like ``water_step1_attempt1_frame001``. If the prefix does not end with an underscore ``_``, one will be automatically added.
:vartype JobPrefix: str | StringKey
:ivar MaxAttemptsPerStep: Maximum number of attempts per active learning step. If this number is exceeded, the active learning will continue to the next step even if the potential is not accurate enough according to the criteria. If the default value is exceeded, it probably means that the criteria are too strict.
:vartype MaxAttemptsPerStep: int | IntKey
:ivar MaxReferenceCalculationsPerAttempt: Maximum number of reference calculations per attempt. For successful attempts, only a single reference calculation is performed. For very short active learning steps, fewer calculations are done than the number specified.
:vartype MaxReferenceCalculationsPerAttempt: int | IntKey
:ivar RestartDirectory: Directory to restart from. It should be a ``jobname.results`` folder containing the file ``simple_active_learning.rkf``.
This will continue an interrupted Active Learning workflow and ignore all other input settings.
To reuse reference data from a previous workflow, instead use the ``ActiveLearning%InitialReferenceData`` block. To reuse a previously trained model, instead use the ``MachineLearning%LoadModel`` key.
:vartype RestartDirectory: str | Path | StringKey
:ivar AtEnd: What to do at the end of the active learning loop.
:vartype AtEnd: SimpleActiveLearning._ActiveLearning._AtEnd
:ivar FromScratchTraining: Custom options when training 'from scratch' (not restarting).
:vartype FromScratchTraining: SimpleActiveLearning._ActiveLearning._FromScratchTraining
:ivar InitialReferenceData: Options for loading reference data.
:vartype InitialReferenceData: SimpleActiveLearning._ActiveLearning._InitialReferenceData
:ivar ReasonableSimulationCriteria: Criteria for determining whether a simulation is reasonable. If any of the criteria are exceeded, this will be reported as 'ENERGY_UNCERTAINTY', 'TEMPERATURE', etc., with capital letters in the output. If a simulation is unreasonable, it will never lead to an increase of the Step, even if the number of attempts exceeds ``MaxAttemptsPerStep``.
:vartype ReasonableSimulationCriteria: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria
:ivar Save: The files/directories on disk to keep. If you set these options to ``All``, a lot of output will be created. This output is usually not necessary but can be used for debugging purposes, or to better understand what the workflow is doing.
:vartype Save: SimpleActiveLearning._ActiveLearning._Save
:ivar Steps: Settings to determine the number of MD steps per active learning step.
:vartype Steps: SimpleActiveLearning._ActiveLearning._Steps
:ivar SuccessCriteria: Criteria for determining whether an active learning step was successful. These criteria compare one or more reference calculations to the predictions. If any of the criteria are exceeded, the active learning loop will reparametrize the model and repeat the step.
:vartype SuccessCriteria: SimpleActiveLearning._ActiveLearning._SuccessCriteria
"""
[docs] class _AtEnd(FixedBlock):
r"""
What to do at the end of the active learning loop.
:ivar RerunSimulation: Rerun the MD simulation (folder: ``final_production_simulation``) using the last set of parameters. This guarantees that the entire trajectory is calculated using the same model / potential energy surface, and that the trajectory has a consistent sampling frequency. This means that it can be used with all MD postanalysis tools.
:vartype RerunSimulation: BoolType | BoolKey
:ivar RetrainModel: Train a final model (folder: ``final_training``) using all reference (training and validation) data, including any reference calculations that have not yet been trained to.
:vartype RetrainModel: BoolType | BoolKey
"""
def __post_init__(self):
self.RerunSimulation: BoolType | BoolKey = BoolKey(name='RerunSimulation', comment='Rerun the MD simulation (folder: ``final_production_simulation``) using the last set of parameters. This guarantees that the entire trajectory is calculated using the same model / potential energy surface, and that the trajectory has a consistent sampling frequency. This means that it can be used with all MD postanalysis tools.', default=True)
self.RetrainModel: BoolType | BoolKey = BoolKey(name='RetrainModel', comment='Train a final model (folder: ``final_training``) using all reference (training and validation) data, including any reference calculations that have not yet been trained to.', default=False)
[docs] class _FromScratchTraining(FixedBlock):
r"""
Custom options when training 'from scratch' (not restarting).
:ivar Enabled: With the given probability, start parameter training from the original starting point (from 'scratch') instead of restarting from the previous step/attempt.
:vartype Enabled: BoolType | BoolKey
:ivar EpochMultiplier: The maximum number of epochs is multiplier by this number when training from scratch. When not restarting from the previous parameters, it is usually a good idea to train for more epochs.
:vartype EpochMultiplier: float | FloatKey
:ivar Probability: With the given probability, start parameter training from the original starting point (from 'scratch') instead of restarting from the previous step/attempt.
:vartype Probability: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment="With the given probability, start parameter training from the original starting point (from 'scratch') instead of restarting from the previous step/attempt.", default=False)
self.EpochMultiplier: float | FloatKey = FloatKey(name='EpochMultiplier', comment='The maximum number of epochs is multiplier by this number when training from scratch. When not restarting from the previous parameters, it is usually a good idea to train for more epochs.', default=5.0)
self.Probability: float | FloatKey = FloatKey(name='Probability', comment="With the given probability, start parameter training from the original starting point (from 'scratch') instead of restarting from the previous step/attempt.", default=0.1)
[docs] class _InitialReferenceData(FixedBlock):
r"""
Options for loading reference data.
:ivar Generate: How to generate initial reference data from the initial structure. Can also be combined with the ``Load`` block.
The purpose of these options is to get some initial reference structures/data around the current structure that can be used for Step 1 of the active learning loop.
The ``ReferenceMD`` option will be automatically enabled if no data is otherwise loaded or generated.
:vartype Generate: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Generate
:ivar Load: How to load initial reference data from other sources. Can also be combined with the ``Generate`` block
:vartype Load: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Load
"""
[docs] class _Generate(FixedBlock):
r"""
How to generate initial reference data from the initial structure. Can also be combined with the ``Load`` block.
The purpose of these options is to get some initial reference structures/data around the current structure that can be used for Step 1 of the active learning loop.
The ``ReferenceMD`` option will be automatically enabled if no data is otherwise loaded or generated.
:ivar M3GNetShortMD: Structure sampler using M3GNet-UP-2022
:vartype M3GNetShortMD: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Generate._M3GNetShortMD
:ivar ReferenceMD: Run a very short MD simulation using the reference engine.
:vartype ReferenceMD: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Generate._ReferenceMD
"""
[docs] class _M3GNetShortMD(FixedBlock):
r"""
Structure sampler using M3GNet-UP-2022
:ivar Enabled: Run 300 steps with M3GNet-UP-2022 at T=600 K. If the system is 3D-periodic the density will be scanned around the initial value. Extract 5 frames and run reference calculations on those.
:vartype Enabled: BoolType | BoolKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Run 300 steps with M3GNet-UP-2022 at T=600 K. If the system is 3D-periodic the density will be scanned around the initial value. Extract 5 frames and run reference calculations on those.', gui_name='M3GNet-UP short MD: ', default=False)
[docs] class _ReferenceMD(FixedBlock):
r"""
Run a very short MD simulation using the reference engine.
:ivar Enabled: Run 3 steps with the reference engine and add those 3 frames to the training and validation sets. If no other reference data is loaded or generated, this option will automatically be enabled.
:vartype Enabled: BoolType | BoolKey
:ivar NSteps: Number of steps to run using the reference engine.
:vartype NSteps: int | IntKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Run 3 steps with the reference engine and add those 3 frames to the training and validation sets. If no other reference data is loaded or generated, this option will automatically be enabled.', gui_name='Reference MD: ', default=False)
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='Number of steps to run using the reference engine.', hidden=True, default=3)
def __post_init__(self):
self.M3GNetShortMD: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Generate._M3GNetShortMD = self._M3GNetShortMD(name='M3GNetShortMD', comment='Structure sampler using M3GNet-UP-2022')
self.ReferenceMD: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Generate._ReferenceMD = self._ReferenceMD(name='ReferenceMD', comment='Run a very short MD simulation using the reference engine.')
[docs] class _Load(FixedBlock):
r"""
How to load initial reference data from other sources. Can also be combined with the ``Generate`` block
:ivar Directory: Directory containing initial reference data. It can be
* a ParAMS input directory or a ``stepX_attemptY_reference_data`` directory containing the files job_collection.yaml, training_set.yaml, and validation_set.yaml.
* a ParAMS results directory.
If a directory is specified here it will be used instead of the data from a previously loaded model.
:vartype Directory: str | Path | StringKey
:ivar FromPreviousModel: If ``MachineLearning%LoadModel`` is set, reuse reference data from that ParAMS run.
If ``MachineLearning%LoadModel`` is not set, or if ``Directory`` is specified, then this input option is ignored.
:vartype FromPreviousModel: BoolType | BoolKey
"""
def __post_init__(self):
self.Directory: str | Path | StringKey = PathStringKey(name='Directory', comment='Directory containing initial reference data. It can be \n* a ParAMS input directory or a ``stepX_attemptY_reference_data`` directory containing the files job_collection.yaml, training_set.yaml, and validation_set.yaml.\n* a ParAMS results directory.\n\nIf a directory is specified here it will be used instead of the data from a previously loaded model.', default='', ispath=True, gui_type='directory')
self.FromPreviousModel: BoolType | BoolKey = BoolKey(name='FromPreviousModel', comment='If ``MachineLearning%LoadModel`` is set, reuse reference data from that ParAMS run.\n\nIf ``MachineLearning%LoadModel`` is not set, or if ``Directory`` is specified, then this input option is ignored.', default=True)
def __post_init__(self):
self.Generate: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Generate = self._Generate(name='Generate', comment='How to generate initial reference data from the initial structure. Can also be combined with the ``Load`` block.\n\nThe purpose of these options is to get some initial reference structures/data around the current structure that can be used for Step 1 of the active learning loop.\n\nThe ``ReferenceMD`` option will be automatically enabled if no data is otherwise loaded or generated.')
self.Load: SimpleActiveLearning._ActiveLearning._InitialReferenceData._Load = self._Load(name='Load', comment='How to load initial reference data from other sources. Can also be combined with the ``Generate`` block')
[docs] class _ReasonableSimulationCriteria(FixedBlock):
r"""
Criteria for determining whether a simulation is reasonable. If any of the criteria are exceeded, this will be reported as 'ENERGY_UNCERTAINTY', 'TEMPERATURE', etc., with capital letters in the output. If a simulation is unreasonable, it will never lead to an increase of the Step, even if the number of attempts exceeds ``MaxAttemptsPerStep``.
:ivar Distance: Stop the simulation if any interatomic distance is smaller than the specified value.
:vartype Distance: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._Distance
:ivar EnergyUncertainty: Stop the simulation if the uncertainty in the energy is too high. Currently only applicable when training committees.
:vartype EnergyUncertainty: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._EnergyUncertainty
:ivar GradientsUncertainty: Stop the simulation if the uncertainty in the gradients (forces) is too high. Currently only applicable when training committees.
:vartype GradientsUncertainty: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._GradientsUncertainty
:ivar Temperature: Discard all frames after the temperature has reached the specified value.
:vartype Temperature: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._Temperature
"""
[docs] class _Distance(FixedBlock):
r"""
Stop the simulation if any interatomic distance is smaller than the specified value.
:ivar Enabled: Stop the simulation if any interatomic distance is smaller than the specified value.
:vartype Enabled: BoolType | BoolKey
:ivar MinValue: Minimum allowed interatomic distance.
:vartype MinValue: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Stop the simulation if any interatomic distance is smaller than the specified value.', default=True)
self.MinValue: float | FloatKey = FloatKey(name='MinValue', comment='Minimum allowed interatomic distance.', gui_name='Minimum:', default=0.6, unit='angstrom')
[docs] class _EnergyUncertainty(FixedBlock):
r"""
Stop the simulation if the uncertainty in the energy is too high. Currently only applicable when training committees.
:ivar Enabled: Stop the simulation if the uncertainty in the energy is too high. Currently only applicable when training committees. If CommitteeSize = 1 then this keyword has no effect.
:vartype Enabled: BoolType | BoolKey
:ivar MaxValue: Threshold for allowed [energy uncertainty divided by ``Normalization``].
:vartype MaxValue: float | FloatKey
:ivar Normalization: Normalize (divide) the energy uncertainty by this number before comparing to the specified threshold. If not specified, it will become the number of atoms.
:vartype Normalization: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Stop the simulation if the uncertainty in the energy is too high. Currently only applicable when training committees. If CommitteeSize = 1 then this keyword has no effect.', default=False)
self.MaxValue: float | FloatKey = FloatKey(name='MaxValue', comment='Threshold for allowed [energy uncertainty divided by ``Normalization``].', gui_name='Maximum:', default=0.015, unit='eV')
self.Normalization: float | FloatKey = FloatKey(name='Normalization', comment='Normalize (divide) the energy uncertainty by this number before comparing to the specified threshold. If not specified, it will become the number of atoms.')
[docs] class _GradientsUncertainty(FixedBlock):
r"""
Stop the simulation if the uncertainty in the gradients (forces) is too high. Currently only applicable when training committees.
:ivar Enabled: Stop the simulation if the uncertainty in the gradients (forces) is too high. Currently only applicable when training committees. If CommitteeSize = 1 then this keyword has no effect.
:vartype Enabled: BoolType | BoolKey
:ivar MaxValue: Maximum allowed gradients (forces) uncertainty.
:vartype MaxValue: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Stop the simulation if the uncertainty in the gradients (forces) is too high. Currently only applicable when training committees. If CommitteeSize = 1 then this keyword has no effect.', default=False)
self.MaxValue: float | FloatKey = FloatKey(name='MaxValue', comment='Maximum allowed gradients (forces) uncertainty.', gui_name='Maximum:', default=0.5, unit='eV/angstrom')
[docs] class _Temperature(FixedBlock):
r"""
Discard all frames after the temperature has reached the specified value.
:ivar Enabled: Discard all frames after the temperature has reached the specified value.
:vartype Enabled: BoolType | BoolKey
:ivar MaxValue: Maximum allowed temperature
:vartype MaxValue: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Discard all frames after the temperature has reached the specified value.', default=True)
self.MaxValue: float | FloatKey = FloatKey(name='MaxValue', comment='Maximum allowed temperature', gui_name='Maximum:', default=5000.0, unit='K')
def __post_init__(self):
self.Distance: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._Distance = self._Distance(name='Distance', comment='Stop the simulation if any interatomic distance is smaller than the specified value.')
self.EnergyUncertainty: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._EnergyUncertainty = self._EnergyUncertainty(name='EnergyUncertainty', comment='Stop the simulation if the uncertainty in the energy is too high. Currently only applicable when training committees.')
self.GradientsUncertainty: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._GradientsUncertainty = self._GradientsUncertainty(name='GradientsUncertainty', comment='Stop the simulation if the uncertainty in the gradients (forces) is too high. Currently only applicable when training committees.')
self.Temperature: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria._Temperature = self._Temperature(name='Temperature', comment='Discard all frames after the temperature has reached the specified value.')
[docs] class _Save(FixedBlock):
r"""
The files/directories on disk to keep. If you set these options to ``All``, a lot of output will be created. This output is usually not necessary but can be used for debugging purposes, or to better understand what the workflow is doing.
:ivar ReferenceCalculations: The reference calculation directories (``initial_reference_calculations`` or ``stepX_attemptY_ref_calcZ``) including the original input and output.
These directories may take up a lot of disk space and are not kept by default. Enable this option if you need to investigate why reference calculations fail (incorrect input, SCF convergence problems, ...), or if you want to keep them for some other reason.
Note: The output used for parametrization (energy, forces) is always stored in the ReferenceData (training and validation sets).
:vartype ReferenceCalculations: Literal["None", "All"]
:ivar ReferenceData: The reference data directories (``stepX_attemptY_reference_data``) containing the training and validation sets in ParAMS .yaml format (and ASE .xyz format). These can be opened in the ParAMS GUI or used as input for ParAMS.
:vartype ReferenceData: Literal["Latest", "All"]
:ivar TrainingDirectories: The ParAMS training directories (``stepX_attemptY_training``).
:vartype TrainingDirectories: Literal["Latest", "All"]
:ivar Trajectories: The MD trajectory calculation directories (``stepX_attemptY_simulation``) using the trained ML potential. Note: the trajectories in these directories are the entire trajectories from the beginning of the simulation.
:vartype Trajectories: Literal["Latest", "All"]
"""
def __post_init__(self):
self.ReferenceCalculations: Literal["None", "All"] = MultipleChoiceKey(name='ReferenceCalculations', comment='The reference calculation directories (``initial_reference_calculations`` or ``stepX_attemptY_ref_calcZ``) including the original input and output. \nThese directories may take up a lot of disk space and are not kept by default. Enable this option if you need to investigate why reference calculations fail (incorrect input, SCF convergence problems, ...), or if you want to keep them for some other reason.\nNote: The output used for parametrization (energy, forces) is always stored in the ReferenceData (training and validation sets).', default='None', choices=['None', 'All'])
self.ReferenceData: Literal["Latest", "All"] = MultipleChoiceKey(name='ReferenceData', comment='The reference data directories (``stepX_attemptY_reference_data``) containing the training and validation sets in ParAMS .yaml format (and ASE .xyz format). These can be opened in the ParAMS GUI or used as input for ParAMS.', default='Latest', choices=['Latest', 'All'])
self.TrainingDirectories: Literal["Latest", "All"] = MultipleChoiceKey(name='TrainingDirectories', comment='The ParAMS training directories (``stepX_attemptY_training``).', default='Latest', choices=['Latest', 'All'])
self.Trajectories: Literal["Latest", "All"] = MultipleChoiceKey(name='Trajectories', comment='The MD trajectory calculation directories (``stepX_attemptY_simulation``) using the trained ML potential. Note: the trajectories in these directories are the entire trajectories from the beginning of the simulation.', default='Latest', choices=['Latest', 'All'])
[docs] class _Steps(FixedBlock):
r"""
Settings to determine the number of MD steps per active learning step.
:ivar List: List of MD frame indices, for example ``10 50 200 1000 10000 100000``. Only indices smaller than ``MolecularDynamics%NSteps`` are considered. Note: the final frame of the MD simulation is always considered to be the end of a step and does not need to be specified here.
:vartype List: Iterable[int] | IntListKey
:ivar Type: How to determine the number of MD steps per active learning step.
:vartype Type: Literal["Geometric", "List", "Linear"]
:ivar Geometric: Options for geometric.
:vartype Geometric: SimpleActiveLearning._ActiveLearning._Steps._Geometric
:ivar Linear: Options for linear.
:vartype Linear: SimpleActiveLearning._ActiveLearning._Steps._Linear
"""
[docs] class _Geometric(FixedBlock):
r"""
Options for geometric.
:ivar NumSteps: The number of active learning steps to perform. The MD simulation will be split into this number of active learning steps. The active learning steps will progressively contain more and more MD steps.
:vartype NumSteps: int | IntKey
:ivar Start: The length of the first step (in MD time steps).
:vartype Start: int | IntKey
"""
def __post_init__(self):
self.NumSteps: int | IntKey = IntKey(name='NumSteps', comment='The number of active learning steps to perform. The MD simulation will be split into this number of active learning steps. The active learning steps will progressively contain more and more MD steps. ', default=10)
self.Start: int | IntKey = IntKey(name='Start', comment='The length of the first step (in MD time steps).', default=10)
[docs] class _Linear(FixedBlock):
r"""
Options for linear.
:ivar Start: The length of the first step (in MD time steps).
:vartype Start: int | IntKey
:ivar StepSize: The length of every subsequent active learning step (in MD time steps).
:vartype StepSize: int | IntKey
"""
def __post_init__(self):
self.Start: int | IntKey = IntKey(name='Start', comment='The length of the first step (in MD time steps).', default=10)
self.StepSize: int | IntKey = IntKey(name='StepSize', comment='The length of every subsequent active learning step (in MD time steps).', default=1000)
def __post_init__(self):
self.List: Iterable[int] | IntListKey = IntListKey(name='List', comment='List of MD frame indices, for example ``10 50 200 1000 10000 100000``. Only indices smaller than ``MolecularDynamics%NSteps`` are considered. Note: the final frame of the MD simulation is always considered to be the end of a step and does not need to be specified here.')
self.Type: Literal["Geometric", "List", "Linear"] = MultipleChoiceKey(name='Type', comment='How to determine the number of MD steps per active learning step.', gui_name='Step sequence type: ', default='Geometric', choices=['Geometric', 'List', 'Linear'])
self.Geometric: SimpleActiveLearning._ActiveLearning._Steps._Geometric = self._Geometric(name='Geometric', comment='Options for geometric.')
self.Linear: SimpleActiveLearning._ActiveLearning._Steps._Linear = self._Linear(name='Linear', comment='Options for linear.')
[docs] class _SuccessCriteria(FixedBlock):
r"""
Criteria for determining whether an active learning step was successful. These criteria compare one or more reference calculations to the predictions. If any of the criteria are exceeded, the active learning loop will reparametrize the model and repeat the step.
:ivar Energy: Conditions to decide whether the calculated energy is are accurate enough with respect to reference energies.
:vartype Energy: SimpleActiveLearning._ActiveLearning._SuccessCriteria._Energy
:ivar Forces: Conditions to decide whether calculated forces are accurate enough with respect to reference forces.
:vartype Forces: SimpleActiveLearning._ActiveLearning._SuccessCriteria._Forces
"""
[docs] class _Energy(FixedBlock):
r"""
Conditions to decide whether the calculated energy is are accurate enough with respect to reference energies.
:ivar Enabled: Enable energy checking during the active learning.
:vartype Enabled: BoolType | BoolKey
:ivar Normalization: Normalize (divide) energies by this number before comparing to the specified thresholds. If not specified, it will become the number of atoms.
:vartype Normalization: float | FloatKey
:ivar Relative: ``|ΔΔE|/Normalization``: Maximum allowed difference between the calculated relative reference energies and relative predicted energies. The relative energies are calculated for the current structure with respect to the structure in the previous reference calculation.
ΔE_ref = E_ref(current) - E_ref(previous).
ΔE_pred = E_pred(current) - E_pred(previous).
``|ΔΔE| = |ΔE_pred - ΔE_ref|``
:vartype Relative: float | FloatKey
:ivar Total: ``|ΔE|/Normalization``: Maximum allowed total energy difference between the reference and predicted energy. This criterion is mostly useful when restarting a workflow from a previously trained model but on a new stoichiometry / system, for which the total energy prediction may be very far from the target. The default value is quite large so it is normally not exceeded.
``|∆E| = |E_pred - E_ref|``
:vartype Total: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable energy checking during the active learning.', default=True)
self.Normalization: float | FloatKey = FloatKey(name='Normalization', comment='Normalize (divide) energies by this number before comparing to the specified thresholds. If not specified, it will become the number of atoms.')
self.Relative: float | FloatKey = FloatKey(name='Relative', comment='``|ΔΔE|/Normalization``: Maximum allowed difference between the calculated relative reference energies and relative predicted energies. The relative energies are calculated for the current structure with respect to the structure in the previous reference calculation.\nΔE_ref = E_ref(current) - E_ref(previous).\nΔE_pred = E_pred(current) - E_pred(previous).\n``|ΔΔE| = |ΔE_pred - ΔE_ref|``', gui_name='Relative energy: ', default=0.005, unit='eV')
self.Total: float | FloatKey = FloatKey(name='Total', comment='``|ΔE|/Normalization``: Maximum allowed total energy difference between the reference and predicted energy. This criterion is mostly useful when restarting a workflow from a previously trained model but on a new stoichiometry / system, for which the total energy prediction may be very far from the target. The default value is quite large so it is normally not exceeded.\n``|∆E| = |E_pred - E_ref|``', gui_name='Total energy: ', default=0.2, unit='eV')
[docs] class _Forces(FixedBlock):
r"""
Conditions to decide whether calculated forces are accurate enough with respect to reference forces.
:ivar Enabled: Enable checking the forces during the active learning.
:vartype Enabled: BoolType | BoolKey
:ivar MaxDeviationForZeroForce: The maximum allowed deviation between a calculated force component and the corresponding reference force component. For larger reference forces, the allowed deviation will also be larger (see the documentation). If any deviation is larger than the (magnitude-dependent) threshold, the active learning step will be repeated after a reparametrization.
:vartype MaxDeviationForZeroForce: float | FloatKey
:ivar MaxMAE: Maximum allowed mean absolute error when comparing reference and predicted forces for a single frame at the end of an active learning step. If the obtained MAE is larger than this threshold, the active learning step will be repeated after a reparametrization.
:vartype MaxMAE: float | FloatKey
:ivar MinR2: Minimum allowed value for R^2 when comparing reference and predicted forces for a single frame at the end of an active learning step. If the obtained R^2 is smaller than this threshold, the active learning step will be repeated after a reparametrization. Note that if you have very small forces (for example by running the active learning at a very low temperature or starting from a geometry-optimized structure), then you should decrease the MinR2 since it is difficult for the ML model predict very small forces accurately.
:vartype MinR2: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable checking the forces during the active learning.', default=True)
self.MaxDeviationForZeroForce: float | FloatKey = FloatKey(name='MaxDeviationForZeroForce', comment='The maximum allowed deviation between a calculated force component and the corresponding reference force component. For larger reference forces, the allowed deviation will also be larger (see the documentation). If any deviation is larger than the (magnitude-dependent) threshold, the active learning step will be repeated after a reparametrization.', default=0.5, unit='eV/angstrom')
self.MaxMAE: float | FloatKey = FloatKey(name='MaxMAE', comment='Maximum allowed mean absolute error when comparing reference and predicted forces for a single frame at the end of an active learning step. If the obtained MAE is larger than this threshold, the active learning step will be repeated after a reparametrization.', gui_name='Max MAE: ', default=0.3, unit='eV/angstrom')
self.MinR2: float | FloatKey = FloatKey(name='MinR2', comment='Minimum allowed value for R^2 when comparing reference and predicted forces for a single frame at the end of an active learning step. If the obtained R^2 is smaller than this threshold, the active learning step will be repeated after a reparametrization. Note that if you have very small forces (for example by running the active learning at a very low temperature or starting from a geometry-optimized structure), then you should decrease the MinR2 since it is difficult for the ML model predict very small forces accurately.', gui_name='Min R²: ', default=0.2)
def __post_init__(self):
self.Energy: SimpleActiveLearning._ActiveLearning._SuccessCriteria._Energy = self._Energy(name='Energy', comment='Conditions to decide whether the calculated energy is are accurate enough with respect to reference energies.')
self.Forces: SimpleActiveLearning._ActiveLearning._SuccessCriteria._Forces = self._Forces(name='Forces', comment='Conditions to decide whether calculated forces are accurate enough with respect to reference forces.')
def __post_init__(self):
self.JobPrefix: str | StringKey = StringKey(name='JobPrefix', comment='Jobs added to the job collection will receive this prefix. Example: set to ``water_`` to get jobs like ``water_step1_attempt1_frame001``. If the prefix does not end with an underscore ``_``, one will be automatically added.', default='')
self.MaxAttemptsPerStep: int | IntKey = IntKey(name='MaxAttemptsPerStep', comment='Maximum number of attempts per active learning step. If this number is exceeded, the active learning will continue to the next step even if the potential is not accurate enough according to the criteria. If the default value is exceeded, it probably means that the criteria are too strict.', default=15)
self.MaxReferenceCalculationsPerAttempt: int | IntKey = IntKey(name='MaxReferenceCalculationsPerAttempt', comment='Maximum number of reference calculations per attempt. For successful attempts, only a single reference calculation is performed. For very short active learning steps, fewer calculations are done than the number specified.', gui_name='Max ref calcs per attempt: ', default=4)
self.RestartDirectory: str | Path | StringKey = PathStringKey(name='RestartDirectory', comment='Directory to restart from. It should be a ``jobname.results`` folder containing the file ``simple_active_learning.rkf``.\n\nThis will continue an interrupted Active Learning workflow and ignore all other input settings.\n\nTo reuse reference data from a previous workflow, instead use the ``ActiveLearning%InitialReferenceData`` block. To reuse a previously trained model, instead use the ``MachineLearning%LoadModel`` key.', hidden=True, gui_name='Restart directory: ', default='', ispath=True, gui_type='directory')
self.AtEnd: SimpleActiveLearning._ActiveLearning._AtEnd = self._AtEnd(name='AtEnd', comment='What to do at the end of the active learning loop.')
self.FromScratchTraining: SimpleActiveLearning._ActiveLearning._FromScratchTraining = self._FromScratchTraining(name='FromScratchTraining', comment="Custom options when training 'from scratch' (not restarting).")
self.InitialReferenceData: SimpleActiveLearning._ActiveLearning._InitialReferenceData = self._InitialReferenceData(name='InitialReferenceData', comment='Options for loading reference data.')
self.ReasonableSimulationCriteria: SimpleActiveLearning._ActiveLearning._ReasonableSimulationCriteria = self._ReasonableSimulationCriteria(name='ReasonableSimulationCriteria', comment="Criteria for determining whether a simulation is reasonable. If any of the criteria are exceeded, this will be reported as 'ENERGY_UNCERTAINTY', 'TEMPERATURE', etc., with capital letters in the output. If a simulation is unreasonable, it will never lead to an increase of the Step, even if the number of attempts exceeds ``MaxAttemptsPerStep``.")
self.Save: SimpleActiveLearning._ActiveLearning._Save = self._Save(name='Save', comment='The files/directories on disk to keep. If you set these options to ``All``, a lot of output will be created. This output is usually not necessary but can be used for debugging purposes, or to better understand what the workflow is doing.')
self.Steps: SimpleActiveLearning._ActiveLearning._Steps = self._Steps(name='Steps', comment='Settings to determine the number of MD steps per active learning step.')
self.SuccessCriteria: SimpleActiveLearning._ActiveLearning._SuccessCriteria = self._SuccessCriteria(name='SuccessCriteria', comment='Criteria for determining whether an active learning step was successful. These criteria compare one or more reference calculations to the predictions. If any of the criteria are exceeded, the active learning loop will reparametrize the model and repeat the step.')
[docs] class _Constraints(FixedBlock):
r"""
The Constraints block allows geometry optimizations and potential energy surface scans with constraints. The constraints do not have to be satisfied at the start of the calculation.
:ivar All: Fix multiple distances using one the following formats:
All [bondOrder] bonds at1 at2 [to distance]
All triangles at1 at2 at3
The first option constrains all bonds between atoms at1 at2 to a certain length, while the second - bonds at1-at2 and at2-at3 as well as the angle between them.
The [bondOrder] can be a number or a string such as single, double, triple or aromatic. If it's omitted then any bond between specified atoms will be constrained. Atom names are case-sensitive and they must be as they are in the Atoms block, or an asterisk '*' denoting any atom. If the distance is omitted then the bond length from the initial geometry is used.
Important: only the bonds present in the system at the start of the simulation can be constrained, which means that the bonds may need to be specified in the System block.
Valid examples:
All single bonds C C to 1.4
All bonds O H to 0.98
All bonds O H
All bonds H *
All triangles H * H
:vartype All: str | StringKey
:ivar Angle: Fix the angle between three atoms. Three atom indices followed by an angle in degrees.
:vartype Angle: str | StringKey
:ivar Atom: Fix the position of an atom. Just one integer referring to the index of the atom in the [System%Atoms] block.
:vartype Atom: int | IntKey
:ivar AtomList: Fix positions of the specified atoms. A list of integers referring to indices of atoms in the [System%Atoms] block.
:vartype AtomList: Iterable[int] | IntListKey
:ivar Block: Name of the region to constrain as a rigid block. Regions are specified in the System%Atoms block.
:vartype Block: str | StringKey
:ivar BlockAtoms: List of atom indices for a block constraint, where the internal degrees of freedom are frozen.
:vartype BlockAtoms: Iterable[int] | IntListKey
:ivar Coordinate: Fix a particular coordinate of an atom. Atom index followed by (x|y|z).
:vartype Coordinate: str | StringKey
:ivar DifDist: Four atom indices i j k l followed by the distance in Angstrom. This will constrain the difference R(ij)-R(kl) at the given value.
:vartype DifDist: str | StringKey
:ivar Dihedral: Fix the dihedral angle between four atoms. Four atom indices followed by an angle in degrees.
:vartype Dihedral: str | StringKey
:ivar Distance: Fix the distance between two atoms. Two atom indices followed by the distance in Angstrom.
:vartype Distance: str | StringKey
:ivar EqualStrain: Exclusively for lattice optimizations:
Accepts a set of strain components [xx, xy, xz, yy, yz, zz] which are to be kept equal.
The applied strain will be determined by the average of the corresponding stress tensors components.
In AMSinput just check the corresponding check buttons.
:vartype EqualStrain: str | StringKey
:ivar FixedRegion: Fix positions of all atoms in a region.
:vartype FixedRegion: str | StringKey
:ivar FreezeStrain: Exclusively for lattice optimizations:
Freezes any lattice deformation corresponding to a particular component of the strain tensor.
Accepts a set of strain components [xx, xy, xz, yy, yz, zz] to be frozen.
In AMSinput just check the corresponding check buttons.
:vartype FreezeStrain: str | StringKey
:ivar SumDist: Four atom indices i j k l followed by the distance in Angstrom. This will constrain the sum R(ij)+R(kl) at the given value.
:vartype SumDist: str | StringKey
"""
def __post_init__(self):
self.All: str | StringKey = StringKey(name='All', comment="Fix multiple distances using one the following formats: \nAll [bondOrder] bonds at1 at2 [to distance]\nAll triangles at1 at2 at3\n\nThe first option constrains all bonds between atoms at1 at2 to a certain length, while the second - bonds at1-at2 and at2-at3 as well as the angle between them.\n\nThe [bondOrder] can be a number or a string such as single, double, triple or aromatic. If it's omitted then any bond between specified atoms will be constrained. Atom names are case-sensitive and they must be as they are in the Atoms block, or an asterisk '*' denoting any atom. If the distance is omitted then the bond length from the initial geometry is used.\n\nImportant: only the bonds present in the system at the start of the simulation can be constrained, which means that the bonds may need to be specified in the System block.\n\nValid examples:\nAll single bonds C C to 1.4\nAll bonds O H to 0.98\nAll bonds O H\nAll bonds H *\nAll triangles H * H", unique=False)
self.Angle: str | StringKey = StringKey(name='Angle', comment='Fix the angle between three atoms. Three atom indices followed by an angle in degrees.', unique=False)
self.Atom: int | IntKey = IntKey(name='Atom', comment='Fix the position of an atom. Just one integer referring to the index of the atom in the [System%Atoms] block.', unique=False)
self.AtomList: Iterable[int] | IntListKey = IntListKey(name='AtomList', comment='Fix positions of the specified atoms. A list of integers referring to indices of atoms in the [System%Atoms] block.', unique=False)
self.Block: str | StringKey = StringKey(name='Block', comment='Name of the region to constrain as a rigid block. Regions are specified in the System%Atoms block.', unique=False, gui_type='region')
self.BlockAtoms: Iterable[int] | IntListKey = IntListKey(name='BlockAtoms', comment='List of atom indices for a block constraint, where the internal degrees of freedom are frozen.', unique=False)
self.Coordinate: str | StringKey = StringKey(name='Coordinate', comment='Fix a particular coordinate of an atom. Atom index followed by (x|y|z).', unique=False)
self.DifDist: str | StringKey = StringKey(name='DifDist', comment='Four atom indices i j k l followed by the distance in Angstrom. This will constrain the difference R(ij)-R(kl) at the given value.', unique=False)
self.Dihedral: str | StringKey = StringKey(name='Dihedral', comment='Fix the dihedral angle between four atoms. Four atom indices followed by an angle in degrees.', unique=False)
self.Distance: str | StringKey = StringKey(name='Distance', comment='Fix the distance between two atoms. Two atom indices followed by the distance in Angstrom.', unique=False)
self.EqualStrain: str | StringKey = StringKey(name='EqualStrain', comment='Exclusively for lattice optimizations:\n\nAccepts a set of strain components [xx, xy, xz, yy, yz, zz] which are to be kept equal.\n\nThe applied strain will be determined by the average of the corresponding stress tensors components.\n\nIn AMSinput just check the corresponding check buttons.')
self.FixedRegion: str | StringKey = StringKey(name='FixedRegion', comment='Fix positions of all atoms in a region.', unique=False, gui_type='region')
self.FreezeStrain: str | StringKey = StringKey(name='FreezeStrain', comment='Exclusively for lattice optimizations:\n\nFreezes any lattice deformation corresponding to a particular component of the strain tensor.\n\nAccepts a set of strain components [xx, xy, xz, yy, yz, zz] to be frozen.\n\nIn AMSinput just check the corresponding check buttons.')
self.SumDist: str | StringKey = StringKey(name='SumDist', comment='Four atom indices i j k l followed by the distance in Angstrom. This will constrain the sum R(ij)+R(kl) at the given value.', unique=False)
[docs] class _Engine(EngineBlock):
r"""
The reference engine settings.
"""
def __post_init__(self):
pass
[docs] class _LoadSystem(FixedBlock):
r"""
Block that controls reading the chemical system from a KF file instead of the [System] block.
:ivar File: The path of the KF file from which to load the system. It may also be the results directory containing it.
:vartype File: str | Path | StringKey
:ivar Section: The section on the KF file from which to load the system.
:vartype Section: str | StringKey
"""
def __post_init__(self):
self.File: str | Path | StringKey = PathStringKey(name='File', comment='The path of the KF file from which to load the system. It may also be the results directory containing it.', ispath=True)
self.Section: str | StringKey = StringKey(name='Section', comment='The section on the KF file from which to load the system.', default='Molecule')
[docs] class _MachineLearning(FixedBlock):
r"""
Options for Task MachineLearning.
:ivar Backend: The backend to use. You must separately install the backend before running a training job.
:vartype Backend: Literal["Custom", "M3GNet", "NequIP", "Test"]
:ivar CommitteeSize: The number of independently trained ML potentials.
:vartype CommitteeSize: int | IntKey
:ivar LoadModel: Load a previously fitted model from a ParAMS results directory. A ParAMS results directory should contain two subdirectories ``optimization`` and ``settings_and_initial_data``. This option ignores all settings inside model blocks.
:vartype LoadModel: str | Path | StringKey
:ivar MaxEpochs: Set the maximum number of epochs a backend should perform.
:vartype MaxEpochs: int | IntKey
:ivar RunAMSAtEnd: Whether to run the (committee) ML potential through AMS at the end. This will create the energy/forces scatter plots for the final trained model.
:vartype RunAMSAtEnd: BoolType | BoolKey
:ivar Custom: Set up a custom fitting program within ParAMS
:vartype Custom: SimpleActiveLearning._MachineLearning._Custom
:ivar LossCoeffs: Modify the coefficients for the machine learning loss function. For backends that support weights, this is on top of the supplied dataset weights and sigmas.
:vartype LossCoeffs: SimpleActiveLearning._MachineLearning._LossCoeffs
:ivar M3GNet: Options for M3GNet fitting.
:vartype M3GNet: SimpleActiveLearning._MachineLearning._M3GNet
:ivar NequIP: Options for NequIP fitting.
:vartype NequIP: SimpleActiveLearning._MachineLearning._NequIP
:ivar Target: Target values for stopping training. If both the training and validation metrics are smaller than the specified values, the training will stop early. Only supported by the M3GNet backend.
:vartype Target: SimpleActiveLearning._MachineLearning._Target
"""
[docs] class _Custom(FixedBlock):
r"""
Set up a custom fitting program within ParAMS
:ivar File: Python file containing a function called 'get_fit_job' that returns a subclass of 'FitJob'
:vartype File: str | Path | StringKey
:ivar Arguments: Pass on keyword arguments to the 'get_fit_job' function.
:vartype Arguments: str | Sequence[str] | FreeBlock
"""
[docs] class _Arguments(FreeBlock):
r"""
Pass on keyword arguments to the 'get_fit_job' function.
"""
def __post_init__(self):
pass
def __post_init__(self):
self.File: str | Path | StringKey = PathStringKey(name='File', comment="Python file containing a function called 'get_fit_job' that returns a subclass of 'FitJob'", ispath=True)
self.Arguments: str | Sequence[str] | FreeBlock = self._Arguments(name='Arguments', comment="Pass on keyword arguments to the 'get_fit_job' function.")
[docs] class _LossCoeffs(FixedBlock):
r"""
Modify the coefficients for the machine learning loss function. For backends that support weights, this is on top of the supplied dataset weights and sigmas.
:ivar AverageForcePerAtom: For each force data entry, divide the loss contribution by the number of concomittent atoms. This is the same as the behavior for ParAMS Optimization, but it is turned off by default in Task MachineLearning. For machine learning, setting this to 'No' can be better since larger molecules will contribute more to the loss. For backends that support weights, this is on top of the supplied dataset weights and sigmas.
:vartype AverageForcePerAtom: BoolType | BoolKey
:ivar Energy: Coefficient for the contribution of loss due to the energy. For backends that support weights, this is on top of the supplied dataset weights and sigmas.
:vartype Energy: float | FloatKey
:ivar Forces: Coefficient for the contribution of loss due to the forces. For backends that support weights, this is on top of the supplied dataset weights and sigmas.
:vartype Forces: float | FloatKey
"""
def __post_init__(self):
self.AverageForcePerAtom: BoolType | BoolKey = BoolKey(name='AverageForcePerAtom', comment="For each force data entry, divide the loss contribution by the number of concomittent atoms. This is the same as the behavior for ParAMS Optimization, but it is turned off by default in Task MachineLearning. For machine learning, setting this to 'No' can be better since larger molecules will contribute more to the loss. For backends that support weights, this is on top of the supplied dataset weights and sigmas.", default=False)
self.Energy: float | FloatKey = FloatKey(name='Energy', comment='Coefficient for the contribution of loss due to the energy. For backends that support weights, this is on top of the supplied dataset weights and sigmas.', gui_name='Energy coefficient:', default=10.0)
self.Forces: float | FloatKey = FloatKey(name='Forces', comment='Coefficient for the contribution of loss due to the forces. For backends that support weights, this is on top of the supplied dataset weights and sigmas.', gui_name='Forces coefficient:', default=1.0)
[docs] class _M3GNet(FixedBlock):
r"""
Options for M3GNet fitting.
:ivar LearningRate: Learning rate for the M3GNet weight optimization.
:vartype LearningRate: float | FloatKey
:ivar Model: How to specify the model for the M3GNet backend. Either a Custom model can be made from scratch or an existing model directory can be loaded to obtain the model settings.
:vartype Model: Literal["UniversalPotential", "Custom", "ModelDir"]
:ivar ModelDir: Path to the directory defining the model. This folder should contain the files: 'checkpoint', 'm3gnet.data-00000-of-00001', ' m3gnet.index' and 'm3gnet.json'
:vartype ModelDir: str | Path | StringKey
:ivar Custom: Specify a custom M3GNet model.
:vartype Custom: SimpleActiveLearning._MachineLearning._M3GNet._Custom
:ivar UniversalPotential: Settings for (transfer) learning with the M3GNet Universal Potential.
:vartype UniversalPotential: SimpleActiveLearning._MachineLearning._M3GNet._UniversalPotential
"""
[docs] class _Custom(FixedBlock):
r"""
Specify a custom M3GNet model.
:ivar Cutoff: Cutoff radius of the graph
:vartype Cutoff: float | FloatKey
:ivar MaxL: Include spherical components up to order MaxL. Higher gives a better angular resolution, but increases computational cost substantially.
:vartype MaxL: int | IntKey
:ivar MaxN: Include radial components up to the MaxN'th root of the spherical Bessel function. Higher gives a better radial resolution, but increases computational cost substantially.
:vartype MaxN: int | IntKey
:ivar NumBlocks: Number of convolution blocks.
:vartype NumBlocks: int | IntKey
:ivar NumNeurons: Number of neurons in each layer.
:vartype NumNeurons: int | IntKey
:ivar ThreebodyCutoff: Cutoff radius of the three-body interaction.
:vartype ThreebodyCutoff: float | FloatKey
"""
def __post_init__(self):
self.Cutoff: float | FloatKey = FloatKey(name='Cutoff', comment='Cutoff radius of the graph', default=5.0, unit='angstrom')
self.MaxL: int | IntKey = IntKey(name='MaxL', comment='Include spherical components up to order MaxL. Higher gives a better angular resolution, but increases computational cost substantially.', default=3)
self.MaxN: int | IntKey = IntKey(name='MaxN', comment="Include radial components up to the MaxN'th root of the spherical Bessel function. Higher gives a better radial resolution, but increases computational cost substantially.", default=3)
self.NumBlocks: int | IntKey = IntKey(name='NumBlocks', comment='Number of convolution blocks.', gui_name='Number of convolution blocks: ', default=3)
self.NumNeurons: int | IntKey = IntKey(name='NumNeurons', comment='Number of neurons in each layer.', gui_name='Number of neurons per layer:', default=64)
self.ThreebodyCutoff: float | FloatKey = FloatKey(name='ThreebodyCutoff', comment='Cutoff radius of the three-body interaction.', default=4.0, unit='angstrom')
[docs] class _UniversalPotential(FixedBlock):
r"""
Settings for (transfer) learning with the M3GNet Universal Potential.
:ivar Featurizer: Train the Featurizer layer of the M3GNet universal potential.
:vartype Featurizer: BoolType | BoolKey
:ivar Final: Train the Final layer of the M3GNet universal potential.
:vartype Final: BoolType | BoolKey
:ivar GraphLayer1: Train the first Graph layer of the M3GNet universal potential.
:vartype GraphLayer1: BoolType | BoolKey
:ivar GraphLayer2: Train the second Graph layer of the M3GNet universal potential.
:vartype GraphLayer2: BoolType | BoolKey
:ivar GraphLayer3: Train the third Graph layer of the M3GNet universal potential.
:vartype GraphLayer3: BoolType | BoolKey
:ivar ThreeDInteractions1: Train the first ThreeDInteractions (three-body terms) layer of the M3GNet universal potential.
:vartype ThreeDInteractions1: BoolType | BoolKey
:ivar ThreeDInteractions2: Train the second ThreeDInteractions (three-body terms) layer of the M3GNet universal potential.
:vartype ThreeDInteractions2: BoolType | BoolKey
:ivar ThreeDInteractions3: Train the third ThreeDInteractions (three-body terms) layer of the M3GNet universal potential.
:vartype ThreeDInteractions3: BoolType | BoolKey
:ivar Version: Which version of the M3GNet Universal Potential to use.
:vartype Version: Literal["2022"]
"""
def __post_init__(self):
self.Featurizer: BoolType | BoolKey = BoolKey(name='Featurizer', comment='Train the Featurizer layer of the M3GNet universal potential.', gui_name='Train featurizer:', default=False)
self.Final: BoolType | BoolKey = BoolKey(name='Final', comment='Train the Final layer of the M3GNet universal potential.', gui_name='Train final layer:', default=True)
self.GraphLayer1: BoolType | BoolKey = BoolKey(name='GraphLayer1', comment='Train the first Graph layer of the M3GNet universal potential.', gui_name='Train layer 1 - graph:', default=False)
self.GraphLayer2: BoolType | BoolKey = BoolKey(name='GraphLayer2', comment='Train the second Graph layer of the M3GNet universal potential.', gui_name='Train layer 2 - graph:', default=False)
self.GraphLayer3: BoolType | BoolKey = BoolKey(name='GraphLayer3', comment='Train the third Graph layer of the M3GNet universal potential.', gui_name='Train layer 3 - graph:', default=True)
self.ThreeDInteractions1: BoolType | BoolKey = BoolKey(name='ThreeDInteractions1', comment='Train the first ThreeDInteractions (three-body terms) layer of the M3GNet universal potential.', gui_name='Train layer 1 - 3D interactions:', default=False)
self.ThreeDInteractions2: BoolType | BoolKey = BoolKey(name='ThreeDInteractions2', comment='Train the second ThreeDInteractions (three-body terms) layer of the M3GNet universal potential.', gui_name='Train layer 2 - 3D interactions:', default=False)
self.ThreeDInteractions3: BoolType | BoolKey = BoolKey(name='ThreeDInteractions3', comment='Train the third ThreeDInteractions (three-body terms) layer of the M3GNet universal potential.', gui_name='Train layer 3 - 3D interactions:', default=True)
self.Version: Literal["2022"] = MultipleChoiceKey(name='Version', comment='Which version of the M3GNet Universal Potential to use.', hidden=True, default='2022', choices=['2022'])
def __post_init__(self):
self.LearningRate: float | FloatKey = FloatKey(name='LearningRate', comment='Learning rate for the M3GNet weight optimization.', default=0.001)
self.Model: Literal["UniversalPotential", "Custom", "ModelDir"] = MultipleChoiceKey(name='Model', comment='How to specify the model for the M3GNet backend. Either a Custom model can be made from scratch or an existing model directory can be loaded to obtain the model settings.', default='UniversalPotential', choices=['UniversalPotential', 'Custom', 'ModelDir'])
self.ModelDir: str | Path | StringKey = PathStringKey(name='ModelDir', comment="Path to the directory defining the model. This folder should contain the files: 'checkpoint', 'm3gnet.data-00000-of-00001', ' m3gnet.index' and 'm3gnet.json'", ispath=True, gui_type='file')
self.Custom: SimpleActiveLearning._MachineLearning._M3GNet._Custom = self._Custom(name='Custom', comment='Specify a custom M3GNet model.')
self.UniversalPotential: SimpleActiveLearning._MachineLearning._M3GNet._UniversalPotential = self._UniversalPotential(name='UniversalPotential', comment='Settings for (transfer) learning with the M3GNet Universal Potential.')
[docs] class _NequIP(FixedBlock):
r"""
Options for NequIP fitting.
:ivar LearningRate: Learning rate for the NequIP weight optimization
:vartype LearningRate: float | FloatKey
:ivar Model: How to specify the model for the NequIP backend. Either a Custom model can be made from scratch or an existing 'model.pth' file can be loaded to obtain the model settings.
:vartype Model: Literal["Custom", "ModelFile"]
:ivar ModelFile: Path to the model.pth file defining the model.
:vartype ModelFile: str | Path | StringKey
:ivar UseRescalingFromLoadedModel: When loading a model with LoadModel or NequiP%ModelFile do not recalculate the dataset rescaling but use the value from the loaded model.
:vartype UseRescalingFromLoadedModel: BoolType | BoolKey
:ivar Custom: Specify a custom NequIP model.
:vartype Custom: SimpleActiveLearning._MachineLearning._NequIP._Custom
"""
[docs] class _Custom(FixedBlock):
r"""
Specify a custom NequIP model.
:ivar LMax: Maximum L value. 1 is probably high enough.
:vartype LMax: int | IntKey
:ivar MetricsKey: Which metric to use to generate the 'best' model.
:vartype MetricsKey: Literal["training_loss", "validation_loss"]
:ivar NumLayers: Number of interaction layers in the NequIP neural network.
:vartype NumLayers: int | IntKey
:ivar RMax: Distance cutoff for interactions.
:vartype RMax: float | FloatKey
"""
def __post_init__(self):
self.LMax: int | IntKey = IntKey(name='LMax', comment='Maximum L value. 1 is probably high enough.', default=1)
self.MetricsKey: Literal["training_loss", "validation_loss"] = MultipleChoiceKey(name='MetricsKey', comment="Which metric to use to generate the 'best' model.", default='validation_loss', choices=['training_loss', 'validation_loss'])
self.NumLayers: int | IntKey = IntKey(name='NumLayers', comment='Number of interaction layers in the NequIP neural network.', default=4)
self.RMax: float | FloatKey = FloatKey(name='RMax', comment='Distance cutoff for interactions.', gui_name='Distance cutoff:', default=3.5, unit='angstrom')
def __post_init__(self):
self.LearningRate: float | FloatKey = FloatKey(name='LearningRate', comment='Learning rate for the NequIP weight optimization', default=0.005)
self.Model: Literal["Custom", "ModelFile"] = MultipleChoiceKey(name='Model', comment="How to specify the model for the NequIP backend. Either a Custom model can be made from scratch or an existing 'model.pth' file can be loaded to obtain the model settings.", default='Custom', choices=['Custom', 'ModelFile'])
self.ModelFile: str | Path | StringKey = PathStringKey(name='ModelFile', comment='Path to the model.pth file defining the model.', ispath=True, gui_type='file')
self.UseRescalingFromLoadedModel: BoolType | BoolKey = BoolKey(name='UseRescalingFromLoadedModel', comment='When loading a model with LoadModel or NequiP%ModelFile do not recalculate the dataset rescaling but use the value from the loaded model.', default=True)
self.Custom: SimpleActiveLearning._MachineLearning._NequIP._Custom = self._Custom(name='Custom', comment='Specify a custom NequIP model.')
[docs] class _Target(FixedBlock):
r"""
Target values for stopping training. If both the training and validation metrics are smaller than the specified values, the training will stop early. Only supported by the M3GNet backend.
:ivar Forces: Forces (as reported by the backend)
:vartype Forces: SimpleActiveLearning._MachineLearning._Target._Forces
"""
[docs] class _Forces(FixedBlock):
r"""
Forces (as reported by the backend)
:ivar Enabled: Whether to use target values for forces.
:vartype Enabled: BoolType | BoolKey
:ivar MAE: MAE for forces (as reported by the backend).
:vartype MAE: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Whether to use target values for forces.', default=True)
self.MAE: float | FloatKey = FloatKey(name='MAE', comment='MAE for forces (as reported by the backend).', default=0.05, unit='eV/angstrom')
def __post_init__(self):
self.Forces: SimpleActiveLearning._MachineLearning._Target._Forces = self._Forces(name='Forces', comment='Forces (as reported by the backend)')
def __post_init__(self):
self.Backend: Literal["Custom", "M3GNet", "NequIP", "Test"] = MultipleChoiceKey(name='Backend', comment='The backend to use. You must separately install the backend before running a training job.', default='M3GNet', choices=['Custom', 'M3GNet', 'NequIP', 'Test'], hiddenchoices=['Custom', 'Test'], gui_type='literal choices')
self.CommitteeSize: int | IntKey = IntKey(name='CommitteeSize', comment='The number of independently trained ML potentials.', default=1)
self.LoadModel: str | Path | StringKey = PathStringKey(name='LoadModel', comment='Load a previously fitted model from a ParAMS results directory. A ParAMS results directory should contain two subdirectories ``optimization`` and ``settings_and_initial_data``. This option ignores all settings inside model blocks.', ispath=True, gui_type='directory')
self.MaxEpochs: int | IntKey = IntKey(name='MaxEpochs', comment='Set the maximum number of epochs a backend should perform.', default=1000)
self.RunAMSAtEnd: BoolType | BoolKey = BoolKey(name='RunAMSAtEnd', comment='Whether to run the (committee) ML potential through AMS at the end. This will create the energy/forces scatter plots for the final trained model.', gui_name='Run AMS at end:', default=True)
self.Custom: SimpleActiveLearning._MachineLearning._Custom = self._Custom(name='Custom', comment='Set up a custom fitting program within ParAMS', hidden=True)
self.LossCoeffs: SimpleActiveLearning._MachineLearning._LossCoeffs = self._LossCoeffs(name='LossCoeffs', comment='Modify the coefficients for the machine learning loss function. For backends that support weights, this is on top of the supplied dataset weights and sigmas.')
self.M3GNet: SimpleActiveLearning._MachineLearning._M3GNet = self._M3GNet(name='M3GNet', comment='Options for M3GNet fitting.')
self.NequIP: SimpleActiveLearning._MachineLearning._NequIP = self._NequIP(name='NequIP', comment='Options for NequIP fitting.')
self.Target: SimpleActiveLearning._MachineLearning._Target = self._Target(name='Target', comment='Target values for stopping training. If both the training and validation metrics are smaller than the specified values, the training will stop early. Only supported by the M3GNet backend.')
[docs] class _MolecularDynamics(FixedBlock):
r"""
Settings for Molecular Dynamics
:ivar CalcPressure: Calculate the pressure in periodic systems.
This may be computationally expensive for some engines that require numerical differentiation.
Some other engines can calculate the pressure for negligible additional cost and will always do so, even if this option is disabled.
:vartype CalcPressure: BoolType | BoolKey
:ivar CopyRestartTrajectory: If the keyword Restart is present, the content of the restartfile is copied to the ams.rkf file.
:vartype CopyRestartTrajectory: BoolType | BoolKey
:ivar NSteps: The number of steps to be taken in the MD simulation.
:vartype NSteps: int | IntKey
:ivar Restart: The path to the ams.rkf file from which to restart the simulation.
:vartype Restart: str | Path | StringKey
:ivar TimeStep: The time difference per step.
:vartype TimeStep: float | FloatKey
:ivar AddMolecules: This block controls adding molecules to the system (a.k.a. the Molecule Gun). Multiple occurrences of this block are possible.
By default, molecules are added at random positions in the simulation box with velocity matching the current system temperature. The initial position can be modified using one of the following keywords: Coords, CoordsBox, FractionalCoords, FractionalCoordsBox. The Coords and FractionalCoords keys can optionally be accompanied by CoordsSigma or FractionalCoordsSigma, respectively.
:vartype AddMolecules: SimpleActiveLearning._MolecularDynamics._AddMolecules
:ivar ApplyForce: The ApplyForce keyword can be used to apply an arbitrary constant force to a certain (subgroups of) atoms in the system
:vartype ApplyForce: SimpleActiveLearning._MolecularDynamics._ApplyForce
:ivar ApplyVelocity: The ApplyVelocity keyword can be used to move an arbitrary group of atoms in the system with a constant net velocity
:vartype ApplyVelocity: SimpleActiveLearning._MolecularDynamics._ApplyVelocity
:ivar Barostat: This block allows to specify the use of a barostat during the simulation.
:vartype Barostat: SimpleActiveLearning._MolecularDynamics._Barostat
:ivar BinLog: This block controls writing the BinLog section in ams.rkf, which contains the selected MD state scalars and tensors from every MD step. No per-atom data is written. If you need the per-atom data then you can set the sampling frequency to 1 and get the required data from the MDHistory section. The tensors are written per component, that is, the pressure tensor is written as six variables: PressureTensor_xx, PressureTensor_yy, etc.. To reduce the file size, all data is written in blocks.
:vartype BinLog: SimpleActiveLearning._MolecularDynamics._BinLog
:ivar BondBoost: Forced reaction (bond boost) definitions. Multiple BondBoost blocks may be specified, which will be treated independently.
:vartype BondBoost: SimpleActiveLearning._MolecularDynamics._BondBoost
:ivar CRESTMTD: Input for CREST metadynamics simulation.
:vartype CRESTMTD: SimpleActiveLearning._MolecularDynamics._CRESTMTD
:ivar CVHD: Input for the Collective Variable-driven HyperDynamics (CVHD).
:vartype CVHD: SimpleActiveLearning._MolecularDynamics._CVHD
:ivar CheckTemperature: Check at every time step if the temperature has exceeded a threshold. If it has, it is assumed the system exploded, and the simulation will stop.
:vartype CheckTemperature: SimpleActiveLearning._MolecularDynamics._CheckTemperature
:ivar Checkpoint: Sets the frequency for storing the entire MD state necessary for restarting the calculation.
:vartype Checkpoint: SimpleActiveLearning._MolecularDynamics._Checkpoint
:ivar CosineShear: Apply an external acceleration to all atoms of a fluid using a periodic (cosine) function along a selected coordinate axis. This induces a periodic shear flow profile which can be used to determine the viscosity.
:vartype CosineShear: SimpleActiveLearning._MolecularDynamics._CosineShear
:ivar Deformation: Deform the periodic lattice of the system during the simulation.
:vartype Deformation: SimpleActiveLearning._MolecularDynamics._Deformation
:ivar Gravity: Apply a constant acceleration in -z.
:vartype Gravity: SimpleActiveLearning._MolecularDynamics._Gravity
:ivar HeatExchange: Input for the heat-exchange non-equilibrium MD (T-NEMD).
:vartype HeatExchange: SimpleActiveLearning._MolecularDynamics._HeatExchange
:ivar InitialVelocities: Sets the frequency for printing to stdout and storing the molecular configuration on the .rkf file.
:vartype InitialVelocities: SimpleActiveLearning._MolecularDynamics._InitialVelocities
:ivar MovingRestraints: Define a set of moving restraints.
:vartype MovingRestraints: SimpleActiveLearning._MolecularDynamics._MovingRestraints
:ivar PRD: This block is used for Parallel Replica Dynamics simulations.
:vartype PRD: SimpleActiveLearning._MolecularDynamics._PRD
:ivar Plumed: Input for PLUMED (version 2.5.0). The parallel option is still experimental.
:vartype Plumed: SimpleActiveLearning._MolecularDynamics._Plumed
:ivar Preserve: Periodically remove numerical drift accumulated during the simulation to preserve different whole-system parameters.
:vartype Preserve: SimpleActiveLearning._MolecularDynamics._Preserve
:ivar Print: This block controls the printing of additional information to stdout.
:vartype Print: SimpleActiveLearning._MolecularDynamics._Print
:ivar ReactionBoost: Define a series of transitions between different states of the system.
Each transition is defined by a TargetSystem and by a set of restraints that force the transition.
:vartype ReactionBoost: SimpleActiveLearning._MolecularDynamics._ReactionBoost
:ivar Reactor: Define one phase of the nanoreactor. A reactor is a region of space surrounded by an elastic wall. Atoms inside the region are not affected. Atoms outside it will be pushed back with force depending on the [ForceConstant] and the [MassScaled] flag.
:vartype Reactor: SimpleActiveLearning._MolecularDynamics._Reactor
:ivar ReflectiveWall: Apply a reflective wall in space
:vartype ReflectiveWall: SimpleActiveLearning._MolecularDynamics._ReflectiveWall
:ivar Remap: Control periodic remapping (backtranslation) of atoms into the PBC box.
:vartype Remap: SimpleActiveLearning._MolecularDynamics._Remap
:ivar RemoveMolecules: This block controls removal of molecules from the system. Multiple occurrences of this block are possible.
:vartype RemoveMolecules: SimpleActiveLearning._MolecularDynamics._RemoveMolecules
:ivar ReplicaExchange: This block is used for (temperature) Replica Exchange MD (Parallel Tempering) simulations.
:vartype ReplicaExchange: SimpleActiveLearning._MolecularDynamics._ReplicaExchange
:ivar Shake: Parameters of the Shake/Rattle algorithm.
:vartype Shake: SimpleActiveLearning._MolecularDynamics._Shake
:ivar Thermostat: This block allows to specify the use of a thermostat during the simulation. Depending on the selected thermostat type, different additional options may be needed to characterize the specific thermostat's behavior.
:vartype Thermostat: SimpleActiveLearning._MolecularDynamics._Thermostat
:ivar Trajectory: Sets the frequency for printing to stdout and storing the molecular configuration on the .rkf file.
:vartype Trajectory: SimpleActiveLearning._MolecularDynamics._Trajectory
:ivar fbMC: This block sets up force bias Monte Carlo interleaved with the molecular dynamics simulation.
:vartype fbMC: SimpleActiveLearning._MolecularDynamics._fbMC
"""
[docs] class _AddMolecules(FixedBlock):
r"""
This block controls adding molecules to the system (a.k.a. the Molecule Gun). Multiple occurrences of this block are possible.
By default, molecules are added at random positions in the simulation box with velocity matching the current system temperature. The initial position can be modified using one of the following keywords: Coords, CoordsBox, FractionalCoords, FractionalCoordsBox. The Coords and FractionalCoords keys can optionally be accompanied by CoordsSigma or FractionalCoordsSigma, respectively.
:ivar AtomTemperature: Add random velocity corresponding to the specified temperature to individual atoms of the molecule. This only affects rotational and internal degrees of freedom, not the net translational velocity of the inserted molecule as set by the other options.
:vartype AtomTemperature: float | FloatKey
:ivar ContactDistance: Translate the bullet along the velocity vector until it comes within ContactDistance of any other atom.
:vartype ContactDistance: float | FloatKey
:ivar Coords: Place molecules at or around the specified Cartesian coordinates.
This setting takes precedence over other ways to specify initial coordinates of the molecule: [CoordsBox], [FractionalCoords], and [FractionalCoordsBox].
:vartype Coords: Iterable[float] | FloatListKey
:ivar CoordsBox: Place molecules at random locations inside the specified box in Cartesian coordinates.
Coordinates of the box corners are specified as: Xmin, Xmax, Ymin, Ymax, Zmin, Zmax.
This setting is ignored if Coords is used.
In AMSinput, if this field is not empty it will be used instead of the default Coords.
:vartype CoordsBox: Iterable[float] | FloatListKey
:ivar CoordsSigma: Sigma values (one per Cartesian axis) for a Gauss distribution of the initial coordinates. Can only be used together with Coords.
:vartype CoordsSigma: Iterable[float] | FloatListKey
:ivar DeviationAngle: Randomly tilt the shooting direction up to this angle away from the VelocityDirection vector.
:vartype DeviationAngle: float | FloatKey
:ivar Energy: Initial kinetic energy of the molecule in the shooting direction.
:vartype Energy: float | FloatKey
:ivar EnergySigma: Sigma value for the Gauss distribution of the initial kinetic energy around the specified value. Should only be used together with Energy.
:vartype EnergySigma: float | FloatKey
:ivar FractionalCoords: Place molecules at or around the specified fractional coordinates in the main system's lattice. For non-periodic dimensions a Cartesian value in Angstrom is expected. This setting is ignored if [Coords] or [CoordsBox] is used.
:vartype FractionalCoords: Iterable[float] | FloatListKey
:ivar FractionalCoordsBox: Place molecules at random locations inside the box specified as fractional coordinates in the main system's lattice.
Coordinates of the box corners are specified as: Xmin, Xmax, Ymin, Ymax, Zmin, Zmax.
For non-periodic dimensions the Cartesian value in Angstrom is expected.
This setting is ignored if [Coords], [CoordsBox], or [FractionalCoords] is used.
:vartype FractionalCoordsBox: Iterable[float] | FloatListKey
:ivar FractionalCoordsSigma: Sigma values (one per axis) for a Gauss distribution of the initial coordinates. For non-periodic dimensions the Cartesian value in Angstrom is expected. Can only be used together with FractionalCoords.
:vartype FractionalCoordsSigma: Iterable[float] | FloatListKey
:ivar Frequency: A molecule is added every [Frequency] steps after the StartStep.
There is never a molecule added at step 0.
:vartype Frequency: int | IntKey
:ivar MinDistance: Keep the minimal distance to other atoms of the system when adding the molecule.
:vartype MinDistance: float | FloatKey
:ivar MoleFraction: Defines a mixture to be deposited using one AddMolecules block per component.
AMS will randomly alternate between any guns that have MoleFraction set. These need to all have the same settings for StartStep, StopStep and Frequency. Any additional AddMolecules blocks without MoleFraction will remain completely independent.
:vartype MoleFraction: float | FloatKey
:ivar NumAttempts: Try adding the molecule up to the specified number of times or until the MinDistance constraint is satisfied. If all attempts fail a message will be printed and the simulation will continue normally.
:vartype NumAttempts: int | IntKey
:ivar Rotate: Rotate the molecule randomly before adding it to the system.
:vartype Rotate: BoolType | BoolKey
:ivar StartStep: Step number when the first molecule should be added. After that, molecules are added every Frequency steps.
For example, ff StartStep=99 and Frequency=100 then a molecule will be added at steps 99, 199, 299, etc...
No molecule will be added at step 0, so if StartStep=0 the first molecule is added at the step number equal to [Frequency].
:vartype StartStep: int | IntKey
:ivar StopStep: Do not add this molecule after the specified step.
:vartype StopStep: int | IntKey
:ivar System: String ID of the [System] that will be added with this 'gun'.
The lattice specified with this System is ignored and the main system's lattice is used instead.
AMSinput adds the system at the coordinates of the System (thus setting Coords to the center of the System).
:vartype System: str | StringKey
:ivar Temperature: Initial energy of the molecule in the shooting direction will correspond to the given temperature.
:vartype Temperature: float | FloatKey
:ivar TemperatureSigma: Sigma value for the Gauss distribution of the initial temperature the specified value. Should only be used together with Temperature.
:vartype TemperatureSigma: float | FloatKey
:ivar Velocity: Initial velocity of the molecule in the shooting direction.
:vartype Velocity: float | FloatKey
:ivar VelocityDirection: Velocity direction vector for aimed shooting. It will be random if not specified.
In AMSinput add one or two atoms (which may be dummies).
One atom: use vector from center of the system to add to that atom.
Two atoms: use vector from the first to the second atom.
:vartype VelocityDirection: Iterable[float] | FloatListKey
:ivar VelocitySigma: Sigma value for the Gauss distribution of the initial velocity around the specified value. Should only be used together with Velocity.
:vartype VelocitySigma: float | FloatKey
"""
def __post_init__(self):
self.AtomTemperature: float | FloatKey = FloatKey(name='AtomTemperature', comment='Add random velocity corresponding to the specified temperature to individual atoms of the molecule. This only affects rotational and internal degrees of freedom, not the net translational velocity of the inserted molecule as set by the other options.', default=0.0, unit='Kelvin')
self.ContactDistance: float | FloatKey = FloatKey(name='ContactDistance', comment='Translate the bullet along the velocity vector until it comes within ContactDistance of any other atom.', default=0.0, unit='Angstrom')
self.Coords: Iterable[float] | FloatListKey = FloatListKey(name='Coords', comment='Place molecules at or around the specified Cartesian coordinates.\n\nThis setting takes precedence over other ways to specify initial coordinates of the molecule: [CoordsBox], [FractionalCoords], and [FractionalCoordsBox].', unit='Angstrom')
self.CoordsBox: Iterable[float] | FloatListKey = FloatListKey(name='CoordsBox', comment='Place molecules at random locations inside the specified box in Cartesian coordinates.\n\nCoordinates of the box corners are specified as: Xmin, Xmax, Ymin, Ymax, Zmin, Zmax.\nThis setting is ignored if Coords is used.\n\nIn AMSinput, if this field is not empty it will be used instead of the default Coords.', unit='Angstrom', gui_type='nfloat 6')
self.CoordsSigma: Iterable[float] | FloatListKey = FloatListKey(name='CoordsSigma', comment='Sigma values (one per Cartesian axis) for a Gauss distribution of the initial coordinates. Can only be used together with Coords.', unit='Angstrom', gui_type='nfloat 3')
self.DeviationAngle: float | FloatKey = FloatKey(name='DeviationAngle', comment='Randomly tilt the shooting direction up to this angle away from the VelocityDirection vector.', default=0.0, unit='Degree')
self.Energy: float | FloatKey = FloatKey(name='Energy', comment='Initial kinetic energy of the molecule in the shooting direction.', unit='Hartree')
self.EnergySigma: float | FloatKey = FloatKey(name='EnergySigma', comment='Sigma value for the Gauss distribution of the initial kinetic energy around the specified value. Should only be used together with Energy.', default=0.0, unit='Hartree')
self.FractionalCoords: Iterable[float] | FloatListKey = FloatListKey(name='FractionalCoords', comment="Place molecules at or around the specified fractional coordinates in the main system's lattice. For non-periodic dimensions a Cartesian value in Angstrom is expected. This setting is ignored if [Coords] or [CoordsBox] is used.")
self.FractionalCoordsBox: Iterable[float] | FloatListKey = FloatListKey(name='FractionalCoordsBox', comment="Place molecules at random locations inside the box specified as fractional coordinates in the main system's lattice.\n\nCoordinates of the box corners are specified as: Xmin, Xmax, Ymin, Ymax, Zmin, Zmax.\n\nFor non-periodic dimensions the Cartesian value in Angstrom is expected.\n\nThis setting is ignored if [Coords], [CoordsBox], or [FractionalCoords] is used.", gui_type='nfloat 6')
self.FractionalCoordsSigma: Iterable[float] | FloatListKey = FloatListKey(name='FractionalCoordsSigma', comment='Sigma values (one per axis) for a Gauss distribution of the initial coordinates. For non-periodic dimensions the Cartesian value in Angstrom is expected. Can only be used together with FractionalCoords.')
self.Frequency: int | IntKey = IntKey(name='Frequency', comment='A molecule is added every [Frequency] steps after the StartStep.\n\nThere is never a molecule added at step 0.', default=0)
self.MinDistance: float | FloatKey = FloatKey(name='MinDistance', comment='Keep the minimal distance to other atoms of the system when adding the molecule.', default=0.0, unit='Angstrom')
self.MoleFraction: float | FloatKey = FloatKey(name='MoleFraction', comment='Defines a mixture to be deposited using one AddMolecules block per component.\n\nAMS will randomly alternate between any guns that have MoleFraction set. These need to all have the same settings for StartStep, StopStep and Frequency. Any additional AddMolecules blocks without MoleFraction will remain completely independent.')
self.NumAttempts: int | IntKey = IntKey(name='NumAttempts', comment='Try adding the molecule up to the specified number of times or until the MinDistance constraint is satisfied. If all attempts fail a message will be printed and the simulation will continue normally.', default=10)
self.Rotate: BoolType | BoolKey = BoolKey(name='Rotate', comment='Rotate the molecule randomly before adding it to the system.', default=False)
self.StartStep: int | IntKey = IntKey(name='StartStep', comment='Step number when the first molecule should be added. After that, molecules are added every Frequency steps.\n\nFor example, ff StartStep=99 and Frequency=100 then a molecule will be added at steps 99, 199, 299, etc...\n\nNo molecule will be added at step 0, so if StartStep=0 the first molecule is added at the step number equal to [Frequency].', default=0)
self.StopStep: int | IntKey = IntKey(name='StopStep', comment='Do not add this molecule after the specified step.')
self.System: str | StringKey = StringKey(name='System', comment="String ID of the [System] that will be added with this 'gun'.\n\nThe lattice specified with this System is ignored and the main system's lattice is used instead.\n\nAMSinput adds the system at the coordinates of the System (thus setting Coords to the center of the System).", gui_type='region')
self.Temperature: float | FloatKey = FloatKey(name='Temperature', comment='Initial energy of the molecule in the shooting direction will correspond to the given temperature.', unit='Kelvin')
self.TemperatureSigma: float | FloatKey = FloatKey(name='TemperatureSigma', comment='Sigma value for the Gauss distribution of the initial temperature the specified value. Should only be used together with Temperature.', default=0.0, unit='Kelvin')
self.Velocity: float | FloatKey = FloatKey(name='Velocity', comment='Initial velocity of the molecule in the shooting direction.', unit='Angstrom/fs')
self.VelocityDirection: Iterable[float] | FloatListKey = FloatListKey(name='VelocityDirection', comment='Velocity direction vector for aimed shooting. It will be random if not specified.\n\nIn AMSinput add one or two atoms (which may be dummies).\n\nOne atom: use vector from center of the system to add to that atom.\n\nTwo atoms: use vector from the first to the second atom.')
self.VelocitySigma: float | FloatKey = FloatKey(name='VelocitySigma', comment='Sigma value for the Gauss distribution of the initial velocity around the specified value. Should only be used together with Velocity.', default=0.0, unit='Angstrom/fs')
[docs] class _ApplyForce(FixedBlock):
r"""
The ApplyForce keyword can be used to apply an arbitrary constant force to a certain (subgroups of) atoms in the system
:ivar CalculateViscosity: Calculates Viscosity property yes/no. If yes is chosen, the global viscosity of the system is calculated and written into the RKF-file. The formula used for the viscosity calculation is eta = - Pxz / (dVx/dz)
:vartype CalculateViscosity: BoolType | BoolKey
:ivar CalculateViscosityBins: Amount of bins used to determine (dVx/dz)
:vartype CalculateViscosityBins: int | IntKey
:ivar CalculateViscosityEnd: end index to select region in space to calculate (dVx/dz)
:vartype CalculateViscosityEnd: int | IntKey
:ivar CalculateViscosityStart: Start index to select region in space to calculate (dVx/dz)
:vartype CalculateViscosityStart: int | IntKey
:ivar Force: Defines the constant force vector
:vartype Force: Iterable[float] | FloatListKey
:ivar PerAtom: If enabled, the Force vector is applied separately to every atom in the selected Region, so that the total net force on the Region equals the value of Force times the number of atoms in Region. This was the behavior of ApplyForce in AMS2022. By default, with PerAtom disabled, the Force vector defines the total net force on the Region, so the force applied to each atom equals the value of Force divided by the number of atoms in Region.
:vartype PerAtom: BoolType | BoolKey
:ivar Region: Apply the constant force to all atoms in this region.
:vartype Region: str | StringKey
"""
def __post_init__(self):
self.CalculateViscosity: BoolType | BoolKey = BoolKey(name='CalculateViscosity', comment='Calculates Viscosity property yes/no. If yes is chosen, the global viscosity of the system is calculated and written into the RKF-file. The formula used for the viscosity calculation is eta = - Pxz / (dVx/dz)', hidden=True)
self.CalculateViscosityBins: int | IntKey = IntKey(name='CalculateViscosityBins', comment='Amount of bins used to determine (dVx/dz)', hidden=True, default=20)
self.CalculateViscosityEnd: int | IntKey = IntKey(name='CalculateViscosityEnd', comment='end index to select region in space to calculate (dVx/dz)', hidden=True, default=3)
self.CalculateViscosityStart: int | IntKey = IntKey(name='CalculateViscosityStart', comment='Start index to select region in space to calculate (dVx/dz)', hidden=True, default=1)
self.Force: Iterable[float] | FloatListKey = FloatListKey(name='Force', comment='Defines the constant force vector', default=[0.0, 0.0, 0.0], unit='Hartree/Bohr', gui_type='nfloat 3')
self.PerAtom: BoolType | BoolKey = BoolKey(name='PerAtom', comment='If enabled, the Force vector is applied separately to every atom in the selected Region, so that the total net force on the Region equals the value of Force times the number of atoms in Region. This was the behavior of ApplyForce in AMS2022. By default, with PerAtom disabled, the Force vector defines the total net force on the Region, so the force applied to each atom equals the value of Force divided by the number of atoms in Region.', default=False)
self.Region: str | StringKey = StringKey(name='Region', comment='Apply the constant force to all atoms in this region.', unique=False, gui_type='region')
[docs] class _ApplyVelocity(FixedBlock):
r"""
The ApplyVelocity keyword can be used to move an arbitrary group of atoms in the system with a constant net velocity
:ivar CalculateViscosity: Calculates Viscosity property yes/no. If yes is chosen, the global viscosity of the system is calculated and written into the RKF-file. The formula used for the viscosity calculation is eta = - Pxz / (dVx/dz)
:vartype CalculateViscosity: BoolType | BoolKey
:ivar CalculateViscosityBins: Amount of bins used to determine (dVx/dz)
:vartype CalculateViscosityBins: int | IntKey
:ivar CalculateViscosityEnd: end index to select region in space to calculate (dVx/dz)
:vartype CalculateViscosityEnd: int | IntKey
:ivar CalculateViscosityStart: Start index to select region in space to calculate (dVx/dz)
:vartype CalculateViscosityStart: int | IntKey
:ivar Components: Select which components of the Velocity vector are used to set the corresponding components of the net velocity of the specified set of atoms. Any other components of Velocity are ignored and the motion of the selected atoms in those directions is unaffected by ApplyVelocity.
:vartype Components: Literal["X", "Y", "Z", "XY", "YZ", "XZ", "XYZ"]
:ivar Region: Applies the defined velocity to all atoms in this region.
:vartype Region: str | StringKey
:ivar Velocity: The constant velocity that will be applied to the specified atoms.
:vartype Velocity: Iterable[float] | FloatListKey
"""
def __post_init__(self):
self.CalculateViscosity: BoolType | BoolKey = BoolKey(name='CalculateViscosity', comment='Calculates Viscosity property yes/no. If yes is chosen, the global viscosity of the system is calculated and written into the RKF-file. The formula used for the viscosity calculation is eta = - Pxz / (dVx/dz)', hidden=True)
self.CalculateViscosityBins: int | IntKey = IntKey(name='CalculateViscosityBins', comment='Amount of bins used to determine (dVx/dz)', hidden=True, default=20)
self.CalculateViscosityEnd: int | IntKey = IntKey(name='CalculateViscosityEnd', comment='end index to select region in space to calculate (dVx/dz)', hidden=True, default=3)
self.CalculateViscosityStart: int | IntKey = IntKey(name='CalculateViscosityStart', comment='Start index to select region in space to calculate (dVx/dz)', hidden=True, default=1)
self.Components: Literal["X", "Y", "Z", "XY", "YZ", "XZ", "XYZ"] = MultipleChoiceKey(name='Components', comment='Select which components of the Velocity vector are used to set the corresponding components of the net velocity of the specified set of atoms. Any other components of Velocity are ignored and the motion of the selected atoms in those directions is unaffected by ApplyVelocity.', default='XY', choices=['X', 'Y', 'Z', 'XY', 'YZ', 'XZ', 'XYZ'])
self.Region: str | StringKey = StringKey(name='Region', comment='Applies the defined velocity to all atoms in this region.', unique=False, gui_type='region')
self.Velocity: Iterable[float] | FloatListKey = FloatListKey(name='Velocity', comment='The constant velocity that will be applied to the specified atoms.', default=[0.0, 0.0, 0.0], unit='Angstrom/fs', gui_type='nfloat 3')
[docs] class _Barostat(FixedBlock):
r"""
This block allows to specify the use of a barostat during the simulation.
:ivar BulkModulus: An estimate of the bulk modulus (inverse compressibility) of the system for the Berendsen barostat.
This is only used to make Tau correspond to the true observed relaxation time constant. Values are commonly on the order of 10-100 GPa (1e10 to 1e11) for solids and 1 GPa (1e9) for liquids (2.2e9 for water). Use 1e9 to match the behavior of standalone ReaxFF.
:vartype BulkModulus: float | FloatKey
:ivar ConstantVolume: Keep the volume constant while allowing the box shape to change.
This is currently supported only by the MTK barostat.
:vartype ConstantVolume: BoolType | BoolKey
:ivar Duration: Specifies how many steps should a transition from a particular pressure to the next one in sequence take.
:vartype Duration: Iterable[int] | IntListKey
:ivar Equal: Enforce equal scaling of the selected set of dimensions. They will be barostatted as one dimension according to the average pressure over the components.
:vartype Equal: Literal["None", "XYZ", "XY", "YZ", "XZ"]
:ivar Pressure: Specifies the target pressure.
You can specify multiple pressures (separated by spaces). In that case the Duration field specifies how many steps to use for the transition from one p to the next p (using a linear ramp).
:vartype Pressure: Iterable[float] | FloatListKey
:ivar Scale: Dimensions that should be scaled by the barostat to maintain pressure. Selecting Shape means that all three dimensions and also all the cell angles are allowed to change.
:vartype Scale: Literal["XYZ", "Shape", "X", "Y", "Z", "XY", "YZ", "XZ"]
:ivar Tau: Specifies the time constant of the barostat.
:vartype Tau: float | FloatKey
:ivar Type: Selects the type of the barostat.
:vartype Type: Literal["None", "Berendsen", "MTK"]
"""
def __post_init__(self):
self.BulkModulus: float | FloatKey = FloatKey(name='BulkModulus', comment='An estimate of the bulk modulus (inverse compressibility) of the system for the Berendsen barostat.\n\nThis is only used to make Tau correspond to the true observed relaxation time constant. Values are commonly on the order of 10-100 GPa (1e10 to 1e11) for solids and 1 GPa (1e9) for liquids (2.2e9 for water). Use 1e9 to match the behavior of standalone ReaxFF.', default=2200000000.0, unit='Pascal')
self.ConstantVolume: BoolType | BoolKey = BoolKey(name='ConstantVolume', comment='Keep the volume constant while allowing the box shape to change.\n\nThis is currently supported only by the MTK barostat.', default=False)
self.Duration: Iterable[int] | IntListKey = IntListKey(name='Duration', comment='Specifies how many steps should a transition from a particular pressure to the next one in sequence take.')
self.Equal: Literal["None", "XYZ", "XY", "YZ", "XZ"] = MultipleChoiceKey(name='Equal', comment='Enforce equal scaling of the selected set of dimensions. They will be barostatted as one dimension according to the average pressure over the components.', default='None', choices=['None', 'XYZ', 'XY', 'YZ', 'XZ'])
self.Pressure: Iterable[float] | FloatListKey = FloatListKey(name='Pressure', comment='Specifies the target pressure. \n\nYou can specify multiple pressures (separated by spaces). In that case the Duration field specifies how many steps to use for the transition from one p to the next p (using a linear ramp).', unit='Pascal')
self.Scale: Literal["XYZ", "Shape", "X", "Y", "Z", "XY", "YZ", "XZ"] = MultipleChoiceKey(name='Scale', comment='Dimensions that should be scaled by the barostat to maintain pressure. Selecting Shape means that all three dimensions and also all the cell angles are allowed to change.', default='XYZ', choices=['XYZ', 'Shape', 'X', 'Y', 'Z', 'XY', 'YZ', 'XZ'])
self.Tau: float | FloatKey = FloatKey(name='Tau', comment='Specifies the time constant of the barostat.', gui_name='Damping constant:', unit='Femtoseconds')
self.Type: Literal["None", "Berendsen", "MTK"] = MultipleChoiceKey(name='Type', comment='Selects the type of the barostat.', gui_name='Barostat:', default='None', choices=['None', 'Berendsen', 'MTK'])
[docs] class _BinLog(FixedBlock):
r"""
This block controls writing the BinLog section in ams.rkf, which contains the selected MD state scalars and tensors from every MD step. No per-atom data is written. If you need the per-atom data then you can set the sampling frequency to 1 and get the required data from the MDHistory section. The tensors are written per component, that is, the pressure tensor is written as six variables: PressureTensor_xx, PressureTensor_yy, etc.. To reduce the file size, all data is written in blocks.
:ivar BiasEnergy: Write the CVHD bias energy at every time step.
:vartype BiasEnergy: BoolType | BoolKey
:ivar BoostFactor: Write the CVHD boost factor at every time step.
:vartype BoostFactor: BoolType | BoolKey
:ivar ConservedEnergy: Write the conserved energy value at every time step.
:vartype ConservedEnergy: BoolType | BoolKey
:ivar Density: Write the density at every time step.
:vartype Density: BoolType | BoolKey
:ivar DipoleMoment: Write the dipole moment at every time step. Each component of the tensor is written in its own variable.
:vartype DipoleMoment: BoolType | BoolKey
:ivar Hypertime: Write the CVHD hypertime at every time step.
:vartype Hypertime: BoolType | BoolKey
:ivar KineticEnergy: Write the kinetic energy value at every time step.
:vartype KineticEnergy: BoolType | BoolKey
:ivar MaxBiasEnergy: Write the max CVHD bias energy at every time step.
:vartype MaxBiasEnergy: BoolType | BoolKey
:ivar MaxBoostFactor: Write the max CVHD boost factor at every time step.
:vartype MaxBoostFactor: BoolType | BoolKey
:ivar PotentialEnergy: Write the potential energy value at every time step.
:vartype PotentialEnergy: BoolType | BoolKey
:ivar Pressure: Write the pressure at every time step.
:vartype Pressure: BoolType | BoolKey
:ivar PressureTensor: Write the pressure tensor in Voigt notation at every time step. Each component of the tensor is written in its own variable.
:vartype PressureTensor: BoolType | BoolKey
:ivar Step: Write the step index during the simulation at every time step.
:vartype Step: BoolType | BoolKey
:ivar Temperature: Write the temperature at every time step.
:vartype Temperature: BoolType | BoolKey
:ivar Time: Write the simulation time (fs) at every time step.
:vartype Time: BoolType | BoolKey
:ivar TotalEnergy: Write the total energy value at every time step.
:vartype TotalEnergy: BoolType | BoolKey
:ivar Volume: Write the simulation cell volume, area or length, depending on the system periodicity, at every time step.
:vartype Volume: BoolType | BoolKey
"""
def __post_init__(self):
self.BiasEnergy: BoolType | BoolKey = BoolKey(name='BiasEnergy', comment='Write the CVHD bias energy at every time step.', default=False)
self.BoostFactor: BoolType | BoolKey = BoolKey(name='BoostFactor', comment='Write the CVHD boost factor at every time step.', default=False)
self.ConservedEnergy: BoolType | BoolKey = BoolKey(name='ConservedEnergy', comment='Write the conserved energy value at every time step.', default=False)
self.Density: BoolType | BoolKey = BoolKey(name='Density', comment='Write the density at every time step.', default=False)
self.DipoleMoment: BoolType | BoolKey = BoolKey(name='DipoleMoment', comment='Write the dipole moment at every time step. Each component of the tensor is written in its own variable.', gui_name='Dipole moment binlog:', default=False)
self.Hypertime: BoolType | BoolKey = BoolKey(name='Hypertime', comment='Write the CVHD hypertime at every time step.', default=False)
self.KineticEnergy: BoolType | BoolKey = BoolKey(name='KineticEnergy', comment='Write the kinetic energy value at every time step.', default=False)
self.MaxBiasEnergy: BoolType | BoolKey = BoolKey(name='MaxBiasEnergy', comment='Write the max CVHD bias energy at every time step.', default=False)
self.MaxBoostFactor: BoolType | BoolKey = BoolKey(name='MaxBoostFactor', comment='Write the max CVHD boost factor at every time step.', default=False)
self.PotentialEnergy: BoolType | BoolKey = BoolKey(name='PotentialEnergy', comment='Write the potential energy value at every time step.', default=False)
self.Pressure: BoolType | BoolKey = BoolKey(name='Pressure', comment='Write the pressure at every time step.', default=False)
self.PressureTensor: BoolType | BoolKey = BoolKey(name='PressureTensor', comment='Write the pressure tensor in Voigt notation at every time step. Each component of the tensor is written in its own variable.', gui_name='Pressure tensor binlog:', default=False)
self.Step: BoolType | BoolKey = BoolKey(name='Step', comment='Write the step index during the simulation at every time step.', default=False)
self.Temperature: BoolType | BoolKey = BoolKey(name='Temperature', comment='Write the temperature at every time step.', default=False)
self.Time: BoolType | BoolKey = BoolKey(name='Time', comment='Write the simulation time (fs) at every time step.', gui_name='Time (fs) binlog:', default=False)
self.TotalEnergy: BoolType | BoolKey = BoolKey(name='TotalEnergy', comment='Write the total energy value at every time step.', default=False)
self.Volume: BoolType | BoolKey = BoolKey(name='Volume', comment='Write the simulation cell volume, area or length, depending on the system periodicity, at every time step.', default=False)
[docs] class _BondBoost(FixedBlock):
r"""
Forced reaction (bond boost) definitions. Multiple BondBoost blocks may be specified, which will be treated independently.
:ivar AddBond: [Reserved] Add a bond to the system or change its order. Specify two atom indices followed by the bond's order. The indices indicate positions of the atoms in the AtomNames key. Currently no engine will honor bond changes caused by this key.
:vartype AddBond: str | StringKey
:ivar DistanceRestraint: Specify two atom indices followed by the target distance in Angstrom, the first parameter and, optionally, the profile type and the second parameter.
For periodic systems, restraints follow the minimum image convention.
Each atom index indicates a position of the corresponding atom in the AtomNames key. Currently recognized restraint profile types: Harmonic (default), Hyperbolic, Erf, GaussianWell. The profile name can optionally be prefixed by "OneSided-", thus making this particular restraint one-sided. A one-sided restraint will only push or pull the distance towards its target value depending on the sign of the difference between the initial and the target distance. For example, if the initial distance is larger than the target one then the restraint will only push the value down. This is especially useful with moving restraints because then the restraint will effectively disappear as soon as the system crosses a barrier along the reaction path. By default, the restraints are two-sided, which means they will try to keep the distance between the two specified atoms near the (possibly moving) target value. For moving restraints, this means that after crossing a reaction barrier the system will slide slowly towards products held back by the restraints.
The first parameter is the force constant for the Harmonic, Hyperbolic, and Erf profiles, or well depth for GaussianWell. The second parameter is the asymptotic force value F(Inf) for Hyperbolic and Erf profiles, or the factor before x^2 in the exponent for GaussianWell.
Note: the GaussianWell restraint should be used with the Moving flag.
:vartype DistanceRestraint: str | StringKey
:ivar Moving: Move the restraints created with this BondBoost. The restraint value will start at the current coordinate's value and will move towards the optimum during the restraint's lifetime. The increment is calculated from the initial deviation and the [NSteps] parameter.
This feature should be used with the GaussianWell restraint types.
:vartype Moving: BoolType | BoolKey
:ivar NSteps: Number of steps the restraints will remain active until removed. Atoms participating in one reaction are not available for the given number of steps.
:vartype NSteps: int | IntKey
:ivar NumInstances: Number of reactions of this type taking place simultaneously.
:vartype NumInstances: int | IntKey
:ivar RemoveBond: [Reserved] Remove a bond from the system. Specify two atom indices. The indices indicate positions of the atoms in the AtomNames key. Currently no engine will honor bond changes caused by this key.
:vartype RemoveBond: str | StringKey
:ivar SetAtomName: Change the specified atom's name. Specify atom index followed by the new name. The index indicates position of the atom in the AtomNames key. Note: this action will change the atom name only and not other properties (element name, mass, etc.). This may be useful to change atom names to affect future chain detections. The atom name length is limited to 32 characters.
:vartype SetAtomName: str | StringKey
:ivar Units: Change energy, force and force constant units in the DistanceRestraint key from the default (atomic units) to those often used in the MD community (based on kcal/mol and Angstrom). Units for the optimum distances are not affected.
:vartype Units: Literal["Default", "MD"]
:ivar Chain: Specifications of a chain of atoms. When a chain is detected the distance restraints will be activated. No other chain of this type will be detected while any restraints for this chain is active.
:vartype Chain: SimpleActiveLearning._MolecularDynamics._BondBoost._Chain
"""
[docs] class _Chain(FixedBlock):
r"""
Specifications of a chain of atoms. When a chain is detected the distance restraints will be activated. No other chain of this type will be detected while any restraints for this chain is active.
:ivar AtomNames: Atom names specifying the chain. An atom name can optionally be followed by '@' and a region name, in this case only atoms of this type from the given region will be matched. A leading '@' followed by a number indicates that this position in the chain must be occupied by the atom found earlier at the specified position in the chain. For example "O H N C @1" indicates that the last atom in the chain of the five atoms must be the first oxygen, thus defining a 4-membered ring. This is the only way to define a ring because implicit rings will not be detected. For example, "O H N C O" does not include rings.
:vartype AtomNames: str | StringKey
:ivar MaxDistances: Maximum distances for each pair of atoms in the chain. The number of distances must be one less than the number of AtomNames.
:vartype MaxDistances: Iterable[float] | FloatListKey
:ivar MinDistances: Minimum distances for each pair of atoms in the chain. The number of distances must be one less than the number of AtomNames.
:vartype MinDistances: Iterable[float] | FloatListKey
"""
def __post_init__(self):
self.AtomNames: str | StringKey = StringKey(name='AtomNames', comment='Atom names specifying the chain. An atom name can optionally be followed by \'@\' and a region name, in this case only atoms of this type from the given region will be matched. A leading \'@\' followed by a number indicates that this position in the chain must be occupied by the atom found earlier at the specified position in the chain. For example "O H N C @1" indicates that the last atom in the chain of the five atoms must be the first oxygen, thus defining a 4-membered ring. This is the only way to define a ring because implicit rings will not be detected. For example, "O H N C O" does not include rings.')
self.MaxDistances: Iterable[float] | FloatListKey = FloatListKey(name='MaxDistances', comment='Maximum distances for each pair of atoms in the chain. The number of distances must be one less than the number of AtomNames.', unit='Angstrom')
self.MinDistances: Iterable[float] | FloatListKey = FloatListKey(name='MinDistances', comment='Minimum distances for each pair of atoms in the chain. The number of distances must be one less than the number of AtomNames.', unit='Angstrom')
def __post_init__(self):
self.AddBond: str | StringKey = StringKey(name='AddBond', comment="[Reserved] Add a bond to the system or change its order. Specify two atom indices followed by the bond's order. The indices indicate positions of the atoms in the AtomNames key. Currently no engine will honor bond changes caused by this key.", hidden=True, unique=False)
self.DistanceRestraint: str | StringKey = StringKey(name='DistanceRestraint', comment='Specify two atom indices followed by the target distance in Angstrom, the first parameter and, optionally, the profile type and the second parameter.\n\nFor periodic systems, restraints follow the minimum image convention.\n\nEach atom index indicates a position of the corresponding atom in the AtomNames key. Currently recognized restraint profile types: Harmonic (default), Hyperbolic, Erf, GaussianWell. The profile name can optionally be prefixed by "OneSided-", thus making this particular restraint one-sided. A one-sided restraint will only push or pull the distance towards its target value depending on the sign of the difference between the initial and the target distance. For example, if the initial distance is larger than the target one then the restraint will only push the value down. This is especially useful with moving restraints because then the restraint will effectively disappear as soon as the system crosses a barrier along the reaction path. By default, the restraints are two-sided, which means they will try to keep the distance between the two specified atoms near the (possibly moving) target value. For moving restraints, this means that after crossing a reaction barrier the system will slide slowly towards products held back by the restraints. \n\nThe first parameter is the force constant for the Harmonic, Hyperbolic, and Erf profiles, or well depth for GaussianWell. The second parameter is the asymptotic force value F(Inf) for Hyperbolic and Erf profiles, or the factor before x^2 in the exponent for GaussianWell.\n\nNote: the GaussianWell restraint should be used with the Moving flag.', unique=False)
self.Moving: BoolType | BoolKey = BoolKey(name='Moving', comment="Move the restraints created with this BondBoost. The restraint value will start at the current coordinate's value and will move towards the optimum during the restraint's lifetime. The increment is calculated from the initial deviation and the [NSteps] parameter.\n\n This feature should be used with the GaussianWell restraint types.", gui_name='Move restraint', default=False)
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='Number of steps the restraints will remain active until removed. Atoms participating in one reaction are not available for the given number of steps.', gui_name='Boost lifetime:')
self.NumInstances: int | IntKey = IntKey(name='NumInstances', comment='Number of reactions of this type taking place simultaneously.', gui_name='Number of instances:', default=1)
self.RemoveBond: str | StringKey = StringKey(name='RemoveBond', comment='[Reserved] Remove a bond from the system. Specify two atom indices. The indices indicate positions of the atoms in the AtomNames key. Currently no engine will honor bond changes caused by this key.', hidden=True, unique=False)
self.SetAtomName: str | StringKey = StringKey(name='SetAtomName', comment="Change the specified atom's name. Specify atom index followed by the new name. The index indicates position of the atom in the AtomNames key. Note: this action will change the atom name only and not other properties (element name, mass, etc.). This may be useful to change atom names to affect future chain detections. The atom name length is limited to 32 characters.", hidden=True, unique=False)
self.Units: Literal["Default", "MD"] = MultipleChoiceKey(name='Units', comment='Change energy, force and force constant units in the DistanceRestraint key from the default (atomic units) to those often used in the MD community (based on kcal/mol and Angstrom). Units for the optimum distances are not affected.', gui_name='Restr. parameter units:', default='Default', choices=['Default', 'MD'])
self.Chain: SimpleActiveLearning._MolecularDynamics._BondBoost._Chain = self._Chain(name='Chain', comment='Specifications of a chain of atoms. When a chain is detected the distance restraints will be activated. No other chain of this type will be detected while any restraints for this chain is active.')
[docs] class _CRESTMTD(FixedBlock):
r"""
Input for CREST metadynamics simulation.
:ivar AddEnergy: Add the bias energy to the potential energy (to match the gradients)
:vartype AddEnergy: BoolType | BoolKey
:ivar Height: The height of the Gaussians added
:vartype Height: float | FloatKey
:ivar NGaussiansMax: Maximum number of Gaussians stored
:vartype NGaussiansMax: int | IntKey
:ivar NSteps: Interval of Gaussian placement
:vartype NSteps: int | IntKey
:ivar Region: Restrict the range of atoms for RMSD calculation to the specified region.
:vartype Region: str | StringKey
:ivar RestartFile: Filename for file from which to read data on Gaussians placed previously.
:vartype RestartFile: str | Path | StringKey
:ivar Width: The width of the Gaussians added in terms of the RMSD
:vartype Width: float | FloatKey
:ivar GaussianScaling: Options for gradual introduction of the Gaussians
:vartype GaussianScaling: SimpleActiveLearning._MolecularDynamics._CRESTMTD._GaussianScaling
"""
[docs] class _GaussianScaling(FixedBlock):
r"""
Options for gradual introduction of the Gaussians
:ivar ScaleGaussians: Introduce the Gaussians gradually, using a scaling function
:vartype ScaleGaussians: BoolType | BoolKey
:ivar ScalingSlope: Slope of the scaling function for the Gaussians with respect to time
:vartype ScalingSlope: float | FloatKey
"""
def __post_init__(self):
self.ScaleGaussians: BoolType | BoolKey = BoolKey(name='ScaleGaussians', comment='Introduce the Gaussians gradually, using a scaling function', default=True)
self.ScalingSlope: float | FloatKey = FloatKey(name='ScalingSlope', comment='Slope of the scaling function for the Gaussians with respect to time', default=0.03)
def __post_init__(self):
self.AddEnergy: BoolType | BoolKey = BoolKey(name='AddEnergy', comment='Add the bias energy to the potential energy (to match the gradients)', default=False)
self.Height: float | FloatKey = FloatKey(name='Height', comment='The height of the Gaussians added', unit='Hartree')
self.NGaussiansMax: int | IntKey = IntKey(name='NGaussiansMax', comment='Maximum number of Gaussians stored')
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='Interval of Gaussian placement')
self.Region: str | StringKey = StringKey(name='Region', comment='Restrict the range of atoms for RMSD calculation to the specified region.', default='*', gui_type='region')
self.RestartFile: str | Path | StringKey = PathStringKey(name='RestartFile', comment='Filename for file from which to read data on Gaussians placed previously.', ispath=True)
self.Width: float | FloatKey = FloatKey(name='Width', comment='The width of the Gaussians added in terms of the RMSD', unit='Bohr')
self.GaussianScaling: SimpleActiveLearning._MolecularDynamics._CRESTMTD._GaussianScaling = self._GaussianScaling(name='GaussianScaling', comment='Options for gradual introduction of the Gaussians')
[docs] class _CVHD(FixedBlock):
r"""
Input for the Collective Variable-driven HyperDynamics (CVHD).
:ivar Frequency: Frequency of adding a new bias peak, in steps.
New bias is deposited every [Frequency] steps after [StartStep] if the following conditions are satisfied:
the current CV value is less than 0.9 (to avoid creating barriers at the transition state),
the step number is greater than or equal to [StartStep], and
the step number is less than or equal to [StopStep].
:vartype Frequency: int | IntKey
:ivar MaxEvents: Max number of events to allow during dynamics. When this number is reached no new bias will be added for this input block.
:vartype MaxEvents: int | IntKey
:ivar StartStep: If this key is specified, the first bias will be deposited at this step. Otherwise, the first bias peak is added at the step number equal to the Frequency parameter. The bias is never deposited at step 0.
:vartype StartStep: int | IntKey
:ivar StopStep: No bias will be deposited after the specified step. The already deposited bias will continue to be applied until the reaction event occurs. After that no new CVHD will be started. By default, the CVHD runs for the whole duration of the MD calculation.
:vartype StopStep: int | IntKey
:ivar WaitSteps: If the CV value becomes equal to 1 and remains at this value for this many steps then the reaction event is considered having taken place. After this, the collective variable will be reset and the bias will be removed.
:vartype WaitSteps: int | IntKey
:ivar Bias: The bias is built from a series of Gaussian peaks deposited on the collective variable axis every [Frequency] steps during MD. Each peak is characterized by its (possibly damped) height and the RMS width (standard deviation).
:vartype Bias: SimpleActiveLearning._MolecularDynamics._CVHD._Bias
:ivar ColVarBB: Description of a bond-breaking collective variable (CV) as described in [Bal & Neyts, JCTC, 11 (2015)]. A collective variable may consist of multiple ColVar blocks.
:vartype ColVarBB: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBB
:ivar ColVarBM: Description of a bond-making collective variable (CV). A collective variable may consist of multiple ColVar blocks.
:vartype ColVarBM: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBM
"""
[docs] class _Bias(FixedBlock):
r"""
The bias is built from a series of Gaussian peaks deposited on the collective variable axis every [Frequency] steps during MD. Each peak is characterized by its (possibly damped) height and the RMS width (standard deviation).
:ivar DampingTemp: During well-tempered hyperdynamics the height of the added bias is scaled down with an exp(-E/kT) factor [PhysRevLett 100, 020603 (2008)], where E is the current value of the bias at the given CV value and T is the damping temperature DampingTemp. If DampingTemp is zero then no damping is applied.
:vartype DampingTemp: float | FloatKey
:ivar Delta: Standard deviation parameter of the Gaussian bias peak.
:vartype Delta: float | FloatKey
:ivar Height: Height of the Gaussian bias peak.
:vartype Height: float | FloatKey
"""
def __post_init__(self):
self.DampingTemp: float | FloatKey = FloatKey(name='DampingTemp', comment='During well-tempered hyperdynamics the height of the added bias is scaled down with an exp(-E/kT) factor [PhysRevLett 100, 020603 (2008)], where E is the current value of the bias at the given CV value and T is the damping temperature DampingTemp. If DampingTemp is zero then no damping is applied.', gui_name='Bias damping T:', default=0.0, unit='Kelvin')
self.Delta: float | FloatKey = FloatKey(name='Delta', comment='Standard deviation parameter of the Gaussian bias peak.')
self.Height: float | FloatKey = FloatKey(name='Height', comment='Height of the Gaussian bias peak.', unit='Hartree')
[docs] class _ColVarBB(FixedBlock):
r"""
Description of a bond-breaking collective variable (CV) as described in [Bal & Neyts, JCTC, 11 (2015)]. A collective variable may consist of multiple ColVar blocks.
:ivar cutoff: Bond order cutoff. Bonds with BO below this value are ignored when creating the initial bond list for the CV. The bond list does not change during lifetime of the variable even if some bond orders drop below the cutoff.
:vartype cutoff: float | FloatKey
:ivar p: Exponent value p used to calculate the p-norm for this CV.
:vartype p: int | IntKey
:ivar rmax: Max bond distance parameter Rmax used for calculating the CV. It should be close to the transition-state distance for the corresponding bond.
:vartype rmax: float | FloatKey
:ivar rmin: Min bond distance parameter Rmin used for calculating the CV. It should be close to equilibrium distance for the corresponding bond.
:vartype rmin: float | FloatKey
:ivar at1: Specifies the first bonded atom in the collective variable.
:vartype at1: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBB._at1
:ivar at2: Specifies the second bonded atom in the collective variable.
:vartype at2: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBB._at2
"""
[docs] class _at1(FixedBlock):
r"""
Specifies the first bonded atom in the collective variable.
:ivar region: Restrict the selection of bonded atoms to a specific region. If this is not set, atoms anywhere in the system will be selected.
:vartype region: str | StringKey
:ivar symbol: Atom type name of the first atom of the bond. The name must be as it appears in the System block. That is, if the atom name contains an extension (e.g C.1) then the full name including the extension must be used here.
:vartype symbol: str | StringKey
"""
def __post_init__(self):
self.region: str | StringKey = StringKey(name='region', comment='Restrict the selection of bonded atoms to a specific region. If this is not set, atoms anywhere in the system will be selected.', default='*', gui_type='region')
self.symbol: str | StringKey = StringKey(name='symbol', comment='Atom type name of the first atom of the bond. The name must be as it appears in the System block. That is, if the atom name contains an extension (e.g C.1) then the full name including the extension must be used here.')
[docs] class _at2(FixedBlock):
r"""
Specifies the second bonded atom in the collective variable.
:ivar region: Restrict the selection of bonded atoms to a specific region. If this is not set, atoms anywhere in the system will be selected.
:vartype region: str | StringKey
:ivar symbol: Atom type name of the second atom of the bond. The value is allowed to be the same as [at1], in which case bonds between atoms of the same type will be included.
:vartype symbol: str | StringKey
"""
def __post_init__(self):
self.region: str | StringKey = StringKey(name='region', comment='Restrict the selection of bonded atoms to a specific region. If this is not set, atoms anywhere in the system will be selected.', default='*', gui_type='region')
self.symbol: str | StringKey = StringKey(name='symbol', comment='Atom type name of the second atom of the bond. The value is allowed to be the same as [at1], in which case bonds between atoms of the same type will be included.')
def __post_init__(self):
self.cutoff: float | FloatKey = FloatKey(name='cutoff', comment='Bond order cutoff. Bonds with BO below this value are ignored when creating the initial bond list for the CV. The bond list does not change during lifetime of the variable even if some bond orders drop below the cutoff.', gui_name='Bond order cutoff:', default=0.3)
self.p: int | IntKey = IntKey(name='p', comment='Exponent value p used to calculate the p-norm for this CV.', gui_name='Exponent p:', default=6)
self.rmax: float | FloatKey = FloatKey(name='rmax', comment='Max bond distance parameter Rmax used for calculating the CV. It should be close to the transition-state distance for the corresponding bond.', gui_name='R max:', unit='Angstrom')
self.rmin: float | FloatKey = FloatKey(name='rmin', comment='Min bond distance parameter Rmin used for calculating the CV. It should be close to equilibrium distance for the corresponding bond.', gui_name='R min:', unit='Angstrom')
self.at1: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBB._at1 = self._at1(name='at1', comment='Specifies the first bonded atom in the collective variable.')
self.at2: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBB._at2 = self._at2(name='at2', comment='Specifies the second bonded atom in the collective variable.')
[docs] class _ColVarBM(FixedBlock):
r"""
Description of a bond-making collective variable (CV). A collective variable may consist of multiple ColVar blocks.
:ivar cutoff: Bond order cutoff. Bonds with BO above this value are ignored when creating the initial atom-pair list for the CV. The list does not change during lifetime of the variable even if some bond orders rise above the cutoff.
:vartype cutoff: float | FloatKey
:ivar p: Exponent value p used to calculate the p-norm for this CV.
:vartype p: int | IntKey
:ivar rmax: Max bond distance parameter Rmax used for calculating the CV. It should be much larger than the corresponding Rmin.
:vartype rmax: float | FloatKey
:ivar rmin: Min bond distance parameter Rmin used for calculating the CV. It should be close to the transition-state distance for the corresponding bond.
:vartype rmin: float | FloatKey
:ivar at1: Specifies selection criteria for the first atom of a pair in the collective variable.
:vartype at1: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBM._at1
:ivar at2: Specifies selection criteria for the second atom of a pair in the collective variable.
:vartype at2: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBM._at2
"""
[docs] class _at1(FixedBlock):
r"""
Specifies selection criteria for the first atom of a pair in the collective variable.
:ivar region: Restrict the selection to a specific region. If this is not set, atoms anywhere in the system will be selected.
:vartype region: str | StringKey
:ivar symbol: Atom type name of the first atom of the pair. The name must be as it appears in the System block. That is, if the atom name contains an extension (e.g C.1) then the full name including the extension must be used here.
:vartype symbol: str | StringKey
"""
def __post_init__(self):
self.region: str | StringKey = StringKey(name='region', comment='Restrict the selection to a specific region. If this is not set, atoms anywhere in the system will be selected.', default='*', gui_type='region')
self.symbol: str | StringKey = StringKey(name='symbol', comment='Atom type name of the first atom of the pair. The name must be as it appears in the System block. That is, if the atom name contains an extension (e.g C.1) then the full name including the extension must be used here.')
[docs] class _at2(FixedBlock):
r"""
Specifies selection criteria for the second atom of a pair in the collective variable.
:ivar region: Restrict the selection to a specific region. If this is not set, atoms anywhere in the system will be selected.
:vartype region: str | StringKey
:ivar symbol: Atom type name of the second atom of the pair. The value is allowed to be the same as [at1], in which case pairs of atoms of the same type will be included.
:vartype symbol: str | StringKey
"""
def __post_init__(self):
self.region: str | StringKey = StringKey(name='region', comment='Restrict the selection to a specific region. If this is not set, atoms anywhere in the system will be selected.', default='*', gui_type='region')
self.symbol: str | StringKey = StringKey(name='symbol', comment='Atom type name of the second atom of the pair. The value is allowed to be the same as [at1], in which case pairs of atoms of the same type will be included.')
def __post_init__(self):
self.cutoff: float | FloatKey = FloatKey(name='cutoff', comment='Bond order cutoff. Bonds with BO above this value are ignored when creating the initial atom-pair list for the CV. The list does not change during lifetime of the variable even if some bond orders rise above the cutoff.', gui_name='Bond order cutoff:', default=0.3)
self.p: int | IntKey = IntKey(name='p', comment='Exponent value p used to calculate the p-norm for this CV.', gui_name='Exponent p:', default=6)
self.rmax: float | FloatKey = FloatKey(name='rmax', comment='Max bond distance parameter Rmax used for calculating the CV. It should be much larger than the corresponding Rmin.', gui_name='R max:', unit='Angstrom')
self.rmin: float | FloatKey = FloatKey(name='rmin', comment='Min bond distance parameter Rmin used for calculating the CV. It should be close to the transition-state distance for the corresponding bond.', gui_name='R min:', unit='Angstrom')
self.at1: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBM._at1 = self._at1(name='at1', comment='Specifies selection criteria for the first atom of a pair in the collective variable.')
self.at2: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBM._at2 = self._at2(name='at2', comment='Specifies selection criteria for the second atom of a pair in the collective variable.')
def __post_init__(self):
self.Frequency: int | IntKey = IntKey(name='Frequency', comment='Frequency of adding a new bias peak, in steps. \n New bias is deposited every [Frequency] steps after [StartStep] if the following conditions are satisfied: \n the current CV value is less than 0.9 (to avoid creating barriers at the transition state), \n the step number is greater than or equal to [StartStep], and \n the step number is less than or equal to [StopStep].')
self.MaxEvents: int | IntKey = IntKey(name='MaxEvents', comment='Max number of events to allow during dynamics. When this number is reached no new bias will be added for this input block. ', default=0)
self.StartStep: int | IntKey = IntKey(name='StartStep', comment='If this key is specified, the first bias will be deposited at this step. Otherwise, the first bias peak is added at the step number equal to the Frequency parameter. The bias is never deposited at step 0.')
self.StopStep: int | IntKey = IntKey(name='StopStep', comment='No bias will be deposited after the specified step. The already deposited bias will continue to be applied until the reaction event occurs. After that no new CVHD will be started. By default, the CVHD runs for the whole duration of the MD calculation.')
self.WaitSteps: int | IntKey = IntKey(name='WaitSteps', comment='If the CV value becomes equal to 1 and remains at this value for this many steps then the reaction event is considered having taken place. After this, the collective variable will be reset and the bias will be removed.')
self.Bias: SimpleActiveLearning._MolecularDynamics._CVHD._Bias = self._Bias(name='Bias', comment='The bias is built from a series of Gaussian peaks deposited on the collective variable axis every [Frequency] steps during MD. Each peak is characterized by its (possibly damped) height and the RMS width (standard deviation).')
self.ColVarBB: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBB = self._ColVarBB(name='ColVarBB', comment='Description of a bond-breaking collective variable (CV) as described in [Bal & Neyts, JCTC, 11 (2015)]. A collective variable may consist of multiple ColVar blocks.', unique=False, gui_name='Collective Variable', gui_type='Repeat at least once')
self.ColVarBM: SimpleActiveLearning._MolecularDynamics._CVHD._ColVarBM = self._ColVarBM(name='ColVarBM', comment='Description of a bond-making collective variable (CV). A collective variable may consist of multiple ColVar blocks.', unique=False, gui_name='Collective Variable', gui_type='Repeat at least once')
[docs] class _CheckTemperature(FixedBlock):
r"""
Check at every time step if the temperature has exceeded a threshold. If it has, it is assumed the system exploded, and the simulation will stop.
:ivar Enabled: If enabled, the simulation will stop if the temperature becomes too large.
:vartype Enabled: BoolType | BoolKey
:ivar MaxTemperature: Maximum temperature the system can have. If larger, the simulation will stop.
:vartype MaxTemperature: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='If enabled, the simulation will stop if the temperature becomes too large.', default=True)
self.MaxTemperature: float | FloatKey = FloatKey(name='MaxTemperature', comment='Maximum temperature the system can have. If larger, the simulation will stop.', default=1e+20)
[docs] class _Checkpoint(FixedBlock):
r"""
Sets the frequency for storing the entire MD state necessary for restarting the calculation.
:ivar Frequency: Write the MD state to the Molecule and MDResults sections on ams.rkf once every N steps. Setting this to zero disables checkpointing during the simulation, but one checkpoint at the very end of the simulation will always be written.
:vartype Frequency: int | IntKey
:ivar WriteProperties: Honor top-level Properties input block when writing engine results files.
DEPRECATED: This input option will be removed in AMS2026 and will be considered always enabled. If you rely on it being disabled, please contact [email protected].
:vartype WriteProperties: BoolType | BoolKey
"""
def __post_init__(self):
self.Frequency: int | IntKey = IntKey(name='Frequency', comment='Write the MD state to the Molecule and MDResults sections on ams.rkf once every N steps. Setting this to zero disables checkpointing during the simulation, but one checkpoint at the very end of the simulation will always be written.', gui_name='Checkpoint frequency:', default=1000)
self.WriteProperties: BoolType | BoolKey = BoolKey(name='WriteProperties', comment='Honor top-level Properties input block when writing engine results files.\n\nDEPRECATED: This input option will be removed in AMS2026 and will be considered always enabled. If you rely on it being disabled, please contact [email protected].', default=False)
[docs] class _CosineShear(FixedBlock):
r"""
Apply an external acceleration to all atoms of a fluid using a periodic (cosine) function along a selected coordinate axis. This induces a periodic shear flow profile which can be used to determine the viscosity.
:ivar Acceleration: Amplitude of the applied cosine shear acceleration profile. The default value should be a rough first guess for water and it needs to be adjusted by experimentation for other systems.
:vartype Acceleration: float | FloatKey
:ivar Enabled: Apply a cosine shear acceleration profile for a NEMD calculation of viscosity.
:vartype Enabled: BoolType | BoolKey
:ivar FlowDirection: The direction in which to apply the shear acceleration, in Cartesian coordinates. The magnitude of this vector is ignored (AMS will normalize it internally). FlowDirection has to be perpendicular to ProfileAxis.
:vartype FlowDirection: Iterable[float] | FloatListKey
:ivar ProfileAxis: The Cartesian coordinate axis along which the cosine wave runs
:vartype ProfileAxis: Literal["X", "Y", "Z"]
"""
def __post_init__(self):
self.Acceleration: float | FloatKey = FloatKey(name='Acceleration', comment='Amplitude of the applied cosine shear acceleration profile. The default value should be a rough first guess for water and it needs to be adjusted by experimentation for other systems.', default=5e-06, unit='Angstrom/fs^2')
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Apply a cosine shear acceleration profile for a NEMD calculation of viscosity.', gui_name='Enable cosine shear', default=False)
self.FlowDirection: Iterable[float] | FloatListKey = FloatListKey(name='FlowDirection', comment='The direction in which to apply the shear acceleration, in Cartesian coordinates. The magnitude of this vector is ignored (AMS will normalize it internally). FlowDirection has to be perpendicular to ProfileAxis.', default=[1.0, 0.0, 0.0], gui_type='nfloat 3')
self.ProfileAxis: Literal["X", "Y", "Z"] = MultipleChoiceKey(name='ProfileAxis', comment='The Cartesian coordinate axis along which the cosine wave runs', default='Z', choices=['X', 'Y', 'Z'])
[docs] class _Gravity(FixedBlock):
r"""
Apply a constant acceleration in -z.
:ivar Acceleration: Magnitude of the applied acceleration.
:vartype Acceleration: float | FloatKey
"""
def __post_init__(self):
self.Acceleration: float | FloatKey = FloatKey(name='Acceleration', comment='Magnitude of the applied acceleration.', default=0.0, unit='Angstrom/fs^2')
[docs] class _HeatExchange(FixedBlock):
r"""
Input for the heat-exchange non-equilibrium MD (T-NEMD).
:ivar HeatingRate: Rate at which the energy is added to the Source and removed from the Sink. A heating rate of 1 Hartree/fs equals to about 0.00436 Watt of power being transferred through the system.
:vartype HeatingRate: float | FloatKey
:ivar Method: Heat exchange method used.
Simple: kinetic energy of the atoms of the source and sink regions is modified irrespective of that of the center of mass (CoM) of the region (recommended for solids).
HEX: kinetic energy of the atoms of these regions is modified keeping that of the corresponding CoM constant.
eHEX: an enhanced version of HEX that conserves the total energy better (recommended for gases and liquids).
:vartype Method: Literal["Simple", "HEX", "eHEX"]
:ivar StartStep: Index of the MD step at which the heat exchange will start.
:vartype StartStep: int | IntKey
:ivar StopStep: Index of the MD step at which the heat exchange will stop.
:vartype StopStep: int | IntKey
:ivar Sink: Defines the heat sink region (where the heat will be removed).
:vartype Sink: SimpleActiveLearning._MolecularDynamics._HeatExchange._Sink
:ivar Source: Defines the heat source region (where the heat will be added).
:vartype Source: SimpleActiveLearning._MolecularDynamics._HeatExchange._Source
"""
[docs] class _Sink(FixedBlock):
r"""
Defines the heat sink region (where the heat will be removed).
:ivar AtomList: The atoms that are part of the sink.
This key is ignored if the [Box] block or [Region] key is present.
:vartype AtomList: Iterable[int] | IntListKey
:ivar FirstAtom: Index of the first atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.
:vartype FirstAtom: int | IntKey
:ivar LastAtom: Index of the last atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.
:vartype LastAtom: int | IntKey
:ivar Region: The region that is the sink.
This key is ignored if the [Box] block is present.
:vartype Region: str | StringKey
:ivar Show: Show the sink in the AMSinput
:vartype Show: BoolType | BoolKey
:ivar Box: Part of the simulation box (in fractional cell coordinates) defining the heat sink. If this block is specified, then by default, the whole box in each of the three dimensions is used, which usually does not make much sense. Normally, you will want to set the bounds along one of the axes.
:vartype Box: SimpleActiveLearning._MolecularDynamics._HeatExchange._Sink._Box
"""
[docs] class _Box(FixedBlock):
r"""
Part of the simulation box (in fractional cell coordinates) defining the heat sink. If this block is specified, then by default, the whole box in each of the three dimensions is used, which usually does not make much sense. Normally, you will want to set the bounds along one of the axes.
:ivar Amax: Coordinate of the upper bound along the first axis.
:vartype Amax: float | FloatKey
:ivar Amin: Coordinate of the lower bound along the first axis.
:vartype Amin: float | FloatKey
:ivar Bmax: Coordinate of the upper bound along the second axis.
:vartype Bmax: float | FloatKey
:ivar Bmin: Coordinate of the lower bound along the second axis.
:vartype Bmin: float | FloatKey
:ivar Cmax: Coordinate of the upper bound along the third axis.
:vartype Cmax: float | FloatKey
:ivar Cmin: Coordinate of the lower bound along the third axis.
:vartype Cmin: float | FloatKey
"""
def __post_init__(self):
self.Amax: float | FloatKey = FloatKey(name='Amax', comment='Coordinate of the upper bound along the first axis.', default=1.0)
self.Amin: float | FloatKey = FloatKey(name='Amin', comment='Coordinate of the lower bound along the first axis.', default=0.0)
self.Bmax: float | FloatKey = FloatKey(name='Bmax', comment='Coordinate of the upper bound along the second axis.', default=1.0)
self.Bmin: float | FloatKey = FloatKey(name='Bmin', comment='Coordinate of the lower bound along the second axis.', default=0.0)
self.Cmax: float | FloatKey = FloatKey(name='Cmax', comment='Coordinate of the upper bound along the third axis.', default=1.0)
self.Cmin: float | FloatKey = FloatKey(name='Cmin', comment='Coordinate of the lower bound along the third axis.', default=0.0)
def __post_init__(self):
self.AtomList: Iterable[int] | IntListKey = IntListKey(name='AtomList', comment='The atoms that are part of the sink.\n\nThis key is ignored if the [Box] block or [Region] key is present.', gui_name='Sink region:', gui_type='region')
self.FirstAtom: int | IntKey = IntKey(name='FirstAtom', comment='Index of the first atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.', hidden=True)
self.LastAtom: int | IntKey = IntKey(name='LastAtom', comment='Index of the last atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.', hidden=True)
self.Region: str | StringKey = StringKey(name='Region', comment='The region that is the sink.\n\nThis key is ignored if the [Box] block is present.', gui_name='Sink region:', gui_type='region')
self.Show: BoolType | BoolKey = BoolKey(name='Show', comment='Show the sink in the AMSinput', hidden=True, gui_name='Sink box: Show', default=False)
self.Box: SimpleActiveLearning._MolecularDynamics._HeatExchange._Sink._Box = self._Box(name='Box', comment='Part of the simulation box (in fractional cell coordinates) defining the heat sink. If this block is specified, then by default, the whole box in each of the three dimensions is used, which usually does not make much sense. Normally, you will want to set the bounds along one of the axes.')
[docs] class _Source(FixedBlock):
r"""
Defines the heat source region (where the heat will be added).
:ivar AtomList: The atoms that are part of the source.
This key is ignored if the [Box] block or [Region] key is present.
:vartype AtomList: Iterable[int] | IntListKey
:ivar FirstAtom: Index of the first atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.
:vartype FirstAtom: int | IntKey
:ivar LastAtom: Index of the last atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.
:vartype LastAtom: int | IntKey
:ivar Region: The region that is the source.
This key is ignored if the [Box] block is present.
:vartype Region: str | StringKey
:ivar Show: Show the source in the AMSinput
:vartype Show: BoolType | BoolKey
:ivar Box: Part of the simulation box (in fractional cell coordinates) defining the heat source. If this block is specified, then by default, the whole box in each of the three dimensions is used, which usually does not make much sense. Normally, you will want to set the bounds along one of the axes. This block is mutually exclusive with the FirstAtom/LastAtom setting.
:vartype Box: SimpleActiveLearning._MolecularDynamics._HeatExchange._Source._Box
"""
[docs] class _Box(FixedBlock):
r"""
Part of the simulation box (in fractional cell coordinates) defining the heat source. If this block is specified, then by default, the whole box in each of the three dimensions is used, which usually does not make much sense. Normally, you will want to set the bounds along one of the axes. This block is mutually exclusive with the FirstAtom/LastAtom setting.
:ivar Amax: Coordinate of the upper bound along the first axis.
:vartype Amax: float | FloatKey
:ivar Amin: Coordinate of the lower bound along the first axis.
:vartype Amin: float | FloatKey
:ivar Bmax: Coordinate of the upper bound along the second axis.
:vartype Bmax: float | FloatKey
:ivar Bmin: Coordinate of the lower bound along the second axis.
:vartype Bmin: float | FloatKey
:ivar Cmax: Coordinate of the upper bound along the third axis.
:vartype Cmax: float | FloatKey
:ivar Cmin: Coordinate of the lower bound along the third axis.
:vartype Cmin: float | FloatKey
"""
def __post_init__(self):
self.Amax: float | FloatKey = FloatKey(name='Amax', comment='Coordinate of the upper bound along the first axis.', default=1.0)
self.Amin: float | FloatKey = FloatKey(name='Amin', comment='Coordinate of the lower bound along the first axis.', default=0.0)
self.Bmax: float | FloatKey = FloatKey(name='Bmax', comment='Coordinate of the upper bound along the second axis.', default=1.0)
self.Bmin: float | FloatKey = FloatKey(name='Bmin', comment='Coordinate of the lower bound along the second axis.', default=0.0)
self.Cmax: float | FloatKey = FloatKey(name='Cmax', comment='Coordinate of the upper bound along the third axis.', default=1.0)
self.Cmin: float | FloatKey = FloatKey(name='Cmin', comment='Coordinate of the lower bound along the third axis.', default=0.0)
def __post_init__(self):
self.AtomList: Iterable[int] | IntListKey = IntListKey(name='AtomList', comment='The atoms that are part of the source.\n\nThis key is ignored if the [Box] block or [Region] key is present.', gui_name='Source region:', gui_type='region')
self.FirstAtom: int | IntKey = IntKey(name='FirstAtom', comment='Index of the first atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.', hidden=True)
self.LastAtom: int | IntKey = IntKey(name='LastAtom', comment='Index of the last atom of the region. This key is ignored if the [Box] block or the [AtomList] key is present.', hidden=True)
self.Region: str | StringKey = StringKey(name='Region', comment='The region that is the source.\n\nThis key is ignored if the [Box] block is present.', gui_name='Source region:', gui_type='region')
self.Show: BoolType | BoolKey = BoolKey(name='Show', comment='Show the source in the AMSinput', hidden=True, gui_name='Source box: Show', default=False)
self.Box: SimpleActiveLearning._MolecularDynamics._HeatExchange._Source._Box = self._Box(name='Box', comment='Part of the simulation box (in fractional cell coordinates) defining the heat source. If this block is specified, then by default, the whole box in each of the three dimensions is used, which usually does not make much sense. Normally, you will want to set the bounds along one of the axes. This block is mutually exclusive with the FirstAtom/LastAtom setting.')
def __post_init__(self):
self.HeatingRate: float | FloatKey = FloatKey(name='HeatingRate', comment='Rate at which the energy is added to the Source and removed from the Sink. A heating rate of 1 Hartree/fs equals to about 0.00436 Watt of power being transferred through the system. ', unit='Hartree/fs')
self.Method: Literal["Simple", "HEX", "eHEX"] = MultipleChoiceKey(name='Method', comment='Heat exchange method used.\n\n Simple: kinetic energy of the atoms of the source and sink regions is modified irrespective of that of the center of mass (CoM) of the region (recommended for solids). \n\n HEX: kinetic energy of the atoms of these regions is modified keeping that of the corresponding CoM constant. \n\n eHEX: an enhanced version of HEX that conserves the total energy better (recommended for gases and liquids).', default='Simple', choices=['Simple', 'HEX', 'eHEX'])
self.StartStep: int | IntKey = IntKey(name='StartStep', comment='Index of the MD step at which the heat exchange will start.', default=0)
self.StopStep: int | IntKey = IntKey(name='StopStep', comment='Index of the MD step at which the heat exchange will stop.')
self.Sink: SimpleActiveLearning._MolecularDynamics._HeatExchange._Sink = self._Sink(name='Sink', comment='Defines the heat sink region (where the heat will be removed).')
self.Source: SimpleActiveLearning._MolecularDynamics._HeatExchange._Source = self._Source(name='Source', comment='Defines the heat source region (where the heat will be added).')
[docs] class _InitialVelocities(FixedBlock):
r"""
Sets the frequency for printing to stdout and storing the molecular configuration on the .rkf file.
:ivar File: AMS RKF file containing the initial velocities.
:vartype File: str | Path | StringKey
:ivar RandomVelocitiesMethod: Specifies how are random velocities generated. Three methods are available.
Exact: Velocities are scaled to exactly match set random velocities temperature.
Boltzmann: Velocities are not scaled and sample Maxwell-Boltzmann distribution. However, the distribution is not corrected for constraints.
Gromacs: Velocities are scaled to match set random velocities temperature, but removal of net momentum is performed only after the scaling. Resulting kinetic energy is lower based on how much net momentum the system had.
:vartype RandomVelocitiesMethod: Literal["Exact", "Boltzmann", "Gromacs"]
:ivar Temperature: Sets the temperature for the Maxwell-Boltzmann distribution when the type of the initial velocities is set to random, in which case specifying this key is mandatory.
AMSinput will use the first temperature of the first thermostat as default.
:vartype Temperature: float | FloatKey
:ivar Type: Specifies the initial velocities to assign to the atoms. Three methods to assign velocities are available.
Zero: All atom are at rest at the beginning of the calculation.
Random: Initial atom velocities follow a Maxwell-Boltzmann distribution for the temperature given by the [MolecularDynamics%InitialVelocities%Temperature] keyword.
FromFile: Load the velocities from a previous ams result file.
Input: Atom's velocities are set to the values specified in the [MolecularDynamics%InitialVelocities%Values] block, which can be accessed via the Expert AMS panel in AMSinput.
:vartype Type: Literal["Zero", "Random", "FromFile", "Input"]
:ivar Values: This block specifies the velocity of each atom, in Angstrom/fs, when [MolecularDynamics%InitialVelocities%Type] is set to Input. Each row must contain three floating point values (corresponding to the x,y,z component of the velocity vector) and a number of rows equal to the number of atoms must be present, given in the same order as the [System%Atoms] block.
:vartype Values: str | Sequence[str] | FreeBlock
"""
[docs] class _Values(FreeBlock):
r"""
This block specifies the velocity of each atom, in Angstrom/fs, when [MolecularDynamics%InitialVelocities%Type] is set to Input. Each row must contain three floating point values (corresponding to the x,y,z component of the velocity vector) and a number of rows equal to the number of atoms must be present, given in the same order as the [System%Atoms] block.
"""
def __post_init__(self):
pass
def __post_init__(self):
self.File: str | Path | StringKey = PathStringKey(name='File', comment='AMS RKF file containing the initial velocities.', ispath=True, gui_type='{} {{{AMS result file} .rkf}}')
self.RandomVelocitiesMethod: Literal["Exact", "Boltzmann", "Gromacs"] = MultipleChoiceKey(name='RandomVelocitiesMethod', comment='Specifies how are random velocities generated. Three methods are available.\n\nExact: Velocities are scaled to exactly match set random velocities temperature. \n\nBoltzmann: Velocities are not scaled and sample Maxwell-Boltzmann distribution. However, the distribution is not corrected for constraints.\n\nGromacs: Velocities are scaled to match set random velocities temperature, but removal of net momentum is performed only after the scaling. Resulting kinetic energy is lower based on how much net momentum the system had.', gui_name='Velocity randomization method:', default='Exact', choices=['Exact', 'Boltzmann', 'Gromacs'])
self.Temperature: float | FloatKey = FloatKey(name='Temperature', comment='Sets the temperature for the Maxwell-Boltzmann distribution when the type of the initial velocities is set to random, in which case specifying this key is mandatory.\n\nAMSinput will use the first temperature of the first thermostat as default.', gui_name='Initial temperature:', unit='Kelvin')
self.Type: Literal["Zero", "Random", "FromFile", "Input"] = MultipleChoiceKey(name='Type', comment="Specifies the initial velocities to assign to the atoms. Three methods to assign velocities are available.\n\nZero: All atom are at rest at the beginning of the calculation.\n\nRandom: Initial atom velocities follow a Maxwell-Boltzmann distribution for the temperature given by the [MolecularDynamics%InitialVelocities%Temperature] keyword.\n\nFromFile: Load the velocities from a previous ams result file.\n\nInput: Atom's velocities are set to the values specified in the [MolecularDynamics%InitialVelocities%Values] block, which can be accessed via the Expert AMS panel in AMSinput.", gui_name='Initial velocities:', default='Random', choices=['Zero', 'Random', 'FromFile', 'Input'])
self.Values: str | Sequence[str] | FreeBlock = self._Values(name='Values', comment='This block specifies the velocity of each atom, in Angstrom/fs, when [MolecularDynamics%InitialVelocities%Type] is set to Input. Each row must contain three floating point values (corresponding to the x,y,z component of the velocity vector) and a number of rows equal to the number of atoms must be present, given in the same order as the [System%Atoms] block.')
[docs] class _MovingRestraints(FixedBlock):
r"""
Define a set of moving restraints.
:ivar Change: Type of function defining how the target restraint value will change over time:
Linear - linearly between the StartValue and EndValue.
Sine - oscillating around StartValue with an amplitude equal to the difference between EndValue and StartValue.
Cosine - oscillating between StartValue and EndValue.
:vartype Change: Literal["Linear", "Sine", "Cosine"]
:ivar Name: Optional name to be used for plotting.
:vartype Name: str | StringKey
:ivar Period: Period of oscillation for Sine and Cosine change types.
:vartype Period: float | FloatKey
:ivar RestraintType: Select type of the moving restraint profile. The force for Hyperbolic and Erf is bounded by a user-defined value, the latter converging to it faster than the former. The GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.
:vartype RestraintType: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"]
:ivar StartStep: First step number at which the restraints will be applied.
:vartype StartStep: int | IntKey
:ivar StopStep: Last step number at which the restraints will be applied.
:vartype StopStep: int | IntKey
:ivar Distance: Define a distance restraint between pair of atoms. For linear-type
:vartype Distance: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Distance
:ivar Erf: Define parameters for the Int(erf) restraint potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:vartype Erf: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Erf
:ivar GaussianWell: Define parameters in the Gaussian well restraint potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:vartype GaussianWell: SimpleActiveLearning._MolecularDynamics._MovingRestraints._GaussianWell
:ivar Harmonic: Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:vartype Harmonic: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Harmonic
:ivar Hyperbolic: Define parameters for the hyperbolic restraint potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:vartype Hyperbolic: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Hyperbolic
"""
[docs] class _Distance(FixedBlock):
r"""
Define a distance restraint between pair of atoms. For linear-type
:ivar Atom1: First atom of the distance restraint.
:vartype Atom1: int | IntKey
:ivar Atom2: Second atom of the distance restraint.
:vartype Atom2: int | IntKey
:ivar EndValue: Linear: final target distance.
Sine: target distance at 1/4 of the period.
Cosine: target distance at 1/2 of the period.
:vartype EndValue: float | FloatKey
:ivar StartValue: Initial target distance.
:vartype StartValue: float | FloatKey
"""
def __post_init__(self):
self.Atom1: int | IntKey = IntKey(name='Atom1', comment='First atom of the distance restraint.')
self.Atom2: int | IntKey = IntKey(name='Atom2', comment='Second atom of the distance restraint.')
self.EndValue: float | FloatKey = FloatKey(name='EndValue', comment='Linear: final target distance.\nSine: target distance at 1/4 of the period.\nCosine: target distance at 1/2 of the period.', unit='Angstrom')
self.StartValue: float | FloatKey = FloatKey(name='StartValue', comment='Initial target distance.', unit='Angstrom')
[docs] class _Erf(FixedBlock):
r"""
Define parameters for the Int(erf) restraint potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', gui_name='Erf force constant:', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', gui_name='Erf F(Inf):', default=0.05, unit='Hartree/Bohr')
[docs] class _GaussianWell(FixedBlock):
r"""
Define parameters in the Gaussian well restraint potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:ivar Sigma: Sigma parameter in the potential expression.
:vartype Sigma: float | FloatKey
:ivar WellDepth: WellDepth parameter in the potential expression.
:vartype WellDepth: float | FloatKey
"""
def __post_init__(self):
self.Sigma: float | FloatKey = FloatKey(name='Sigma', comment='Sigma parameter in the potential expression.', gui_name='Gaussian well sigma:', default=1.0, unit='1/Bohr^2')
self.WellDepth: float | FloatKey = FloatKey(name='WellDepth', comment='WellDepth parameter in the potential expression.', gui_name='Gaussian well depth:', default=1.0, unit='Hartree')
[docs] class _Harmonic(FixedBlock):
r"""
Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:ivar ForceConstant: The FC parameter of the harmonic potential.
:vartype ForceConstant: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The FC parameter of the harmonic potential.', gui_name='Harmonic force constant:', default=0.5, unit='Hartree/Bohr^2')
[docs] class _Hyperbolic(FixedBlock):
r"""
Define parameters for the hyperbolic restraint potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', gui_name='Hyperbolic force constant:', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', gui_name='Hyperbolic F(Inf):', default=0.05, unit='Hartree/Bohr')
def __post_init__(self):
self.Change: Literal["Linear", "Sine", "Cosine"] = MultipleChoiceKey(name='Change', comment='Type of function defining how the target restraint value will change over time:\n\nLinear - linearly between the StartValue and EndValue.\nSine - oscillating around StartValue with an amplitude equal to the difference between EndValue and StartValue.\nCosine - oscillating between StartValue and EndValue.', gui_name='Move type:', default='Linear', choices=['Linear', 'Sine', 'Cosine'])
self.Name: str | StringKey = StringKey(name='Name', comment='Optional name to be used for plotting.', gui_name='Name:')
self.Period: float | FloatKey = FloatKey(name='Period', comment='Period of oscillation for Sine and Cosine change types.', default=0.0, unit='Femtoseconds')
self.RestraintType: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"] = MultipleChoiceKey(name='RestraintType', comment='Select type of the moving restraint profile. The force for Hyperbolic and Erf is bounded by a user-defined value, the latter converging to it faster than the former. The GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.', gui_name='Restraint type:', default='None', choices=['None', 'Harmonic', 'Hyperbolic', 'Erf', 'GaussianWell'])
self.StartStep: int | IntKey = IntKey(name='StartStep', comment='First step number at which the restraints will be applied.', gui_name='Start step:', default=1)
self.StopStep: int | IntKey = IntKey(name='StopStep', comment='Last step number at which the restraints will be applied.', gui_name='End step:', default=0)
self.Distance: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Distance = self._Distance(name='Distance', comment='Define a distance restraint between pair of atoms. For linear-type ', unique=False)
self.Erf: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Erf = self._Erf(name='Erf', comment='Define parameters for the Int(erf) restraint potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.')
self.GaussianWell: SimpleActiveLearning._MolecularDynamics._MovingRestraints._GaussianWell = self._GaussianWell(name='GaussianWell', comment='Define parameters in the Gaussian well restraint potential V=-WellDepth*exp(-Sigma*(r-r0)^2).')
self.Harmonic: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Harmonic = self._Harmonic(name='Harmonic', comment='Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.')
self.Hyperbolic: SimpleActiveLearning._MolecularDynamics._MovingRestraints._Hyperbolic = self._Hyperbolic(name='Hyperbolic', comment='Define parameters for the hyperbolic restraint potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta')
[docs] class _PRD(FixedBlock):
r"""
This block is used for Parallel Replica Dynamics simulations.
:ivar CorrelatedSteps: How many steps to wait for correlated events after detecting an initial event.
:vartype CorrelatedSteps: int | IntKey
:ivar DephasingSteps: Spend this many steps dephasing the individual replicas after an event.
:vartype DephasingSteps: int | IntKey
:ivar nReplicas: Number of replicas to run in parallel.
:vartype nReplicas: int | IntKey
:ivar BondChange: Detect changes to the bonding topology and bond orders returned by the engine.
:vartype BondChange: SimpleActiveLearning._MolecularDynamics._PRD._BondChange
:ivar MolCount: Detect changes to the molecular composition of the system.
:vartype MolCount: SimpleActiveLearning._MolecularDynamics._PRD._MolCount
"""
[docs] class _BondChange(FixedBlock):
r"""
Detect changes to the bonding topology and bond orders returned by the engine.
:ivar ChangeThreshold: Trigger an event when the bond order of a bond changes from the reference state by more than this value.
:vartype ChangeThreshold: float | FloatKey
:ivar DissociationThreshold: Trigger an event when a bond dissociates (its bond order drops below this value while it was above FormationThreshold in the reference state).
:vartype DissociationThreshold: float | FloatKey
:ivar FormationThreshold: Trigger an event when a new bond forms (its bond order exceeds this value while it was below DissociationThreshold in the reference state).
:vartype FormationThreshold: float | FloatKey
"""
def __post_init__(self):
self.ChangeThreshold: float | FloatKey = FloatKey(name='ChangeThreshold', comment='Trigger an event when the bond order of a bond changes from the reference state by more than this value.', default=0.5)
self.DissociationThreshold: float | FloatKey = FloatKey(name='DissociationThreshold', comment='Trigger an event when a bond dissociates (its bond order drops below this value while it was above FormationThreshold in the reference state).', default=0.3)
self.FormationThreshold: float | FloatKey = FloatKey(name='FormationThreshold', comment='Trigger an event when a new bond forms (its bond order exceeds this value while it was below DissociationThreshold in the reference state).', default=0.8)
[docs] class _MolCount(FixedBlock):
r"""
Detect changes to the molecular composition of the system.
"""
def __post_init__(self):
pass
def __post_init__(self):
self.CorrelatedSteps: int | IntKey = IntKey(name='CorrelatedSteps', comment='How many steps to wait for correlated events after detecting an initial event.', default=100)
self.DephasingSteps: int | IntKey = IntKey(name='DephasingSteps', comment='Spend this many steps dephasing the individual replicas after an event.', default=100)
self.nReplicas: int | IntKey = IntKey(name='nReplicas', comment='Number of replicas to run in parallel.', gui_name='Number of replicas:', default=1)
self.BondChange: SimpleActiveLearning._MolecularDynamics._PRD._BondChange = self._BondChange(name='BondChange', comment='Detect changes to the bonding topology and bond orders returned by the engine.', unique=False, gui_name='Bond Change')
self.MolCount: SimpleActiveLearning._MolecularDynamics._PRD._MolCount = self._MolCount(name='MolCount', comment='Detect changes to the molecular composition of the system.', unique=False)
[docs] class _Plumed(FixedBlock):
r"""
Input for PLUMED (version 2.5.0). The parallel option is still experimental.
:ivar Input: Input for PLUMED. Contents of this block is passed to PLUMED as is.
:vartype Input: str | Sequence[str] | FreeBlock
:ivar Parallel: Options for double parallelization, which allows to split the available processor cores into groups working through all the available tasks in parallel, resulting in a better parallel performance. The keys in this block determine how to split the available processor cores into groups working in parallel.
:vartype Parallel: SimpleActiveLearning._MolecularDynamics._Plumed._Parallel
"""
[docs] class _Parallel(FixedBlock):
r"""
Options for double parallelization, which allows to split the available processor cores into groups working through all the available tasks in parallel, resulting in a better parallel performance. The keys in this block determine how to split the available processor cores into groups working in parallel.
:ivar nCoresPerGroup: Number of cores in each working group.
:vartype nCoresPerGroup: int | IntKey
:ivar nGroups: Total number of processor groups. This is the number of tasks that will be executed in parallel.
:vartype nGroups: int | IntKey
:ivar nNodesPerGroup: Number of nodes in each group. This option should only be used on homogeneous compute clusters, where all used compute nodes have the same number of processor cores.
:vartype nNodesPerGroup: int | IntKey
"""
def __post_init__(self):
self.nCoresPerGroup: int | IntKey = IntKey(name='nCoresPerGroup', comment='Number of cores in each working group.', gui_name='Cores per group:')
self.nGroups: int | IntKey = IntKey(name='nGroups', comment='Total number of processor groups. This is the number of tasks that will be executed in parallel.', gui_name='Number of groups:')
self.nNodesPerGroup: int | IntKey = IntKey(name='nNodesPerGroup', comment='Number of nodes in each group. This option should only be used on homogeneous compute clusters, where all used compute nodes have the same number of processor cores.', gui_name='Nodes per group:')
def __post_init__(self):
self.Input: str | Sequence[str] | FreeBlock = self._Input(name='Input', comment='Input for PLUMED. Contents of this block is passed to PLUMED as is.')
self.Parallel: SimpleActiveLearning._MolecularDynamics._Plumed._Parallel = self._Parallel(name='Parallel', comment='Options for double parallelization, which allows to split the available processor cores into groups working through all the available tasks in parallel, resulting in a better parallel performance. The keys in this block determine how to split the available processor cores into groups working in parallel.', extra_info='not_in_fragment', shared_id='AMSParallel')
[docs] class _Preserve(FixedBlock):
r"""
Periodically remove numerical drift accumulated during the simulation to preserve different whole-system parameters.
:ivar AngularMomentum: Remove overall angular momentum of the system. This option is ignored for 2D and 3D-periodic systems, and disabled by default for systems which are not translationally invariant (for example when frozen atoms are present).
:vartype AngularMomentum: BoolType | BoolKey
:ivar CenterOfMass: Translate the system to keep its center of mass at the coordinate origin. This option is not very useful for 3D-periodic systems.
:vartype CenterOfMass: BoolType | BoolKey
:ivar Momentum: Remove overall (linear) momentum of the system. This is disabled by default for systems which are not translationally invariant (for example when frozen atoms are present).
:vartype Momentum: BoolType | BoolKey
"""
def __post_init__(self):
self.AngularMomentum: BoolType | BoolKey = BoolKey(name='AngularMomentum', comment='Remove overall angular momentum of the system. This option is ignored for 2D and 3D-periodic systems, and disabled by default for systems which are not translationally invariant (for example when frozen atoms are present).', gui_name=': Angular momentum', default=True)
self.CenterOfMass: BoolType | BoolKey = BoolKey(name='CenterOfMass', comment='Translate the system to keep its center of mass at the coordinate origin. This option is not very useful for 3D-periodic systems.', gui_name=': Center of mass', default=False)
self.Momentum: BoolType | BoolKey = BoolKey(name='Momentum', comment='Remove overall (linear) momentum of the system. This is disabled by default for systems which are not translationally invariant (for example when frozen atoms are present).', gui_name='Preserve: Total momentum', default=True)
[docs] class _Print(FixedBlock):
r"""
This block controls the printing of additional information to stdout.
:ivar System: Print the chemical system before and after the simulation.
:vartype System: BoolType | BoolKey
:ivar Velocities: Print the atomic velocities before and after the simulation.
:vartype Velocities: BoolType | BoolKey
"""
def __post_init__(self):
self.System: BoolType | BoolKey = BoolKey(name='System', comment='Print the chemical system before and after the simulation.', default=False)
self.Velocities: BoolType | BoolKey = BoolKey(name='Velocities', comment='Print the atomic velocities before and after the simulation.', default=False)
[docs] class _ReactionBoost(FixedBlock):
r"""
Define a series of transitions between different states of the system.
Each transition is defined by a TargetSystem and by a set of restraints that force the transition.
:ivar Change: Select what to change during dynamics.
By default, once the restraints are switched on, AMS will change the restraint's target coordinate towards its final value.
If the [Force] or [LogForce] option is selected then the target coordinate is set to its final value immediately and instead the restraint force is gradually scaled from 0 to 1. The scaling is either linear (Force) or logarithmic (LogForce).
:vartype Change: Literal["TargetCoordinate", "Force", "LogForce"]
:ivar InitialFraction: Initial fraction of the boost variable.
At the first boosting step, the restraint's target value (or force or log(force)) is equal to InitialFraction + 1/NSteps.
:vartype InitialFraction: float | FloatKey
:ivar InterEquilibrationSteps: Number of equilibration steps after reaching a target before setting up restraints for the next one.
:vartype InterEquilibrationSteps: int | IntKey
:ivar MinBondChange: Minimal change in the distance for an individual restraint to be considered bond-breaking/making vs bonded.
:vartype MinBondChange: float | FloatKey
:ivar MinBondStrength: Minimum strength (usually ranges from 0 to 1) for a bond to be considered.
:vartype MinBondStrength: float | FloatKey
:ivar NSteps: Number of steps per target the restraints should be active for.
:vartype NSteps: int | IntKey
:ivar PreEquilibrationSteps: Number of steps before enabling the first set of restraints.
:vartype PreEquilibrationSteps: int | IntKey
:ivar Region: Region to which the restraints should be limited.
:vartype Region: str | StringKey
:ivar TargetSystem: The target system's name for this transition. Multiple targets can be specified to request multiple transitions in one simulation.
Note that only the lattice and the atomic coordinates of the target system are used and other properties (bonds, charge, etc.) are ignored. The target system's lattice is used only to determine connections and it cannot be restrained.
:vartype TargetSystem: str | StringKey
:ivar Type: Reaction Boost uses a series of transitions between different states of the system.
Each transition is defined by a TargetSystem and by a set of restraints that force the transition.
Select the type of the restraint set:
-None: no Reaction Boost
- Pair: use pair restraints
- RMSD: use RMSD restraints.
Pair restraints are defined per atom pair while the RMSD defines one collective restraint for all atoms and is thus suitable for very large systems.
The pair restraints are further divided into four sub-types: bonding, non-bonding, bond-breaking and bond-making. The sub-type of restraints for each pair is determined automatically depending on whether the two atoms are bonded in the initial/final state.
Parameters of the pair restraints are defined by [NonBondedRestraints], [BondedRestraints], [BondBreakingRestraints] and [BondMakingRestraints] blocks, while those of the RMSD restraint by the [RMSDRestraint] block.
:vartype Type: Literal["None", "Pair", "RMSD"]
:ivar BondBreakingRestraints: Define parameters for moving restraints that are added for pairs of atoms that become disconnected during the transition.
It is intended to make sure the corresponding bonds get broken, although this may not always be required because forming other bonds will likely get these bonds broken.
:vartype BondBreakingRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints
:ivar BondMakingRestraints: Define parameters for moving restraints that are added for pairs of atoms that become connected during the transition.
It is intended to make sure the bonds are created as required.
:vartype BondMakingRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints
:ivar BondedRestraints: Define parameters for bonded restraints. A bonded restraint is added for each pair of atoms that are bonded both in the current and in the final state.
It is intended to make sure they remain bonded during simulation.
:vartype BondedRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondedRestraints
:ivar NonBondedRestraints: Define parameters for non-bonded restraints. A non-bonded restraint is added for each pair of atoms that are bonded neither in the current nor in the final state.
It is intended to keep them from forming a bond unintentionally. They are represented by a repulsive potential
:vartype NonBondedRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._NonBondedRestraints
:ivar RMSDRestraint: Define a static restraint that pulls each atom to its position in the target system, but in contrast to the individual restraints, the force for this one depends on the total mass-weighted root-mean-squared distance (RMSD) between the two structures.
:vartype RMSDRestraint: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint
"""
[docs] class _BondBreakingRestraints(FixedBlock):
r"""
Define parameters for moving restraints that are added for pairs of atoms that become disconnected during the transition.
It is intended to make sure the corresponding bonds get broken, although this may not always be required because forming other bonds will likely get these bonds broken.
:ivar Type: Select type of the moving restraint profile.
Harmonic: V=0.5*FC*(r-r0)^2
Hyperbolic: V=alpha*(sqrt(1 + beta*x^2) - 1)
Erf: V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI))
GaussianWell: V=WellDepth*(1-exp(-Sigma*(r-r0)^2))
Here beta=ForceConstant/MaxForce, alpha=MaxForce/beta.
The force for Hyperbolic and Erf is bounded by a user-defined value, the latter converging to it faster than the former.
The GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.
Moving restraints are added for pairs of atoms that become disconnected during the transition.
It is intended to make sure the corresponding bonds get broken, although this may not always be required because forming other bonds will likely get these bonds broken.
:vartype Type: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"]
:ivar Erf: Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:vartype Erf: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Erf
:ivar GaussianWell: Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:vartype GaussianWell: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._GaussianWell
:ivar Harmonic: Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:vartype Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Harmonic
:ivar Hyperbolic: Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:vartype Hyperbolic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Hyperbolic
:ivar Taper:
:vartype Taper: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Taper
"""
[docs] class _Erf(FixedBlock):
r"""
Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', default=0.05, unit='Hartree/Bohr')
[docs] class _GaussianWell(FixedBlock):
r"""
Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:ivar Sigma: Sigma parameter in the potential expression.
:vartype Sigma: float | FloatKey
:ivar WellDepth: WellDepth parameter in the potential expression.
:vartype WellDepth: float | FloatKey
"""
def __post_init__(self):
self.Sigma: float | FloatKey = FloatKey(name='Sigma', comment='Sigma parameter in the potential expression.', default=1.0, unit='1/Bohr^2')
self.WellDepth: float | FloatKey = FloatKey(name='WellDepth', comment='WellDepth parameter in the potential expression.', default=1.0, unit='Hartree')
[docs] class _Harmonic(FixedBlock):
r"""
Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:ivar ForceConstant: The FC parameter of the harmonic potential.
:vartype ForceConstant: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The FC parameter of the harmonic potential.', default=0.5, unit='Hartree/Bohr^2')
[docs] class _Hyperbolic(FixedBlock):
r"""
Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', default=0.05, unit='Hartree/Bohr')
[docs] class _Taper(FixedBlock):
r"""
:ivar Enabled: Enable tapering of the restraint potential and force between the given range of bond distances. A 7-th order tapering function on the actual (not target!) distance will be used. The MaxDistance must be greater than MinDistance.
:vartype Enabled: BoolType | BoolKey
:ivar MaxDistance: Bond length at which the restraint potential and force decays to zero.
:vartype MaxDistance: float | FloatKey
:ivar MinDistance: Bond length at which the restraint potential and force will start decaying to zero.
:vartype MinDistance: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable tapering of the restraint potential and force between the given range of bond distances. A 7-th order tapering function on the actual (not target!) distance will be used. The MaxDistance must be greater than MinDistance.', gui_name='Tapering:', default=False)
self.MaxDistance: float | FloatKey = FloatKey(name='MaxDistance', comment='Bond length at which the restraint potential and force decays to zero.', gui_name='End tapering at:', default=0.0, unit='Angstrom')
self.MinDistance: float | FloatKey = FloatKey(name='MinDistance', comment='Bond length at which the restraint potential and force will start decaying to zero.', gui_name='Start tapering at:', default=0.0, unit='Angstrom')
def __post_init__(self):
self.Type: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"] = MultipleChoiceKey(name='Type', comment='Select type of the moving restraint profile.\n\nHarmonic: V=0.5*FC*(r-r0)^2\n\nHyperbolic: V=alpha*(sqrt(1 + beta*x^2) - 1)\n\nErf: V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI))\n\nGaussianWell: V=WellDepth*(1-exp(-Sigma*(r-r0)^2))\n\nHere beta=ForceConstant/MaxForce, alpha=MaxForce/beta.\n\nThe force for Hyperbolic and Erf is bounded by a user-defined value, the latter converging to it faster than the former.\nThe GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.\n\nMoving restraints are added for pairs of atoms that become disconnected during the transition.\n\nIt is intended to make sure the corresponding bonds get broken, although this may not always be required because forming other bonds will likely get these bonds broken.', gui_name='Bond breaking restraints:', default='Erf', choices=['None', 'Harmonic', 'Hyperbolic', 'Erf', 'GaussianWell'])
self.Erf: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Erf = self._Erf(name='Erf', comment='Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.')
self.GaussianWell: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._GaussianWell = self._GaussianWell(name='GaussianWell', comment='Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).')
self.Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Harmonic = self._Harmonic(name='Harmonic', comment='Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.')
self.Hyperbolic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Hyperbolic = self._Hyperbolic(name='Hyperbolic', comment='Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta')
self.Taper: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints._Taper = self._Taper(name='Taper')
[docs] class _BondMakingRestraints(FixedBlock):
r"""
Define parameters for moving restraints that are added for pairs of atoms that become connected during the transition.
It is intended to make sure the bonds are created as required.
:ivar Type: Select type of the moving restraint profile.
Harmonic: V=0.5*FC*(r-r0)^2
Hyperbolic: V=alpha*(sqrt(1 + beta*x^2) - 1)
Erf: V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI))
GaussianWell: V=-WellDepth*exp(-Sigma*(r-r0)^2)
Here beta=ForceConstant/MaxForce, alpha=MaxForce/beta.
The force for Hyperbolic and Erf is bounded by a user-defined value.
The GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.
Moving restraints are added for pairs of atoms that become connected during the transition.
It is intended to make sure the bonds are created as required.
:vartype Type: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"]
:ivar Erf: Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:vartype Erf: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._Erf
:ivar GaussianWell: Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:vartype GaussianWell: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._GaussianWell
:ivar Harmonic: Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:vartype Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._Harmonic
:ivar Hyperbolic: Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:vartype Hyperbolic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._Hyperbolic
"""
[docs] class _Erf(FixedBlock):
r"""
Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', default=0.05, unit='Hartree/Bohr')
[docs] class _GaussianWell(FixedBlock):
r"""
Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:ivar Sigma: Sigma parameter in the potential expression.
:vartype Sigma: float | FloatKey
:ivar WellDepth: WellDepth parameter in the potential expression.
:vartype WellDepth: float | FloatKey
"""
def __post_init__(self):
self.Sigma: float | FloatKey = FloatKey(name='Sigma', comment='Sigma parameter in the potential expression.', default=1.0, unit='1/Bohr^2')
self.WellDepth: float | FloatKey = FloatKey(name='WellDepth', comment='WellDepth parameter in the potential expression.', default=1.0, unit='Hartree')
[docs] class _Harmonic(FixedBlock):
r"""
Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:ivar ForceConstant: The FC parameter of the harmonic potential.
:vartype ForceConstant: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The FC parameter of the harmonic potential.', default=0.5, unit='Hartree/Bohr^2')
[docs] class _Hyperbolic(FixedBlock):
r"""
Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', default=0.05, unit='Hartree/Bohr')
def __post_init__(self):
self.Type: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"] = MultipleChoiceKey(name='Type', comment='Select type of the moving restraint profile.\n\nHarmonic: V=0.5*FC*(r-r0)^2\n\nHyperbolic: V=alpha*(sqrt(1 + beta*x^2) - 1)\n\nErf: V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI))\n\nGaussianWell: V=-WellDepth*exp(-Sigma*(r-r0)^2)\n\nHere beta=ForceConstant/MaxForce, alpha=MaxForce/beta.\n\nThe force for Hyperbolic and Erf is bounded by a user-defined value.\nThe GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.\n\nMoving restraints are added for pairs of atoms that become connected during the transition.\n\nIt is intended to make sure the bonds are created as required.', gui_name='Bond making restraints:', default='Erf', choices=['None', 'Harmonic', 'Hyperbolic', 'Erf', 'GaussianWell'])
self.Erf: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._Erf = self._Erf(name='Erf', comment='Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.')
self.GaussianWell: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._GaussianWell = self._GaussianWell(name='GaussianWell', comment='Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).')
self.Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._Harmonic = self._Harmonic(name='Harmonic', comment='Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.')
self.Hyperbolic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints._Hyperbolic = self._Hyperbolic(name='Hyperbolic', comment='Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta')
[docs] class _BondedRestraints(FixedBlock):
r"""
Define parameters for bonded restraints. A bonded restraint is added for each pair of atoms that are bonded both in the current and in the final state.
It is intended to make sure they remain bonded during simulation.
:ivar Type: Select type of the bonded restraints:
Harmonic: V=0.5*FC*(r-r0)^2
A bonded restraint is added for each pair of atoms that are bonded both in the current and in the final state.
It is intended to make sure they remain bonded during simulation.
:vartype Type: Literal["None", "Harmonic"]
:ivar Harmonic: Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:vartype Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondedRestraints._Harmonic
"""
[docs] class _Harmonic(FixedBlock):
r"""
Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:ivar ForceConstant: The FC parameter of the harmonic potential.
:vartype ForceConstant: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The FC parameter of the harmonic potential.', default=0.5, unit='Hartree/Bohr^2')
def __post_init__(self):
self.Type: Literal["None", "Harmonic"] = MultipleChoiceKey(name='Type', comment='Select type of the bonded restraints:\n\nHarmonic: V=0.5*FC*(r-r0)^2\n\nA bonded restraint is added for each pair of atoms that are bonded both in the current and in the final state.\n\nIt is intended to make sure they remain bonded during simulation.', gui_name='Bonded restraints:', default='None', choices=['None', 'Harmonic'])
self.Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondedRestraints._Harmonic = self._Harmonic(name='Harmonic', comment='Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.')
[docs] class _NonBondedRestraints(FixedBlock):
r"""
Define parameters for non-bonded restraints. A non-bonded restraint is added for each pair of atoms that are bonded neither in the current nor in the final state.
It is intended to keep them from forming a bond unintentionally. They are represented by a repulsive potential
:ivar Type: Select type of the non-bonded restraints:
Exponential: V=Epsilon*exp(-Sigma*r)
A non-bonded restraint is added for each pair of atoms that are bonded neither in the current nor in the final state.
It is intended to keep them from forming a bond unintentionally. They are represented by a repulsive potential.
:vartype Type: Literal["None", "Exponential"]
:ivar Exponential: Define parameters for the repulsive potential V=Epsilon*exp(-Sigma*r).
:vartype Exponential: SimpleActiveLearning._MolecularDynamics._ReactionBoost._NonBondedRestraints._Exponential
"""
[docs] class _Exponential(FixedBlock):
r"""
Define parameters for the repulsive potential V=Epsilon*exp(-Sigma*r).
:ivar Epsilon: Epsilon parameter in the repulsive potential expression.
:vartype Epsilon: float | FloatKey
:ivar Sigma: Sigma parameter in the repulsive potential expression.
:vartype Sigma: float | FloatKey
"""
def __post_init__(self):
self.Epsilon: float | FloatKey = FloatKey(name='Epsilon', comment='Epsilon parameter in the repulsive potential expression.', default=1.0, unit='Hartree')
self.Sigma: float | FloatKey = FloatKey(name='Sigma', comment='Sigma parameter in the repulsive potential expression.', default=1.0, unit='1/Bohr')
def __post_init__(self):
self.Type: Literal["None", "Exponential"] = MultipleChoiceKey(name='Type', comment='Select type of the non-bonded restraints:\n\nExponential: V=Epsilon*exp(-Sigma*r)\n\nA non-bonded restraint is added for each pair of atoms that are bonded neither in the current nor in the final state.\n\nIt is intended to keep them from forming a bond unintentionally. They are represented by a repulsive potential.', gui_name='Non-bonded restraints:', default='None', choices=['None', 'Exponential'])
self.Exponential: SimpleActiveLearning._MolecularDynamics._ReactionBoost._NonBondedRestraints._Exponential = self._Exponential(name='Exponential', comment='Define parameters for the repulsive potential V=Epsilon*exp(-Sigma*r).')
[docs] class _RMSDRestraint(FixedBlock):
r"""
Define a static restraint that pulls each atom to its position in the target system, but in contrast to the individual restraints, the force for this one depends on the total mass-weighted root-mean-squared distance (RMSD) between the two structures.
:ivar Type: Select type of the RMSD restraint profile:
Harmonic: V=0.5*FC*(r-r0)^2
Hyperbolic: V=alpha*(sqrt(1 + beta*x^2) - 1)
Erf: V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI),
GaussianWell: V=-WellDepth*exp(-Sigma*(r-r0)^2)
Here beta=ForceConstant/MaxForce, alpha=MaxForce/beta.
The Harmonic profile can be problematic at large deviations as it may result in large forces. The force for Hyperbolic and Erf is bounded by a user-defined value. The GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.
:vartype Type: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"]
:ivar Erf: Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:vartype Erf: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._Erf
:ivar GaussianWell: Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:vartype GaussianWell: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._GaussianWell
:ivar Harmonic: Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:vartype Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._Harmonic
:ivar Hyperbolic: Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:vartype Hyperbolic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._Hyperbolic
"""
[docs] class _Erf(FixedBlock):
r"""
Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', default=0.05, unit='Hartree/Bohr')
[docs] class _GaussianWell(FixedBlock):
r"""
Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).
:ivar Sigma: Sigma parameter in the potential expression.
:vartype Sigma: float | FloatKey
:ivar WellDepth: WellDepth parameter in the potential expression.
:vartype WellDepth: float | FloatKey
"""
def __post_init__(self):
self.Sigma: float | FloatKey = FloatKey(name='Sigma', comment='Sigma parameter in the potential expression.', default=1.0, unit='1/Bohr^2')
self.WellDepth: float | FloatKey = FloatKey(name='WellDepth', comment='WellDepth parameter in the potential expression.', default=1.0, unit='Hartree')
[docs] class _Harmonic(FixedBlock):
r"""
Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.
:ivar ForceConstant: The FC parameter of the harmonic potential.
:vartype ForceConstant: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The FC parameter of the harmonic potential.', default=0.5, unit='Hartree/Bohr^2')
[docs] class _Hyperbolic(FixedBlock):
r"""
Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta
:ivar ForceConstant: The force constant (second derivative of the potential) at the optimum point.
:vartype ForceConstant: float | FloatKey
:ivar MaxForce: Asymptotic value of the force at the infinity.
:vartype MaxForce: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='The force constant (second derivative of the potential) at the optimum point.', default=0.5, unit='Hartree/Bohr^2')
self.MaxForce: float | FloatKey = FloatKey(name='MaxForce', comment='Asymptotic value of the force at the infinity.', default=0.05, unit='Hartree/Bohr')
def __post_init__(self):
self.Type: Literal["None", "Harmonic", "Hyperbolic", "Erf", "GaussianWell"] = MultipleChoiceKey(name='Type', comment='Select type of the RMSD restraint profile:\n\nHarmonic: V=0.5*FC*(r-r0)^2\n\nHyperbolic: V=alpha*(sqrt(1 + beta*x^2) - 1)\n\nErf: V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI),\n\nGaussianWell: V=-WellDepth*exp(-Sigma*(r-r0)^2)\n\nHere beta=ForceConstant/MaxForce, alpha=MaxForce/beta.\n\nThe Harmonic profile can be problematic at large deviations as it may result in large forces. The force for Hyperbolic and Erf is bounded by a user-defined value. The GaussianWell has a finite depth so it is suitable for cases when crossing a high reaction barrier is not desirable.', gui_name='Type:', default='None', choices=['None', 'Harmonic', 'Hyperbolic', 'Erf', 'GaussianWell'])
self.Erf: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._Erf = self._Erf(name='Erf', comment='Define parameters for the Int(erf) potential V = alpha*(beta*x*erf(beta*x) + (exp(-(beta*x)**2) - 1)/sqrt(PI)). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce.')
self.GaussianWell: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._GaussianWell = self._GaussianWell(name='GaussianWell', comment='Define parameters in the Gaussian well potential V=-WellDepth*exp(-Sigma*(r-r0)^2).')
self.Harmonic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._Harmonic = self._Harmonic(name='Harmonic', comment='Define parameters for the harmonic potential V=0.5*FC*(r-r0)^2.')
self.Hyperbolic: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint._Hyperbolic = self._Hyperbolic(name='Hyperbolic', comment='Define parameters for the hyperbolic potential V=alpha*(sqrt(1 + beta*x^2) - 1). The alpha and beta parameters are computed from the user-defined ForceConstant and MaxForce: beta=ForceConstant/MaxForce, alpha=MaxForce/beta')
def __post_init__(self):
self.Change: Literal["TargetCoordinate", "Force", "LogForce"] = MultipleChoiceKey(name='Change', comment="Select what to change during dynamics.\n\nBy default, once the restraints are switched on, AMS will change the restraint's target coordinate towards its final value.\n\nIf the [Force] or [LogForce] option is selected then the target coordinate is set to its final value immediately and instead the restraint force is gradually scaled from 0 to 1. The scaling is either linear (Force) or logarithmic (LogForce).", gui_name='Move type:', default='TargetCoordinate', choices=['TargetCoordinate', 'Force', 'LogForce'])
self.InitialFraction: float | FloatKey = FloatKey(name='InitialFraction', comment="Initial fraction of the boost variable.\n\nAt the first boosting step, the restraint's target value (or force or log(force)) is equal to InitialFraction + 1/NSteps.", default=0.0)
self.InterEquilibrationSteps: int | IntKey = IntKey(name='InterEquilibrationSteps', comment='Number of equilibration steps after reaching a target before setting up restraints for the next one.', default=0)
self.MinBondChange: float | FloatKey = FloatKey(name='MinBondChange', comment='Minimal change in the distance for an individual restraint to be considered bond-breaking/making vs bonded.', default=1.0, unit='Bohr')
self.MinBondStrength: float | FloatKey = FloatKey(name='MinBondStrength', comment='Minimum strength (usually ranges from 0 to 1) for a bond to be considered.', default=0.5)
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='Number of steps per target the restraints should be active for.', gui_name='Steps per target:', default=500)
self.PreEquilibrationSteps: int | IntKey = IntKey(name='PreEquilibrationSteps', comment='Number of steps before enabling the first set of restraints.', default=0)
self.Region: str | StringKey = StringKey(name='Region', comment='Region to which the restraints should be limited.', gui_name='Region:', default='*', gui_type='region')
self.TargetSystem: str | StringKey = StringKey(name='TargetSystem', comment="The target system's name for this transition. Multiple targets can be specified to request multiple transitions in one simulation.\n\nNote that only the lattice and the atomic coordinates of the target system are used and other properties (bonds, charge, etc.) are ignored. The target system's lattice is used only to determine connections and it cannot be restrained.", unique=False, gui_name='Target system:', gui_type='molecule')
self.Type: Literal["None", "Pair", "RMSD"] = MultipleChoiceKey(name='Type', comment='Reaction Boost uses a series of transitions between different states of the system.\nEach transition is defined by a TargetSystem and by a set of restraints that force the transition.\n\nSelect the type of the restraint set:\n-None: no Reaction Boost\n- Pair: use pair restraints\n- RMSD: use RMSD restraints.\n\nPair restraints are defined per atom pair while the RMSD defines one collective restraint for all atoms and is thus suitable for very large systems.\n\nThe pair restraints are further divided into four sub-types: bonding, non-bonding, bond-breaking and bond-making. The sub-type of restraints for each pair is determined automatically depending on whether the two atoms are bonded in the initial/final state.\n\nParameters of the pair restraints are defined by [NonBondedRestraints], [BondedRestraints], [BondBreakingRestraints] and [BondMakingRestraints] blocks, while those of the RMSD restraint by the [RMSDRestraint] block.', gui_name='Restraint set type:', default='None', choices=['None', 'Pair', 'RMSD'])
self.BondBreakingRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondBreakingRestraints = self._BondBreakingRestraints(name='BondBreakingRestraints', comment='Define parameters for moving restraints that are added for pairs of atoms that become disconnected during the transition.\n\nIt is intended to make sure the corresponding bonds get broken, although this may not always be required because forming other bonds will likely get these bonds broken.')
self.BondMakingRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondMakingRestraints = self._BondMakingRestraints(name='BondMakingRestraints', comment='Define parameters for moving restraints that are added for pairs of atoms that become connected during the transition.\n\nIt is intended to make sure the bonds are created as required.')
self.BondedRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._BondedRestraints = self._BondedRestraints(name='BondedRestraints', comment='Define parameters for bonded restraints. A bonded restraint is added for each pair of atoms that are bonded both in the current and in the final state.\n\nIt is intended to make sure they remain bonded during simulation.')
self.NonBondedRestraints: SimpleActiveLearning._MolecularDynamics._ReactionBoost._NonBondedRestraints = self._NonBondedRestraints(name='NonBondedRestraints', comment='Define parameters for non-bonded restraints. A non-bonded restraint is added for each pair of atoms that are bonded neither in the current nor in the final state.\n\nIt is intended to keep them from forming a bond unintentionally. They are represented by a repulsive potential')
self.RMSDRestraint: SimpleActiveLearning._MolecularDynamics._ReactionBoost._RMSDRestraint = self._RMSDRestraint(name='RMSDRestraint', comment='Define a static restraint that pulls each atom to its position in the target system, but in contrast to the individual restraints, the force for this one depends on the total mass-weighted root-mean-squared distance (RMSD) between the two structures.', gui_name='RMSD restraint:')
[docs] class _Reactor(FixedBlock):
r"""
Define one phase of the nanoreactor. A reactor is a region of space surrounded by an elastic wall. Atoms inside the region are not affected. Atoms outside it will be pushed back with force depending on the [ForceConstant] and the [MassScaled] flag.
:ivar ForceConstant: Force constant of the reactor wall in Hartree/Bohr^2 (or Hartree/Bohr^2/Dalton if [MassScaled] is true).
:vartype ForceConstant: float | FloatKey
:ivar MassScaled: If this flag is disabled the force on an atom outside of the reactor depends only on the atomic coordinates and the force constant. Otherwise, the force is also multiplied by the mass of the atom. This means that atoms at the same distance from the wall will receive the same accelerate due to the wall potential.
:vartype MassScaled: BoolType | BoolKey
:ivar NSteps: Number of steps for which the reactor will remain active until disabled. The next reactor will be activated immediately after this. After the last reactor is disabled the cycle will repeat.
:vartype NSteps: int | IntKey
:ivar Radius: Radius of the reactor sphere.
:vartype Radius: float | FloatKey
"""
def __post_init__(self):
self.ForceConstant: float | FloatKey = FloatKey(name='ForceConstant', comment='Force constant of the reactor wall in Hartree/Bohr^2 (or Hartree/Bohr^2/Dalton if [MassScaled] is true).', gui_name='Reactor force constant:')
self.MassScaled: BoolType | BoolKey = BoolKey(name='MassScaled', comment='If this flag is disabled the force on an atom outside of the reactor depends only on the atomic coordinates and the force constant. Otherwise, the force is also multiplied by the mass of the atom. This means that atoms at the same distance from the wall will receive the same accelerate due to the wall potential. ', gui_name='Scale force by mass:', default=True)
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='Number of steps for which the reactor will remain active until disabled. The next reactor will be activated immediately after this. After the last reactor is disabled the cycle will repeat.', gui_name='Reactor lifetime:')
self.Radius: float | FloatKey = FloatKey(name='Radius', comment='Radius of the reactor sphere.', gui_name='Reactor radius:', unit='Angstrom')
[docs] class _ReflectiveWall(FixedBlock):
r"""
Apply a reflective wall in space
:ivar Axis: Defines the normal vector perpendicular to the plane of the reflective wall. Any particle moving in this direction will be reflected back.
:vartype Axis: Iterable[float] | FloatListKey
:ivar Direction: Defines the direction of the reflective wall. under will keep the particles under the defined wall, and above will keep the particles above the defined wall
:vartype Direction: Literal["under", "above"]
:ivar Region: Apply the reflective wall to all atoms in this region.
:vartype Region: str | StringKey
:ivar Threshold: Defines the threshold value determining the position of the reflective wall. If the dot product of a position of a particle with Axis exceeds Threshold, the particle will be reflected. This means that the plane of the wall passes through a point given by Axis times Threshold.
:vartype Threshold: float | FloatKey
"""
def __post_init__(self):
self.Axis: Iterable[float] | FloatListKey = FloatListKey(name='Axis', comment='Defines the normal vector perpendicular to the plane of the reflective wall. Any particle moving in this direction will be reflected back.', unit='Angstrom', gui_type='nfloat 3')
self.Direction: Literal["under", "above"] = MultipleChoiceKey(name='Direction', comment='Defines the direction of the reflective wall. under will keep the particles under the defined wall, and above will keep the particles above the defined wall', hidden=True, default='under', choices=['under', 'above'])
self.Region: str | StringKey = StringKey(name='Region', comment='Apply the reflective wall to all atoms in this region.', unique=False, gui_type='region')
self.Threshold: float | FloatKey = FloatKey(name='Threshold', comment='Defines the threshold value determining the position of the reflective wall. If the dot product of a position of a particle with Axis exceeds Threshold, the particle will be reflected. This means that the plane of the wall passes through a point given by Axis times Threshold.', unit='Angstrom')
[docs] class _Remap(FixedBlock):
r"""
Control periodic remapping (backtranslation) of atoms into the PBC box.
:ivar Range: Select the range of fractional coordinates to which atoms are remapped.
Auto: Use PlusMinusHalf if the geometrical center of the starting positions of all atoms lies between -0.25 and 0.25 in fractional coordinates in all periodic directions, ZeroToOne otherwise.
PlusMinusHalf: Remap atoms to lie between -0.5 and 0.5 in fractional coordinates.
ZeroToOne: Remap atoms to lie between 0 and 1 in fractional coordinates.
AroundCenter: Remap atoms to lie within 0.5 in fractional coordinates around the geometrical center of the starting positions of all atoms.
:vartype Range: Literal["Auto", "ZeroToOne", "PlusMinusHalf", "AroundCenter"]
:ivar Type: Select the method used to remap atoms into the unit cell.
None: Disable remapping completely.
Atoms: Remap any atoms that leave the unit cell.
:vartype Type: Literal["None", "Atoms"]
"""
def __post_init__(self):
self.Range: Literal["Auto", "ZeroToOne", "PlusMinusHalf", "AroundCenter"] = MultipleChoiceKey(name='Range', comment='Select the range of fractional coordinates to which atoms are remapped.\n\nAuto: Use PlusMinusHalf if the geometrical center of the starting positions of all atoms lies between -0.25 and 0.25 in fractional coordinates in all periodic directions, ZeroToOne otherwise.\n\nPlusMinusHalf: Remap atoms to lie between -0.5 and 0.5 in fractional coordinates.\n\nZeroToOne: Remap atoms to lie between 0 and 1 in fractional coordinates.\n\nAroundCenter: Remap atoms to lie within 0.5 in fractional coordinates around the geometrical center of the starting positions of all atoms.', default='Auto', choices=['Auto', 'ZeroToOne', 'PlusMinusHalf', 'AroundCenter'])
self.Type: Literal["None", "Atoms"] = MultipleChoiceKey(name='Type', comment='Select the method used to remap atoms into the unit cell.\n\nNone: Disable remapping completely.\n\nAtoms: Remap any atoms that leave the unit cell.', default='Atoms', choices=['None', 'Atoms'])
[docs] class _RemoveMolecules(FixedBlock):
r"""
This block controls removal of molecules from the system. Multiple occurrences of this block are possible.
:ivar Formula: Molecular formula of the molecules that should be removed from the system.
The order of elements in the formula is very important and the correct order is: C, H, all other elements in the strictly alphabetic order.
Element names are case-sensitive, spaces in the formula are not allowed. Digit '1' must be omitted.
Valid formula examples: C2H6O, H2O, O2S. Invalid formula examples: C2H5OH, H2O1, OH, SO2. Invalid formulas are silently ignored.
Use * to remove any molecule, which must be combined with SinkBox or SafeBox.
:vartype Formula: str | StringKey
:ivar Frequency: The specified molecules are removed every so many steps after the StartStep. There is never a molecule removed at step 0.
:vartype Frequency: int | IntKey
:ivar StartStep: Step number when molecules are removed for the first time. After that, molecules are removed every [Frequency] steps.
For example, if StartStep=99 and Frequency=100 then molecules will be removed at steps 99, 199, 299, etc...
No molecule will be removed at step 0, so if StartStep=0 the first molecules are removed at the step number equal to [Frequency].
:vartype StartStep: int | IntKey
:ivar StopStep: Do not remove the specified molecules after this step.
:vartype StopStep: int | IntKey
:ivar SafeBox: Part of the simulation box where molecules may not be removed. Only one of the SinkBox or SafeBox blocks may be present. If this block is present the molecule will not be removed if any of its atoms is within the box. For a periodic dimension it is given as a fraction of the simulation box (the full 0 to 1 range by default). For a non-periodic dimension it represents absolute Cartesian coordinates in Angstrom.
:vartype SafeBox: SimpleActiveLearning._MolecularDynamics._RemoveMolecules._SafeBox
:ivar SinkBox: Part of the simulation box where matching molecules will be removed. By default, molecules matching the formula will be removed regardless of their location. If this block is present then such a molecule will only be removed if any of its atoms is within the box. For a periodic dimension it is given as a fraction of the simulation box (the full 0 to 1 range by default). For a non-periodic dimension it represents absolute Cartesian coordinates in Angstrom.
:vartype SinkBox: SimpleActiveLearning._MolecularDynamics._RemoveMolecules._SinkBox
"""
[docs] class _SafeBox(FixedBlock):
r"""
Part of the simulation box where molecules may not be removed. Only one of the SinkBox or SafeBox blocks may be present. If this block is present the molecule will not be removed if any of its atoms is within the box. For a periodic dimension it is given as a fraction of the simulation box (the full 0 to 1 range by default). For a non-periodic dimension it represents absolute Cartesian coordinates in Angstrom.
:ivar Amax: Coordinate of the upper bound along the first axis.
:vartype Amax: float | FloatKey
:ivar Amin: Coordinate of the lower bound along the first axis.
:vartype Amin: float | FloatKey
:ivar Bmax: Coordinate of the upper bound along the second axis.
:vartype Bmax: float | FloatKey
:ivar Bmin: Coordinate of the lower bound along the second axis.
:vartype Bmin: float | FloatKey
:ivar Cmax: Coordinate of the upper bound along the third axis.
:vartype Cmax: float | FloatKey
:ivar Cmin: Coordinate of the lower bound along the third axis.
:vartype Cmin: float | FloatKey
:ivar FractionalCoordsBox: Do not remove molecules that are (partly) inside the safe box.
Borders of the safe box specified as: Amin, Amax, Bmin, Bmax, Cmin, Cmax.
For periodic dimensions fractional coordinates between 0 and 1 and for non-periodic dimensions Cartesian values in Angstrom are expected.
:vartype FractionalCoordsBox: Iterable[float] | FloatListKey
"""
def __post_init__(self):
self.Amax: float | FloatKey = FloatKey(name='Amax', comment='Coordinate of the upper bound along the first axis.')
self.Amin: float | FloatKey = FloatKey(name='Amin', comment='Coordinate of the lower bound along the first axis.')
self.Bmax: float | FloatKey = FloatKey(name='Bmax', comment='Coordinate of the upper bound along the second axis.')
self.Bmin: float | FloatKey = FloatKey(name='Bmin', comment='Coordinate of the lower bound along the second axis.')
self.Cmax: float | FloatKey = FloatKey(name='Cmax', comment='Coordinate of the upper bound along the third axis.')
self.Cmin: float | FloatKey = FloatKey(name='Cmin', comment='Coordinate of the lower bound along the third axis.')
self.FractionalCoordsBox: Iterable[float] | FloatListKey = FloatListKey(name='FractionalCoordsBox', comment='Do not remove molecules that are (partly) inside the safe box.\n\nBorders of the safe box specified as: Amin, Amax, Bmin, Bmax, Cmin, Cmax.\n\nFor periodic dimensions fractional coordinates between 0 and 1 and for non-periodic dimensions Cartesian values in Angstrom are expected.', gui_name='Safe box:', gui_type='nfloat 6')
[docs] class _SinkBox(FixedBlock):
r"""
Part of the simulation box where matching molecules will be removed. By default, molecules matching the formula will be removed regardless of their location. If this block is present then such a molecule will only be removed if any of its atoms is within the box. For a periodic dimension it is given as a fraction of the simulation box (the full 0 to 1 range by default). For a non-periodic dimension it represents absolute Cartesian coordinates in Angstrom.
:ivar Amax: Coordinate of the upper bound along the first axis.
:vartype Amax: float | FloatKey
:ivar Amin: Coordinate of the lower bound along the first axis.
:vartype Amin: float | FloatKey
:ivar Bmax: Coordinate of the upper bound along the second axis.
:vartype Bmax: float | FloatKey
:ivar Bmin: Coordinate of the lower bound along the second axis.
:vartype Bmin: float | FloatKey
:ivar Cmax: Coordinate of the upper bound along the third axis.
:vartype Cmax: float | FloatKey
:ivar Cmin: Coordinate of the lower bound along the third axis.
:vartype Cmin: float | FloatKey
:ivar FractionalCoordsBox: Remove molecules that are (partly) inside the sink box.
Borders of the sink box specified as: Amin, Amax, Bmin, Bmax, Cmin, Cmax.
For periodic dimensions fractional coordinates between 0 and 1 and for non-periodic dimensions Cartesian values in Angstrom are expected.
:vartype FractionalCoordsBox: Iterable[float] | FloatListKey
"""
def __post_init__(self):
self.Amax: float | FloatKey = FloatKey(name='Amax', comment='Coordinate of the upper bound along the first axis.')
self.Amin: float | FloatKey = FloatKey(name='Amin', comment='Coordinate of the lower bound along the first axis.')
self.Bmax: float | FloatKey = FloatKey(name='Bmax', comment='Coordinate of the upper bound along the second axis.')
self.Bmin: float | FloatKey = FloatKey(name='Bmin', comment='Coordinate of the lower bound along the second axis.')
self.Cmax: float | FloatKey = FloatKey(name='Cmax', comment='Coordinate of the upper bound along the third axis.')
self.Cmin: float | FloatKey = FloatKey(name='Cmin', comment='Coordinate of the lower bound along the third axis.')
self.FractionalCoordsBox: Iterable[float] | FloatListKey = FloatListKey(name='FractionalCoordsBox', comment='Remove molecules that are (partly) inside the sink box.\n\nBorders of the sink box specified as: Amin, Amax, Bmin, Bmax, Cmin, Cmax.\n\nFor periodic dimensions fractional coordinates between 0 and 1 and for non-periodic dimensions Cartesian values in Angstrom are expected.', gui_name='Sink box:', gui_type='nfloat 6')
def __post_init__(self):
self.Formula: str | StringKey = StringKey(name='Formula', comment="Molecular formula of the molecules that should be removed from the system. \n\nThe order of elements in the formula is very important and the correct order is: C, H, all other elements in the strictly alphabetic order. \nElement names are case-sensitive, spaces in the formula are not allowed. Digit '1' must be omitted. \n\nValid formula examples: C2H6O, H2O, O2S. Invalid formula examples: C2H5OH, H2O1, OH, SO2. Invalid formulas are silently ignored. \n\nUse * to remove any molecule, which must be combined with SinkBox or SafeBox.")
self.Frequency: int | IntKey = IntKey(name='Frequency', comment='The specified molecules are removed every so many steps after the StartStep. There is never a molecule removed at step 0.', default=0)
self.StartStep: int | IntKey = IntKey(name='StartStep', comment='Step number when molecules are removed for the first time. After that, molecules are removed every [Frequency] steps.\n\nFor example, if StartStep=99 and Frequency=100 then molecules will be removed at steps 99, 199, 299, etc...\n\nNo molecule will be removed at step 0, so if StartStep=0 the first molecules are removed at the step number equal to [Frequency].', default=0)
self.StopStep: int | IntKey = IntKey(name='StopStep', comment='Do not remove the specified molecules after this step.')
self.SafeBox: SimpleActiveLearning._MolecularDynamics._RemoveMolecules._SafeBox = self._SafeBox(name='SafeBox', comment='Part of the simulation box where molecules may not be removed. Only one of the SinkBox or SafeBox blocks may be present. If this block is present the molecule will not be removed if any of its atoms is within the box. For a periodic dimension it is given as a fraction of the simulation box (the full 0 to 1 range by default). For a non-periodic dimension it represents absolute Cartesian coordinates in Angstrom.')
self.SinkBox: SimpleActiveLearning._MolecularDynamics._RemoveMolecules._SinkBox = self._SinkBox(name='SinkBox', comment='Part of the simulation box where matching molecules will be removed. By default, molecules matching the formula will be removed regardless of their location. If this block is present then such a molecule will only be removed if any of its atoms is within the box. For a periodic dimension it is given as a fraction of the simulation box (the full 0 to 1 range by default). For a non-periodic dimension it represents absolute Cartesian coordinates in Angstrom.')
[docs] class _ReplicaExchange(FixedBlock):
r"""
This block is used for (temperature) Replica Exchange MD (Parallel Tempering) simulations.
:ivar AllowWrongResults: Allow combining Replica Exchange with other features when the combination is known to produce physically incorrect results.
:vartype AllowWrongResults: BoolType | BoolKey
:ivar EWMALength: Length of the exponentially weighted moving average used to smooth swap probabilities for monitoring.
This value is equal to the inverse of the EWMA mixing factor.
:vartype EWMALength: int | IntKey
:ivar SwapFrequency: Attempt an exchange every N steps.
:vartype SwapFrequency: int | IntKey
:ivar TemperatureFactors: This is the ratio of the temperatures of two successive replicas.
The first value sets the temperature of the second replica with respect to the first replica, the second value sets the temperature of the third replica with respect to the second one, and so on. If there are fewer values than nReplicas, the last value of TemperatureFactor is used for all the remaining replicas.
:vartype TemperatureFactors: Iterable[float] | FloatListKey
:ivar Temperatures: List of temperatures for all replicas except for the first one.
This is mutually exclusive with TemperatureFactors. Exactly nReplicas-1 temperature values need to be specified, in increasing order. The temperature of the first replica is given by [Thermostat%Temperature].
:vartype Temperatures: Iterable[float] | FloatListKey
:ivar nReplicas: Number of replicas to run in parallel.
:vartype nReplicas: int | IntKey
"""
def __post_init__(self):
self.AllowWrongResults: BoolType | BoolKey = BoolKey(name='AllowWrongResults', comment='Allow combining Replica Exchange with other features when the combination is known to produce physically incorrect results.', default=False)
self.EWMALength: int | IntKey = IntKey(name='EWMALength', comment='Length of the exponentially weighted moving average used to smooth swap probabilities for monitoring.\n\nThis value is equal to the inverse of the EWMA mixing factor.', default=10)
self.SwapFrequency: int | IntKey = IntKey(name='SwapFrequency', comment='Attempt an exchange every N steps.', default=100)
self.TemperatureFactors: Iterable[float] | FloatListKey = FloatListKey(name='TemperatureFactors', comment='This is the ratio of the temperatures of two successive replicas. \n\nThe first value sets the temperature of the second replica with respect to the first replica, the second value sets the temperature of the third replica with respect to the second one, and so on. If there are fewer values than nReplicas, the last value of TemperatureFactor is used for all the remaining replicas.')
self.Temperatures: Iterable[float] | FloatListKey = FloatListKey(name='Temperatures', comment='List of temperatures for all replicas except for the first one. \n\nThis is mutually exclusive with TemperatureFactors. Exactly nReplicas-1 temperature values need to be specified, in increasing order. The temperature of the first replica is given by [Thermostat%Temperature].')
self.nReplicas: int | IntKey = IntKey(name='nReplicas', comment='Number of replicas to run in parallel.', gui_name='Number of replicas:', default=1)
[docs] class _Shake(FixedBlock):
r"""
Parameters of the Shake/Rattle algorithm.
:ivar All: Constraint description in one the following formats:
All [bondOrder] bonds at1 at2 [to distance]
All triangles at1 at2 at3
The first option constrains all bonds between atoms at1 at2 to a certain length, while the second - bonds at1-at2 and at2-at3 and the angle between them.
The [bondOrder] can be a number or a string such as single, double, triple or aromatic. If it's omitted then all bonds between specified atoms will be constrained. Atom names are case-sensitive and they must be as they are in the Atoms block, or an asterisk '*' denoting any atom. The distance, if present, must be in Angstrom. If it is omitted then the bond length from the initial geometry is used.
Important: only the bonds present in the system at certain points of the simulation (at the start or right after adding/removing atoms) can be constrained, which means that the bonds may need to be specified in the System block.
Warning: the triangles constraint should be used with care because each constrained bond or angle means removing one degree of freedom from the dynamics. When there are too many constraints (for example, "All triangles H C H" in methane) some of them may be linearly dependent, which will lead to an error in the temperature computation.
Valid examples:
All single bonds C C to 1.4
All bonds O H to 0.98
All bonds O H
All bonds H *
All triangles H * H
:vartype All: str | StringKey
:ivar ConvergeR2: Convergence criterion on the max squared difference, in atomic units.
:vartype ConvergeR2: float | FloatKey
:ivar ConvergeRV: Convergence criterion on the orthogonality of the constraint and the relative atomic velocity, in atomic units.
:vartype ConvergeRV: float | FloatKey
:ivar Iterations: Number of iterations.
:vartype Iterations: int | IntKey
:ivar ShakeInitialCoordinates: Apply constraints before computing the first energy and gradients.
:vartype ShakeInitialCoordinates: BoolType | BoolKey
"""
def __post_init__(self):
self.All: str | StringKey = StringKey(name='All', comment='Constraint description in one the following formats: \nAll [bondOrder] bonds at1 at2 [to distance]\nAll triangles at1 at2 at3\n\nThe first option constrains all bonds between atoms at1 at2 to a certain length, while the second - bonds at1-at2 and at2-at3 and the angle between them.\n\nThe [bondOrder] can be a number or a string such as single, double, triple or aromatic. If it\'s omitted then all bonds between specified atoms will be constrained. Atom names are case-sensitive and they must be as they are in the Atoms block, or an asterisk \'*\' denoting any atom. The distance, if present, must be in Angstrom. If it is omitted then the bond length from the initial geometry is used.\n\nImportant: only the bonds present in the system at certain points of the simulation (at the start or right after adding/removing atoms) can be constrained, which means that the bonds may need to be specified in the System block.\n\nWarning: the triangles constraint should be used with care because each constrained bond or angle means removing one degree of freedom from the dynamics. When there are too many constraints (for example, "All triangles H C H" in methane) some of them may be linearly dependent, which will lead to an error in the temperature computation. \n\nValid examples:\nAll single bonds C C to 1.4\nAll bonds O H to 0.98\nAll bonds O H\nAll bonds H *\nAll triangles H * H', unique=False, gui_name='Constrain all:')
self.ConvergeR2: float | FloatKey = FloatKey(name='ConvergeR2', comment='Convergence criterion on the max squared difference, in atomic units.', default=1e-08)
self.ConvergeRV: float | FloatKey = FloatKey(name='ConvergeRV', comment='Convergence criterion on the orthogonality of the constraint and the relative atomic velocity, in atomic units.', default=1e-08)
self.Iterations: int | IntKey = IntKey(name='Iterations', comment='Number of iterations.', default=100)
self.ShakeInitialCoordinates: BoolType | BoolKey = BoolKey(name='ShakeInitialCoordinates', comment='Apply constraints before computing the first energy and gradients.', default=True)
[docs] class _Thermostat(FixedBlock):
r"""
This block allows to specify the use of a thermostat during the simulation. Depending on the selected thermostat type, different additional options may be needed to characterize the specific thermostat's behavior.
:ivar BerendsenApply: Select how to apply the scaling correction for the Berendsen thermostat:
- per-atom-velocity (Local)
- on the molecular system as a whole (Global).
:vartype BerendsenApply: Literal["Local", "Global"]
:ivar ChainLength: Number of individual thermostats forming the NHC thermostat
:vartype ChainLength: int | IntKey
:ivar Duration: Specifies how many steps should a transition from a particular temperature to the next one in sequence take.
:vartype Duration: Iterable[int] | IntListKey
:ivar ExcludedDirection: Exclude a component of the velocities from rescaling by the thermostat. For example in NEMD simulations, when a shear force/velocity is applied in the x direction, the x-direction is often excluded from thermostatting. This currently only works for the Nose-Hoover thermostat.
:vartype ExcludedDirection: Literal["None", "X", "Y", "Z"]
:ivar Friction: Friction coefficient used in langevin dynamics
:vartype Friction: float | FloatKey
:ivar Region: The identifier of the region to thermostat. The default `*` applies the thermostat to the entire system. The value can by a plain region name, or a region expression, e.g. `*-myregion` to thermostat all atoms that are not in myregion, or `regionA+regionB` to thermostat the union of the 'regionA' and 'regionB'. Note that if multiple thermostats are used, their regions may not overlap.
:vartype Region: str | StringKey
:ivar ScaleFrequency: Optional parameter used only by the Scale thermostat.
If specified, the thermostat will be applied every N steps, using that step's ensemble temperature and the specified thermostat temperature to compute the scaling factor.
If not specified, the thermostat will be applied at every step, using the mean temperature of the ensemble and the specified thermostat temperature to compute the scaling factor.
:vartype ScaleFrequency: int | IntKey
:ivar Tau: The time constant of the thermostat.
:vartype Tau: float | FloatKey
:ivar Temperature: The target temperature of the thermostat.
You can specify multiple temperatures (separated by spaces). In that case the Duration field specifies how many steps to use for the transition from one T to the next T (using a linear ramp). For NHC thermostat, the temperature may not be zero.
:vartype Temperature: Iterable[float] | FloatListKey
:ivar Type: Selects the type of the thermostat.
:vartype Type: Literal["None", "Scale", "Berendsen", "NHC", "Langevin"]
"""
def __post_init__(self):
self.BerendsenApply: Literal["Local", "Global"] = MultipleChoiceKey(name='BerendsenApply', comment='Select how to apply the scaling correction for the Berendsen thermostat:\n\n- per-atom-velocity (Local)\n- on the molecular system as a whole (Global).', gui_name='Apply Berendsen:', default='Global', choices=['Local', 'Global'])
self.ChainLength: int | IntKey = IntKey(name='ChainLength', comment='Number of individual thermostats forming the NHC thermostat', gui_name='NHC chain length:', default=10)
self.Duration: Iterable[int] | IntListKey = IntListKey(name='Duration', comment='Specifies how many steps should a transition from a particular temperature to the next one in sequence take.', gui_name='Duration(s)')
self.ExcludedDirection: Literal["None", "X", "Y", "Z"] = MultipleChoiceKey(name='ExcludedDirection', comment='Exclude a component of the velocities from rescaling by the thermostat. For example in NEMD simulations, when a shear force/velocity is applied in the x direction, the x-direction is often excluded from thermostatting. This currently only works for the Nose-Hoover thermostat.', hidden=True, default='None', choices=['None', 'X', 'Y', 'Z'])
self.Friction: float | FloatKey = FloatKey(name='Friction', comment='Friction coefficient used in langevin dynamics', hidden=True, default=1.0)
self.Region: str | StringKey = StringKey(name='Region', comment="The identifier of the region to thermostat. The default `*` applies the thermostat to the entire system. The value can by a plain region name, or a region expression, e.g. `*-myregion` to thermostat all atoms that are not in myregion, or `regionA+regionB` to thermostat the union of the 'regionA' and 'regionB'. Note that if multiple thermostats are used, their regions may not overlap.", default='*', gui_type='region')
self.ScaleFrequency: int | IntKey = IntKey(name='ScaleFrequency', comment="Optional parameter used only by the Scale thermostat.\n\nIf specified, the thermostat will be applied every N steps, using that step's ensemble temperature and the specified thermostat temperature to compute the scaling factor.\n\nIf not specified, the thermostat will be applied at every step, using the mean temperature of the ensemble and the specified thermostat temperature to compute the scaling factor.", hidden=True)
self.Tau: float | FloatKey = FloatKey(name='Tau', comment='The time constant of the thermostat.', gui_name='Damping constant:', unit='Femtoseconds')
self.Temperature: Iterable[float] | FloatListKey = FloatListKey(name='Temperature', comment='The target temperature of the thermostat.\n\nYou can specify multiple temperatures (separated by spaces). In that case the Duration field specifies how many steps to use for the transition from one T to the next T (using a linear ramp). For NHC thermostat, the temperature may not be zero.', gui_name='Temperature(s)', unit='Kelvin')
self.Type: Literal["None", "Scale", "Berendsen", "NHC", "Langevin"] = MultipleChoiceKey(name='Type', comment='Selects the type of the thermostat.', gui_name='Thermostat:', default='None', choices=['None', 'Scale', 'Berendsen', 'NHC', 'Langevin'], hiddenchoices=['Scale', 'Langevin'])
[docs] class _Trajectory(FixedBlock):
r"""
Sets the frequency for printing to stdout and storing the molecular configuration on the .rkf file.
:ivar EngineResultsFreq: Write MDStep*.rkf files with engine-specific results once every N steps. Setting this to zero disables writing engine results files except for one file at the end of the simulation. If unset or negative, defaults to the value of Checkpoint%Frequency.
:vartype EngineResultsFreq: int | IntKey
:ivar ExitConditionFreq: Check the exit conditions every N steps. By default this is done every SamplingFreq steps.
:vartype ExitConditionFreq: int | IntKey
:ivar PrintFreq: Print current thermodynamic properties to the output every N steps. By default this is done every SamplingFreq steps.
:vartype PrintFreq: int | IntKey
:ivar SamplingFreq: Write the molecular geometry (and possibly other properties) to the ams.rkf file once every N steps.
:vartype SamplingFreq: int | IntKey
:ivar TProfileGridPoints: Number of points in the temperature profile. If TProfileGridPoints > 0, a temperature profile along each of the three lattice axes will be written to the .rkf file. The temperature at a given profile point is calculated as the total temperature of all atoms inside the corresponding slice of the simulation box, time-averaged over all MD steps since the previous snapshot. By default, no profile is generated.
:vartype TProfileGridPoints: int | IntKey
:ivar WriteBonds: Write detected bonds to the .rkf file.
:vartype WriteBonds: BoolType | BoolKey
:ivar WriteCharges: Write current atomic point charges (if available) to the .rkf file. Disable this to reduce trajectory size if you do not need to analyze charges.
:vartype WriteCharges: BoolType | BoolKey
:ivar WriteCoordinates: Write atomic coordinates to the .rkf file.
:vartype WriteCoordinates: BoolType | BoolKey
:ivar WriteEngineGradients: Write atomic gradients (negative of the atomic forces, as calculated by the engine) to the History section of ams.rkf.
:vartype WriteEngineGradients: BoolType | BoolKey
:ivar WriteMolecules: Write the results of molecule analysis to the .rkf file.
:vartype WriteMolecules: BoolType | BoolKey
:ivar WriteVelocities: Write velocities to the .rkf file. Disable this to reduce trajectory size if you do not need to analyze the velocities.
:vartype WriteVelocities: BoolType | BoolKey
"""
def __post_init__(self):
self.EngineResultsFreq: int | IntKey = IntKey(name='EngineResultsFreq', comment='Write MDStep*.rkf files with engine-specific results once every N steps. Setting this to zero disables writing engine results files except for one file at the end of the simulation. If unset or negative, defaults to the value of Checkpoint%Frequency.', gui_name='Engine results frequency:')
self.ExitConditionFreq: int | IntKey = IntKey(name='ExitConditionFreq', comment='Check the exit conditions every N steps. By default this is done every SamplingFreq steps.', gui_name='Exit condition frequency:')
self.PrintFreq: int | IntKey = IntKey(name='PrintFreq', comment='Print current thermodynamic properties to the output every N steps. By default this is done every SamplingFreq steps.', gui_name='Printing frequency:')
self.SamplingFreq: int | IntKey = IntKey(name='SamplingFreq', comment='Write the molecular geometry (and possibly other properties) to the ams.rkf file once every N steps.', gui_name='Sample frequency:', default=100)
self.TProfileGridPoints: int | IntKey = IntKey(name='TProfileGridPoints', comment='Number of points in the temperature profile. If TProfileGridPoints > 0, a temperature profile along each of the three lattice axes will be written to the .rkf file. The temperature at a given profile point is calculated as the total temperature of all atoms inside the corresponding slice of the simulation box, time-averaged over all MD steps since the previous snapshot.\u200b By default, no profile is generated.', default=0)
self.WriteBonds: BoolType | BoolKey = BoolKey(name='WriteBonds', comment='Write detected bonds to the .rkf file.', default=True)
self.WriteCharges: BoolType | BoolKey = BoolKey(name='WriteCharges', comment='Write current atomic point charges (if available) to the .rkf file. Disable this to reduce trajectory size if you do not need to analyze charges.', default=True)
self.WriteCoordinates: BoolType | BoolKey = BoolKey(name='WriteCoordinates', comment='Write atomic coordinates to the .rkf file.', default=True)
self.WriteEngineGradients: BoolType | BoolKey = BoolKey(name='WriteEngineGradients', comment='Write atomic gradients (negative of the atomic forces, as calculated by the engine) to the History section of ams.rkf.', default=False)
self.WriteMolecules: BoolType | BoolKey = BoolKey(name='WriteMolecules', comment='Write the results of molecule analysis to the .rkf file.', default=True)
self.WriteVelocities: BoolType | BoolKey = BoolKey(name='WriteVelocities', comment='Write velocities to the .rkf file. Disable this to reduce trajectory size if you do not need to analyze the velocities.', default=True)
[docs] class _fbMC(FixedBlock):
r"""
This block sets up force bias Monte Carlo interleaved with the molecular dynamics simulation.
:ivar Frequency: Run the fbMC procedure every Frequency MD steps.
:vartype Frequency: int | IntKey
:ivar MassRoot: Inverse of the exponent used to mass-weight fbMC steps.
:vartype MassRoot: float | FloatKey
:ivar NSteps: Number of fbMC steps to perform on every invocation of the procedure.
:vartype NSteps: int | IntKey
:ivar PrintFreq: Print current thermodynamic properties to the output every N fbMC steps. This defaults to the PrintFreq set in the Trajectory block. Setting this to zero disables printing fbMC steps.
:vartype PrintFreq: int | IntKey
:ivar StartStep: First step at which the fbMC procedure may run.
:vartype StartStep: int | IntKey
:ivar StepLength: Maximum allowed displacement of the lightest atom in the system in each Cartesian coordinate in one fbMC step.
:vartype StepLength: float | FloatKey
:ivar StopStep: Last step at which the fbMC procedure may run. If unset or zero, there is no limit.
:vartype StopStep: int | IntKey
:ivar Temperature: Temperature used for fbMC.
:vartype Temperature: float | FloatKey
:ivar MolecularMoves: Move molecules as rigid bodies in addition to normal atomic moves.
:vartype MolecularMoves: SimpleActiveLearning._MolecularDynamics._fbMC._MolecularMoves
"""
[docs] class _MolecularMoves(FixedBlock):
r"""
Move molecules as rigid bodies in addition to normal atomic moves.
:ivar Enabled: Enable moving molecules as rigid bodies based on net forces and torques. Ordinary per-atom displacements will then be based on residual atomic forces.
:vartype Enabled: BoolType | BoolKey
:ivar RotationMethod: Select the fbMC method used to generate molecular rotation moves.
:vartype RotationMethod: Literal["Mees", "Rao"]
:ivar RotationStepAngle: Maximum allowed angle of rotation of each molecule in one fbMC step.
:vartype RotationStepAngle: float | FloatKey
:ivar TranslationStepLength: Maximum allowed displacement of each molecule in each Cartesian coordinate in one fbMC step.
:vartype TranslationStepLength: float | FloatKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable moving molecules as rigid bodies based on net forces and torques. Ordinary per-atom displacements will then be based on residual atomic forces.', gui_name='Enable molecular moves', default=False)
self.RotationMethod: Literal["Mees", "Rao"] = MultipleChoiceKey(name='RotationMethod', comment='Select the fbMC method used to generate molecular rotation moves.', hidden=True, default='Mees', choices=['Mees', 'Rao'])
self.RotationStepAngle: float | FloatKey = FloatKey(name='RotationStepAngle', comment='Maximum allowed angle of rotation of each molecule in one fbMC step.', default=0.1, unit='Radian')
self.TranslationStepLength: float | FloatKey = FloatKey(name='TranslationStepLength', comment='Maximum allowed displacement of each molecule in each Cartesian coordinate in one fbMC step.', default=0.1, unit='Angstrom')
def __post_init__(self):
self.Frequency: int | IntKey = IntKey(name='Frequency', comment='Run the fbMC procedure every Frequency MD steps.', default=1)
self.MassRoot: float | FloatKey = FloatKey(name='MassRoot', comment='Inverse of the exponent used to mass-weight fbMC steps.', default=2.0)
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='Number of fbMC steps to perform on every invocation of the procedure.', gui_name='Number of steps:')
self.PrintFreq: int | IntKey = IntKey(name='PrintFreq', comment='Print current thermodynamic properties to the output every N fbMC steps. This defaults to the PrintFreq set in the Trajectory block. Setting this to zero disables printing fbMC steps.', gui_name='Printing frequency:')
self.StartStep: int | IntKey = IntKey(name='StartStep', comment='First step at which the fbMC procedure may run.', default=1)
self.StepLength: float | FloatKey = FloatKey(name='StepLength', comment='Maximum allowed displacement of the lightest atom in the system in each Cartesian coordinate in one fbMC step.', default=0.1, unit='Angstrom')
self.StopStep: int | IntKey = IntKey(name='StopStep', comment='Last step at which the fbMC procedure may run. If unset or zero, there is no limit.', default=0)
self.Temperature: float | FloatKey = FloatKey(name='Temperature', comment='Temperature used for fbMC.', unit='Kelvin')
self.MolecularMoves: SimpleActiveLearning._MolecularDynamics._fbMC._MolecularMoves = self._MolecularMoves(name='MolecularMoves', comment='Move molecules as rigid bodies in addition to normal atomic moves.')
def __post_init__(self):
self.CalcPressure: BoolType | BoolKey = BoolKey(name='CalcPressure', comment='Calculate the pressure in periodic systems.\n\nThis may be computationally expensive for some engines that require numerical differentiation.\n\nSome other engines can calculate the pressure for negligible additional cost and will always do so, even if this option is disabled.', gui_name='Calculate pressure:', default=False)
self.CopyRestartTrajectory: BoolType | BoolKey = BoolKey(name='CopyRestartTrajectory', comment='If the keyword Restart is present, the content of the restartfile is copied to the ams.rkf file.', default=False)
self.NSteps: int | IntKey = IntKey(name='NSteps', comment='The number of steps to be taken in the MD simulation.', gui_name='Number of steps:', default=1000)
self.Restart: str | Path | StringKey = PathStringKey(name='Restart', comment='The path to the ams.rkf file from which to restart the simulation.', gui_name='Restart from:', ispath=True, gui_type='.rkf {{{AMS result file} .rkf}}')
self.TimeStep: float | FloatKey = FloatKey(name='TimeStep', comment='The time difference per step.', default=0.25, unit='Femtoseconds')
self.AddMolecules: SimpleActiveLearning._MolecularDynamics._AddMolecules = self._AddMolecules(name='AddMolecules', comment='This block controls adding molecules to the system (a.k.a. the Molecule Gun). Multiple occurrences of this block are possible.\n\nBy default, molecules are added at random positions in the simulation box with velocity matching the current system temperature. The initial position can be modified using one of the following keywords: Coords, CoordsBox, FractionalCoords, FractionalCoordsBox. The Coords and FractionalCoords keys can optionally be accompanied by CoordsSigma or FractionalCoordsSigma, respectively.', unique=False, gui_name='Add molecules')
self.ApplyForce: SimpleActiveLearning._MolecularDynamics._ApplyForce = self._ApplyForce(name='ApplyForce', comment='The ApplyForce keyword can be used to apply an arbitrary constant force to a certain (subgroups of) atoms in the system', unique=False)
self.ApplyVelocity: SimpleActiveLearning._MolecularDynamics._ApplyVelocity = self._ApplyVelocity(name='ApplyVelocity', comment='The ApplyVelocity keyword can be used to move an arbitrary group of atoms in the system with a constant net velocity', unique=False)
self.Barostat: SimpleActiveLearning._MolecularDynamics._Barostat = self._Barostat(name='Barostat', comment='This block allows to specify the use of a barostat during the simulation.')
self.BinLog: SimpleActiveLearning._MolecularDynamics._BinLog = self._BinLog(name='BinLog', comment='This block controls writing the BinLog section in ams.rkf, which contains the selected MD state scalars and tensors from every MD step. No per-atom data is written. If you need the per-atom data then you can set the sampling frequency to 1 and get the required data from the MDHistory section. The tensors are written per component, that is, the pressure tensor is written as six variables: PressureTensor_xx, PressureTensor_yy, etc.. To reduce the file size, all data is written in blocks.')
self.BondBoost: SimpleActiveLearning._MolecularDynamics._BondBoost = self._BondBoost(name='BondBoost', comment='Forced reaction (bond boost) definitions. Multiple BondBoost blocks may be specified, which will be treated independently. ', unique=False)
self.CRESTMTD: SimpleActiveLearning._MolecularDynamics._CRESTMTD = self._CRESTMTD(name='CRESTMTD', comment='Input for CREST metadynamics simulation. ', gui_name='CREST_MTD')
self.CVHD: SimpleActiveLearning._MolecularDynamics._CVHD = self._CVHD(name='CVHD', comment='Input for the Collective Variable-driven HyperDynamics (CVHD). ', unique=False, gui_name='CVHD')
self.CheckTemperature: SimpleActiveLearning._MolecularDynamics._CheckTemperature = self._CheckTemperature(name='CheckTemperature', comment='Check at every time step if the temperature has exceeded a threshold. If it has, it is assumed the system exploded, and the simulation will stop.')
self.Checkpoint: SimpleActiveLearning._MolecularDynamics._Checkpoint = self._Checkpoint(name='Checkpoint', comment='Sets the frequency for storing the entire MD state necessary for restarting the calculation.')
self.CosineShear: SimpleActiveLearning._MolecularDynamics._CosineShear = self._CosineShear(name='CosineShear', comment='Apply an external acceleration to all atoms of a fluid using a periodic (cosine) function along a selected coordinate axis. This induces a periodic shear flow profile which can be used to determine the viscosity.')
self.Deformation: SimpleActiveLearning._MolecularDynamics._Deformation = self._Deformation(name='Deformation', comment='Deform the periodic lattice of the system during the simulation.', unique=False)
self.Gravity: SimpleActiveLearning._MolecularDynamics._Gravity = self._Gravity(name='Gravity', comment='Apply a constant acceleration in -z.')
self.HeatExchange: SimpleActiveLearning._MolecularDynamics._HeatExchange = self._HeatExchange(name='HeatExchange', comment='Input for the heat-exchange non-equilibrium MD (T-NEMD).', unique=False, gui_name='Heat exchange')
self.InitialVelocities: SimpleActiveLearning._MolecularDynamics._InitialVelocities = self._InitialVelocities(name='InitialVelocities', comment='Sets the frequency for printing to stdout and storing the molecular configuration on the .rkf file.')
self.MovingRestraints: SimpleActiveLearning._MolecularDynamics._MovingRestraints = self._MovingRestraints(name='MovingRestraints', comment='Define a set of moving restraints.', unique=False)
self.PRD: SimpleActiveLearning._MolecularDynamics._PRD = self._PRD(name='PRD', comment='This block is used for Parallel Replica Dynamics simulations.', hidden=True)
self.Plumed: SimpleActiveLearning._MolecularDynamics._Plumed = self._Plumed(name='Plumed', comment='Input for PLUMED (version 2.5.0). The parallel option is still experimental.')
self.Preserve: SimpleActiveLearning._MolecularDynamics._Preserve = self._Preserve(name='Preserve', comment='Periodically remove numerical drift accumulated during the simulation to preserve different whole-system parameters.')
self.Print: SimpleActiveLearning._MolecularDynamics._Print = self._Print(name='Print', comment='This block controls the printing of additional information to stdout.')
self.ReactionBoost: SimpleActiveLearning._MolecularDynamics._ReactionBoost = self._ReactionBoost(name='ReactionBoost', comment='Define a series of transitions between different states of the system.\n\nEach transition is defined by a TargetSystem and by a set of restraints that force the transition.', gui_name='Reaction Boost')
self.Reactor: SimpleActiveLearning._MolecularDynamics._Reactor = self._Reactor(name='Reactor', comment='Define one phase of the nanoreactor. A reactor is a region of space surrounded by an elastic wall. Atoms inside the region are not affected. Atoms outside it will be pushed back with force depending on the [ForceConstant] and the [MassScaled] flag. ', unique=False)
self.ReflectiveWall: SimpleActiveLearning._MolecularDynamics._ReflectiveWall = self._ReflectiveWall(name='ReflectiveWall', comment='Apply a reflective wall in space', unique=False)
self.Remap: SimpleActiveLearning._MolecularDynamics._Remap = self._Remap(name='Remap', comment='Control periodic remapping (backtranslation) of atoms into the PBC box.')
self.RemoveMolecules: SimpleActiveLearning._MolecularDynamics._RemoveMolecules = self._RemoveMolecules(name='RemoveMolecules', comment='This block controls removal of molecules from the system. Multiple occurrences of this block are possible.', unique=False, gui_name='Remove molecules')
self.ReplicaExchange: SimpleActiveLearning._MolecularDynamics._ReplicaExchange = self._ReplicaExchange(name='ReplicaExchange', comment='This block is used for (temperature) Replica Exchange MD (Parallel Tempering) simulations.')
self.Shake: SimpleActiveLearning._MolecularDynamics._Shake = self._Shake(name='Shake', comment='Parameters of the Shake/Rattle algorithm.')
self.Thermostat: SimpleActiveLearning._MolecularDynamics._Thermostat = self._Thermostat(name='Thermostat', comment="This block allows to specify the use of a thermostat during the simulation. Depending on the selected thermostat type, different additional options may be needed to characterize the specific thermostat's behavior.", unique=False)
self.Trajectory: SimpleActiveLearning._MolecularDynamics._Trajectory = self._Trajectory(name='Trajectory', comment='Sets the frequency for printing to stdout and storing the molecular configuration on the .rkf file.')
self.fbMC: SimpleActiveLearning._MolecularDynamics._fbMC = self._fbMC(name='fbMC', comment='This block sets up force bias Monte Carlo interleaved with the molecular dynamics simulation.', unique=False, gui_name='fbMC:')
[docs] class _ParallelLevels(FixedBlock):
r"""
Distribution of threads/processes between the parallelization levels.
:ivar CommitteeMembers: Maximum number of committee member optimizations to run in parallel. If set to zero will take the minimum of MachineLearning%CommitteeSize and the number of available cores (NSCM)
:vartype CommitteeMembers: int | IntKey
:ivar Cores: Number of cores to use per committee member optimization. By default (0) the available cores (NSCM) divided equally among committee members. When using GPU offloading, consider setting this to 1.
:vartype Cores: int | IntKey
:ivar Jobs: Number of JobCollection jobs to run in parallel for each loss function evaluation.
:vartype Jobs: int | IntKey
:ivar Optimizations: Number of independent optimizers to run in parallel.
:vartype Optimizations: int | IntKey
:ivar ParameterVectors: Number of parameter vectors to try in parallel for each optimizer iteration. This level of parallelism can only be used with optimizers that support parallel optimization!
Default (0) will set this value to the number of cores on the system divided by the number of optimizers run in parallel, i.e., each optimizer will be given an equal share of the resources.
:vartype ParameterVectors: int | IntKey
:ivar Processes: Number of processes (MPI ranks) to spawn for each JobCollection job. This effectively sets the NSCM environment variable for each job.
A value of `-1` will disable explicit setting of related variables. We recommend a value of `1` in almost all cases. A value greater than 1 would only be useful if you parametrize DFTB with a serial optimizer and have very few jobs in the job collection.
:vartype Processes: int | IntKey
:ivar Threads: Number of threads to use for each of the processes. This effectively set the OMP_NUM_THREADS environment variable.
Note that the DFTB engine does not use threads, so the value of this variable would not have any effect. We recommend always leaving it at the default value of 1. Please consult the manual of the engine you are parameterizing.
A value of `-1` will disable explicit setting of related variables.
:vartype Threads: int | IntKey
"""
def __post_init__(self):
self.CommitteeMembers: int | IntKey = IntKey(name='CommitteeMembers', comment='Maximum number of committee member optimizations to run in parallel. If set to zero will take the minimum of MachineLearning%CommitteeSize and the number of available cores (NSCM)', gui_name='Number of parallel committee members:', default=1)
self.Cores: int | IntKey = IntKey(name='Cores', comment='Number of cores to use per committee member optimization. By default (0) the available cores (NSCM) divided equally among committee members. When using GPU offloading, consider setting this to 1.', gui_name='Processes (per Job):', default=0)
self.Jobs: int | IntKey = IntKey(name='Jobs', comment='Number of JobCollection jobs to run in parallel for each loss function evaluation.', gui_name='Jobs (per loss function evaluation):', default=0)
self.Optimizations: int | IntKey = IntKey(name='Optimizations', comment='Number of independent optimizers to run in parallel.', gui_name='Number of parallel optimizers:', default=1)
self.ParameterVectors: int | IntKey = IntKey(name='ParameterVectors', comment='Number of parameter vectors to try in parallel for each optimizer iteration. This level of parallelism can only be used with optimizers that support parallel optimization!\n\nDefault (0) will set this value to the number of cores on the system divided by the number of optimizers run in parallel, i.e., each optimizer will be given an equal share of the resources.', gui_name='Loss function evaluations (per optimizer):', default=0)
self.Processes: int | IntKey = IntKey(name='Processes', comment='Number of processes (MPI ranks) to spawn for each JobCollection job. This effectively sets the NSCM environment variable for each job.\n\nA value of `-1` will disable explicit setting of related variables. We recommend a value of `1` in almost all cases. A value greater than 1 would only be useful if you parametrize DFTB with a serial optimizer and have very few jobs in the job collection.', gui_name='Processes (per Job):', default=1)
self.Threads: int | IntKey = IntKey(name='Threads', comment='Number of threads to use for each of the processes. This effectively set the OMP_NUM_THREADS environment variable.\nNote that the DFTB engine does not use threads, so the value of this variable would not have any effect. We recommend always leaving it at the default value of 1. Please consult the manual of the engine you are parameterizing.\n\nA value of `-1` will disable explicit setting of related variables.', gui_name='Threads (per Process):', default=1)
[docs] class _System(FixedBlock):
r"""
Specification of the chemical system. For some applications more than one system may be present in the input. In this case, all systems except one must have a non-empty string ID specified after the System keyword. The system without an ID is considered the main one.
:ivar AllowCloseAtoms: No longer functional. Just here for backwards compatibility.
:vartype AllowCloseAtoms: BoolType | BoolKey
:ivar Charge: The system's total charge in atomic units.
:vartype Charge: float | FloatKey
:ivar FractionalCoords: Whether the atomic coordinates in the Atoms block are given in fractional coordinates of the lattice vectors. Requires the presence of the Lattice block.
:vartype FractionalCoords: BoolType | BoolKey
:ivar GeometryFile: Read the geometry from a file (instead of from Atoms and Lattice blocks). Supported formats: .xyz
:vartype GeometryFile: str | Path | StringKey
:ivar GuessBonds: Equivalent to 'Modify%GuessBonds'. Please update input file to use 'Modify' block instead.
:vartype GuessBonds: BoolType | BoolKey
:ivar LatticeStrain: Equivalent to 'Modify%LatticeStrain'. Please update input file to use 'Modify' block instead.
:vartype LatticeStrain: Iterable[float] | FloatListKey
:ivar MapAtomsToUnitCell: Equivalent to 'Modify%MapAtomsToUnitCell'. Please update input file to use 'Modify' block instead.
:vartype MapAtomsToUnitCell: BoolType | BoolKey
:ivar PerturbCoordinates: Equivalent to 'Modify%PerturbCoordinates'. Please update input file to use 'Modify' block instead.
:vartype PerturbCoordinates: float | FloatKey
:ivar PerturbLattice: Equivalent to 'Modify%PerturbLattice'. Please update input file to use 'Modify' block instead.
:vartype PerturbLattice: float | FloatKey
:ivar ShiftCoordinates: Equivalent to 'Modify%Translate', but in the unit of bohr by default. Please update input file to use 'Modify' block instead.
:vartype ShiftCoordinates: Iterable[float] | FloatListKey
:ivar SuperCell: Equivalent to 'Modify%SuperCell'. Please update input file to use 'Modify' block instead.
:vartype SuperCell: Iterable[int] | IntListKey
:ivar SuperCellTrafo: Equivalent to 'Modify%SuperCellTrafo'. Please update input file to use 'Modify' block instead.
:vartype SuperCellTrafo: Iterable[int] | IntListKey
:ivar Symmetrize: Equivalent to 'Modify%Symmetrize'. Please update input file to use 'Modify' block instead.
:vartype Symmetrize: BoolType | BoolKey
:ivar Atoms: The atom types and coordinates. Unit can be specified in the header. Default unit is Angstrom.
:vartype Atoms: str | Sequence[str] | FreeBlock
:ivar BondOrders: Defined bond orders. Each line should contain two atom indices, followed by the bond order (1, 1.5, 2, 3 for single, aromatic, double and triple bonds) and (optionally) the cell shifts for periodic systems. May be used by MM engines and for defining constraints. If the system is periodic and none of the bonds have the cell shift defined then AMS will attempt to determine them following the minimum image convention.
:vartype BondOrders: str | Sequence[str] | FreeBlock
:ivar ElectrostaticEmbedding: Container for electrostatic embedding options, which can be combined.
:vartype ElectrostaticEmbedding: SimpleActiveLearning._System._ElectrostaticEmbedding
:ivar Lattice: Up to three lattice vectors. Unit can be specified in the header. Default unit is Angstrom.
:vartype Lattice: str | Sequence[str] | FreeBlock
:ivar Modify: Modifications to make to the chemical system after construction. This block is read like a script and the modifications applied top to bottom.
:vartype Modify: SimpleActiveLearning._System._Modify
"""
[docs] class _Atoms(FreeBlock):
r"""
The atom types and coordinates. Unit can be specified in the header. Default unit is Angstrom.
"""
def __post_init__(self):
pass
[docs] class _BondOrders(FreeBlock):
r"""
Defined bond orders. Each line should contain two atom indices, followed by the bond order (1, 1.5, 2, 3 for single, aromatic, double and triple bonds) and (optionally) the cell shifts for periodic systems. May be used by MM engines and for defining constraints. If the system is periodic and none of the bonds have the cell shift defined then AMS will attempt to determine them following the minimum image convention.
"""
def __post_init__(self):
pass
[docs] class _ElectrostaticEmbedding(FixedBlock):
r"""
Container for electrostatic embedding options, which can be combined.
:ivar ElectricField: External homogeneous electric field with three Cartesian components: ex, ey, ez, the default unit being V/Å.
In atomic units: Hartree/(e bohr) = 51.422 V/Angstrom; the relation to SI units is: 1 Hartree/(e bohr) = 5.14 ... e11 V/m.
Supported by the engines adf, band, dftb and mopac.
For periodic systems the field may only have nonzero components orthogonal to the direction(s) of periodicity (i.e. for 1D periodic system the x-component of the electric field should be zero, while for 2D periodic systems both the x and y components should be zero. This options cannot be used for 3D periodic systems.
:vartype ElectricField: Iterable[float] | FloatListKey
:ivar MultipolePotential: External point charges (and dipoles).
:vartype MultipolePotential: SimpleActiveLearning._System._ElectrostaticEmbedding._MultipolePotential
"""
[docs] class _MultipolePotential(FixedBlock):
r"""
External point charges (and dipoles).
:ivar ChargeModel: A multipole may be represented by a point (with a singular potential at its location) or by a spherical Gaussian distribution.
:vartype ChargeModel: Literal["Point", "Gaussian"]
:ivar ChargeWidth: The width parameter in a.u. in case a Gaussian charge model is chosen. A negative value means that the width will be chosen automatically.
:vartype ChargeWidth: float | FloatKey
:ivar Coordinates: Positions and values of the multipoles, one per line. Each line has the following format:
x y z q, or
x y z q µx µy µz.
Here x, y, z are the coordinates in Å, q is the charge (in atomic units of charge) and µx, µy, µz are the (optional) dipole moment components (in atomic units, i.e. e*Bohr).
Periodic systems are not supported.
:vartype Coordinates: str | Sequence[str] | FreeBlock
"""
[docs] class _Coordinates(FreeBlock):
r"""
Positions and values of the multipoles, one per line. Each line has the following format:
x y z q, or
x y z q µx µy µz.
Here x, y, z are the coordinates in Å, q is the charge (in atomic units of charge) and µx, µy, µz are the (optional) dipole moment components (in atomic units, i.e. e*Bohr).
Periodic systems are not supported.
"""
def __post_init__(self):
pass
def __post_init__(self):
self.ChargeModel: Literal["Point", "Gaussian"] = MultipleChoiceKey(name='ChargeModel', comment='A multipole may be represented by a point (with a singular potential at its location) or by a spherical Gaussian distribution.', default='Point', choices=['Point', 'Gaussian'])
self.ChargeWidth: float | FloatKey = FloatKey(name='ChargeWidth', comment='The width parameter in a.u. in case a Gaussian charge model is chosen. A negative value means that the width will be chosen automatically.', default=-1.0)
self.Coordinates: str | Sequence[str] | FreeBlock = self._Coordinates(name='Coordinates', comment='Positions and values of the multipoles, one per line. Each line has the following format:\n\nx y z q, or\nx y z q µx µy µz.\n\nHere x, y, z are the coordinates in Å, q is the charge (in atomic units of charge) and µx, µy, µz are the (optional) dipole moment components (in atomic units, i.e. e*Bohr). \n\nPeriodic systems are not supported.', header=True)
def __post_init__(self):
self.ElectricField: Iterable[float] | FloatListKey = FloatListKey(name='ElectricField', comment='External homogeneous electric field with three Cartesian components: ex, ey, ez, the default unit being V/Å.\n\nIn atomic units: Hartree/(e bohr) = 51.422 V/Angstrom; the relation to SI units is: 1 Hartree/(e bohr) = 5.14 ... e11 V/m.\n\nSupported by the engines adf, band, dftb and mopac.\n\nFor periodic systems the field may only have nonzero components orthogonal to the direction(s) of periodicity (i.e. for 1D periodic system the x-component of the electric field should be zero, while for 2D periodic systems both the x and y components should be zero. This options cannot be used for 3D periodic systems.', unit='V/Angstrom')
self.MultipolePotential: SimpleActiveLearning._System._ElectrostaticEmbedding._MultipolePotential = self._MultipolePotential(name='MultipolePotential', comment='External point charges (and dipoles).')
[docs] class _Lattice(FreeBlock):
r"""
Up to three lattice vectors. Unit can be specified in the header. Default unit is Angstrom.
"""
def __post_init__(self):
pass
[docs] class _Modify(FixedBlock):
r"""
Modifications to make to the chemical system after construction. This block is read like a script and the modifications applied top to bottom.
:ivar EnableAtomicProperties: Enables an atomic property group. This is only necessary if you want a group enabled, but no atom in the input is using any property from that group.
:vartype EnableAtomicProperties: Literal["gui", "adf", "band", "forcefield", "dftb", "reaxff", "qe"]
:ivar GuessBonds: Guesses bonds based on the atomic elements and the geometry. Keeps existing bonds.
:vartype GuessBonds: BoolType | BoolKey
:ivar LatticeStrain: Deform the input system by the specified strain. The strain elements are in Voigt notation, so one should specify 6 numbers for 3D periodic system (order: xx,yy,zz,yz,xz,xy), 3 numbers for 2D periodic systems (order: xx,yy,xy) or 1 number for 1D periodic systems.
:vartype LatticeStrain: Iterable[float] | FloatListKey
:ivar MapAtomsToUnitCell: For periodic systems the atoms will be moved to the central unit cell where all their fractional coordinates are in the range [start_range,start_range+1). No mapping will take place along non-periodic directions. If just a single number is given, it corresponds to start_range. If multiple numbers are given, they should match the number of lattice vectors and will be used as start ranges along the individual lattice vectors. If no number is given at all, the mapping will be done to the [-0.5:0.5) cell.
:vartype MapAtomsToUnitCell: Iterable[float] | FloatListKey
:ivar PerturbCoordinates: Perturb the atomic coordinates by adding random numbers between [-PerturbCoordinates,PerturbCoordinates] to each Cartesian component. This can be useful if you want to break the symmetry of your system (e.g. for a geometry optimization).
:vartype PerturbCoordinates: float | FloatKey
:ivar PerturbLattice: Perturb the lattice vectors by applying random strain with matrix elements between [-PerturbLattice,PerturbLattice]. This can be useful if you want to deviate from an ideal symmetric geometry, for example if you look for a phase change due to high pressure.
:vartype PerturbLattice: float | FloatKey
:ivar SuperCell: Create a supercell of the input system (only possible for periodic systems). The integer numbers represent the diagonal elements of the supercell transformation; you should specify as many numbers as lattice vectors (i.e. 1 number for 1D, 2 numbers for 2D and 3 numbers for 3D periodic systems).
:vartype SuperCell: Iterable[int] | IntListKey
:ivar SuperCellTrafo: Create a supercell of the input system (only possible for periodic systems) :math:`\vec{a}_i' = \sum_j T_{ij} \vec{a}_j`. The integer numbers represent the supercell transformation :math:`T_{ij}`: 1 number for 1D PBC, 4 numbers for 2D PBC corresponding to a 2x2 matrix (order: (1,1),(1,2),(2,1),(2,2)) and 9 numbers for 3D PBC corresponding to a 3x3 matrix (order: (1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)).
:vartype SuperCellTrafo: Iterable[int] | IntListKey
:ivar Symmetrize: Symmetrizes the atomic coordinates to machine precision and rototranslates the molecule to the AMS standard orientation. This allows optimal use of the system's symmetry for calculations with the AMS driver and its engines.
:vartype Symmetrize: BoolType | BoolKey
:ivar Translate: Translate all atoms by a vector.
:vartype Translate: Iterable[float] | FloatListKey
"""
def __post_init__(self):
self.EnableAtomicProperties: Literal["gui", "adf", "band", "forcefield", "dftb", "reaxff", "qe"] = MultipleChoiceKey(name='EnableAtomicProperties', comment='Enables an atomic property group. This is only necessary if you want a group enabled, but no atom in the input is using any property from that group.', unique=False, choices=['gui', 'adf', 'band', 'forcefield', 'dftb', 'reaxff', 'qe'])
self.GuessBonds: BoolType | BoolKey = BoolKey(name='GuessBonds', comment='Guesses bonds based on the atomic elements and the geometry. Keeps existing bonds.', unique=False)
self.LatticeStrain: Iterable[float] | FloatListKey = FloatListKey(name='LatticeStrain', comment='Deform the input system by the specified strain. The strain elements are in Voigt notation, so one should specify 6 numbers for 3D periodic system (order: xx,yy,zz,yz,xz,xy), 3 numbers for 2D periodic systems (order: xx,yy,xy) or 1 number for 1D periodic systems.', unique=False)
self.MapAtomsToUnitCell: Iterable[float] | FloatListKey = FloatListKey(name='MapAtomsToUnitCell', comment='For periodic systems the atoms will be moved to the central unit cell where all their fractional coordinates are in the range [start_range,start_range+1). No mapping will take place along non-periodic directions. If just a single number is given, it corresponds to start_range. If multiple numbers are given, they should match the number of lattice vectors and will be used as start ranges along the individual lattice vectors. If no number is given at all, the mapping will be done to the [-0.5:0.5) cell.', unique=False)
self.PerturbCoordinates: float | FloatKey = FloatKey(name='PerturbCoordinates', comment='Perturb the atomic coordinates by adding random numbers between [-PerturbCoordinates,PerturbCoordinates] to each Cartesian component. This can be useful if you want to break the symmetry of your system (e.g. for a geometry optimization).', unique=False, unit='angstrom')
self.PerturbLattice: float | FloatKey = FloatKey(name='PerturbLattice', comment='Perturb the lattice vectors by applying random strain with matrix elements between [-PerturbLattice,PerturbLattice]. This can be useful if you want to deviate from an ideal symmetric geometry, for example if you look for a phase change due to high pressure.', unique=False)
self.SuperCell: Iterable[int] | IntListKey = IntListKey(name='SuperCell', comment='Create a supercell of the input system (only possible for periodic systems). The integer numbers represent the diagonal elements of the supercell transformation; you should specify as many numbers as lattice vectors (i.e. 1 number for 1D, 2 numbers for 2D and 3 numbers for 3D periodic systems).', unique=False)
self.SuperCellTrafo: Iterable[int] | IntListKey = IntListKey(name='SuperCellTrafo', comment="Create a supercell of the input system (only possible for periodic systems) :math:`\\vec{a}_i' = \\sum_j T_{ij} \\vec{a}_j`. The integer numbers represent the supercell transformation :math:`T_{ij}`: 1 number for 1D PBC, 4 numbers for 2D PBC corresponding to a 2x2 matrix (order: (1,1),(1,2),(2,1),(2,2)) and 9 numbers for 3D PBC corresponding to a 3x3 matrix (order: (1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)).", unique=False)
self.Symmetrize: BoolType | BoolKey = BoolKey(name='Symmetrize', comment="Symmetrizes the atomic coordinates to machine precision and rototranslates the molecule to the AMS standard orientation. This allows optimal use of the system's symmetry for calculations with the AMS driver and its engines.", unique=False, default=False)
self.Translate: Iterable[float] | FloatListKey = FloatListKey(name='Translate', comment='Translate all atoms by a vector.', unique=False, unit='angstrom')
def __post_init__(self):
self.AllowCloseAtoms: BoolType | BoolKey = BoolKey(name='AllowCloseAtoms', comment='No longer functional. Just here for backwards compatibility.', hidden=True, default=True)
self.Charge: float | FloatKey = FloatKey(name='Charge', comment="The system's total charge in atomic units.", gui_name='Total charge:', default=0.0, engines='-forcefield')
self.FractionalCoords: BoolType | BoolKey = BoolKey(name='FractionalCoords', comment='Whether the atomic coordinates in the Atoms block are given in fractional coordinates of the lattice vectors. Requires the presence of the Lattice block.', default=False)
self.GeometryFile: str | Path | StringKey = PathStringKey(name='GeometryFile', comment='Read the geometry from a file (instead of from Atoms and Lattice blocks). Supported formats: .xyz', ispath=True)
self.GuessBonds: BoolType | BoolKey = BoolKey(name='GuessBonds', comment="Equivalent to 'Modify%GuessBonds'. Please update input file to use 'Modify' block instead.", hidden=True)
self.LatticeStrain: Iterable[float] | FloatListKey = FloatListKey(name='LatticeStrain', comment="Equivalent to 'Modify%LatticeStrain'. Please update input file to use 'Modify' block instead.", hidden=True)
self.MapAtomsToUnitCell: BoolType | BoolKey = BoolKey(name='MapAtomsToUnitCell', comment="Equivalent to 'Modify%MapAtomsToUnitCell'. Please update input file to use 'Modify' block instead.", hidden=True)
self.PerturbCoordinates: float | FloatKey = FloatKey(name='PerturbCoordinates', comment="Equivalent to 'Modify%PerturbCoordinates'. Please update input file to use 'Modify' block instead.", hidden=True, unit='angstrom')
self.PerturbLattice: float | FloatKey = FloatKey(name='PerturbLattice', comment="Equivalent to 'Modify%PerturbLattice'. Please update input file to use 'Modify' block instead.", hidden=True)
self.ShiftCoordinates: Iterable[float] | FloatListKey = FloatListKey(name='ShiftCoordinates', comment="Equivalent to 'Modify%Translate', but in the unit of bohr by default. Please update input file to use 'Modify' block instead.", hidden=True, unit='bohr')
self.SuperCell: Iterable[int] | IntListKey = IntListKey(name='SuperCell', comment="Equivalent to 'Modify%SuperCell'. Please update input file to use 'Modify' block instead.", hidden=True)
self.SuperCellTrafo: Iterable[int] | IntListKey = IntListKey(name='SuperCellTrafo', comment="Equivalent to 'Modify%SuperCellTrafo'. Please update input file to use 'Modify' block instead.", hidden=True)
self.Symmetrize: BoolType | BoolKey = BoolKey(name='Symmetrize', comment="Equivalent to 'Modify%Symmetrize'. Please update input file to use 'Modify' block instead.", hidden=True, default=False)
self.Atoms: str | Sequence[str] | FreeBlock = self._Atoms(name='Atoms', comment='The atom types and coordinates. Unit can be specified in the header. Default unit is Angstrom.', header=True)
self.BondOrders: str | Sequence[str] | FreeBlock = self._BondOrders(name='BondOrders', comment='Defined bond orders. Each line should contain two atom indices, followed by the bond order (1, 1.5, 2, 3 for single, aromatic, double and triple bonds) and (optionally) the cell shifts for periodic systems. May be used by MM engines and for defining constraints. If the system is periodic and none of the bonds have the cell shift defined then AMS will attempt to determine them following the minimum image convention.')
self.ElectrostaticEmbedding: SimpleActiveLearning._System._ElectrostaticEmbedding = self._ElectrostaticEmbedding(name='ElectrostaticEmbedding', comment='Container for electrostatic embedding options, which can be combined.')
self.Lattice: str | Sequence[str] | FreeBlock = self._Lattice(name='Lattice', comment='Up to three lattice vectors. Unit can be specified in the header. Default unit is Angstrom.', header=True)
self.Modify: SimpleActiveLearning._System._Modify = self._Modify(name='Modify', comment='Modifications to make to the chemical system after construction. This block is read like a script and the modifications applied top to bottom.', ordered=True)
def __post_init__(self):
self.RNGSeed: Iterable[int] | IntListKey = IntListKey(name='RNGSeed', comment='Initial seed for the (pseudo)random number generator. This should be omitted in most calculations to avoid introducing bias into the results. If this is unset, the generator will be seeded randomly from external sources of entropy. If you want to exactly reproduce an older calculation, set this to the numbers printed in its output.')
self.Task: Literal["MolecularDynamics"] = MultipleChoiceKey(name='Task', comment='The task to perform.', default='MolecularDynamics', choices=['MolecularDynamics'])
self.ActiveLearning: SimpleActiveLearning._ActiveLearning = self._ActiveLearning(name='ActiveLearning', comment='Settings for Active Learning')
self.Constraints: SimpleActiveLearning._Constraints = self._Constraints(name='Constraints', comment='The Constraints block allows geometry optimizations and potential energy surface scans with constraints. The constraints do not have to be satisfied at the start of the calculation.', extra_info='not_in_fragment', shared_id='AMSConstraints')
self.Engine: EngineBlock = self._Engine(name='Engine', comment='The reference engine settings.', header=True)
self.LoadSystem: SimpleActiveLearning._LoadSystem = self._LoadSystem(name='LoadSystem', comment='Block that controls reading the chemical system from a KF file instead of the [System] block.', unique=False, header=True, extra_info='not_in_fragment', shared_id='AMSLoadSystem')
self.MachineLearning: SimpleActiveLearning._MachineLearning = self._MachineLearning(name='MachineLearning', comment='Options for Task MachineLearning.')
self.MolecularDynamics: SimpleActiveLearning._MolecularDynamics = self._MolecularDynamics(name='MolecularDynamics', comment='Settings for Molecular Dynamics', shared_id='AMSMolecularDynamics')
self.ParallelLevels: SimpleActiveLearning._ParallelLevels = self._ParallelLevels(name='ParallelLevels', comment='Distribution of threads/processes between the parallelization levels.', gui_name='Parallelization distribution: ')
self.System: SimpleActiveLearning._System = self._System(name='System', comment='Specification of the chemical system. For some applications more than one system may be present in the input. In this case, all systems except one must have a non-empty string ID specified after the System keyword. The system without an ID is considered the main one.', unique=False, header=True, gui_type='Repeat at least once', shared_id='AMSSystem')