Source code for scm.input_classes.engines.hybrid

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 Hybrid(EngineBlock): r""" :ivar AllowSanityCheckWarnings: Sanity checks will be performed on the setup. If this option is on, only warnings are printed. If not the program will stop on warnings. :vartype AllowSanityCheckWarnings: BoolType | BoolKey :ivar GuessAttributesOnce: If any ForceField subengines are defined, and if automatic atom typing is possible, then the atom typing is done at the level of the Hybrid engine, and not of the ForceField subengines. This ensures that the same atom types and charges are used in each subsystem, so that pair energy terms that should cancel, will cancel. If set to False, then for each energy term the atom types and charges of the subsystem will be determined separately. :vartype GuessAttributesOnce: BoolType | BoolKey :ivar RestartSubEngines: Save all the results of the subengines and pass those in a next geometry step or MD step. :vartype RestartSubEngines: BoolType | BoolKey :ivar TweakRequestForSubEngines: Only request what is really needed, gradients and charges. :vartype TweakRequestForSubEngines: BoolType | BoolKey :ivar Capping: This block is about capping details. Capping occurs with hydrogen atoms when a bond is broken between an atom inside the region and one outside. :vartype Capping: Hybrid._Capping :ivar Committee: Settings for using the hybrid engine as a committee. The factors and region for each engine must be the same. When committee is enabled the standard deviation is also reported as the uncertainty. :vartype Committee: Hybrid._Committee :ivar Energy: This block is there to construct the energy. :vartype Energy: Hybrid._Energy :ivar Engine: The input for the computational (sub) engine. The header of the block determines the type of the engine. An optional second word in the header serves as the EngineID, if not present it defaults to the engine name. Currently it is not allowed to have a Hybrid engine as a sub engine. :vartype Engine: EngineBlock :ivar QMMM: This block is there to identify the QMMM engines. :vartype QMMM: Hybrid._QMMM """
[docs] class _Capping(FixedBlock): r""" This block is about capping details. Capping occurs with hydrogen atoms when a bond is broken between an atom inside the region and one outside. :ivar AllowHighBondOrders: Allows capping of interregional aromatic, double and triple bonds. This is normally not a good idea, since the capping is done with hydrogen atoms. :vartype AllowHighBondOrders: BoolType | BoolKey :ivar AtomicInfoForCappingAtom: The AtomicInfo for the capping atoms. Typically a string like ForceField.Type=X much like forcefield info is entered in the System block for normal atoms. :vartype AtomicInfoForCappingAtom: str | StringKey :ivar CappingElement: The element to be used for capping. The hydrogen atom has the advantage that it is very small. :vartype CappingElement: str | StringKey :ivar CheckCapping: The same outside atom can be involved in multiple capping coordinate definitions. This is not a good idea, and this will not be accepted by using this check. :vartype CheckCapping: BoolType | BoolKey :ivar Distance: A negative value means automatic. In that case the sum of covalent radii is used :vartype Distance: float | FloatKey :ivar Option: The capping atom is always along the broken bond vector. The bond distance between the capping atom and the two atoms are obtained from covalent radii, let us call them D1H and D2H. With option=Fractional the capping is on the bond vector with the fraction D1H/(D1H+D2H). With the Fixed option it at the distance D1H from atom 1. A distance of zero always means the coordinate of the inside atom. :vartype Option: Literal["Fractional", "Fixed"] """ def __post_init__(self): self.AllowHighBondOrders: BoolType | BoolKey = BoolKey(name='AllowHighBondOrders', comment='Allows capping of interregional aromatic, double and triple bonds. This is normally not a good idea, since the capping is done with hydrogen atoms.', default=False) self.AtomicInfoForCappingAtom: str | StringKey = StringKey(name='AtomicInfoForCappingAtom', comment='The AtomicInfo for the capping atoms. Typically a string like ForceField.Type=X much like forcefield info is entered in the System block for normal atoms.', default='ForceField.Type=H_ ForceField.Charge=0.0') self.CappingElement: str | StringKey = StringKey(name='CappingElement', comment='The element to be used for capping. The hydrogen atom has the advantage that it is very small.', default='H') self.CheckCapping: BoolType | BoolKey = BoolKey(name='CheckCapping', comment='The same outside atom can be involved in multiple capping coordinate definitions. This is not a good idea, and this will not be accepted by using this check.', default=True) self.Distance: float | FloatKey = FloatKey(name='Distance', comment='A negative value means automatic. In that case the sum of covalent radii is used', default=-1.0) self.Option: Literal["Fractional", "Fixed"] = MultipleChoiceKey(name='Option', comment='The capping atom is always along the broken bond vector.\n\nThe bond distance between the capping atom and the two atoms are obtained from covalent radii, let us call them D1H and D2H.\n\nWith option=Fractional the capping is on the bond vector with the fraction D1H/(D1H+D2H).\n\nWith the Fixed option it at the distance D1H from atom 1. A distance of zero always means the coordinate of the inside atom.', gui_name='Capping option:', default='Fixed', choices=['Fractional', 'Fixed'])
[docs] class _Committee(FixedBlock): r""" Settings for using the hybrid engine as a committee. The factors and region for each engine must be the same. When committee is enabled the standard deviation is also reported as the uncertainty. :ivar Enabled: Enable committee :vartype Enabled: BoolType | BoolKey """ def __post_init__(self): self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable committee', default=False)
[docs] class _Energy(FixedBlock): r""" This block is there to construct the energy. :ivar DynamicFactors: Default - use factors as set in the corresponding Term blocks; UseLowestEnergy - set all factors to 0 except for that of the engine with the lowest energy, which is set to 1; UseHighestEnergy - set all factors to 0 except for that of the engine with the highest energy, which is set to 1. The last two options make sense only for non-QMMM hybrid calculation (that is, if the QMMM block is not present) and only when using engines whose energies can be compared directly. :vartype DynamicFactors: Literal["Default", "UseLowestEnergy", "UseHighestEnergy"] :ivar Term: This block is there to construct the energy term. Can have multiple occurrences :vartype Term: Hybrid._Energy._Term """
[docs] class _Term(FixedBlock): r""" This block is there to construct the energy term. Can have multiple occurrences :ivar Charge: Net charge to be used for this energy term. :vartype Charge: float | FloatKey :ivar EngineID: Identifier for the engine :vartype EngineID: str | StringKey :ivar Factor: :vartype Factor: float | FloatKey :ivar Region: Identifier for the region :vartype Region: str | StringKey :ivar UseCappingAtoms: Whether to use capping for broken bonds :vartype UseCappingAtoms: BoolType | BoolKey """ def __post_init__(self): self.Charge: float | FloatKey = FloatKey(name='Charge', comment='Net charge to be used for this energy term.', default=0.0) self.EngineID: str | StringKey = StringKey(name='EngineID', comment='Identifier for the engine') self.Factor: float | FloatKey = FloatKey(name='Factor', default=1.0) self.Region: str | StringKey = StringKey(name='Region', comment='Identifier for the region', gui_type='region') self.UseCappingAtoms: BoolType | BoolKey = BoolKey(name='UseCappingAtoms', comment='Whether to use capping for broken bonds', default=True)
def __post_init__(self): self.DynamicFactors: Literal["Default", "UseLowestEnergy", "UseHighestEnergy"] = MultipleChoiceKey(name='DynamicFactors', comment='Default - use factors as set in the corresponding Term blocks; \nUseLowestEnergy - set all factors to 0 except for that of the engine with the lowest energy, which is set to 1; \nUseHighestEnergy - set all factors to 0 except for that of the engine with the highest energy, which is set to 1. \nThe last two options make sense only for non-QMMM hybrid calculation (that is, if the QMMM block is not present) and only when using engines whose energies can be compared directly.', gui_name='Adjust factors:', default='Default', choices=['Default', 'UseLowestEnergy', 'UseHighestEnergy']) self.Term: Hybrid._Energy._Term = self._Term(name='Term', comment='This block is there to construct the energy term. Can have multiple occurrences', unique=False)
[docs] class _Engine(EngineBlock): r""" The input for the computational (sub) engine. The header of the block determines the type of the engine. An optional second word in the header serves as the EngineID, if not present it defaults to the engine name. Currently it is not allowed to have a Hybrid engine as a sub engine. """ def __post_init__(self): pass
[docs] class _QMMM(FixedBlock): r""" This block is there to identify the QMMM engines. :ivar Embedding: Determines how the QM region is embedded into the MM region. Mechanical embedding embedding can also be achieved using the Energy%Terms keywords, but the common case of a two region mechanical QM/MM embedding is easier to set up using this keyword. :vartype Embedding: Literal["Mechanical", "Electrostatic"] :ivar MMCharge: Net charge to be used for the MM region. :vartype MMCharge: float | FloatKey :ivar MMEngineID: Identifier for the MM engine :vartype MMEngineID: str | StringKey :ivar MMEngineIsPolarizable: Whether or not the MM engine has dynamic charges (for now not supported at all). :vartype MMEngineIsPolarizable: BoolType | BoolKey :ivar QMCharge: Net charge to be used for the QM region. :vartype QMCharge: float | FloatKey :ivar QMEngineID: Identifier for the QM engine :vartype QMEngineID: str | StringKey :ivar QMRegion: Identifier for the QM region. The rest of the system is considered the MM region. :vartype QMRegion: str | StringKey :ivar UseCappingAtoms: Whether to use capping for broken bonds. :vartype UseCappingAtoms: BoolType | BoolKey """ def __post_init__(self): self.Embedding: Literal["Mechanical", "Electrostatic"] = MultipleChoiceKey(name='Embedding', comment='Determines how the QM region is embedded into the MM region.\n\nMechanical embedding embedding can also be achieved using the Energy%Terms keywords, but the common case of a two region mechanical QM/MM embedding is easier to set up using this keyword.', default='Electrostatic', choices=['Mechanical', 'Electrostatic']) self.MMCharge: float | FloatKey = FloatKey(name='MMCharge', comment='Net charge to be used for the MM region.', default=0.0) self.MMEngineID: str | StringKey = StringKey(name='MMEngineID', comment='Identifier for the MM engine') self.MMEngineIsPolarizable: BoolType | BoolKey = BoolKey(name='MMEngineIsPolarizable', comment='Whether or not the MM engine has dynamic charges (for now not supported at all).', hidden=True, default=False) self.QMCharge: float | FloatKey = FloatKey(name='QMCharge', comment='Net charge to be used for the QM region.', default=0.0) self.QMEngineID: str | StringKey = StringKey(name='QMEngineID', comment='Identifier for the QM engine') self.QMRegion: str | StringKey = StringKey(name='QMRegion', comment='Identifier for the QM region. The rest of the system is considered the MM region.', gui_type='region') self.UseCappingAtoms: BoolType | BoolKey = BoolKey(name='UseCappingAtoms', comment='Whether to use capping for broken bonds.', default=True)
def __post_init__(self): self.AllowSanityCheckWarnings: BoolType | BoolKey = BoolKey(name='AllowSanityCheckWarnings', comment='Sanity checks will be performed on the setup. If this option is on, only warnings are printed. If not the program will stop on warnings.', default=False) self.GuessAttributesOnce: BoolType | BoolKey = BoolKey(name='GuessAttributesOnce', comment='If any ForceField subengines are defined, and if automatic atom typing is possible, then the atom typing is done at the level of the Hybrid engine, and not of the ForceField subengines. This ensures that the same atom types and charges are used in each subsystem, so that pair energy terms that should cancel, will cancel. If set to False, then for each energy term the atom types and charges of the subsystem will be determined separately.', default=True) self.RestartSubEngines: BoolType | BoolKey = BoolKey(name='RestartSubEngines', comment='Save all the results of the subengines and pass those in a next geometry step or MD step.', default=True) self.TweakRequestForSubEngines: BoolType | BoolKey = BoolKey(name='TweakRequestForSubEngines', comment='Only request what is really needed, gradients and charges.', default=True) self.Capping: Hybrid._Capping = self._Capping(name='Capping', comment='This block is about capping details. Capping occurs with hydrogen atoms when a bond is broken between an atom inside the region and one outside.') self.Committee: Hybrid._Committee = self._Committee(name='Committee', comment='Settings for using the hybrid engine as a committee. The factors and region for each engine must be the same. When committee is enabled the standard deviation is also reported as the uncertainty.') self.Energy: Hybrid._Energy = self._Energy(name='Energy', comment='This block is there to construct the energy.') self.Engine: EngineBlock = self._Engine(name='Engine', comment='The input for the computational (sub) engine. The header of the block determines the type of the engine. An optional second word in the header serves as the EngineID, if not present it defaults to the engine name. Currently it is not allowed to have a Hybrid engine as a sub engine.', unique=False, header=True) self.QMMM: Hybrid._QMMM = self._QMMM(name='QMMM', comment='This block is there to identify the QMMM engines.')