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 OLEDProperties(DriverBlock):
r"""
:ivar CoresPerJob: The number of CPU cores used for each job in the workflow. Combined with the total number of cores used (set by the ``NSCM`` environment variable or the ``-n`` command line argument), this indirectly determines the number of simultaneously running jobs. The default value should usually be a good choice. When changing this value, make sure you are using all allocated cores by setting a value that divides the total number of cores, as well as the number of cores on each node.
:vartype CoresPerJob: int | IntKey
:ivar LogProgressEvery: How often to print progress information to the logfile.
:vartype LogProgressEvery: float | FloatKey
:ivar NumAdditionalOrbitalEnergies: The number of additional orbital energies to write to the HDF5 file. A value of N means to write everything up to HOMO-N and LUMO+N.
:vartype NumAdditionalOrbitalEnergies: int | IntKey
:ivar NumExcitations: The number of exited states to calculate. By default the S_1 and T_1 states will be calculated. The calculation of excited states is currently only supported for systems with a closed-shell ground state.
:vartype NumExcitations: int | IntKey
:ivar NumSelectedMoleculesPerSpecies: Number of molecules per species to calculate properties for. Around 50 molecules per species should be enough to estimate distribution means and standard deviations as input for the Bumblebee KMC code. Mutually exclusive with the ``SelectedMolecules`` keyword. If neither this key nor ``SelectedMolecules`` is present, all molecules will be selected.
:vartype NumSelectedMoleculesPerSpecies: int | IntKey
:ivar OccupationSmearing: Determines for which systems the electron smearing feature in ADF will be used. If enabled, the molecular orbital occupations will be smeared out with a 300K Fermi-Dirac distribution. This makes SCF convergence easier, as the occupation of energetically close orbitals does not jump when their energetic order flips. See the ADF manual for details. It is recommended to keep this option enabled for the ionic systems, which are more likely to suffer from difficult SCF convergence.
:vartype OccupationSmearing: Literal["None", "Ions", "All"]
:ivar Relax: Which geometries to relax prior to taking the energy differences for the calculation of ionization potential and electron affinity. The relaxation is done at the DFTB level using the GFN1-xTB model Hamiltonian with electrostatic embedding in a UFF environment.
• None: Use the geometries directly from the input.
• Neutral: Relax the uncharged molecule and use its optimized geometry for the neutral as well as the ionic systems. This gives (approximately) the vertical ionization potential and electron affinity.
• All: Individually relax the neutral systems and the ions before calculating the total energies. This gives (approximately) the adiabatic ionization potential and electron affinity.
:vartype Relax: Literal["None", "Neutral", "All"]
:ivar Restart: The HDF5 file from a previous calculation on the same morphology. Data already calculated on the restart file will just be copied over and not be recalculated.
:vartype Restart: str | Path | StringKey
:ivar SelectedMolecules: Indices of the molecules to calculate properties for. Note that indexing starts at 0. Mutually exclusive with the ``NumSelectedMoleculesPerSpecies`` keyword. If neither this key nor ``NumSelectedMoleculesPerSpecies`` is present, all molecules will be selected.
:vartype SelectedMolecules: Iterable[int] | IntListKey
:ivar StoreResultFiles: Whether to keep the full result files from all the individual jobs. By default the result files from all jobs for a particular molecule will be deleted after all relevant results have been extracted and stored on the HDF5 file. Note that keeping the full results for all molecules can easily require hundreds of gigabytes of storage space.
:vartype StoreResultFiles: Literal["None", "Failed", "All"]
:ivar Embedding: Configures details of how the environment is taken into account.
:vartype Embedding: OLEDProperties._Embedding
:ivar GW: Perform a GW calculation. G0W0 is the default for GW%SelfConsistency.
:vartype GW: OLEDProperties._GW
:ivar LoadSystem: Block that controls reading the chemical system from a KF file instead of the [System] block.
:vartype LoadSystem: OLEDProperties._LoadSystem
:ivar MBPT: Technical aspects of the MP2 algorithm.
:vartype MBPT: OLEDProperties._MBPT
: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: OLEDProperties._System
:ivar TransferIntegrals: Configures the details of the calculation of electron and hole transfer integrals.
:vartype TransferIntegrals: OLEDProperties._TransferIntegrals
"""
[docs] class _Embedding(FixedBlock):
r"""
Configures details of how the environment is taken into account.
:ivar Charges: Which atomic charges to use for the DRF embedding.
• DFTB: Use the self-consistent Mulliken charges from a quick DFTB calculation with the GFN1-xTB model.
• DFT: Use the MDC-D charges from a relatively quick DFT calculation using LDA and a DZP basis set.
:vartype Charges: Literal["DFTB", "DFT"]
:ivar Cutoff: The cutoff distance determining which molecules will be considered the environment of the central molecule. The maximum possible cutoff distance is half the length of the smallest lattice vector. The distance can be measured using different metrics, see the ``Metric`` keyword.
:vartype Cutoff: float | FloatKey
:ivar Metric: The metric used to calculate the distance between two molecules.
• CoM: use the distance between the centers of mass of the two molecules.
• Atoms: Use the distance between the two closest atoms of two molecules.
• Atoms_noH: Use the distance between the closest non-hydrogen atoms of the two molecules.
:vartype Metric: Literal["CoM", "Atoms", "Atoms_noH"]
:ivar Type: The type of embedding used to simulate the molecular environment.
:vartype Type: Literal["None", "DRF"]
"""
def __post_init__(self):
self.Charges: Literal["DFTB", "DFT"] = MultipleChoiceKey(name='Charges', comment='Which atomic charges to use for the DRF embedding. \n\n• DFTB: Use the self-consistent Mulliken charges from a quick DFTB calculation with the GFN1-xTB model.\n\n• DFT: Use the MDC-D charges from a relatively quick DFT calculation using LDA and a DZP basis set.', default='DFT', choices=['DFTB', 'DFT'])
self.Cutoff: float | FloatKey = FloatKey(name='Cutoff', comment='The cutoff distance determining which molecules will be considered the environment of the central molecule. The maximum possible cutoff distance is half the length of the smallest lattice vector. The distance can be measured using different metrics, see the ``Metric`` keyword.', default=15.0, unit='Angstrom')
self.Metric: Literal["CoM", "Atoms", "Atoms_noH"] = MultipleChoiceKey(name='Metric', comment='The metric used to calculate the distance between two molecules.\n\n• CoM: use the distance between the centers of mass of the two molecules.\n\n• Atoms: Use the distance between the two closest atoms of two molecules. \n\n• Atoms_noH: Use the distance between the closest non-hydrogen atoms of the two molecules.', default='Atoms', choices=['CoM', 'Atoms', 'Atoms_noH'])
self.Type: Literal["None", "DRF"] = MultipleChoiceKey(name='Type', comment='The type of embedding used to simulate the molecular environment.', default='DRF', choices=['None', 'DRF'])
[docs] class _GW(FixedBlock):
r"""
Perform a GW calculation. G0W0 is the default for GW%SelfConsistency.
:ivar AdaptiveMixing: Requests to use adaptive mixing instead of DIIS and sets the staring mixing parameter for mixing of Green's function in case of self-consistency.
Adapative mixing is recommended in case a qsGW calculation does not converge with DIIS.
It is ignored in non-selfconsistent calculation and overwritten by DIIS when DIIS is also present.
:vartype AdaptiveMixing: Iterable[float] | FloatListKey
:ivar DIIS: Requests to use DIIS. This is the Default. Number of expansion coefficients can be requested as well. Ignored in non-selfconsistent calculation
:vartype DIIS: int | IntKey
:ivar Enabled: Enable the calculation of the GW quasi-particle energies.
:vartype Enabled: BoolType | BoolKey
:ivar ExpansionOrder: Order of the expansion of the screened interaction on the SOS-GF(n) method. order 2 (=SOS-GF2) is the default
:vartype ExpansionOrder: int | IntKey
:ivar FixedGridSizes: In a self-consistent GW calculation, recalculate Grids but keep them the same size during the SCF procedure.
:vartype FixedGridSizes: BoolType | BoolKey
:ivar FixedGrids: In a self-consistent GW calculation, do not recalculate Grids. Can be useful in case of convergence problems. Only relevant for qsGW and qsGW0. In case of evGW and evGW0, the grids are always kept fixed.
:vartype FixedGrids: BoolType | BoolKey
:ivar G3W2: Only relevant when self-energy is one of GF2 or G3W2: Full requests that the second-order term is evaluated for the full self-energy matrix. This is very expensive and should only be done for small systems. Diagonal requests, that only the Diagonal of the self-energy matrix is updated. Perturbative means, that only a second-order screened exchange correction is evaluated after the GW calculation is completed. For a G0W0 calculation, all of these options are equivalent.
:vartype G3W2: Literal["Full", "Diagonal", "Perturbative"]
:ivar LinearMixing: Requests to use linear mixing instead of DIIS and sets the mixing parameter for linear mixing of Green's function in case of self-consistency.
It is ignored in non-selfconsistent calculation and overwritten by DIIS when DIIS is also present.
:vartype LinearMixing: Iterable[float] | FloatListKey
:ivar LinearizeQPequations: Instead of solving the non-linear QP equations in a G0W0 (or evGW calculation) by bisection exacly, linearize them by first-order Taylor expansion.
This is not recommended since it does not save computational time when used together with analytical continuation (as implemented in AMS). It might however be useful for benchmarking or for validating results.
If the results os the linearization differ by a lot (for instance, more than 0.1 eV in frontier QP energies) from the non-linearized results, this might indicate that the GW calculation is not reliable.
:vartype LinearizeQPequations: BoolType | BoolKey
:ivar OffDiagonalEFermi: Analytically continue the off-diagonal elements of the KSF2 qsGW Hamiltonian at the Fermi-energy instead of omega=0. Typically leads to slightly lower QP energies, i.e. higher ionization potentials. The HOMO-LUMO gaps are typically not affected.
:vartype OffDiagonalEFermi: BoolType | BoolKey
:ivar Polarizability: Sets the expression for the Polarizability used in the GW calculation.
RPA is the Default and amounts to a standard GW calculation.
BSE denotes screening in the Bethe-Salpeter-equation formalism.
:vartype Polarizability: Literal["RPA", "BSE", "G4W1", "G4V1", "TDHF"]
:ivar PrintAllSolutions: Print out all solutions for all requested states. Detects multiple solutions of the QP equations.
:vartype PrintAllSolutions: BoolType | BoolKey
:ivar PrintImaginaryAxisData: If true, print out the self-energy on the imaginary axis.
:vartype PrintImaginaryAxisData: BoolType | BoolKey
:ivar PrintSpectralFunction: Plot the self-energy as a function of frequency. Automatically done in case of analytical continuation. However, this is expensive in the analytical integration formalism.
:vartype PrintSpectralFunction: BoolType | BoolKey
:ivar PrintZfactor:
:vartype PrintZfactor: BoolType | BoolKey
:ivar QPHamiltonian: The quasi-particle Hamiltonian can be constructed in different ways.
KSF1 refers to the original construction by Kotani, Van Schilfgaarde anf Faleev (KSF) which is also implemented in TURBOMOLE.
KSF2 refers to an alternative construction by KSF.
KSF1 is not recommended since it is numerically less stable than KSF2 in case analytical continuation is used (the default).
In case the analytical integration algorithm is used, only KSF1 is implemented. Therefore, make sure that KSF1 is specified. The results are typically very similar.
The QP energies at which the matrix elements are evaluated can be tweaked further, see the two subsequent keys: However, KSF2 is recommended since it typically leads to QP energies with the best agreement with experiment.
Ignored when not a quasi-particle self-consistent GW calculation is performed
:vartype QPHamiltonian: Literal["KSF1", "KSF2", "SRG", "LQSGW"]
:ivar Scaling: Scale factor for the polarizability in the screened interaction SOS-GF2. Default = 1.0 (corresponds to no scaling)
:vartype Scaling: float | FloatKey
:ivar ScissorShift: Only calculate the HOMO and LUMO QP energies and shift the remaining QP energies by the same amount.
This is a rather crude approximation and not recommended.
It might again be useful for benchmarking purposes.
:vartype ScissorShift: BoolType | BoolKey
:ivar SelfConsistency: Sets the level of self-consistency in a GW calculation.
G0W0 calculates a one-shot, perturbative correction to the KS eigenvalues.
In evGW and evGW0, the quasi-particle energies are updated until self-consistency is reached.
evGW0 requests that the Green's function is evaluated self-consistently but not the screened interaction.
In qsGW, the density is updated as well, however, the self-energy is mapped to a static effective potential and the Dyson equation is solved by diagonalization instead of inversion. The results of a qsGW are independent of the choice of the underlying exchange-correlation functional and are usually the most accurate ones.
The same is done in qsGW0, but the screened interaction is not updated.
:vartype SelfConsistency: Literal["None", "G0W0", "EVGW0", "EVGW", "QSGW0", "QSGW"]
:ivar SelfConsistentSigmaVertex: If active, evaluate the vertex correction in Sigma in qsGW self-consistent. Only supported for GWGammaInf so far
:vartype SelfConsistentSigmaVertex: BoolType | BoolKey
:ivar SelfEnergy: Controls the form of the self-energy.
GW is the default and corresponds to the standard GW calculation.
G3W2 is a GW calculation plus a perturbative second-order statically screened exchange correction (second order expansion in the self-energy). Note, that there the self-energy is always static.
:vartype SelfEnergy: Literal["HF", "GW", "G3W2", "SOSEX", "GWGamma", "G3W2dynamic", "GWGammaInf", "GWGammaInfDyn"]
:ivar TabulateGridPoints: pretabulate grid points for numerical integration.
:vartype TabulateGridPoints: BoolType | BoolKey
:ivar nIterations: The maximum number of iterations within the (partially or fully) self-consistent GW calculation has to converge.
Ignored when Formalism is set to G0W0
:vartype nIterations: Iterable[int] | IntListKey
:ivar nLowest: Number of lowest occupied QP levels to be evaluated, overwrites nStates'
:vartype nLowest: int | IntKey
:ivar nStates: Number of Quasiparticle States to be printed to output.
The default is 5 states which in this case means that min(5, Number of particle states) occupied and min(5, Number of hole states) hole states are printed. The whole list of states can be printed by setting this parameter to -1'
:vartype nStates: int | IntKey
:ivar preconditionQSGW: If true, the QSGW equations are solved but prior to each diagonalization, i.e. a G0W0 calculation is performed to find the optimal QP energies at which to analytically continue the self-energy.
This is in principle a more consistent construction than KSF1 or KSF2 since the diagonal elements are consistent with G0W0.
In KSF1 and KSF2, the diagonal elements are evaluated at the QP energies from the previous iteration which is equivalent to a zeroth-order Taylor expansion of the diagonal elements around the previous QP energies.\Enabling this option typically leads to slightly lower QP energies.
:vartype preconditionQSGW: BoolType | BoolKey
:ivar AnalyticalIntegration: Use analytical integration to calculate the self-energy. Very slow, unless the system is very small but useful to check the accuracy of the frequency integration
:vartype AnalyticalIntegration: OLEDProperties._GW._AnalyticalIntegration
:ivar Converge: Sets convergence criteria for the GW calculation in self-consistent case
:vartype Converge: OLEDProperties._GW._Converge
"""
[docs] class _AnalyticalIntegration(FixedBlock):
r"""
Use analytical integration to calculate the self-energy. Very slow, unless the system is very small but useful to check the accuracy of the frequency integration
:ivar Enabled: Enable the calculation of the GW quasi-particle energies via analytical integration.
:vartype Enabled: BoolType | BoolKey
:ivar SpectralFunctionResolution: Number of points at which spectral function is evaluated.
:vartype SpectralFunctionResolution: int | IntKey
:ivar TDA: Solve the linear response equations in the Tamm-Dancoff approximation.
:vartype TDA: BoolType | BoolKey
:ivar eta: Artificial (positive) broadening parameter for evaluation of self-energy in analytical integration.
Ideally should be as small as possible but this might lead to convergence issues in partially self-consistent approaches.
In this case, a value of up to 0.1 is possible.
:vartype eta: float | FloatKey
:ivar printBSEexcitationsInLastIteration: Print out BSE excitations in the last iteration in a qsGW calculation. Can be used in the BAND engine.
In ADF, one should instead just calculate excitation energies using the excitation block.
:vartype printBSEexcitationsInLastIteration: BoolType | BoolKey
"""
def __post_init__(self):
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable the calculation of the GW quasi-particle energies via analytical integration.', gui_name='analytical integration:', default=False)
self.SpectralFunctionResolution: int | IntKey = IntKey(name='SpectralFunctionResolution', comment='Number of points at which spectral function is evaluated.', default=800)
self.TDA: BoolType | BoolKey = BoolKey(name='TDA', comment='Solve the linear response equations in the Tamm-Dancoff approximation.', default=False)
self.eta: float | FloatKey = FloatKey(name='eta', comment='Artificial (positive) broadening parameter for evaluation of self-energy in analytical integration.\n\nIdeally should be as small as possible but this might lead to convergence issues in partially self-consistent approaches.\n\nIn this case, a value of up to 0.1 is possible.', default=0.001)
self.printBSEexcitationsInLastIteration: BoolType | BoolKey = BoolKey(name='printBSEexcitationsInLastIteration', comment='Print out BSE excitations in the last iteration in a qsGW calculation. Can be used in the BAND engine.\n\nIn ADF, one should instead just calculate excitation energies using the excitation block.', hidden=True, default=False)
[docs] class _Converge(FixedBlock):
r"""
Sets convergence criteria for the GW calculation in self-consistent case
:ivar Density: First Criterion for self-consistency procedure to terminate.
Criterion is the trace of the density matrix. Ignored in non-selfconsistent Calculation and in eigenvalue self-consistent GW
It is possible to run a qsGW calculation with an inner SCF loop which updates the static part of the elf-energy only. This can be useful to accelerate the convergence in case linear mixing is used. It is not recommended to use linear mixing, so it is also not recommended to use that inner loop as well. The second number in this list specifies the convergence criterion for the inner SCF loop.
:vartype Density: Iterable[float] | FloatListKey
:ivar HOMO: Criterion for self-consistency procedure to terminate.
The self-consistent GW calculation terminates, when the difference between the HOMO QP energies between 2 consecutive iterations is below this number.
The LUMO energy converged faster than the HOMO energy so when the HOMO energy is converged according to this criterion, the LUMO energy will be converged as well.
In non-selfconsistent Calculation, this criterion is ignored.
:vartype HOMO: float | FloatKey
"""
def __post_init__(self):
self.Density: Iterable[float] | FloatListKey = FloatListKey(name='Density', comment='First Criterion for self-consistency procedure to terminate.\n\nCriterion is the trace of the density matrix. Ignored in non-selfconsistent Calculation and in eigenvalue self-consistent GW\n\nIt is possible to run a qsGW calculation with an inner SCF loop which updates the static part of the elf-energy only. This can be useful to accelerate the convergence in case linear mixing is used. It is not recommended to use linear mixing, so it is also not recommended to use that inner loop as well. The second number in this list specifies the convergence criterion for the inner SCF loop.', default=[1e-08, 1e-05], gui_type='nfloat 2')
self.HOMO: float | FloatKey = FloatKey(name='HOMO', comment='Criterion for self-consistency procedure to terminate.\n\nThe self-consistent GW calculation terminates, when the difference between the HOMO QP energies between 2 consecutive iterations is below this number.\n\nThe LUMO energy converged faster than the HOMO energy so when the HOMO energy is converged according to this criterion, the LUMO energy will be converged as well.\n\nIn non-selfconsistent Calculation, this criterion is ignored.', gui_name='HOMO energy convergence:', default=0.003, unit='eV')
def __post_init__(self):
self.AdaptiveMixing: Iterable[float] | FloatListKey = FloatListKey(name='AdaptiveMixing', comment="Requests to use adaptive mixing instead of DIIS and sets the staring mixing parameter for mixing of Green's function in case of self-consistency.\n\nAdapative mixing is recommended in case a qsGW calculation does not converge with DIIS.\n\nIt is ignored in non-selfconsistent calculation and overwritten by DIIS when DIIS is also present.", gui_type='nfloat 1')
self.DIIS: int | IntKey = IntKey(name='DIIS', comment='Requests to use DIIS. This is the Default. Number of expansion coefficients can be requested as well. Ignored in non-selfconsistent calculation', default=10)
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable the calculation of the GW quasi-particle energies.', gui_name='Calculate GW quasi-particle energies:', default=False)
self.ExpansionOrder: int | IntKey = IntKey(name='ExpansionOrder', comment='Order of the expansion of the screened interaction on the SOS-GF(n) method. order 2 (=SOS-GF2) is the default', hidden=True, default=2)
self.FixedGridSizes: BoolType | BoolKey = BoolKey(name='FixedGridSizes', comment='In a self-consistent GW calculation, recalculate Grids but keep them the same size during the SCF procedure.', hidden=True, default=True)
self.FixedGrids: BoolType | BoolKey = BoolKey(name='FixedGrids', comment='In a self-consistent GW calculation, do not recalculate Grids. Can be useful in case of convergence problems. Only relevant for qsGW and qsGW0. In case of evGW and evGW0, the grids are always kept fixed.', hidden=True, default=False)
self.G3W2: Literal["Full", "Diagonal", "Perturbative"] = MultipleChoiceKey(name='G3W2', comment='Only relevant when self-energy is one of GF2 or G3W2: Full requests that the second-order term is evaluated for the full self-energy matrix. This is very expensive and should only be done for small systems. Diagonal requests, that only the Diagonal of the self-energy matrix is updated. Perturbative means, that only a second-order screened exchange correction is evaluated after the GW calculation is completed. For a G0W0 calculation, all of these options are equivalent.', hidden=True, default='Perturbative', choices=['Full', 'Diagonal', 'Perturbative'])
self.LinearMixing: Iterable[float] | FloatListKey = FloatListKey(name='LinearMixing', comment="Requests to use linear mixing instead of DIIS and sets the mixing parameter for linear mixing of Green's function in case of self-consistency.\n\nIt is ignored in non-selfconsistent calculation and overwritten by DIIS when DIIS is also present.", gui_type='nfloat 1')
self.LinearizeQPequations: BoolType | BoolKey = BoolKey(name='LinearizeQPequations', comment='Instead of solving the non-linear QP equations in a G0W0 (or evGW calculation) by bisection exacly, linearize them by first-order Taylor expansion.\n\nThis is not recommended since it does not save computational time when used together with analytical continuation (as implemented in AMS). It might however be useful for benchmarking or for validating results.\n\nIf the results os the linearization differ by a lot (for instance, more than 0.1 eV in frontier QP energies) from the non-linearized results, this might indicate that the GW calculation is not reliable.', default=False)
self.OffDiagonalEFermi: BoolType | BoolKey = BoolKey(name='OffDiagonalEFermi', comment='Analytically continue the off-diagonal elements of the KSF2 qsGW Hamiltonian at the Fermi-energy instead of omega=0. Typically leads to slightly lower QP energies, i.e. higher ionization potentials. The HOMO-LUMO gaps are typically not affected.', hidden=True, default=False)
self.Polarizability: Literal["RPA", "BSE", "G4W1", "G4V1", "TDHF"] = MultipleChoiceKey(name='Polarizability', comment='Sets the expression for the Polarizability used in the GW calculation.\n\nRPA is the Default and amounts to a standard GW calculation.\n\nBSE denotes screening in the Bethe-Salpeter-equation formalism.', default='RPA', choices=['RPA', 'BSE', 'G4W1', 'G4V1', 'TDHF'])
self.PrintAllSolutions: BoolType | BoolKey = BoolKey(name='PrintAllSolutions', comment='Print out all solutions for all requested states. Detects multiple solutions of the QP equations.', default=False)
self.PrintImaginaryAxisData: BoolType | BoolKey = BoolKey(name='PrintImaginaryAxisData', comment='If true, print out the self-energy on the imaginary axis.', hidden=True, default=False)
self.PrintSpectralFunction: BoolType | BoolKey = BoolKey(name='PrintSpectralFunction', comment='Plot the self-energy as a function of frequency. Automatically done in case of analytical continuation. However, this is expensive in the analytical integration formalism.', default=False)
self.PrintZfactor: BoolType | BoolKey = BoolKey(name='PrintZfactor', hidden=True, default=False)
self.QPHamiltonian: Literal["KSF1", "KSF2", "SRG", "LQSGW"] = MultipleChoiceKey(name='QPHamiltonian', comment='The quasi-particle Hamiltonian can be constructed in different ways.\n\nKSF1 refers to the original construction by Kotani, Van Schilfgaarde anf Faleev (KSF) which is also implemented in TURBOMOLE.\n\nKSF2 refers to an alternative construction by KSF.\n\nKSF1 is not recommended since it is numerically less stable than KSF2 in case analytical continuation is used (the default).\n\nIn case the analytical integration algorithm is used, only KSF1 is implemented. Therefore, make sure that KSF1 is specified. The results are typically very similar.\n\nThe QP energies at which the matrix elements are evaluated can be tweaked further, see the two subsequent keys: However, KSF2 is recommended since it typically leads to QP energies with the best agreement with experiment.\n\nIgnored when not a quasi-particle self-consistent GW calculation is performed', default='KSF2', choices=['KSF1', 'KSF2', 'SRG', 'LQSGW'])
self.Scaling: float | FloatKey = FloatKey(name='Scaling', comment='Scale factor for the polarizability in the screened interaction SOS-GF2. Default = 1.0 (corresponds to no scaling)', hidden=True, default=1.0)
self.ScissorShift: BoolType | BoolKey = BoolKey(name='ScissorShift', comment='Only calculate the HOMO and LUMO QP energies and shift the remaining QP energies by the same amount.\n\nThis is a rather crude approximation and not recommended.\n\nIt might again be useful for benchmarking purposes.', default=False)
self.SelfConsistency: Literal["None", "G0W0", "EVGW0", "EVGW", "QSGW0", "QSGW"] = MultipleChoiceKey(name='SelfConsistency', comment="Sets the level of self-consistency in a GW calculation.\n\nG0W0 calculates a one-shot, perturbative correction to the KS eigenvalues.\n\nIn evGW and evGW0, the quasi-particle energies are updated until self-consistency is reached.\n\nevGW0 requests that the Green's function is evaluated self-consistently but not the screened interaction.\n\nIn qsGW, the density is updated as well, however, the self-energy is mapped to a static effective potential and the Dyson equation is solved by diagonalization instead of inversion. The results of a qsGW are independent of the choice of the underlying exchange-correlation functional and are usually the most accurate ones.\n\nThe same is done in qsGW0, but the screened interaction is not updated.", default='G0W0', choices=['None', 'G0W0', 'EVGW0', 'EVGW', 'QSGW0', 'QSGW'], hiddenchoices=['None'])
self.SelfConsistentSigmaVertex: BoolType | BoolKey = BoolKey(name='SelfConsistentSigmaVertex', comment='If active, evaluate the vertex correction in Sigma in qsGW self-consistent. Only supported for GWGammaInf so far', hidden=True, default=False)
self.SelfEnergy: Literal["HF", "GW", "G3W2", "SOSEX", "GWGamma", "G3W2dynamic", "GWGammaInf", "GWGammaInfDyn"] = MultipleChoiceKey(name='SelfEnergy', comment='Controls the form of the self-energy. \n\nGW is the default and corresponds to the standard GW calculation.\n\nG3W2 is a GW calculation plus a perturbative second-order statically screened exchange correction (second order expansion in the self-energy). Note, that there the self-energy is always static.', default='GW', choices=['HF', 'GW', 'G3W2', 'SOSEX', 'GWGamma', 'G3W2dynamic', 'GWGammaInf', 'GWGammaInfDyn'])
self.TabulateGridPoints: BoolType | BoolKey = BoolKey(name='TabulateGridPoints', comment='pretabulate grid points for numerical integration.', hidden=True, default=False)
self.nIterations: Iterable[int] | IntListKey = IntListKey(name='nIterations', comment='The maximum number of iterations within the (partially or fully) self-consistent GW calculation has to converge.\n\nIgnored when Formalism is set to G0W0', gui_name='Number of iterations:', default=[10], gui_type='nint 1')
self.nLowest: int | IntKey = IntKey(name='nLowest', comment="Number of lowest occupied QP levels to be evaluated, overwrites nStates'", gui_name='N Lowest:', default=1)
self.nStates: int | IntKey = IntKey(name='nStates', comment="Number of Quasiparticle States to be printed to output.\n\nThe default is 5 states which in this case means that min(5, Number of particle states) occupied and min(5, Number of hole states) hole states are printed. The whole list of states can be printed by setting this parameter to -1'", gui_name='N states:', default=5)
self.preconditionQSGW: BoolType | BoolKey = BoolKey(name='preconditionQSGW', comment='If true, the QSGW equations are solved but prior to each diagonalization, i.e. a G0W0 calculation is performed to find the optimal QP energies at which to analytically continue the self-energy.\n\nThis is in principle a more consistent construction than KSF1 or KSF2 since the diagonal elements are consistent with G0W0.\n\nIn KSF1 and KSF2, the diagonal elements are evaluated at the QP energies from the previous iteration which is equivalent to a zeroth-order Taylor expansion of the diagonal elements around the previous QP energies.\\Enabling this option typically leads to slightly lower QP energies.', hidden=True, default=False)
self.AnalyticalIntegration: OLEDProperties._GW._AnalyticalIntegration = self._AnalyticalIntegration(name='AnalyticalIntegration', comment='Use analytical integration to calculate the self-energy. Very slow, unless the system is very small but useful to check the accuracy of the frequency integration')
self.Converge: OLEDProperties._GW._Converge = self._Converge(name='Converge', comment='Sets convergence criteria for the GW calculation in self-consistent case')
[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 _MBPT(FixedBlock):
r"""
Technical aspects of the MP2 algorithm.
:ivar Dependency: If true, to improve numerical stability, almost linearly-dependent combination of basis functions are removed from the Green's function that are used in the MBPT equations. Disabling this key is strongly discouraged. Its value can however be changed. The key to adjust this value is RiHartreeFock%DependencyThreshold
:vartype Dependency: BoolType | BoolKey
:ivar Enabled: Enable the calculation of the MP2 energy.
:vartype Enabled: BoolType | BoolKey
:ivar ExcludeCore: If active, excludes core states from the calculation of the optimal imaginary time and frequency grids.
The core states are still included in all parts of the calculations.
In case a frozen care calculation is performed, this key is ignored.
For MP2 and double hybrid calculation, it defaults to false. For RPA and GW calculations, it defaults to true.
:vartype ExcludeCore: BoolType | BoolKey
:ivar FitSetQuality: Specifies the fit set to be used in the MBPT calculation.
'Normal' quality is generally sufficient for basis sets up to and including TZ2P.
For larger basis sets (or for benchmarking purposes) a 'VeryGood' fit set is recommended. Note that the FitSetQuality heavily influences the computational cost of the calculation.
If not specified or 'Auto', the RIHartreeFock%FitSetQuality is used.
:vartype FitSetQuality: Literal["Auto", "VeryBasic", "Basic", "Normal", "Good", "VeryGood"]
:ivar Formalism: Specifies the formalism for the calculation of the MP2 correlation energy.
'LT' means Laplace Transformed MP2 (also referred to as AO-PARI-MP2),
'RI' means that a conventional RI-MP2 is carried out.
If 'Auto', LT will be used in case of DOD double hybrids and SOS MP2, and RI will be used in all other cases.
'All' means that both RI and LT formalisms are used in the calculation.
For a RPA or GW calculation, the formalism is always LT, irrespective of the formalism specified with this key.
:vartype Formalism: Literal["Auto", "RI", "LT", "All"]
:ivar FrequencyGridType: Use Gauss-legendre grid for imaginary frequency integration in RPA and GW calculations instead of the usually used Least-Square optimized ones. Has the advantage that it can be systematically converged and an arbitrary number of grid points can be used. Typically more grid points will be needed to get the same level of accuracy. However, the convergence of the results with the size of the grid can be more systematic. These grids can only be used when Formalism is set to RI.
:vartype FrequencyGridType: Literal["LeastSquare", "GaussLegendre"]
:ivar IntegrationQuality: Specifies the integration quality to be used in the MBPT calculation. If not specified, the RIHartreeFock%IntegrationQuality is used.
:vartype IntegrationQuality: Literal["VeryBasic", "Basic", "Normal", "Good", "VeryGood"]
:ivar PrintOutSigma: Print out additional output for sigma-functional for parametrization.
:vartype PrintOutSigma: BoolType | BoolKey
:ivar SigmaFunctionalParametrization: Only relevant if a sigma-functional calculation is performed. Possible choices for the parametrization of the sigma-functional. Not all options are supported for all functionals.
:vartype SigmaFunctionalParametrization: Literal["W1", "W2", "S1", "S2", "S1re"]
:ivar ThresholdQuality: Controls the distances between atomic centers for which the product of two basis functions is not fitted any more. Especially for spatially extended, large systems, 'VERYBASIC' and 'BASIC' can lead to large computational savings, but the fit is also more approximate. If not specified, the RIHartreeFock%ThresholdQuality is used.
:vartype ThresholdQuality: Literal["VeryBasic", "Basic", "Normal", "Good", "VeryGood", "Excellent"]
:ivar UseScaledZORA: If true, use the scaled ZORA orbital energies instead of the ZORA orbital energies in the MBPT equations.
:vartype UseScaledZORA: BoolType | BoolKey
:ivar cutOfftransition: Energy above which states are ignored in a MBPT calculation (must be a positive number). The default energy is chosen so high, that all states are included except for the ones which have been removed.
:vartype cutOfftransition: float | FloatKey
:ivar frozencore: Freeze core states in correlation part of MBPT calculation
:vartype frozencore: BoolType | BoolKey
:ivar nCore: Number of core states which will be excluded from the correlated calculation.
Will be ignored if frozencore is false.
In case nothing is specified, the number of core levels will be determined automatically.
Needs to be smaller than the number of occupied states.
:vartype nCore: int | IntKey
:ivar nFreqIntegration: Number of imaginary frequency points for G3W2 integration
:vartype nFreqIntegration: int | IntKey
:ivar nFrequency: Number of imaginary frequency points. This key is only relevant for RPA and GW and will be ignored if used in an AO-PARI-MP2 calculation. 12 Points is the default for a RPA calculation. It is technically possible to use a different number of imaginary frequency points than for imaginary time. The maximum number of points which can be requested for imaginary frequency integration is 42. Important note: The computation time and memory requirements roughly scale linearly with the number of imaginary frequency points. However, memory can be an issue for RPA and GW when the number of imaginary frequency points is high. In case a job crashes, it is advised to increase the number of nodes since the necessary memory distributes over all nodes.
:vartype nFrequency: int | IntKey
:ivar nLambda: Size of coupling constant integration grid for SOSEX variants in RPA. Default is 4 points
:vartype nLambda: int | IntKey
:ivar nTime: Number of imaginary time points (only relevant in case the Laplace Transformed (LT) formalism is used).
In the many-body-perturbation theory module in ADF, the polarizability (or Kohn-Sham density response function) is evaluated in imaginary time to exploit sparsity in the AO basis. For MP2, this is often referred to as a Laplace transform. For MP2, 9 points are the default. This is a safe choice, guaranteeing accuracies higher than 1 Kj/mol for most systems (For many simple organic systems, 6 points are sufficient for good accuracy).
Only for systems with a very small HOMO-LUMO gap or low-lying core states (heavy elements starting from the 4th row of the periodic table) more points might be necessary.
In principle, the same considerations apply for RPA and GW as well, however, the accuracy requirements are somewhat higher and 12 point are the default for RPA. In a GW calculation, the number of points is adjusted according to the numerical quality. Using less than 9 points is strongly discouraged except for the simplest molecules.
In ADF2019, it can happen that the algorithm determining the imaginary time grid does not converge. In this case, the usual reason is that the number of points is too small and more points need to be specified. Starting from AMS2020, this does not happen any more. In case the imaginary time grid does not converge, the number of points is automatically adjusted until it does.
The computation time of AO-PARI-MP2, RPA, and GW scales linearly with the number of imaginary time points.
:vartype nTime: int | IntKey
:ivar useGreenXgrids: Use GreenX library to generate grid points. This is recommended for larger number of grid points (> 20). Up to 34 points can be requested.
:vartype useGreenXgrids: BoolType | BoolKey
"""
def __post_init__(self):
self.Dependency: BoolType | BoolKey = BoolKey(name='Dependency', comment="If true, to improve numerical stability, almost linearly-dependent combination of basis functions are removed from the Green's function that are used in the MBPT equations. Disabling this key is strongly discouraged. Its value can however be changed. The key to adjust this value is RiHartreeFock%DependencyThreshold", default=True)
self.Enabled: BoolType | BoolKey = BoolKey(name='Enabled', comment='Enable the calculation of the MP2 energy.', hidden=True, default=False)
self.ExcludeCore: BoolType | BoolKey = BoolKey(name='ExcludeCore', comment='If active, excludes core states from the calculation of the optimal imaginary time and frequency grids.\n\nThe core states are still included in all parts of the calculations.\n\nIn case a frozen care calculation is performed, this key is ignored.\n\nFor MP2 and double hybrid calculation, it defaults to false. For RPA and GW calculations, it defaults to true.')
self.FitSetQuality: Literal["Auto", "VeryBasic", "Basic", "Normal", "Good", "VeryGood"] = MultipleChoiceKey(name='FitSetQuality', comment="Specifies the fit set to be used in the MBPT calculation.\n\n'Normal' quality is generally sufficient for basis sets up to and including TZ2P.\n\nFor larger basis sets (or for benchmarking purposes) a 'VeryGood' fit set is recommended. Note that the FitSetQuality heavily influences the computational cost of the calculation.\n\nIf not specified or 'Auto', the RIHartreeFock%FitSetQuality is used.", default='Auto', choices=['Auto', 'VeryBasic', 'Basic', 'Normal', 'Good', 'VeryGood'])
self.Formalism: Literal["Auto", "RI", "LT", "All"] = MultipleChoiceKey(name='Formalism', comment="Specifies the formalism for the calculation of the MP2 correlation energy.\n\n'LT' means Laplace Transformed MP2 (also referred to as AO-PARI-MP2),\n\n'RI' means that a conventional RI-MP2 is carried out.\n\nIf 'Auto', LT will be used in case of DOD double hybrids and SOS MP2, and RI will be used in all other cases.\n\n'All' means that both RI and LT formalisms are used in the calculation.\n\nFor a RPA or GW calculation, the formalism is always LT, irrespective of the formalism specified with this key.", default='Auto', choices=['Auto', 'RI', 'LT', 'All'])
self.FrequencyGridType: Literal["LeastSquare", "GaussLegendre"] = MultipleChoiceKey(name='FrequencyGridType', comment='Use Gauss-legendre grid for imaginary frequency integration in RPA and GW calculations instead of the usually used Least-Square optimized ones. Has the advantage that it can be systematically converged and an arbitrary number of grid points can be used. Typically more grid points will be needed to get the same level of accuracy. However, the convergence of the results with the size of the grid can be more systematic. These grids can only be used when Formalism is set to RI.', default='LeastSquare', choices=['LeastSquare', 'GaussLegendre'])
self.IntegrationQuality: Literal["VeryBasic", "Basic", "Normal", "Good", "VeryGood"] = MultipleChoiceKey(name='IntegrationQuality', comment='Specifies the integration quality to be used in the MBPT calculation. If not specified, the RIHartreeFock%IntegrationQuality is used.', choices=['VeryBasic', 'Basic', 'Normal', 'Good', 'VeryGood'])
self.PrintOutSigma: BoolType | BoolKey = BoolKey(name='PrintOutSigma', comment='Print out additional output for sigma-functional for parametrization. ', hidden=True, default=False)
self.SigmaFunctionalParametrization: Literal["W1", "W2", "S1", "S2", "S1re"] = MultipleChoiceKey(name='SigmaFunctionalParametrization', comment='Only relevant if a sigma-functional calculation is performed. Possible choices for the parametrization of the sigma-functional. Not all options are supported for all functionals.', default='S1re', choices=['W1', 'W2', 'S1', 'S2', 'S1re'])
self.ThresholdQuality: Literal["VeryBasic", "Basic", "Normal", "Good", "VeryGood", "Excellent"] = MultipleChoiceKey(name='ThresholdQuality', comment="Controls the distances between atomic centers for which the product of two basis functions is not fitted any more. Especially for spatially extended, large systems, 'VERYBASIC' and 'BASIC' can lead to large computational savings, but the fit is also more approximate. If not specified, the RIHartreeFock%ThresholdQuality is used.", choices=['VeryBasic', 'Basic', 'Normal', 'Good', 'VeryGood', 'Excellent'])
self.UseScaledZORA: BoolType | BoolKey = BoolKey(name='UseScaledZORA', comment='If true, use the scaled ZORA orbital energies instead of the ZORA orbital energies in the MBPT equations.', default=True)
self.cutOfftransition: float | FloatKey = FloatKey(name='cutOfftransition', comment='Energy above which states are ignored in a MBPT calculation (must be a positive number). The default energy is chosen so high, that all states are included except for the ones which have been removed.', hidden=True, default=20000000000.0)
self.frozencore: BoolType | BoolKey = BoolKey(name='frozencore', comment='Freeze core states in correlation part of MBPT calculation', default=False)
self.nCore: int | IntKey = IntKey(name='nCore', comment='Number of core states which will be excluded from the correlated calculation.\n\nWill be ignored if frozencore is false.\n\nIn case nothing is specified, the number of core levels will be determined automatically.\n\nNeeds to be smaller than the number of occupied states.', gui_name='Number of core levels:', default=0)
self.nFreqIntegration: int | IntKey = IntKey(name='nFreqIntegration', comment='Number of imaginary frequency points for G3W2 integration', gui_name='N freq points for G3W2 integration:', default=32)
self.nFrequency: int | IntKey = IntKey(name='nFrequency', comment='Number of imaginary frequency points. This key is only relevant for RPA and GW and will be ignored if used in an AO-PARI-MP2 calculation. 12 Points is the default for a RPA calculation. It is technically possible to use a different number of imaginary frequency points than for imaginary time. The maximum number of points which can be requested for imaginary frequency integration is 42. Important note: The computation time and memory requirements roughly scale linearly with the number of imaginary frequency points. However, memory can be an issue for RPA and GW when the number of imaginary frequency points is high. In case a job crashes, it is advised to increase the number of nodes since the necessary memory distributes over all nodes.', gui_name='N freq points:', default=12)
self.nLambda: int | IntKey = IntKey(name='nLambda', comment='Size of coupling constant integration grid for SOSEX variants in RPA. Default is 4 points', gui_name='Number of lambda points:', default=1)
self.nTime: int | IntKey = IntKey(name='nTime', comment='Number of imaginary time points (only relevant in case the Laplace Transformed (LT) formalism is used).\n\nIn the many-body-perturbation theory module in ADF, the polarizability (or Kohn-Sham density response function) is evaluated in imaginary time to exploit sparsity in the AO basis. For MP2, this is often referred to as a Laplace transform. For MP2, 9 points are the default. This is a safe choice, guaranteeing accuracies higher than 1 Kj/mol for most systems (For many simple organic systems, 6 points are sufficient for good accuracy).\n\nOnly for systems with a very small HOMO-LUMO gap or low-lying core states (heavy elements starting from the 4th row of the periodic table) more points might be necessary.\n\nIn principle, the same considerations apply for RPA and GW as well, however, the accuracy requirements are somewhat higher and 12 point are the default for RPA. In a GW calculation, the number of points is adjusted according to the numerical quality. Using less than 9 points is strongly discouraged except for the simplest molecules.\n\nIn ADF2019, it can happen that the algorithm determining the imaginary time grid does not converge. In this case, the usual reason is that the number of points is too small and more points need to be specified. Starting from AMS2020, this does not happen any more. In case the imaginary time grid does not converge, the number of points is automatically adjusted until it does.\n\nThe computation time of AO-PARI-MP2, RPA, and GW scales linearly with the number of imaginary time points.', gui_name='Number of time points:')
self.useGreenXgrids: BoolType | BoolKey = BoolKey(name='useGreenXgrids', comment='Use GreenX library to generate grid points. This is recommended for larger number of grid points (> 20). Up to 34 points can be requested.', default=False)
[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: OLEDProperties._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: OLEDProperties._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: OLEDProperties._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: OLEDProperties._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: OLEDProperties._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: OLEDProperties._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)
[docs] class _TransferIntegrals(FixedBlock):
r"""
Configures the details of the calculation of electron and hole transfer integrals.
:ivar Type: The method used for the calculation of the transfer integrals.
:vartype Type: Literal["None", "DFTB", "Fast", "Full"]
:ivar Exclude: Configures which dimers NOT to calculate transfer integrals for.
:vartype Exclude: OLEDProperties._TransferIntegrals._Exclude
:ivar Include: Configures which dimers transfer integrals are calculated for.
:vartype Include: OLEDProperties._TransferIntegrals._Include
"""
[docs] class _Exclude(FixedBlock):
r"""
Configures which dimers NOT to calculate transfer integrals for.
:ivar Cutoff: Exclude dimers for which the distance is larger than this threshold. Acts as a quick pre-screening to reduce the number of dimers to calculate transfer integrals for.
:vartype Cutoff: float | FloatKey
:ivar Metric: The metric used to calculate the distance between two molecules.
• CoM: use the distance between the centers of mass of the two molecules.
• Atoms: Use the distance between the two closest atoms of two molecules.
• Atoms_noH: Use the distance between the closest non-hydrogen atoms of the two molecules.
:vartype Metric: Literal["CoM", "Atoms", "Atoms_noH"]
"""
def __post_init__(self):
self.Cutoff: float | FloatKey = FloatKey(name='Cutoff', comment='Exclude dimers for which the distance is larger than this threshold. Acts as a quick pre-screening to reduce the number of dimers to calculate transfer integrals for.', gui_name='Exclude beyond:', default=4.0, unit='Angstrom')
self.Metric: Literal["CoM", "Atoms", "Atoms_noH"] = MultipleChoiceKey(name='Metric', comment='The metric used to calculate the distance between two molecules.\n\n• CoM: use the distance between the centers of mass of the two molecules.\n\n• Atoms: Use the distance between the two closest atoms of two molecules. \n\n• Atoms_noH: Use the distance between the closest non-hydrogen atoms of the two molecules.', default='Atoms', choices=['CoM', 'Atoms', 'Atoms_noH'], gui_type='literal choices')
[docs] class _Include(FixedBlock):
r"""
Configures which dimers transfer integrals are calculated for.
:ivar Cutoff: Transfer integrals will be calculated for all molecule pairs within a cutoff distance from each other. This distance can be measured using different metrics, see the corresponding ``Metric`` keyword.
:vartype Cutoff: float | FloatKey
:ivar Metric: The metric used to calculate the distance between two molecules.
• CoM: use the distance between the centers of mass of the two molecules.
• Atoms: Use the distance between the two closest atoms of two molecules.
• Atoms_noH: Use the distance between the closest non-hydrogen atoms of the two molecules.
:vartype Metric: Literal["CoM", "Atoms", "Atoms_noH"]
"""
def __post_init__(self):
self.Cutoff: float | FloatKey = FloatKey(name='Cutoff', comment='Transfer integrals will be calculated for all molecule pairs within a cutoff distance from each other. This distance can be measured using different metrics, see the corresponding ``Metric`` keyword.', gui_name='Include within:', default=4.0, unit='Angstrom')
self.Metric: Literal["CoM", "Atoms", "Atoms_noH"] = MultipleChoiceKey(name='Metric', comment='The metric used to calculate the distance between two molecules.\n\n• CoM: use the distance between the centers of mass of the two molecules.\n\n• Atoms: Use the distance between the two closest atoms of two molecules. \n\n• Atoms_noH: Use the distance between the closest non-hydrogen atoms of the two molecules.', default='Atoms', choices=['CoM', 'Atoms', 'Atoms_noH'], gui_type='literal choices')
def __post_init__(self):
self.Type: Literal["None", "DFTB", "Fast", "Full"] = MultipleChoiceKey(name='Type', comment='The method used for the calculation of the transfer integrals.', default='Fast', choices=['None', 'DFTB', 'Fast', 'Full'], hiddenchoices=['DFTB'])
self.Exclude: OLEDProperties._TransferIntegrals._Exclude = self._Exclude(name='Exclude', comment='Configures which dimers NOT to calculate transfer integrals for.')
self.Include: OLEDProperties._TransferIntegrals._Include = self._Include(name='Include', comment='Configures which dimers transfer integrals are calculated for.')
def __post_init__(self):
self.CoresPerJob: int | IntKey = IntKey(name='CoresPerJob', comment='The number of CPU cores used for each job in the workflow. Combined with the total number of cores used (set by the ``NSCM`` environment variable or the ``-n`` command line argument), this indirectly determines the number of simultaneously running jobs. The default value should usually be a good choice. When changing this value, make sure you are using all allocated cores by setting a value that divides the total number of cores, as well as the number of cores on each node.', default=8)
self.LogProgressEvery: float | FloatKey = FloatKey(name='LogProgressEvery', comment='How often to print progress information to the logfile.', default=600.0, unit='Seconds')
self.NumAdditionalOrbitalEnergies: int | IntKey = IntKey(name='NumAdditionalOrbitalEnergies', comment='The number of additional orbital energies to write to the HDF5 file. A value of N means to write everything up to HOMO-N and LUMO+N.', default=1)
self.NumExcitations: int | IntKey = IntKey(name='NumExcitations', comment='The number of exited states to calculate. By default the S_1 and T_1 states will be calculated. The calculation of excited states is currently only supported for systems with a closed-shell ground state.', default=1)
self.NumSelectedMoleculesPerSpecies: int | IntKey = IntKey(name='NumSelectedMoleculesPerSpecies', comment='Number of molecules per species to calculate properties for. Around 50 molecules per species should be enough to estimate distribution means and standard deviations as input for the Bumblebee KMC code. Mutually exclusive with the ``SelectedMolecules`` keyword. If neither this key nor ``SelectedMolecules`` is present, all molecules will be selected.')
self.OccupationSmearing: Literal["None", "Ions", "All"] = MultipleChoiceKey(name='OccupationSmearing', comment='Determines for which systems the electron smearing feature in ADF will be used. If enabled, the molecular orbital occupations will be smeared out with a 300K Fermi-Dirac distribution. This makes SCF convergence easier, as the occupation of energetically close orbitals does not jump when their energetic order flips. See the ADF manual for details. It is recommended to keep this option enabled for the ionic systems, which are more likely to suffer from difficult SCF convergence.', default='Ions', choices=['None', 'Ions', 'All'])
self.Relax: Literal["None", "Neutral", "All"] = MultipleChoiceKey(name='Relax', comment='Which geometries to relax prior to taking the energy differences for the calculation of ionization potential and electron affinity. The relaxation is done at the DFTB level using the GFN1-xTB model Hamiltonian with electrostatic embedding in a UFF environment.\n\n• None: Use the geometries directly from the input.\n\n• Neutral: Relax the uncharged molecule and use its optimized geometry for the neutral as well as the ionic systems. This gives (approximately) the vertical ionization potential and electron affinity.\n\n• All: Individually relax the neutral systems and the ions before calculating the total energies. This gives (approximately) the adiabatic ionization potential and electron affinity.', default='All', choices=['None', 'Neutral', 'All'])
self.Restart: str | Path | StringKey = PathStringKey(name='Restart', comment='The HDF5 file from a previous calculation on the same morphology. Data already calculated on the restart file will just be copied over and not be recalculated.', ispath=True, gui_type='.hdf5 {{{HDF5 Result Files} .hdf5} {{Any Files} *}}')
self.SelectedMolecules: Iterable[int] | IntListKey = IntListKey(name='SelectedMolecules', comment='Indices of the molecules to calculate properties for. Note that indexing starts at 0. Mutually exclusive with the ``NumSelectedMoleculesPerSpecies`` keyword. If neither this key nor ``NumSelectedMoleculesPerSpecies`` is present, all molecules will be selected.')
self.StoreResultFiles: Literal["None", "Failed", "All"] = MultipleChoiceKey(name='StoreResultFiles', comment='Whether to keep the full result files from all the individual jobs. By default the result files from all jobs for a particular molecule will be deleted after all relevant results have been extracted and stored on the HDF5 file. Note that keeping the full results for all molecules can easily require hundreds of gigabytes of storage space.', default='Failed', choices=['None', 'Failed', 'All'])
self.Embedding: OLEDProperties._Embedding = self._Embedding(name='Embedding', comment='Configures details of how the environment is taken into account.')
self.GW: OLEDProperties._GW = self._GW(name='GW', comment='Perform a GW calculation. G0W0 is the default for GW%SelfConsistency.', extra_info='not_in_fragment')
self.LoadSystem: OLEDProperties._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.MBPT: OLEDProperties._MBPT = self._MBPT(name='MBPT', comment='Technical aspects of the MP2 algorithm.', extra_info='not_in_fragment')
self.System: OLEDProperties._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')
self.TransferIntegrals: OLEDProperties._TransferIntegrals = self._TransferIntegrals(name='TransferIntegrals', comment='Configures the details of the calculation of electron and hole transfer integrals.')