"""Pydantic model for the input of `pw.x` version `develop`.
This file has been generated automatically. Do not edit it manually.
"""
from pathlib import Path
from textwrap import dedent
from typing import Annotated, Literal
from pydantic import Field, field_validator
from pydantic_espresso.base import EspressoInput
from pydantic_espresso.models.pw.cards.atomic_forces import AtomicForce
from pydantic_espresso.models.pw.cards.atomic_positions import AtomicPositionsCard
from pydantic_espresso.models.pw.cards.atomic_species import AtomicSpecies
from pydantic_espresso.models.pw.cards.atomic_velocities import AtomicVelocity
from pydantic_espresso.models.pw.cards.cell_parameters import CellParametersCard
from pydantic_espresso.models.pw.cards.constraints import Constraint
from pydantic_espresso.models.pw.cards.hubbard import HubbardCard
from pydantic_espresso.models.pw.cards.k_points import KPointsCard
from pydantic_espresso.models.pw.cards.occupations import PositiveFloat0to1, PositiveFloat0to2
from pydantic_espresso.models.pw.cards.solvents import SolventsCard, SolventsLRCard
from pydantic_espresso.namelist import Namelist
from pydantic_espresso.quantity import Quantity
[docs]
class ControlNamelist(Namelist):
"""Pydantic model for the `CONTROL` namelist."""
[docs]
@field_validator("verbosity", mode="before")
@classmethod
def map_verbosity(cls, v: str) -> str:
"""Map equivalent values for `verbosity` onto a canonical value."""
mapping = {"medium": "high", "debug": "high", "default": "low", "minimal": "low"}
return mapping.get(v, v)
calculation: Literal["scf", "nscf", "bands", "relax", "md", "vc-relax", "vc-md"] = Field(
"scf",
description=dedent(
"""\
A string describing the task to be performed. Options are: (vc = variable-cell)."""
),
)
title: str | None = Field(None, description="reprinted on output.")
verbosity: Literal["high", "low"] = Field(
"low", description="Currently two verbosity levels are implemented:"
)
restart_mode: Literal["from_scratch", "restart"] = Field(
"from_scratch",
description=dedent(
"""\
Available options are:
- 'from_scratch': From scratch. This is the normal way to perform a PWscf calculation.
- 'restart': From previous interrupted run. Use this switch only if you want to
continue, using the same number of processors and parallelization, an interrupted
calculation. Do not use to start a new one, or to perform a non-scf calculations.
Works only if the calculation was cleanly stopped using variable max_seconds, or by
user request with an 'exit file' (i.e.: create a file 'prefix'.EXIT, in directory
'outdir'; see variables prefix, outdir). The default for startingwfc and startingpot
is set to 'file'."""
),
)
nstep: int | None = Field(
None,
json_schema_extra={
"conditional_default": [
{
"when": "calculation=='scf' || calculation=='nscf' || calculation=='bands'",
"value": "1",
},
{"when": None, "value": "50"},
],
},
description=dedent(
"""\
number of molecular-dynamics or structural optimization steps performed in this run. If
set to 0, the code performs a quick 'dry run', stopping just after initialization. This
is useful to check for input correctness and to have the summary printed. NOTE: in MD
calculations, the code will perform 'nstep' steps even if restarting from a previously
interrupted calculation."""
),
)
iprint: int = Field(
100000,
description=dedent(
"""\
When calculation == 'md' (molecular dynamics) trajectory is written every iprint md
steps. With the default value, output is written only at convergence."""
),
)
tstress: bool = Field(
False,
description=dedent(
"""\
calculate stress. It is set to .TRUE. automatically if calculation == 'vc-md' or
'vc-relax"""
),
)
tprnfor: bool = Field(
False,
description=dedent(
"""\
calculate forces. It is set to .TRUE. automatically if calculation ==
'relax','md','vc-md"""
),
)
dt: Annotated[
float, Quantity(units="bohr electron_mass^1/2 Ry^-1/2", dimensionality="time")
] = Field(
20.0,
description=dedent(
"""\
time step for molecular dynamics, in Rydberg atomic units (1 a.u.=4.8378 * 10^-17 s :
beware, the CP code uses Hartree atomic units, half that much!!!)"""
),
)
outdir: Path | None = Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "ESPRESSO_TMPDIR is set", "value": "from_environment"},
{"when": None, "value": "./"},
],
},
description="input, temporary, output files are found in this directory, see also wfcdir",
)
wfcdir: Path | None = Field(
None,
json_schema_extra={"default_ref": "outdir"},
description=dedent(
"""\
This directory specifies where to store files generated by each processor (*.wfc{N},
*.igk{N}, etc.). Useful for machines without a parallel file system: set wfcdir to a
local file system, while outdir should be a parallel or network file system, visible to
all processors. Beware: in order to restart from interrupted runs, or to perform
further calculations using the produced data files, you may need to copy files to
outdir. Works only for pw.x."""
),
)
prefix: str = Field(
"pwscf", description="prepended to input/output filenames: prefix.wfc, prefix.rho, etc."
)
max_seconds: Annotated[float, Quantity(units="s", dimensionality="time")] = Field(
10000000.0,
description=dedent(
"""\
Jobs stops after max_seconds CPU time. Use this option in conjunction with option
restart_mode if you need to split a job too long to complete into shorter jobs that fit
into your batch queues. The default value (10000000 s, about 150 days) effectively
means that no time limit is imposed."""
),
)
etot_conv_thr: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.0001,
description=dedent(
"""\
Convergence threshold on total energy (a.u) for ionic minimization: the convergence
criterion is satisfied when the total energy changes less than etot_conv_thr between
two consecutive scf steps. Note that etot_conv_thr is extensive, like the total energy.
See also forc_conv_thr - both criteria must be satisfied"""
),
)
forc_conv_thr: Annotated[
float, Quantity(units="Ry bohr^-1", dimensionality="energy length^-1")
] = Field(
0.001,
description=dedent(
"""\
Convergence threshold on forces for ionic minimization: the convergence criterion is
satisfied when all components of all forces are smaller than forc_conv_thr. See also
etot_conv_thr - both criteria must be satisfied"""
),
)
disk_io: Literal["default", "high", "medium", "low", "nowf", "minimal", "none"] = Field(
"default",
description=dedent(
"""\
Specifies the amount of disk I/O activity: (only for binary files and xml data file in
data directory; other files printed at each molecular dynamics / structural
optimization step are not controlled by this option ) Default is 'low' for the scf
case, 'medium' otherwise. Note that the needed RAM increases as disk I/O decreases
- 'default': the amount of disk I/O is chosen automatically depending on the kind of
calculation.
- 'high': save charge to disk at each SCF step, keep wavefunctions on disk (in
'distributed' format), save mixing data as well. Do not use this option unless you
have a good reason! It is no longer needed to specify 'high' in order to be able to
restart from an interrupted calculation (see restart_mode).
- 'medium': save charge to disk at each SCF step, keep wavefunctions on disk only if
more than one k-point, per process is present, otherwise keep them in memory; save
them to disk only at the end (in 'portable' format).
- 'low': save charge to disk at each SCF step, keep wavefunctions in memory (for all
k-points), save them to disk only at the end (in 'portable' format). Reduces I/O but
increases memory wrt the previous cases.
- 'nowf': save to disk only the xml data file and the charge density at convergence,
never save wavefunctions. Restarting from an interrupted calculation is not possible
with this option.
- 'minimal': save to disk only the xml data file at convergence.
- 'none': do not save anything to disk."""
),
)
pseudo_dir: Path | None = Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "ESPRESSO_PSEUDO is set", "value": "from_environment"},
{"when": None, "value": "$HOME/espresso/pseudo/"},
],
},
description="directory containing pseudopotential files",
)
tefield: bool = Field(
False,
description=dedent(
"""\
If .TRUE. a saw-like potential simulating an electric field is added to the bare ionic
potential. See variables edir, eamp, emaxpos, eopreg for the form and size of the added
potential."""
),
)
dipfield: bool = Field(
False,
description=dedent(
"""\
If .TRUE. and tefield==.TRUE. a dipole correction is also added to the bare ionic
potential - implements the recipe of L. Bengtsson, PRB 59, 12301 (1999)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.59.12301). See variables edir,
emaxpos, eopreg for the form of the correction. Must be used ONLY in a slab geometry,
for surface calculations, with the discontinuity FALLING IN THE EMPTY SPACE."""
),
)
lelfield: bool = Field(
False,
description=dedent(
"""\
If .TRUE. a homogeneous finite electric field described through the modern theory of
the polarization is applied. This is different from tefield == .true. !"""
),
)
nberrycyc: int = Field(
1,
description=dedent(
"""\
In the case of a finite electric field ( lelfield == .TRUE. ) it defines the number of
iterations for converging the wavefunctions in the electric field Hamiltonian, for each
external iteration on the charge density"""
),
)
lorbm: bool = Field(
False,
description=dedent(
"""\
If .TRUE. perform orbital magnetization calculation. If finite electric field is
applied (lelfield==.true.) only Kubo terms are computed [for details see New J. Phys.
12, 053032 (2010), doi:10.1088/1367-2630/12/5/053032
(https://doi.org/10.1088/1367-2630/12/5/053032)]. The type of calculation is 'nscf'
and should be performed on an automatically generated uniform grid of k points. Works
ONLY with norm-conserving pseudopotentials."""
),
)
lberry: bool = Field(
False,
description=dedent(
"""\
If .TRUE. perform a Berry phase calculation. See the header of PW/src/bp_c_phase.f90
for documentation."""
),
)
gdir: Literal[0, 1, 2, 3] = Field(
0,
description=dedent(
"""\
For Berry phase calculation: direction of the k-point strings in reciprocal space. For
calculations with finite electric fields (lelfield == .true.) this is the direction of
the field. A value of 1, 2 or 3 is required when lberry == .true. or lelfield ==
.true.; PW/src/setup.f90 raises an error otherwise.
- '0': No Berry-phase or finite-field calculation requested (the value is unused).
- '1': first reciprocal lattice vector.
- '2': second reciprocal lattice vector.
- '3': third reciprocal lattice vector."""
),
)
nppstr: int = Field(
0,
description=dedent(
"""\
For Berry phase calculation: number of k-points to be calculated along each
symmetry-reduced string. The same for calculation with finite electric fields
(lelfield==.true.)."""
),
)
gate: bool = Field(
False,
description=dedent(
"""\
In the case of charged cells (tot_charge .ne. 0) setting gate = .TRUE. represents the
counter charge (i.e. -tot_charge) not by a homogeneous background charge but with a
charged plate, which is placed at zgate (see below). Details of the gate potential can
be found in T. Brumme, M. Calandra, F. Mauri; PRB 89, 245406 (2014)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.89.245406). Note, that in
systems which are not symmetric with respect to the plate, one needs to enable the
dipole correction! (dipfield=.true.). Currently, symmetry can be used with gate=.true.
but carefully check that no symmetry is included which maps z to -z even if in
principle one could still use them for symmetric systems (i.e. no dipole correction).
For nosym=.false. verbosity is set to 'high'. Note: this option was called 'monopole'
in v6.0 and 6.1 of pw.x"""
),
)
twochem: bool = Field(
False,
description=dedent(
"""\
IF .TRUE. , a two chemical potential calculation for the simulation of photoexcited
systems is performed, constraining a fraction of the electrons in the conduction
manifold. See G. Marini, M. Calandra; PRB 104, 144103 (2021)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.104.144103). Note: requires
occupations to be set to 'smearing'."""
),
)
lfcp: bool = Field(
False,
description=dedent(
"""\
If .TRUE. perform a constant bias potential (constant-mu) calculation for a system with
ESM method. See the header of PW/src/fcp_module.f90 for documentation. To perform the
calculation, you must set a namelist FCP. NB: - The total energy displayed in output
includes the potentiostat contribution (-mu*N). - calculation must be 'relax' or 'md'.
- assume_isolated = 'esm' and esm_bc = 'bc2' or 'bc3' must be set in SYSTEM namelist. -
ESM-RISM is also supported (assume_isolated = 'esm' and esm_bc = 'bc1' and trism =
.TRUE.). - ignore_wolfe is always .TRUE., for BFGS."""
),
)
trism: bool = Field(
False,
description=dedent(
"""\
If .TRUE. perform a 3D-RISM-SCF calculation [for details see H.Sato et al., JCP 112,
9463 (2000), doi:10.1063/1.481564 (https://doi.org/10.1063/1.481564)]. The solvent's
distributions are calculated by 3D-RISM, though solute is treated as SCF. The charge
density and the atomic positions are optimized, simultaneously with the solvents. To
perform the calculation, you must set a namelist RISM and a card SOLVENTS. If
assume_isolated = 'esm' and esm_bc = 'bc1', Laue-RISM is calculated instead of 3D-RISM
and coupled with ESM method (i.e. ESM-RISM). [for details see S.Nishihara and M.Otani,
PRB 96, 115429 (2017)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.96.115429)]. The default of
mixing_beta is 0.2 for both 3D-RISM and Laue-RISM. For structural relaxation with
BFGS, ignore_wolfe is always .TRUE. ."""
),
)
[docs]
class SystemNamelist(Namelist):
"""Pydantic model for the `SYSTEM` namelist."""
[docs]
@field_validator("smearing", mode="before")
@classmethod
def map_smearing(cls, v: str) -> str:
"""Map equivalent values for `smearing` onto a canonical value."""
mapping = {
"gauss": "gaussian",
"m-p": "methfessel-paxton",
"mp": "methfessel-paxton",
"cold": "marzari-vanderbilt",
"m-v": "marzari-vanderbilt",
"mv": "marzari-vanderbilt",
"f-d": "fermi-dirac",
"fd": "fermi-dirac",
}
return mapping.get(v, v)
[docs]
@field_validator("assume_isolated", mode="before")
@classmethod
def map_assume_isolated(cls, v: str) -> str:
"""Map equivalent values for `assume_isolated` onto a canonical value."""
mapping = {
"m-p": "makov-payne",
"mp": "makov-payne",
"m-t": "martyna-tuckerman",
"mt": "martyna-tuckerman",
}
return mapping.get(v, v)
[docs]
@field_validator("vdw_corr", mode="before")
@classmethod
def map_vdw_corr(cls, v: str) -> str:
"""Map equivalent values for `vdw_corr` onto a canonical value."""
mapping = {
"Grimme-D2": "grimme-d2",
"DFT-D": "grimme-d2",
"dft-d": "grimme-d2",
"Grimme-D3": "grimme-d3",
"DFT-D3": "grimme-d3",
"dft-d3": "grimme-d3",
"TS": "tkatchenko-scheffler",
"ts": "tkatchenko-scheffler",
"ts-vdw": "tkatchenko-scheffler",
"ts-vdW": "tkatchenko-scheffler",
"MBD": "many-body-dispersion",
"mbd": "many-body-dispersion",
"mbd_vdw": "many-body-dispersion",
"xdm": "XDM",
}
return mapping.get(v, v)
ibrav: Literal[0, 1, 2, 3, -3, 4, 5, -5, 6, 7, 8, 9, -9, 91, 10, 11, 12, -12, 13, -13, 14] = (
Field(
...,
description=dedent(
"""\
Bravais-lattice index. Optional only if space_group is set. If ibrav /= 0, specify
EITHER [ celldm(1)-celldm(6) ] OR [ A, B, C, cosAB, cosAC, cosBC ] but NOT both.
The lattice parameter 'alat' is set to alat = celldm(1) (in a.u.) or alat = A (in
Angstrom); see below for the other parameters. For ibrav=0 specify the lattice
vectors in CELL_PARAMETERS, optionally the lattice parameter alat = celldm(1) (in
a.u.) or = A (in Angstrom). If not specified, the lattice parameter is taken from
CELL_PARAMETERS IMPORTANT NOTICE 1: with ibrav=0 lattice vectors must be given with
a sufficiently large number of digits and with the correct symmetry, or else
symmetry detection may fail and strange problems may arise in symmetrization.
IMPORTANT NOTICE 2: do not use celldm(1) or A as a.u. to Ang conversion factor, use
the true lattice parameters or nothing, specify units in CELL_PARAMETERS and
ATOMIC_POSITIONS The accepted values of ibrav and the corresponding lattices (with
the required celldm(2)-celldm(6), or equivalently b,c,cosbc,cosac,cosab) are listed
below.
- '0': free crystal axis provided in input: see card CELL_PARAMETERS.
- '1': cubic P (sc) v1 = a(1,0,0), v2 = a(0,1,0), v3 = a(0,0,1).
- '2': cubic F (fcc) v1 = (a/2)(-1,0,1), v2 = (a/2)(0,1,1), v3 = (a/2)(-1,1,0).
- '3': cubic I (bcc) v1 = (a/2)(1,1,1), v2 = (a/2)(-1,1,1), v3 = (a/2)(-1,-1,1).
- '-3': cubic I (bcc), more symmetric axis: v1 = (a/2)(-1,1,1), v2 = (a/2)(1,-1,1),
v3 = (a/2)(1,1,-1).
- '4': Hexagonal and Trigonal P celldm(3)=c/a v1 = a(1,0,0), v2 =
a(-1/2,sqrt(3)/2,0), v3 = a(0,0,c/a).
- '5': Trigonal R, 3fold axis c celldm(4)=cos(gamma) The crystallographic
vectors form a three-fold star around the z-axis, the primitive cell is a simple
rhombohedron: v1 = a(tx,-ty,tz), v2 = a(0,2ty,tz), v3 = a(-tx,-ty,tz) where
c=cos(gamma) is the cosine of the angle gamma between any pair of
crystallographic vectors, tx, ty, tz are: tx=sqrt((1-c)/2), ty=sqrt((1-c)/6),
tz=sqrt((1+2c)/3).
- '-5': Trigonal R, 3fold axis <111> celldm(4)=cos(gamma) The crystallographic
vectors form a three-fold star around <111>. Defining a' = a/sqrt(3) : v1 = a'
(u,v,v), v2 = a' (v,u,v), v3 = a' (v,v,u) where u and v are defined as u = tz
- 2*sqrt(2)*ty, v = tz + sqrt(2)*ty and tx, ty, tz as for case ibrav=5 Note: if
you prefer x,y,z as axis in the cubic limit, set u = tz + 2*sqrt(2)*ty, v = tz
- sqrt(2)*ty See also the note in Modules/latgen.f90.
- '6': Tetragonal P (st) celldm(3)=c/a v1 = a(1,0,0), v2 = a(0,1,0),
v3 = a(0,0,c/a).
- '7': Tetragonal I (bct) celldm(3)=c/a v1=(a/2)(1,-1,c/a),
v2=(a/2)(1,1,c/a), v3=(a/2)(-1,-1,c/a).
- '8': Orthorhombic P celldm(2)=b/a, celldm(3)=c/a v1 = (a,0,0),
v2 = (0,b,0), v3 = (0,0,c).
- '9': Orthorhombic base-centered(bco) celldm(2)=b/a, celldm(3)=c/a v1 = (a/2,
b/2,0), v2 = (-a/2,b/2,0), v3 = (0,0,c).
- '-9': as 9, alternate description v1 = (a/2,-b/2,0), v2 = (a/2, b/2,0), v3 =
(0,0,c).
- '91': Orthorhombic one-face base-centered A-type, celldm(2)=b/a, celldm(3)=c/a v1
= (a, 0, 0), v2 = (0,b/2,-c/2), v3 = (0,b/2,c/2).
- '10': Orthorhombic face-centered celldm(2)=b/a, celldm(3)=c/a v1 =
(a/2,0,c/2), v2 = (a/2,b/2,0), v3 = (0,b/2,c/2).
- '11': Orthorhombic body-centered celldm(2)=b/a, celldm(3)=c/a
v1=(a/2,b/2,c/2), v2=(-a/2,b/2,c/2), v3=(-a/2,-b/2,c/2).
- '12': Monoclinic P, unique axis c celldm(2)=b/a, celldm(3)=c/a,
celldm(4)=cos(ab) v1=(a,0,0), v2=(b*cos(gamma),b*sin(gamma),0), v3 = (0,0,c)
where gamma is the angle between axis a and b.
- '-12': Monoclinic P, unique axis b celldm(2)=b/a, celldm(3)=c/a,
celldm(5)=cos(ac) v1 = (a,0,0), v2 = (0,b,0), v3 = (c*cos(beta),0,c*sin(beta))
where beta is the angle between axis a and c.
- '13': Monoclinic base-centered (unique axis c) celldm(2)=b/a, celldm(3)=c/a,
celldm(4)=cos(gamma) v1 = ( a/2, 0, -c/2), v2 = (b*cos(gamma),
b*sin(gamma), 0 ), v3 = ( a/2, 0, c/2), where gamma=angle
between axis a and b projected on xy plane.
- '-13': Monoclinic base-centered (unique axis b) celldm(2)=b/a, celldm(3)=c/a,
celldm(5)=cos(beta) v1 = ( a/2, b/2, 0), v2 = ( -a/2,
b/2, 0), v3 = (c*cos(beta), 0, c*sin(beta)), where beta=angle
between axis a and c projected on xz plane IMPORTANT NOTICE: until QE v.6.4.1,
axis for ibrav=-13 had a different definition: v1(old) =-v2(now), v2(old) =
v1(now).
- '14': Triclinic celldm(2)= b/a, celldm(3)= c/a, celldm(4)=
cos(bc), celldm(5)= cos(ac), celldm(6)= cos(ab) v1 = (a, 0, 0), v2 =
(b*cos(gamma), b*sin(gamma), 0) v3 = (c*cos(beta),
c*(cos(alpha)-cos(beta)cos(gamma))/sin(gamma), c*sqrt( 1 +
2*cos(alpha)cos(beta)cos(gamma) - cos(alpha)^2-cos(beta)^2-cos(gamma)^2
)/sin(gamma) ) where alpha is the angle between axis b and c beta is the angle
between axis a and c gamma is the angle between axis a and b."""
),
)
)
A: Annotated[float, Quantity(units="angstrom", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Traditional crystallographic constants: a,b,c in ANGSTROM cosAB = cosine of the angle
between axis a and b (gamma) cosAC = cosine of the angle between axis a and c (beta)
cosBC = cosine of the angle between axis b and c (alpha) The axis are chosen according
to the value of ibrav. Specify either these OR celldm but NOT both. Only needed values
(depending on ibrav) must be specified. The lattice parameter alat = A (in ANGSTROM ).
If ibrav == 0, only A is used if present, and cell vectors are read from card
CELL_PARAMETERS."""
),
)
B: Annotated[float, Quantity(units="angstrom", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Traditional crystallographic constants: a,b,c in ANGSTROM cosAB = cosine of the angle
between axis a and b (gamma) cosAC = cosine of the angle between axis a and c (beta)
cosBC = cosine of the angle between axis b and c (alpha) The axis are chosen according
to the value of ibrav. Specify either these OR celldm but NOT both. Only needed values
(depending on ibrav) must be specified. The lattice parameter alat = A (in ANGSTROM ).
If ibrav == 0, only A is used if present, and cell vectors are read from card
CELL_PARAMETERS."""
),
)
C: Annotated[float, Quantity(units="angstrom", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Traditional crystallographic constants: a,b,c in ANGSTROM cosAB = cosine of the angle
between axis a and b (gamma) cosAC = cosine of the angle between axis a and c (beta)
cosBC = cosine of the angle between axis b and c (alpha) The axis are chosen according
to the value of ibrav. Specify either these OR celldm but NOT both. Only needed values
(depending on ibrav) must be specified. The lattice parameter alat = A (in ANGSTROM ).
If ibrav == 0, only A is used if present, and cell vectors are read from card
CELL_PARAMETERS."""
),
)
cosAB: float = Field( # noqa: N815
0.0,
description=dedent(
"""\
Traditional crystallographic constants: a,b,c in ANGSTROM cosAB = cosine of the angle
between axis a and b (gamma) cosAC = cosine of the angle between axis a and c (beta)
cosBC = cosine of the angle between axis b and c (alpha) The axis are chosen according
to the value of ibrav. Specify either these OR celldm but NOT both. Only needed values
(depending on ibrav) must be specified. The lattice parameter alat = A (in ANGSTROM ).
If ibrav == 0, only A is used if present, and cell vectors are read from card
CELL_PARAMETERS."""
),
)
cosAC: float = Field( # noqa: N815
0.0,
description=dedent(
"""\
Traditional crystallographic constants: a,b,c in ANGSTROM cosAB = cosine of the angle
between axis a and b (gamma) cosAC = cosine of the angle between axis a and c (beta)
cosBC = cosine of the angle between axis b and c (alpha) The axis are chosen according
to the value of ibrav. Specify either these OR celldm but NOT both. Only needed values
(depending on ibrav) must be specified. The lattice parameter alat = A (in ANGSTROM ).
If ibrav == 0, only A is used if present, and cell vectors are read from card
CELL_PARAMETERS."""
),
)
cosBC: float = Field( # noqa: N815
0.0,
description=dedent(
"""\
Traditional crystallographic constants: a,b,c in ANGSTROM cosAB = cosine of the angle
between axis a and b (gamma) cosAC = cosine of the angle between axis a and c (beta)
cosBC = cosine of the angle between axis b and c (alpha) The axis are chosen according
to the value of ibrav. Specify either these OR celldm but NOT both. Only needed values
(depending on ibrav) must be specified. The lattice parameter alat = A (in ANGSTROM ).
If ibrav == 0, only A is used if present, and cell vectors are read from card
CELL_PARAMETERS."""
),
)
nat: int = Field(
...,
description=dedent(
"""\
number of atoms in the unit cell (ALL atoms, except if space_group is set, in which
case, INEQUIVALENT atoms)"""
),
)
ntyp: int = Field(..., description="number of types of atoms in the unit cell")
nbnd: int | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Number of electronic states (bands) to be calculated. Note that in spin-polarized
calculations the number of k-point, not the number of bands per k-point, is doubled By
default, for an insulator nbnd is set to the number of valence bands (nbnd = number of
electrons / 2); for a metal, 20% more (with a minimum of 4 more) states are added."""
),
)
nbnd_cond: int | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Number of electronic states in the conduction manifold for a two chemical-potential
calculation (twochem=.true.). By default it is set to nbnd - (number of electrons / 2)
in the collinear case, and to nbnd - (number of electrons) in the noncollinear case."""
),
)
tot_charge: Annotated[float, Quantity(units="e", dimensionality="charge")] = Field(
0.0,
description=dedent(
"""\
Total charge of the system. Useful for simulations with charged cells. By default the
unit cell is assumed to be neutral (tot_charge=0). tot_charge=+1 means one electron
missing from the system, tot_charge=-1 means one additional electron, and so on. In a
periodic calculation a compensating jellium background is inserted to remove
divergences if the cell is not neutral."""
),
)
tot_magnetization: float = Field(
-10000,
description=dedent(
"""\
Total majority spin charge - minority spin charge. Used to impose a specific total
electronic magnetization. The default value -10000 is a sentinel meaning 'unspecified':
if left unspecified the tot_magnetization variable is ignored and the amount of
electronic magnetization is determined during the self-consistent cycle."""
),
)
ecutwfc: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
..., description="kinetic energy cutoff for wavefunctions"
)
ecutrho: Annotated[float | None, Quantity(units="Ry", dimensionality="energy")] = Field(
None,
json_schema_extra={"default_expr": "4 * ecutwfc"},
description=dedent(
"""\
Kinetic energy cutoff for charge density and potential For norm-conserving
pseudopotential you should stick to the default value, you can reduce it by a little
but it will introduce noise especially on forces and stress. If there are ultrasoft PP,
a larger value than the default is often desirable (ecutrho = 8 to 12 times ecutwfc,
typically). PAW datasets can often be used at 4*ecutwfc, but it depends on the shape of
augmentation charge: testing is mandatory. The use of gradient-corrected functional,
especially in cells with vacuum, or for pseudopotential without non-linear core
correction, usually requires an higher values of ecutrho to be accurately converged."""
),
)
ecutfock: Annotated[float | None, Quantity(units="Ry", dimensionality="energy")] = Field(
None,
json_schema_extra={"default_ref": "ecutrho"},
description=dedent(
"""\
Kinetic energy cutoff for the exact exchange operator in EXX type calculations. By
default this is the same as ecutrho but in some EXX calculations, a significant
speed-up can be obtained by reducing ecutfock, at the expense of some loss in accuracy.
Must be .gt. ecutwfc. Not implemented for stress calculation and for US-PP and PAW
pseudopotentials. Use with care, especially in metals where it may give raise to
instabilities."""
),
)
nr1: int = Field(
0,
description=dedent(
"""\
Three-dimensional FFT mesh (hard grid) for charge density (and scf potential). If not
specified the grid is calculated based on the cutoff for charge density (see also
ecutrho) Note: you must specify all three dimensions for this setting to be used."""
),
)
nr2: int = Field(
0,
description=dedent(
"""\
Three-dimensional FFT mesh (hard grid) for charge density (and scf potential). If not
specified the grid is calculated based on the cutoff for charge density (see also
ecutrho) Note: you must specify all three dimensions for this setting to be used."""
),
)
nr3: int = Field(
0,
description=dedent(
"""\
Three-dimensional FFT mesh (hard grid) for charge density (and scf potential). If not
specified the grid is calculated based on the cutoff for charge density (see also
ecutrho) Note: you must specify all three dimensions for this setting to be used."""
),
)
nr1s: int = Field(
0,
description=dedent(
"""\
Three-dimensional mesh for wavefunction FFT and for the smooth part of charge density (
smooth grid ). Coincides with nr1, nr2, nr3 if ecutrho = 4 * ecutwfc ( default ) Note:
you must specify all three dimensions for this setting to be used."""
),
)
nr2s: int = Field(
0,
description=dedent(
"""\
Three-dimensional mesh for wavefunction FFT and for the smooth part of charge density (
smooth grid ). Coincides with nr1, nr2, nr3 if ecutrho = 4 * ecutwfc ( default ) Note:
you must specify all three dimensions for this setting to be used."""
),
)
nr3s: int = Field(
0,
description=dedent(
"""\
Three-dimensional mesh for wavefunction FFT and for the smooth part of charge density (
smooth grid ). Coincides with nr1, nr2, nr3 if ecutrho = 4 * ecutwfc ( default ) Note:
you must specify all three dimensions for this setting to be used."""
),
)
nosym: bool = Field(
False,
description=dedent(
"""\
if (.TRUE.) symmetry is not used. Consequences: - if a list of k points is provided in
input, it is used 'as is': symmetry-inequivalent k-points are not generated, and the
charge density is not symmetrized; - if a uniform (Monkhorst-Pack) k-point grid is
provided in input, it is expanded to cover the entire Brillouin Zone, irrespective of
the crystal symmetry. Time reversal symmetry is assumed so k and -k are considered as
equivalent unless noinv=.true. is specified. Do not use this option unless you know
exactly what you want and what you get. May be useful in the following cases: - in
low-symmetry large cells, if you cannot afford a k-point grid with the correct symmetry
- in MD simulations - in calculations for isolated atoms"""
),
)
nosym_evc: bool = Field(
False,
description=dedent(
"""\
if (.TRUE.) symmetry is not used, and k points are forced to have the symmetry of the
Bravais lattice; an automatically generated Monkhorst-Pack grid will contain all points
of the grid over the entire Brillouin Zone, plus the points rotated by the symmetries
of the Bravais lattice which were not in the original grid. The same applies if a
k-point list is provided in input instead of a Monkhorst-Pack grid. Time reversal
symmetry is assumed so k and -k are equivalent unless noinv=.true. is specified. This
option differs from nosym because it forces k-points in all cases to have the full
symmetry of the Bravais lattice (not all uniform grids have such property!)"""
),
)
noinv: bool = Field(
False,
description=dedent(
"""\
if (.TRUE.) disable the usage of k => -k symmetry (time reversal) in k-point
generation"""
),
)
no_t_rev: bool = Field(
False,
description=dedent(
"""\
if (.TRUE.) disable the usage of magnetic symmetry operations that consist in a
rotation + time reversal."""
),
)
force_symmorphic: bool = Field(
False,
description=dedent(
"""\
if (.TRUE.) force the symmetry group to be symmorphic by disabling symmetry operations
having an associated fractionary translation"""
),
)
use_all_frac: bool = Field(
False,
description=dedent(
"""\
if (.FALSE.) force real-space FFT grids to be commensurate with fractionary
translations of non-symmorphic symmetry operations, if present (e.g.: if a fractional
translation (0,0,c/4) exists, the FFT dimension along the c axis must be multiple of
4). if (.TRUE.) do not impose any constraints to FFT grids, even in the presence of
non-symmorphic symmetry operations. BEWARE: use_all_frac=.TRUE. may lead to wrong
results for hybrid functionals and phonon calculations. Both cases use symmetrization
in real space that works for non-symmorphic operations only if the real-space FFT grids
are commensurate."""
),
)
occupations: Literal[
"smearing", "tetrahedra", "tetrahedra_lin", "tetrahedra_opt", "fixed", "from_input"
] = Field(
"fixed",
description=dedent(
"""\
Available options are:
- 'smearing': gaussian smearing for metals; see variables smearing and degauss.
- 'tetrahedra': Tetrahedron method, Bloechl's version: P.E. Bloechl, PRB 49, 16223
(1994) (https://journals.aps.org/prb/abstract/10.1103/PhysRevB.49.16223) Requires
uniform grid of k-points, to be automatically generated (see card K_POINTS). Well
suited for calculation of DOS, less so (because not variational) for
force/optimization/dynamics calculations.
- 'tetrahedra_lin': Original linear tetrahedron method. To be used only as a reference;
the optimized tetrahedron method is more efficient.
- 'tetrahedra_opt': Optimized tetrahedron method: see M. Kawamura, PRB 89, 094515
(2014) (https://journals.aps.org/prb/abstract/10.1103/PhysRevB.89.094515). Can be
used for phonon calculations as well.
- 'fixed': for insulators with a gap.
- 'from_input': The occupation are read from input file, card OCCUPATIONS. Option valid
only for a single k-point, requires nbnd to be set in input. Occupations should be
consistent with the value of tot_charge."""
),
)
one_atom_occupations: bool = Field(
False,
description=dedent(
"""\
This flag is used for isolated atoms (nat=1) together with occupations='from_input'. If
it is .TRUE., the wavefunctions are ordered as the atomic starting wavefunctions,
independently from their eigenvalue. The occupations indicate which atomic states are
filled. The order of the states is written inside the UPF pseudopotential file. In the
scalar relativistic case: S -> l=0, m=0 P -> l=1, z, x, y D -> l=2, r^2-3z^2, xz, yz,
xy, x^2-y^2 In the noncollinear magnetic case (with or without spin-orbit), each group
of states is doubled. For instance: P -> l=1, z, x, y for spin up, l=1, z, x, y for
spin down. Up and down is relative to the direction of the starting magnetization. In
the case with spin-orbit and time-reversal (starting_magnetization=0.0) the atomic
wavefunctions are radial functions multiplied by spin-angle functions. For instance: P
-> l=1, j=1/2, m_j=-1/2,1/2. l=1, j=3/2, m_j=-3/2, -1/2, 1/2, 3/2. In the magnetic
case with spin-orbit the atomic wavefunctions can be forced to be spin-angle functions
by setting starting_spin_angle to .TRUE.."""
),
)
starting_spin_angle: bool = Field(
False,
description=dedent(
"""\
In the spin-orbit case when domag=.TRUE., by default, the starting wavefunctions are
initialized as in scalar relativistic noncollinear case without spin-orbit. By setting
starting_spin_angle=.TRUE. this behaviour can be changed and the initial wavefunctions
are radial functions multiplied by spin-angle functions. When domag=.FALSE. the
initial wavefunctions are always radial functions multiplied by spin-angle functions
independently from this flag. When lspinorb is .FALSE. this flag is not used."""
),
)
degauss_cond: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.0,
description=dedent(
"""\
value of the gaussian spreading for brillouin-zone integration in the conduction
manifold in a two-chemical potential calculation (twochem=.true.)."""
),
)
nelec_cond: float = Field(
0.0,
description=dedent(
"""\
Number of electrons placed in the conduction manifold in a two-chemical potential
calculation (twochem=.true.). Of the total # of electrons nelec, nelec-nelec_cond will
occupy the valence manifold and nelec_cond will be constrained in the conduction
manifold."""
),
)
degauss: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.0, description="value of the gaussian spreading for brillouin-zone integration in metals."
)
smearing: Literal["gaussian", "methfessel-paxton", "marzari-vanderbilt", "fermi-dirac"] = Field(
"gaussian",
description=dedent(
"""\
Available options are:
- 'gaussian': ordinary Gaussian spreading.
- 'methfessel-paxton': Methfessel-Paxton first-order spreading (see PRB 40, 3616 (1989)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.40.3616)).
- 'marzari-vanderbilt': Marzari-Vanderbilt-DeVita-Payne cold smearing (see PRL 82, 3296
(1999) (https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.82.3296)).
- 'fermi-dirac': smearing with Fermi-Dirac function."""
),
)
nspin: Literal[1, 2, 4] = Field(
1,
description=dedent(
"""\
Spin polarization mode of the calculation.
- '1': non-polarized calculation.
- '2': spin-polarized calculation, LSDA (magnetization along z axis).
- '4': spin-polarized calculation, noncollinear (magnetization in generic direction) DO
NOT specify nspin in this case; specify noncolin=.TRUE. instead."""
),
)
sic_gamma: float = Field(0.0, description="Strength of the gammaDFT potential.")
pol_type: Literal["none", "e", "h"] = Field(
"none",
description=dedent(
"""\
Type of polaron in gammaDFT.
- 'none': no polaron.
- 'e': electron polaron.
- 'h': hole polaron."""
),
)
sic_energy: bool = Field(
False,
description=dedent(
"""\
Enable the calculation of the total energy in gammaDFT. When .true., a preliminary
calculation is performed to calculate the electron density in the absence of the
polaron. When .false., the total energy printed in output should not be considered. For
structural relaxations, it is recommended to use .false. to avoid doubling the
computational cost."""
),
)
sci_vb: Annotated[float, Quantity(units="eV", dimensionality="energy")] = Field(
0.0,
description=dedent(
"""\
Valence band shift through self-consistent scissor operator. When performing gammaDFT
calculations of polarons, the polaron level is not shifted."""
),
)
sci_cb: Annotated[float, Quantity(units="eV", dimensionality="energy")] = Field(
0.0,
description=dedent(
"""\
Conduction band band shift through self-consistent scissor operator. When performing
gammaDFT calculations of polarons, the polaron level is not shifted."""
),
)
noncolin: bool = Field(
False, description="if .true. the program will perform a noncollinear calculation."
)
ecfixed: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.0, description=""
)
qcutz: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.0, description=""
)
q2sigma: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.01,
description=dedent(
"""\
ecfixed, qcutz, q2sigma: parameters for modified functional to be used in
variable-cell molecular dynamics (or in stress calculation). 'ecfixed' is the value of
the constant-cutoff; 'qcutz' and 'q2sigma' are the height and the width of the energy
step for reciprocal vectors whose square modulus is greater than 'ecfixed'. In the
kinetic energy, G^2 is replaced by G^2 + qcutz * (1 + erf ( (G^2 - ecfixed)/q2sigma) )
See: M. Bernasconi et al, J. Phys. Chem. Solids 56, 501 (1995),
doi:10.1016/0022-3697(94)00228-2 (https://doi.org/10.1016/0022-3697(94)00228-2)"""
),
)
input_dft: str | None = Field(
None,
json_schema_extra={
"conditional_default": [{"when": None, "value": "from_pseudopotential"}],
},
description=dedent(
"""\
Exchange-correlation functional: eg 'PBE', 'BLYP' etc See Modules/funct.f90 for allowed
values. Overrides the value read from pseudopotential files. Use with care and if you
know what you are doing!"""
),
)
ace: bool = Field(
True,
description=dedent(
"""\
Use Adaptively Compressed Exchange operator as in Lin Lin, J. Chem. Theory Comput.
2016, 12, 2242--2249, doi:10.1021/acs.jctc.6b00092
(https://doi.org/10.1021/acs.jctc.6b00092) Set to false to use standard Exchange (much
slower)"""
),
)
exx_fraction: float | None = Field(
None,
json_schema_extra={"conditional_default": [{"when": None, "value": "internal"}]},
description=dedent(
"""\
Fraction of EXX for hybrid functional calculations. In the case of input_dft='PBE0',
the default value is 0.25, while for input_dft='B3LYP' the exx_fraction default value
is 0.20."""
),
)
screening_parameter: Annotated[float, Quantity(units="bohr^-1", dimensionality="length^-1")] = (
Field(
0.106,
description=dedent(
"""\
screening_parameter for HSE like hybrid functionals. For more information, see: J.
Chem. Phys. 118, 8207 (2003), doi:10.1063/1.1564060
(https://doi.org/10.1063/1.1564060) J. Chem. Phys. 124, 219906 (2006),
doi:10.1063/1.2204597 (https://doi.org/10.1063/1.2204597)"""
),
)
)
exxdiv_treatment: Literal["gygi-baldereschi", "vcut_spherical", "vcut_ws", "none"] = Field(
"gygi-baldereschi",
description=dedent(
"""\
Specific for EXX. It selects the kind of approach to be used for treating the Coulomb
potential divergencies at small q vectors.
- 'gygi-baldereschi': appropriate for cubic and quasi-cubic supercells.
- 'vcut_spherical': appropriate for cubic and quasi-cubic supercells (untested for
non-orthogonal crystal axis).
- 'vcut_ws': appropriate for strongly anisotropic supercells, see also ecutvcut
(untested for non-orthogonal crystal axis).
- 'none': sets Coulomb potential at G,q=0 to 0.0 (required for GAU-PBE)."""
),
)
exx_type: Literal["bands", "band_pairs"] = Field(
"band_pairs",
description=dedent(
"""\
Specific for EXX. This keyword defines the band distribution scheme to use when band
groups are enabled. When band groups are not used (-nb=1 or not specified), the two
schemes are equivalent, but their internal implementations differ.
- 'bands': distribute bands among band groups (GPU execution not yet implemented).
- 'band_pairs': distribute band pairs among band groups (see Barnes et al., Computer
Physics Communications, Volume 214, 2017, Pages 52-58)."""
),
)
x_gamma_extrapolation: bool = Field(
True,
description=dedent(
"""\
Specific for EXX. If .true., extrapolate the G=0 term of the potential (see README in
examples/EXX_example for more) Set this to .false. for GAU-PBE."""
),
)
ecutvcut: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.0,
description=dedent(
"""\
Reciprocal space cutoff for correcting Coulomb potential divergencies at small q
vectors."""
),
)
nqx1: int | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Three-dimensional mesh for q (k1-k2) sampling of the Fock operator (EXX). Can be
smaller than the number of k-points. Currently this defaults to the size of the
k-point mesh used. In QE =< 5.0.2 it defaulted to nqx1=nqx2=nqx3=1."""
),
)
nqx2: int | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Three-dimensional mesh for q (k1-k2) sampling of the Fock operator (EXX). Can be
smaller than the number of k-points. Currently this defaults to the size of the
k-point mesh used. In QE =< 5.0.2 it defaulted to nqx1=nqx2=nqx3=1."""
),
)
nqx3: int | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Three-dimensional mesh for q (k1-k2) sampling of the Fock operator (EXX). Can be
smaller than the number of k-points. Currently this defaults to the size of the
k-point mesh used. In QE =< 5.0.2 it defaulted to nqx1=nqx2=nqx3=1."""
),
)
localization_thr: float = Field(
0.0,
description=dedent(
"""\
Overlap threshold over which the exchange integral over a pair of localized orbitals is
included in the evaluation of EXX operator. Any value greater than 0.0 triggers the
SCDM localization and the evaluation on EXX using the localized orbitals. Very small
value of the threshold should yield the same result as the default EXX evaluation"""
),
)
dmft: bool = Field(
False,
description=dedent(
"""\
If true, nscf calculation will exit in restart mode, scf calculation will restart from
there if DMFT updates are provided as hdf5 archive. Scf calculation should be used only
with electron_maxstep = 1. K_POINTS have to be identical and given explicitly with
nosym."""
),
)
dmft_prefix: str | None = Field(
None,
json_schema_extra={"default_ref": "prefix"},
description=dedent(
"""\
prepended to hdf5 archive: dmft_prefix.h5 DMFT update should be provided in
group/dataset as: - dft_misc_input/band_window with dimension [1, number of k-points, 2
(real + complex)] - dft_update/delta_N with dimension [number of k-points, number of
correlated orbitals, number of correlated orbitals, 2 (real + complex)]"""
),
)
ensemble_energies: bool = Field(
False,
description=dedent(
"""\
If ensemble_energies = .true., an ensemble of xc energies is calculated
non-selfconsistently for perturbed exchange-enhancement factors and LDA vs. PBE
correlation ratios after each converged electronic ground state calculation. Ensemble
energies can be analyzed with the 'bee' utility included with libbeef. Requires
linking against libbeef. input_dft must be set to a BEEF-type functional (e.g.
input_dft = 'BEEF-vdW')"""
),
)
edir: int = Field(
1,
description=dedent(
"""\
The direction of the electric field or dipole correction is parallel to the bg(:,edir)
reciprocal lattice vector, so the potential is constant in planes defined by FFT grid
points; edir = 1, 2 or 3. Used only if tefield is .TRUE."""
),
)
emaxpos: float = Field(
0.5,
description=dedent(
"""\
Position of the maximum of the saw-like potential along crystal axis edir, within the
unit cell (see below), 0 < emaxpos < 1 Used only if tefield is .TRUE."""
),
)
eopreg: float = Field(
0.1,
description=dedent(
"""\
Zone in the unit cell where the saw-like potential decreases. ( see below, 0 < eopreg <
1 ). Used only if tefield is .TRUE."""
),
)
eamp: Annotated[
float, Quantity(units="Ry e^-1 bohr^-1", dimensionality="energy charge^-1 length^-1")
] = Field(
0.0,
description=dedent(
"""\
Amplitude of the electric field, in ***Hartree*** a.u.; 1 a.u. = 51.4220632*10^10 V/m.
Used only if tefield==.TRUE. The saw-like potential increases with slope eamp in the
region from (emaxpos+eopreg-1) to (emaxpos), then decreases to 0 until
(emaxpos+eopreg), in units of the crystal vector edir. Important: the change of slope
of this potential must be located in the empty region, or else unphysical forces will
result."""
),
)
lforcet: bool = Field(
False,
description=dedent(
"""\
When starting a non collinear calculation using an existing density file from a
collinear lsda calculation assumes previous density points in z direction and rotates
it in the direction described by angle1 and angle2 variables for atomic type 1"""
),
)
constrained_magnetization: Literal[
"none", "total", "atomic", "total direction", "atomic direction"
] = Field(
"none",
description=dedent(
"""\
Used to perform constrained calculations in magnetic systems. Currently available
choices: N.B.: symmetrization may prevent to reach the desired orientation of the
magnetization. Try not to start with very highly symmetric configurations or use the
nosym flag (only as a last remedy)
- 'none': no constraint.
- 'total': total magnetization is constrained by adding a penalty functional to the
total energy: LAMBDA * SUM_{i} ( magnetization(i) - fixed_magnetization(i) )**2
where the sum over i runs over the three components of the magnetization. Lambda is a
real number (see below). Noncolinear case only. Use tot_magnetization for LSDA.
- 'atomic': atomic magnetization are constrained to the defined starting magnetization
adding a penalty: LAMBDA * SUM_{i,itype} ( magnetic_moment(i,itype) - mcons(i,itype)
)**2 where i runs over the cartesian components (or just z in the collinear case)
and itype over the types (1-ntype). mcons(:,:) array is defined from
starting_magnetization, (also from angle1, angle2 in the noncollinear case). lambda
is a real number.
- 'total direction': the angle theta of the total magnetization with the z axis (theta
= fixed_magnetization(3)) is constrained: LAMBDA * (
arccos(magnetization(3)/mag_tot) - theta )**2 where mag_tot is the modulus of the
total magnetization.
- 'atomic direction': not all the components of the atomic magnetic moment are
constrained but only the cosine of angle1, and the penalty functional is: LAMBDA *
SUM_{itype} ( mag_mom(3,itype)/mag_mom_tot - cos(angle1(ityp)) )**2."""
),
)
Lambda: float = Field(
1.0,
description=dedent(
"""\
parameter used for constrained_magnetization calculations N.B.: if the scf calculation
does not converge, try to reduce lambda to obtain convergence, then restart the run
with a larger lambda"""
),
)
report: int = Field(
-1,
description=dedent(
"""\
determines when atomic magnetic moments are printed on output: report = 0 never report
=-1 at the beginning of the scf and at convergence report = N as -1, plus every N scf
iterations"""
),
)
lspinorb: bool = Field(
False,
description="if .TRUE. the noncollinear code can use a pseudopotential with spin-orbit.",
)
assume_isolated: Literal["none", "makov-payne", "martyna-tuckerman", "esm", "2D"] = Field(
"none",
description=dedent(
"""\
Used to perform calculation assuming the system to be isolated (a molecule or a cluster
in a 3D supercell). Currently available choices:
- 'none': regular periodic calculation w/o any correction.
- 'makov-payne': the Makov-Payne correction to the total energy is computed. An
estimate of the vacuum level is also calculated so that eigenvalues can be properly
aligned. ONLY FOR CUBIC SYSTEMS (ibrav=1,2,3). Theory: G.Makov, and M.C.Payne,
'Periodic boundary conditions in ab initio calculations' , PRB 51, 4014 (1995)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.51.4014).
- 'martyna-tuckerman': Martyna-Tuckerman correction to both total energy and scf
potential. Adapted from: G.J. Martyna, and M.E. Tuckerman, 'A reciprocal space based
method for treating long range interactions in ab-initio and force-field-based
calculation in clusters', J. Chem. Phys. 110, 2810 (1999), doi:10.1063/1.477923
(https://doi.org/10.1063/1.477923).
- 'esm': Effective Screening Medium Method. For polarized or charged slab calculation,
embeds the simulation cell within an effective semi- infinite medium in the
perpendicular direction (along z). Embedding regions can be vacuum or semi-infinite
metal electrodes (use esm_bc to choose boundary conditions). If between two
electrodes, an optional electric field (esm_efield) may be applied. Method described
in M. Otani and O. Sugino, 'First-principles calculations of charged surfaces and
interfaces: A plane-wave nonrepeated slab approach', PRB 73, 115407 (2006)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.73.115407). NB: - Two
dimensional (xy plane) average charge density and electrostatic potentials are
printed out to 'prefix.esm1'. - Requires cell with a_3 lattice vector along z,
normal to the xy plane, with the slab centered around z=0. - For bc2 with an
electric field and bc3 boundary conditions, the inversion symmetry along z-direction
is automatically eliminated. - In case of calculation='vc-relax', use
cell_dofree='2Dxy' or other parameters so that c-vector along z-axis should not be
moved. See esm_bc, esm_efield, esm_w, esm_nfit.
- '2D': Truncation of the Coulomb interaction in the z direction for structures
periodic in the x-y plane. Total energy, forces and stresses are computed in a
two-dimensional framework. Linear-response calculations () done on top of a
self-consistent calculation with this flag will automatically be performed in the
2D framework as well. Please refer to: Sohier, T., Calandra, M., & Mauri, F.
(2017), 'Density functional perturbation theory for gated two-dimensional
heterostructures: Theoretical developments and application to flexural phonons in
graphene', PRB, 96, 075448 (2017)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.96.075448). NB: - The
length of the unit-cell along the z direction should be larger than twice the
thickness of the 2D material (including electrons). A reasonable estimate for a
layer's thickness could be the interlayer distance in the corresponding layered
bulk material. Otherwise, the atomic thickness + 10 bohr should be a safe
estimate. There is also a lower limit of 20 bohr imposed by the cutoff radius used
to read pseudopotentials (see read_pseudo.f90 in Modules). - As for ESM above,
only in-plane stresses make sense and one should use cell_dofree= '2Dxy' in a
vc-relax calculation."""
),
)
esm_bc: Literal["pbc", "bc1", "bc2", "bc3"] = Field(
"pbc",
description=dedent(
"""\
If assume_isolated = 'esm', determines the boundary conditions used for either side of
the slab. Currently available choices:
- 'pbc': regular periodic calculation (no ESM).
- 'bc1': Vacuum-slab-vacuum (open boundary conditions).
- 'bc2': Metal-slab-metal (dual electrode configuration). See also esm_efield.
- 'bc3': Vacuum-slab-metal."""
),
)
esm_w: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
If assume_isolated = 'esm', determines the position offset of the start of the
effective screening region, measured relative to the cell edge. (ESM region begins at z
= +/- [L_z/2 + esm_w] )."""
),
)
esm_efield: Annotated[
float, Quantity(units="Ry e^-1 bohr^-1", dimensionality="energy charge^-1 length^-1")
] = Field(
0.0,
description=dedent(
"""\
If assume_isolated = 'esm' and esm_bc = 'bc2', gives the magnitude of the electric
field to be applied between semi-infinite ESM electrodes."""
),
)
esm_nfit: int = Field(
4,
description=dedent(
"""\
If assume_isolated = 'esm', gives the number of z-grid points for the polynomial fit
along the cell edge."""
),
)
lgcscf: bool = Field(
False,
description=dedent(
"""\
If .TRUE. perform a constant bias potential (constant-mu) calculation with
Grand-Canonical SCF. (JCP 146, 114104 (2017), R.Sundararaman, et al.) NB: - The total
energy displayed in output includes the potentiostat contribution (-mu*N). -
assume_isolated = 'esm' and esm_bc = 'bc2' or 'bc3' must be set in SYSTEM namelist. -
ESM-RISM is also supported (assume_isolated = 'esm' and esm_bc = 'bc1' and trism =
.TRUE.). - mixing_mode has to be 'TF' or 'local-TF', also its default is 'TF.' - The
default of mixing_beta is 0.1 with ESM-RISM, 0.2 without ESM-RISM. - The default of
diago_thr_init is 1.D-5. - diago_full_acc is always .TRUE. . - diago_rmm_conv is always
.TRUE. ."""
),
)
gcscf_mu: Annotated[float | None, Quantity(units="eV", dimensionality="energy")] = Field(
None,
description=dedent(
"""\
The target Fermi energy of GC-SCF. One can start with appropriate total charge of the
system by giving tot_charge ."""
),
)
gcscf_conv_thr: Annotated[float, Quantity(units="eV", dimensionality="energy")] = Field(
0.01, description="Convergence threshold of Fermi energy for GC-SCF."
)
gcscf_beta: float = Field(
0.05,
description=dedent(
"""\
Mixing factor for GC-SCF. Larger values are recommended, if systems with small DOS on
Fermi surface as graphite."""
),
)
vdw_corr: Literal[
"none", "grimme-d2", "grimme-d3", "tkatchenko-scheffler", "many-body-dispersion", "XDM"
] = Field(
"none",
description=dedent(
"""\
Type of the van der Waals correction. Allowed values: Note that non-local functionals
(eg vdw-DF) are NOT specified here but in input_dft
- 'none': no van der Waals correction.
- 'grimme-d2': Semiempirical Grimme's DFT-D2. Optional variables: london_s6,
london_rcut, london_c6, london_rvdw S. Grimme, J. Comp. Chem. 27, 1787 (2006),
doi:10.1002/jcc.20495 (https://doi.org/10.1002/jcc.20495) V. Barone et al., J. Comp.
Chem. 30, 934 (2009), doi:10.1002/jcc.21112 (https://doi.org/10.1002/jcc.21112).
- 'grimme-d3': Semiempirical Grimme's DFT-D3. Optional variables: dftd3_version,
dftd3_threebody S. Grimme et al, J. Chem. Phys 132, 154104 (2010),
doi:10.1063/1.3382344 (https://doi.org/10.1063/1.3382344).
- 'tkatchenko-scheffler': Tkatchenko-Scheffler dispersion corrections with
first-principle derived C6 coefficients. Optional variables: ts_vdw_econv_thr,
ts_vdw_isolated See A. Tkatchenko and M. Scheffler, PRL 102, 073005 (2009)
(https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.102.073005). J. Hermann et
al., J. Chem. Phys. 159, 174802 (2023), doi:10.1063/5.0170972
(https://doi.org/10.1063/5.0170972).
- 'many-body-dispersion': Many-body dipersion (MBD) correction to long-range
interactions. Optional variables: ts_vdw_isolated A. Ambrosetti et al., J. Chem.
Phys. 140, 18A508 (2014), doi:10.1063/1.4865104 (https://doi.org/10.1063/1.4865104)
J. Hermann et al., J. Chem. Phys. 159, 174802 (2023), doi:10.1063/5.0170972
(https://doi.org/10.1063/5.0170972).
- 'XDM': Exchange-hole dipole-moment model. Optional variables: xdm_a1, xdm_a2 A. D.
Becke et al., J. Chem. Phys. 127, 154108 (2007), doi:10.1063/1.2795701
(https://doi.org/10.1063/1.2795701) A. Otero de la Roza et al., J. Chem. Phys. 136,
174109 (2012), doi:10.1063/1.4705760 (https://doi.org/10.1063/1.4705760)."""
),
)
london: bool = Field(False, description="")
london_s6: float = Field(
0.75, description="global scaling parameter for DFT-D. Default is good for PBE."
)
london_rcut: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
200.0, description="cutoff radius for dispersion interactions"
)
dftd3_version: Literal[2, 3, 4, 5, 6] = Field(
3,
description=dedent(
"""\
Version of Grimme implementation of Grimme-D3: NOTE: not all functionals are
parametrized.
- '2': Original Grimme-D2 parametrization.
- '3': Grimme-D3 (zero damping).
- '4': Grimme-D3 (BJ damping).
- '5': Grimme-D3M (zero damping).
- '6': Grimme-D3M (BJ damping)."""
),
)
dftd3_threebody: bool = Field(
True,
description=dedent(
"""\
Turn three-body terms in Grimme-D3 on. If .false. two-body contributions only are
computed, using two-body parameters of Grimme-D3. If dftd3_version=2, three-body
contribution is always disabled."""
),
)
ts_vdw_econv_thr: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
1e-06,
description=dedent(
"""\
Optional: controls the convergence of the vdW energy (and forces). The default value is
a safe choice, likely too safe, but you do not gain much in increasing it"""
),
)
ts_vdw_isolated: bool = Field(
False,
description=dedent(
"""\
Optional: set it to .TRUE. when computing the Tkatchenko-Scheffler vdW energy or the
Many-Body dispersion (MBD) energy for an isolated (non-periodic) system."""
),
)
xdm: bool = Field(False, description="")
xdm_a1: float | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Damping function parameter a1 (adimensional). It is NOT necessary to give a value if
the functional is one of B86bPBE, PW86PBE, PBE, BLYP. For functionals in this list, the
coefficients are given in:
https://github.com/aoterodelaroza/postg/blob/master/xdm.param or
https://erin-r-johnson.github.io/software/ A. Otero de la Roza, E. R. Johnson, J. Chem.
Phys. 138, 204109 (2013), doi:10.1063/1.4705760 (https://doi.org/10.1063/1.4705760)"""
),
)
xdm_a2: Annotated[float | None, Quantity(units="angstrom", dimensionality="length")] = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Damping function parameter a2. It is NOT necessary to give a value if the functional is
one of B86bPBE, PW86PBE, PBE, BLYP. For functionals in this list, the coefficients are
given in: https://github.com/aoterodelaroza/postg/blob/master/xdm.param or
https://erin-r-johnson.github.io/software/ A. Otero de la Roza, E. R. Johnson, J. Chem.
Phys. 138, 204109 (2013), doi:10.1063/1.4705760 (https://doi.org/10.1063/1.4705760)"""
),
)
space_group: int = Field(
0,
description=dedent(
"""\
The number of the space group of the crystal, as given in the International Tables of
Crystallography A (ITA). This allows to give in input only the inequivalent atomic
positions. The positions of all the symmetry equivalent atoms are calculated by the
code. Used only when the atomic positions are of type crystal_sg. See also uniqueb,
origin_choice, rhombohedral"""
),
)
uniqueb: bool = Field(
False,
description=dedent(
"""\
Used only for monoclinic lattices. If .TRUE. the b unique ibrav (-12 or -13) are used,
and symmetry equivalent positions are chosen assuming that the twofold axis or the
mirror normal is parallel to the b axis. If .FALSE. it is parallel to the c axis."""
),
)
origin_choice: Literal[1, 2] = Field(
1,
description=dedent(
"""\
Used only for space groups that in the ITA allow the use of two different origins.
- '1': the first origin.
- '2': the second origin."""
),
)
rhombohedral: bool = Field(
True,
description=dedent(
"""\
Used only for rhombohedral space groups. When .TRUE. the coordinates of the
inequivalent atoms are given with respect to the rhombohedral axes, when .FALSE. the
coordinates of the inequivalent atoms are given with respect to the hexagonal axes.
They are converted internally to the rhombohedral axes and ibrav=5 is used in both
cases."""
),
)
zgate: float = Field(
0.5,
description=dedent(
"""\
used only if gate = .TRUE. Specifies the position of the charged plate which represents
the counter charge in doped systems (tot_charge .ne. 0). In units of the unit cell
length in z direction, zgate in ]0,1[ Details of the gate potential can be found in T.
Brumme, M. Calandra, F. Mauri; PRB 89, 245406 (2014)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.89.245406)."""
),
)
relaxz: bool = Field(
False,
description=dedent(
"""\
used only if gate = .TRUE. Allows the relaxation of the system towards the charged
plate. Use carefully and utilize either a layer of fixed atoms or a potential barrier
(block=.TRUE.) to avoid the atoms moving to the position of the plate or the dipole of
the dipole correction (dipfield=.TRUE.)."""
),
)
block: bool = Field(
False,
description=dedent(
"""\
used only if gate = .TRUE. Adds a potential barrier to the total potential seen by the
electrons to mimic a dielectric in field effect configuration and/or to avoid electrons
spilling into the vacuum region for electron doping. Potential barrier is from block_1
to block_2 and has a height of block_height. If dipfield = .TRUE. then eopreg is used
for a smooth increase and decrease of the potential barrier."""
),
)
block_1: float = Field(
0.45,
description=dedent(
"""\
used only if gate = .TRUE. and block = .TRUE. lower beginning of the potential barrier,
in units of the unit cell size along z, block_1 in ]0,1["""
),
)
block_2: float = Field(
0.55,
description=dedent(
"""\
used only if gate = .TRUE. and block = .TRUE. upper beginning of the potential barrier,
in units of the unit cell size along z, block_2 in ]0,1["""
),
)
block_height: float = Field(
0.0,
description=dedent(
"""\
used only if gate = .TRUE. and block = .TRUE. Height of the potential barrier in
Rydberg."""
),
)
nextffield: int = Field(
0,
description=dedent(
"""\
Number of activated external ionic force fields. See Doc/ExternalForceFields.tex for
further explanation and parameterizations"""
),
)
celldm: Annotated[
tuple[float, float, float, float, float, float],
Quantity(units="1:bohr", dimensionality="dimensionless, 1:length"),
] = Field(
(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
description=dedent(
"""\
Crystallographic constants - see the ibrav variable. Specify either these OR
A,B,C,cosAB,cosBC,cosAC NOT both. Only needed values (depending on 'ibrav') must be
specified alat = celldm(1) is the lattice parameter 'a' If ibrav==0, only celldm(1) is
used if present; cell vectors are read from card CELL_PARAMETERS"""
),
)
starting_charge: Annotated[list[float], Quantity(units="e", dimensionality="charge")] = Field(
default_factory=list,
description=dedent(
"""\
starting charge on atomic type 'i', to create starting potential with startingpot =
'atomic'. (start = 1, end = ntyp)"""
),
)
starting_magnetization: list[float] = Field(
default_factory=list,
description=dedent(
"""\
Starting spin polarization on atomic type 'i' in a spin-polarized (LSDA or
non-collinear/spin-orbit) calculation. The input values can have an absolute value
greater than or equal to 1, which will be interpreted as the site's magnetic moment.
Alternatively, the values can range between -1 and 1, which will be interpreted as the
site magnetization per valence electron. For QE-v7.2 and older versions, only the
second option is allowed. If you expect a nonzero magnetization in your ground state,
you MUST either specify a nonzero value for at least one atomic type, or constrain the
magnetization using variable tot_magnetization for LSDA, constrained_magnetization for
noncollinear/spin-orbit calculations. If you don't, you will get a nonmagnetic (zero
magnetization) state. In order to perform LSDA calculations for an antiferromagnetic
state, define two different atomic species corresponding to sublattices of the same
atomic type. NOTE 1: starting_magnetization is ignored in most BUT NOT ALL cases in
non-scf calculations: it is safe to keep the same values for the scf and subsequent
non-scf calculation. NOTE 2: If you fix the magnetization with tot_magnetization, do
not specify starting_magnetization. NOTE 3: In the noncollinear/spin-orbit case,
starting with zero starting_magnetization on all atoms imposes time reversal symmetry.
The magnetization is never calculated and is set to zero (the internal variable domag
is set to .FALSE.). (start = 1, end = ntyp)"""
),
)
Hubbard_beta: Annotated[list[float], Quantity(units="eV", dimensionality="energy")] = Field(
default_factory=list,
description=dedent(
"""\
Hubbard_beta(i) is the perturbation (on atom i) used to compute J0 with the
linear-response method of Cococcioni and de Gironcoli, PRB 71, 035105 (2005)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.71.035105) (only for DFT+U or
DFT+U+V). See also PRB 84, 115108 (2011)
(https://journals.aps.org/prb/abstract/10.1103/PhysRevB.84.115108). (start = 1, end =
ntyp)"""
),
)
angle1: list[float] = Field(
default_factory=list,
description=dedent(
"""\
The angle expressed in degrees between the initial magnetization and the z-axis. For
noncollinear calculations only; index i runs over the atom types. (start = 1, end =
ntyp)"""
),
)
angle2: list[float] = Field(
default_factory=list,
description=dedent(
"""\
The angle expressed in degrees between the projection of the initial magnetization on
x-y plane and the x-axis. For noncollinear calculations only. (start = 1, end = ntyp)"""
),
)
fixed_magnetization: tuple[float, float, float] = Field(
(0.0, 0.0, 0.0),
description=dedent(
"""\
total magnetization vector (x,y,z components) to be kept fixed when
constrained_magnetization=='total"""
),
)
london_c6: Annotated[
list[float] | None, Quantity(units="Ry bohr^6", dimensionality="energy length^6")
] = Field(
None,
json_schema_extra={"conditional_default": [{"when": None, "value": "internal"}]},
description=dedent(
"""\
atomic C6 coefficient of each atom type ( if not specified default values from S.
Grimme, J. Comp. Chem. 27, 1787 (2006), doi:10.1002/jcc.20495
(https://doi.org/10.1002/jcc.20495) are used; see file Modules/mm_dispersion.f90 )
(start = 1, end = ntyp)"""
),
)
london_rvdw: Annotated[list[float] | None, Quantity(units="bohr", dimensionality="length")] = (
Field(
None,
json_schema_extra={"conditional_default": [{"when": None, "value": "internal"}]},
description=dedent(
"""\
atomic vdw radii of each atom type ( if not specified default values from S.
Grimme, J. Comp. Chem. 27, 1787 (2006), doi:10.1002/jcc.20495
(https://doi.org/10.1002/jcc.20495) are used; see file Modules/mm_dispersion.f90 )
(start = 1, end = ntyp)"""
),
)
)
[docs]
class ElectronsNamelist(Namelist):
"""Pydantic model for the `ELECTRONS` namelist."""
[docs]
@field_validator("diagonalization", mode="before")
@classmethod
def map_diagonalization(cls, v: str) -> str:
"""Map equivalent values for `diagonalization` onto a canonical value."""
mapping = {"ParO": "paro", "rmm": "rmm-davidson", "rmm-diis": "rmm-davidson"}
return mapping.get(v, v)
electron_maxstep: int = Field(
100,
description=dedent(
"""\
In a scf calculation: maximum number of scf iterations. If exact exchange is active:
maximum number of iterations in the inner loop. If restarting from a previously
interrupted calculation: maximum number of scf iterations performed in the current run,
irrespective of how many have already been performed in previous runs."""
),
)
exx_maxstep: int = Field(
100,
description="maximum number of outer iterations in a scf calculation with exact exchange.",
)
scf_must_converge: bool = Field(
True,
description=dedent(
"""\
If .false. do not stop molecular dynamics or ionic relaxation when electron_maxstep is
reached. Use with care."""
),
)
conv_thr: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
1e-06,
description=dedent(
"""\
Convergence threshold for selfconsistency: estimated energy error < conv_thr (note that
conv_thr is extensive, like the total energy). For non-self-consistent calculations,
conv_thr is used to set the default value of the threshold (ethr) for iterative
diagonalization: see diago_thr_init"""
),
)
adaptive_thr: bool = Field(
False,
description=dedent(
"""\
If .TRUE. this turns on the use of an adaptive conv_thr for the inner scf loops when
using EXX."""
),
)
conv_thr_init: Annotated[float, Quantity(units="Ry", dimensionality="energy")] = Field(
0.001,
description=dedent(
"""\
When adaptive_thr = .TRUE. this is the convergence threshold used for the first scf
cycle."""
),
)
conv_thr_multi: float = Field(
0.1,
description=dedent(
"""\
When adaptive_thr = .TRUE. the convergence threshold for each scf cycle is given by:
max( conv_thr, conv_thr_multi * dexx )"""
),
)
mixing_mode: Literal["plain", "TF", "local-TF"] = Field(
"plain",
description=dedent(
"""\
Available options are:
- 'plain': charge density Broyden mixing.
- 'TF': as above, with simple Thomas-Fermi screening (for highly homogeneous systems).
- 'local-TF': as above, with local-density-dependent TF screening (for highly
inhomogeneous systems)."""
),
)
mixing_beta: float = Field(0.7, description="mixing factor for self-consistency")
mixing_ndim: int = Field(
8,
description=dedent(
"""\
number of iterations used in mixing scheme. If you are tight with memory, you may
reduce it to 4 or so."""
),
)
mixing_fixed_ns: int = Field(
0,
description=dedent(
"""\
For DFT+U : number of iterations with fixed ns ( ns is the atomic density appearing in
the Hubbard term )."""
),
)
diagonalization: Literal[
"david", "cg", "ppcg", "paro", "rmm-davidson", "rmm-paro", "direct"
] = Field(
"david",
description=dedent(
"""\
Available options are:
- 'david': Davidson iterative diagonalization with overlap matrix. Fast, may in some
rare cases fail.
- 'cg': Conjugate-gradient-like band-by-band diagonalization. MUCH slower than 'david'
but uses less memory and is (a little bit) more robust.
- 'ppcg': PPCG iterative diagonalization (end support on Dec 2024).
- 'paro': ParO iterative diagonalization.
- 'rmm-davidson': RMM-DIIS iterative diagonalization. To stabilize the SCF loop
RMM-DIIS is alternated with calls to Davidson or ParO solvers depending on the
string used. Other variables that can be used to tune the behavior of RMM-DIIS are:
diago_rmm_ndim and diago_rmm_conv.
- 'rmm-paro': RMM-DIIS iterative diagonalization. To stabilize the SCF loop RMM-DIIS is
alternated with calls to Davidson or ParO solvers depending on the string used.
Other variables that can be used to tune the behavior of RMM-DIIS are:
diago_rmm_ndim and diago_rmm_conv.
- 'direct': Direct diagonalization of the dense Hamiltonian in the plane-wave basis.
Use ONLY when a large number of unoccupied states are needed."""
),
)
diago_thr_init: float = Field(
0.0,
description=dedent(
"""\
Convergence threshold (ethr) for iterative diagonalization (the check is on eigenvalue
convergence). For scf calculations: default is 1.D-2 if starting from a superposition
of atomic orbitals; 1.D-5 if starting from a charge density. During self consistency
the threshold is automatically reduced (but never below 1.D-13) when approaching
convergence. For non-scf calculations: default is (conv_thr/N elec)/10."""
),
)
diago_cg_maxiter: int = Field(
20, description="For conjugate gradient diagonalization: max number of iterations"
)
diago_david_ndim: int = Field(
2,
description=dedent(
"""\
For Davidson diagonalization: dimension of workspace (number of wavefunction
packets, at least 2 needed). A larger value may yield a smaller number of iterations
in the algorithm but uses more memory and more CPU time in subspace diagonalization
(cdiaghg/rdiaghg). You may try diago_david_ndim=4 if you are not tight on memory and
if the time spent in subspace diagonalization is small compared to the time spent in
h_psi"""
),
)
diago_rmm_ndim: int = Field(
4,
description=dedent(
"""\
For RMM-DIIS diagonalization: dimension of workspace (number of wavefunction packets,
at least 2 needed)."""
),
)
diago_rmm_conv: bool = Field(
False,
description=dedent(
"""\
If .TRUE., RMM-DIIS is performed up to converge. If .FALSE., RMM-DIIS is performed only
once."""
),
)
diago_gs_nblock: int = Field(
16,
description="For RMM-DIIS diagonalization: blocking size of Gram-Schmidt orthogonalization",
)
diago_full_acc: bool = Field(
False,
description=dedent(
"""\
If .TRUE. all the empty states are diagonalized at the same level of accuracy of the
occupied ones. Otherwise the empty states are diagonalized using a larger threshold
(this should not affect total energy, forces, and other ground-state properties)."""
),
)
efield: Annotated[
float, Quantity(units="Ry e^-1 bohr^-1", dimensionality="energy charge^-1 length^-1")
] = Field(
0.0,
description=dedent(
"""\
Amplitude of the finite electric field (1 a.u. = 36.3609*10^10 V/m). Used only if
lelfield==.TRUE. and if k-points (K_POINTS card) are not automatic."""
),
)
efield_phase: Literal["read", "write", "none"] = Field(
"none",
description=dedent(
"""\
Available options are:
- 'read': set the zero of the electronic polarization (with lelfield==.true..) to the
result of a previous calculation.
- 'write': write on disk data on electronic polarization to be read in another
calculation.
- 'none': none of the above points."""
),
)
startingpot: Literal["atomic", "file"] = Field(
"atomic",
description=dedent(
"""\
Available options are:
- 'atomic': starting potential from atomic charge superposition (default for scf,
*relax, *md).
- 'file': start from existing 'charge-density.xml' file in the directory specified by
variables prefix and outdir For nscf and bands calculation this is the default and
the only sensible possibility."""
),
)
startingwfc: Literal["atomic", "atomic+random", "random", "file"] = Field(
"atomic+random",
description=dedent(
"""\
Available options are:
- 'atomic': Start from superposition of atomic orbitals. If not enough atomic orbitals
are available, fill with random numbers the remaining wfcs The scf typically starts
better with this option, but in some high-symmetry cases one can 'loose' valence
states, ending up in the wrong ground state.
- 'atomic+random': As above, plus a superimposed 'randomization' of atomic orbitals.
Prevents the 'loss' of states mentioned above.
- 'random': Start from random wfcs. Slower start of scf but safe. It may also reduce
memory usage in conjunction with diagonalization='cg'.
- 'file': Start from an existing wavefunction file in the directory specified by
variables prefix and outdir."""
),
)
tqr: bool = Field(
False,
description=dedent(
"""\
If .true., use a real-space algorithm for augmentation charges of ultrasoft
pseudopotentials and PAWsets. Faster but numerically less accurate than the default
G-space algorithm. Use with care and after testing!"""
),
)
real_space: bool = Field(
False,
description=dedent(
"""\
If .true., exploit real-space localization to compute matrix elements for nonlocal
projectors. Faster and in principle better scaling than the default G-space algorithm,
but numerically less accurate, may lead to some loss of translational invariance. Use
with care and after testing!"""
),
)
efield_cart: Annotated[
tuple[float, float, float],
Quantity(units="Ry e^-1 bohr^-1", dimensionality="energy charge^-1 length^-1"),
] = Field(
(0.0, 0.0, 0.0),
description=dedent(
"""\
Finite electric field (1 a.u. = 36.3609*10^10 V/m) in cartesian axis. Used only if
lelfield==.TRUE. and if k-points (K_POINTS card) are automatic."""
),
)
[docs]
class IonsNamelist(Namelist):
"""Pydantic model for the `IONS` namelist."""
ion_positions: Literal["default", "from_input"] = Field(
"default",
description=dedent(
"""\
Available options are:
- 'default': if restarting, use atomic positions read from the restart file; in all
other cases, use atomic positions from standard input.
- 'from_input': read atomic positions from standard input, even if restarting."""
),
)
ion_velocities: Literal["default", "from_input"] = Field(
"default",
description=dedent(
"""\
Initial ionic velocities. Available options are:
- 'default': start a new simulation from random thermalized distribution of velocities
if tempw is set, with zero velocities otherwise; restart from atomic velocities read
from the restart file.
- 'from_input': start or continue the simulation with atomic velocities read from
standard input - see card ATOMIC_VELOCITIES."""
),
)
ion_dynamics: Literal[
"none",
"bfgs",
"damp",
"fire",
"verlet",
"velocity-verlet",
"langevin",
"langevin-smc",
"bfgs",
"damp",
"beeman",
] = Field(
"none",
description=dedent(
"""\
Specify the type of ionic dynamics. For different type of calculation different
possibilities are allowed and different default values apply: CASE ( calculation ==
'relax' ) CASE ( calculation == 'md' ) CASE ( calculation == 'vc-relax' ) CASE (
calculation == 'vc-md' )
- 'none': no ionic dynamics (this is the default for calculation = 'scf', 'nscf',
'bands').
- 'bfgs': (default) use BFGS quasi-newton algorithm, based on the trust radius
procedure, for structural relaxation.
- 'damp': use damped (quick-min Verlet) dynamics for structural relaxation Can be used
for constrained optimisation: see CONSTRAINTS card.
- 'fire': use the FIRE minimization algorithm employing the semi-implicit Euler
integration scheme see: Bitzek et al.,PRL, 97, 170201, (2006)
(https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.97.170201), doi:
10.1103/PhysRevLett.97.170201 (https://doi.org/10.1103/PhysRevLett.97.170201) Guenole
et al.,CMS, 175, 109584, (2020), doi: 10.1016/j.commatsci.2020.109584
(https://doi.org/10.1016/j.commatsci.2020.109584) Can be used for constrained
optimisation: see CONSTRAINTS card.
- 'verlet': (default) use Verlet algorithm to integrate Newton's equation. For
constrained dynamics, see CONSTRAINTS card.
- 'velocity-verlet': use velocity-Verlet algorithm to integrate Newton's equation. For
constrained dynamics, see CONSTRAINTS card.
- 'langevin': ion dynamics is over-damped Langevin.
- 'langevin-smc': over-damped Langevin with Smart Monte Carlo: see R.J. Rossky, JCP,
69, 4628 (1978), doi:10.1063/1.436415 (https://doi.org/10.1063/1.436415).
- 'bfgs': (default) use BFGS quasi-newton algorithm; cell_dynamics must be 'bfgs' too.
- 'damp': use damped (Beeman) dynamics for structural relaxation.
- 'beeman': (default) use Beeman algorithm to integrate Newton's equation."""
),
)
pot_extrapolation: Literal["none", "atomic", "first_order", "second_order"] = Field(
"atomic",
description=dedent(
"""\
Used to extrapolate the potential from preceding ionic steps. Note: 'first_order' and
'second-order' extrapolation make sense only for molecular dynamics calculations
- 'none': no extrapolation.
- 'atomic': extrapolate the potential as if it was a sum of atomic-like orbitals.
- 'first_order': extrapolate the potential with first-order formula.
- 'second_order': as above, with second order formula."""
),
)
wfc_extrapolation: Literal["none", "first_order", "second_order"] = Field(
"none",
description=dedent(
"""\
Used to extrapolate the wavefunctions from preceding ionic steps. Note: 'first_order'
and 'second-order' extrapolation make sense only for molecular dynamics calculations
- 'none': no extrapolation.
- 'first_order': extrapolate the wave-functions with first-order formula.
- 'second_order': as above, with second order formula."""
),
)
remove_rigid_rot: bool = Field(
False,
description=dedent(
"""\
This keyword is useful when simulating the dynamics and/or the thermodynamics of an
isolated system. If set to true the total torque of the internal forces is set to zero
by adding new forces that compensate the spurious interaction with the periodic images.
This allows for the use of smaller supercells. BEWARE: since the potential energy is
no longer consistent with the forces (it still contains the spurious interaction with
the repeated images), the total energy is not conserved anymore. However the dynamical
and thermodynamical properties should be in closer agreement with those of an isolated
system. Also the final energy of a structural relaxation will be higher, but the
relaxation itself should be faster."""
),
)
ion_temperature: Literal[
"rescaling",
"rescale-v",
"rescale-T",
"reduce-T",
"nose",
"berendsen",
"andersen",
"svr",
"initial",
"not_controlled",
] = Field(
"not_controlled",
description=dedent(
"""\
Available options are:
- 'rescaling': control ionic temperature via velocity rescaling (first method) see
parameters tempw, tolp, and nraise (for VC-MD only).
- 'rescale-v': control ionic temperature via velocity rescaling (second method) see
parameters tempw and nraise.
- 'rescale-T': scale temperature of the thermostat every nraise steps by delta_t,
starting from tempw. The temperature is controlled via velocitiy rescaling.
- 'reduce-T': reduce temperature of the thermostat every nraise steps by the (negative)
value delta_t, starting from tempw. If delta_t is positive, the target temperature
is augmented. The temperature is controlled via velocitiy rescaling.
- 'nose': control ionic temperature using Nose-Hoover thermostat. See also parameters
fnosep , tempw , nhpcl, ndega , nhptyp.
- 'berendsen': control ionic temperature using 'soft' velocity rescaling - see
parameters tempw and nraise.
- 'andersen': control ionic temperature using Andersen thermostat see parameters tempw
and nraise.
- 'svr': control ionic temperature using stochastic-velocity rescaling (Donadio, Bussi,
Parrinello, J. Chem. Phys. 126, 014101, 2007), with parameters tempw and nraise.
- 'initial': initialize ion velocities to temperature tempw and leave uncontrolled
further on.
- 'not_controlled': ionic temperature is not controlled."""
),
)
tempw: Annotated[float, Quantity(units="K", dimensionality="temperature")] = Field(
300.0,
description="Starting temperature in MD runs target temperature for most thermostats.",
)
fnosep: Annotated[float, Quantity(units="THz", dimensionality="time^-1")] = Field(
1.0,
description=dedent(
"""\
oscillation frequency of the Nose thermorstat [note that 3 THz = 100 cm^-1], meaningful
only with 'ion_temperature = 'nose'' for Nose-Hoover chain one can ser frequncies for
all nhpcl thermostats ( fnosep = X Y Z etc.) If only first is set, the defaults for the
others will be the same."""
),
)
nhpcl: int = Field(
0,
description=dedent(
"""\
number of thermostats in the Nose-Hoover chain; currently maximum allowed is 4"""
),
)
nhptyp: Literal[0, 1, 2, 3] = Field(
0,
description=dedent(
"""\
type of the 'massive' Nose-Hoover chain thermostat.
- '0': uses one NH chain for all atoms.
- '1': uses a NH chain per each atomic type.
- '2': use a NH chaing per atom, this one is usefulf for extremely rapid equipartioning.
- '3': together with nhgrp allows fine grained thermostat control."""
),
)
ndega: int = Field(
0,
description=dedent(
"""\
number of degrees of freedom used for temperature calculation ndega <= 0 sets the
number of degrees of freedom to [3*nat-abs(ndega)], ndega > 0 is used as the target
number"""
),
)
tolp: Annotated[float, Quantity(units="K", dimensionality="temperature")] = Field(
100.0,
description=dedent(
"""\
Tolerance for velocity rescaling. Velocities are rescaled if the run-averaged and
target temperature differ more than tolp."""
),
)
delta_t: float = Field(
1.0,
description=dedent(
"""\
if ion_temperature == 'rescale-T' : at each step the instantaneous temperature is
multiplied by delta_t; this is done rescaling all the velocities. if ion_temperature
== 'reduce-T' : every 'nraise' steps the instantaneous temperature is reduced by
-delta_t (i.e. delta_t < 0 is added to T) The instantaneous temperature is calculated
at the end of every ionic move and BEFORE rescaling. This is the temperature reported
in the main output. For delta_t < 0, the actual average rate of heating or cooling
should be roughly C*delta_t/(nraise*dt) (C=1 for an ideal gas, C=0.5 for a harmonic
solid, theorem of energy equipartition between all quadratic degrees of freedom)."""
),
)
nraise: int = Field(
1,
description=dedent(
"""\
if ion_temperature == 'reduce-T' : every nraise steps the instantaneous temperature is
reduced by -delta_t (i.e. delta_t is added to the temperature) if ion_temperature ==
'rescale-v' : every nraise steps the average temperature, computed from the last nraise
steps, is rescaled to tempw if ion_temperature == 'rescaling' and calculation ==
'vc-md' : every nraise steps the instantaneous temperature is rescaled to tempw if
ion_temperature == 'berendsen' : the 'rise time' parameter is given in units of the
time step: tau = nraise*dt, so dt/tau = 1/nraise if ion_temperature == 'andersen' :
the 'collision frequency' parameter is given as nu=1/tau defined above, so nu*dt =
1/nraise if ion_temperature == 'svr' : the 'characteristic time' of the thermostat is
set to tau = nraise*dt"""
),
)
refold_pos: bool = Field(
False,
description=dedent(
"""\
This keyword applies only in the case of molecular dynamics or damped dynamics. If true
the ions are refolded at each step into the supercell."""
),
)
upscale: float = Field(
100.0,
description=dedent(
"""\
Max reduction factor for conv_thr during structural optimization conv_thr is
automatically reduced when the relaxation approaches convergence so that forces are
still accurate, but conv_thr will not be reduced to less that conv_thr / upscale."""
),
)
bfgs_ndim: int = Field(
1,
description=dedent(
"""\
Number of old forces and displacements vectors used in the PULAY (GDIIS) mixing of the
residual vectors obtained on the basis of the inverse hessian matrix given by the BFGS
algorithm. The variable tgdiis_step in this case sets whether to use to full GDIIS
step or the BFGS trust_radius. When bfgs_ndim = 1, the standard quasi-Newton BFGS
method is used. (bfgs only)"""
),
)
tgdiis_step: bool = Field(
True,
description=dedent(
"""\
When G-DIIS (bfgs_ndim > 1) is used for the structural relaxation this variable selects
whether to use to full gdiis step or the BFGS trus radius. (bfgs only)"""
),
)
trust_radius_max: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.8, description="Maximum ionic displacement in the structural relaxation. (bfgs only)"
)
trust_radius_min: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.0001,
description=dedent(
"""\
Minimum ionic displacement in the structural relaxation BFGS is reset when trust_radius
< trust_radius_min. (bfgs only)"""
),
)
trust_radius_ini: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.5, description="Initial ionic displacement in the structural relaxation. (bfgs only)"
)
w_1: float = Field(0.01, description="")
w_2: float = Field(
0.5, description="Parameters used in line search based on the Wolfe conditions. (bfgs only)"
)
fire_alpha_init: float = Field(
0.2,
description=dedent(
"""\
Initial value of the alpha mixing factor in the FIRE minimization scheme; recommended
values are between 0.1 and 0.3"""
),
)
fire_falpha: float = Field(
0.99, description="Scaling of the alpha mixing parameter for steps with P > 0;"
)
fire_nmin: int = Field(
5, description="Minimum number of steps with P > 0 before increase of dt"
)
fire_f_inc: float = Field(1.1, description="Factor for increasing dt")
fire_f_dec: float = Field(0.5, description="Factor for decreasing dt")
fire_dtmax: float = Field(
10.0,
description=dedent(
"""\
Determines the maximum value of dt in the FIRE minimization; dtmax = fire_dtmax*dt"""
),
)
nhgrp: list[int] = Field(
default_factory=list,
description=dedent(
"""\
specifies which thermostat group to use for given atomic type when >0 assigns all the
atoms in this type to thermostat labeled nhgrp(i), when =0 each atom in the type gets
its own thermostat. Finally, when <0, then this atomic type will have temperature 'not
controlled'. Example: HCOOLi, with types H (1), C(2), O(3), Li(4); setting nhgrp={2 2 0
-1} will add a common thermostat for both H & C, one thermostat per each O (2 in
total), and a non-updated thermostat for Li which will effectively make temperature for
Li 'not controlled (start = 1, end = ntyp)"""
),
)
fnhscl: list[float] | None = Field(
None,
json_schema_extra={"default_expr": "(Nat-1)/Nat"},
description=dedent(
"""\
these are the scaling factors to be used together with nhptyp=3 and nhgrp(i) in order
to take care of possible reduction in the degrees of freedom due to constraints.
Suppose that with the previous example HCOOLi, C-H bond is constrained. Then, these 2
atoms will have 5 degrees of freedom in total instead of 6, and one can set fnhscl={5/6
5/6 1. 1.}. This way the target kinetic energy for H&C will become 6(kT/2)*5/6 =
5(kT/2). This option is to be used for simulations with many constraints, such as rigid
water with something else in there (start = 1, end = ntyp)"""
),
)
[docs]
class CellNamelist(Namelist):
"""Pydantic model for the `CELL` namelist."""
cell_dynamics: Literal["none", "sd", "damp-pr", "damp-w", "bfgs", "none", "pr", "w"] = Field(
"none",
description=dedent(
"""\
Specify the type of dynamics for the cell. For different type of calculation different
possibilities are allowed and different default values apply: CASE ( calculation ==
'vc-relax' ) CASE ( calculation == 'vc-md' )
- 'none': no dynamics.
- 'sd': steepest descent ( not implemented ).
- 'damp-pr': damped (Beeman) dynamics of the Parrinello-Rahman extended lagrangian.
- 'damp-w': damped (Beeman) dynamics of the new Wentzcovitch extended lagrangian.
- 'bfgs': BFGS quasi-newton algorithm (default) ion_dynamics must be 'bfgs' too.
- 'none': no dynamics.
- 'pr': (Beeman) molecular dynamics of the Parrinello-Rahman extended lagrangian.
- 'w': (Beeman) molecular dynamics of the new Wentzcovitch extended lagrangian."""
),
)
press: Annotated[float, Quantity(units="kbar", dimensionality="energy length^-3")] = Field(
0.0, description="Target pressure in a variable-cell md or relaxation run."
)
wmass: Annotated[float | None, Quantity(units="amu", dimensionality="mass")] = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Fictitious cell mass for variable-cell simulations (both 'vc-md' and 'vc-relax') If
not specified, it is computed from the total mass of the system as
0.75*Tot_Mass/pi**2 for Parrinello-Rahman MD, and as
0.75*Tot_Mass/pi**2/Omega**(2/3) for Wentzcovitch MD."""
),
)
cell_factor: float | None = Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "variable-cell calculation", "value": "2.0"},
{"when": None, "value": "1.0"},
],
},
description=dedent(
"""\
Used in the construction of the pseudopotential tables. It should exceed the maximum
linear contraction of the cell during a simulation."""
),
)
press_conv_thr: Annotated[float, Quantity(units="kbar", dimensionality="energy length^-3")] = (
Field(
0.5,
description=dedent(
"""\
Convergence threshold on the pressure for variable cell relaxation ('vc-relax' :
note that the other convergence thresholds for ionic relaxation apply as well)."""
),
)
)
cell_dofree: Literal[
"all",
"ibrav",
"a",
"b",
"c",
"fixa",
"fixb",
"fixc",
"x",
"y",
"z",
"xy",
"xz",
"yz",
"xyz",
"shape",
"volume",
"2Dxy",
"2Dshape",
"epitaxial_ab",
"epitaxial_ac",
"epitaxial_bc",
] = Field(
"all",
description=dedent(
"""\
Select which of the cell parameters should be moved: BEWARE: if axis are not
orthogonal, some of these options do not work (symmetry is broken). If you are not
happy with them, edit subroutine init_dofree in file Modules/cell_base.f90
- 'all': all axis and angles are moved.
- 'ibrav': all axis and angles are moved, but the lattice remains consistent with the
initial ibrav choice. You can use this option in combination with any other one by
specifying 'ibrav+option'. Please note that some combinations do not make sense for
some crystals and will guarantee that the relax will never converge. E.g.
'ibrav+2Dxy' is not a problem for hexagonal cells, but will never converge for cubic
ones.
- 'a': the x component of axis 1 (v1_x) is fixed.
- 'b': the y component of axis 2 (v2_y) is fixed.
- 'c': the z component of axis 3 (v3_z) is fixed.
- 'fixa': axis 1 (v1_x,v1_y,v1_z) is fixed.
- 'fixb': axis 2 (v2_x,v2_y,v2_z) is fixed.
- 'fixc': axis 3 (v3_x,v3_y,v3_z) is fixed.
- 'x': only the x component of axis 1 (v1_x) is moved.
- 'y': only the y component of axis 2 (v2_y) is moved.
- 'z': only the z component of axis 3 (v3_z) is moved.
- 'xy': only v1_x and v2_y are moved.
- 'xz': only v1_x and v3_z are moved.
- 'yz': only v2_y and v3_z are moved.
- 'xyz': only v1_x, v2_y, v3_z are moved.
- 'shape': all axis and angles, keeping the volume fixed.
- 'volume': the volume changes, keeping all angles fixed (i.e. only celldm(1) changes).
- '2Dxy': only x and y components are allowed to change.
- '2Dshape': as above, keeping the area in xy plane fixed.
- 'epitaxial_ab': fix axis 1 and 2 while allowing axis 3 to move.
- 'epitaxial_ac': fix axis 1 and 3 while allowing axis 2 to move.
- 'epitaxial_bc': fix axis 2 and 3 while allowing axis 1 to move."""
),
)
[docs]
class FcpNamelist(Namelist):
"""Pydantic model for the `FCP` namelist."""
fcp_mu: Annotated[float, Quantity(units="eV", dimensionality="energy")] = Field(
...,
description=dedent(
"""\
The target Fermi energy. One can start with appropriate total charge of the system by
giving tot_charge ."""
),
)
fcp_dynamics: Literal["none", "bfgs", "newton", "damp", "lm", "velocity-verlet", "verlet"] = (
Field(
"none",
description=dedent(
"""\
Specify the type of dynamics for the Fictitious Charge Particle (FCP). For
different type of calculation different possibilities are allowed and different
default values apply: CASE ( calculation == 'relax' ) CASE ( calculation == 'md' )
- 'none': no FCP dynamics.
- 'bfgs': (default) BFGS quasi-newton algorithm, coupling with ions relaxation
ion_dynamics must be 'bfgs' too.
- 'newton': Newton-Raphson algorithm with DIIS ion_dynamics must be 'damp' too.
- 'damp': damped (quick-min Verlet) dynamics for FCP relaxation ion_dynamics must
be 'damp' too.
- 'lm': Line-Minimization algorithm for FCP relaxation ion_dynamics must be 'damp'
too.
- 'velocity-verlet': (default) Velocity-Verlet algorithm to integrate Newton's
equation. ion_dynamics must be 'verlet' too.
- 'verlet': Verlet algorithm to integrate Newton's equation. ion_dynamics must be
'verlet' too."""
),
)
)
fcp_conv_thr: Annotated[float, Quantity(units="eV", dimensionality="energy")] = Field(
0.01, description="Convergence threshold on force for FCP relaxation."
)
fcp_ndiis: int = Field(
4, description="Size of DIIS for FCP relaxation, used only if fcp_dynamics = 'newton'."
)
fcp_mass: float | None = Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "esm_bc=='bc2' || esm_bc=='bc3'", "value": "5.D+6 / xy_area"},
{"when": None, "value": "5.D+4 / xy_area"},
],
},
description="Mass of the FCP.",
)
fcp_velocity: float | None = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
Initial velocity of the FCP. If not specified, it is determined by fcp_temperature."""
),
)
fcp_temperature: Literal[
None,
"rescaling",
"rescale-v",
"rescale-T",
"reduce-T",
"berendsen",
"andersen",
"initial",
"not_controlled",
] = Field(
None,
json_schema_extra={"default_ref": "ion_temperature"},
description=dedent(
"""\
Available options are:
- 'rescaling': control FCP's temperature via velocity rescaling (first method) see
parameters fpc_tempw and fcp_tolp.
- 'rescale-v': control FCP's temperature via velocity rescaling (second method) see
parameters fcp_tempw and fcp_nraise.
- 'rescale-T': control FCP's temperature via velocity rescaling (third method) see
parameter fcp_delta_t.
- 'reduce-T': reduce FCP's temperature every fcp_nraise steps by the (negative) value
fcp_delta_t.
- 'berendsen': control FCP's temperature using 'soft' velocity rescaling - see
parameters fcp_tempw and fcp_nraise.
- 'andersen': control FCP's temperature using Andersen thermostat see parameters
fcp_tempw and fcp_nraise.
- 'initial': initialize FCP's velocities to temperature fcp_tempw and leave
uncontrolled further on.
- 'not_controlled': FCP's temperature is not controlled."""
),
)
fcp_tempw: Annotated[float | None, Quantity(units="K", dimensionality="temperature")] = Field(
None,
json_schema_extra={"default_ref": "tempw"},
description=dedent(
"""\
Starting temperature in FCP dynamics runs target temperature for most thermostats."""
),
)
fcp_tolp: Annotated[float | None, Quantity(units="K", dimensionality="temperature")] = Field(
None,
json_schema_extra={"default_ref": "tolp"},
description=dedent(
"""\
Tolerance for velocity rescaling. Velocities are rescaled if the run-averaged and
target temperature differ more than tolp."""
),
)
fcp_delta_t: float | None = Field(
None,
json_schema_extra={"default_ref": "delta_t"},
description=dedent(
"""\
if fcp_temperature == 'rescale-T' : at each step the instantaneous temperature is
multiplied by fcp_delta_t; this is done rescaling all the velocities. if
fcp_temperature == 'reduce-T' : every fcp_nraise steps the instantaneous temperature is
reduced by -fcp_delta_t (i.e. fcp_delta_t < 0 is added to T) The instantaneous
temperature is calculated at the end of FCP's move and BEFORE rescaling. This is the
temperature reported in the main output. For fcp_delta_t < 0, the actual average rate
of heating or cooling should be roughly C*fcp_delta_t/(fcp_nraise*dt) (C=1 for an ideal
gas, C=0.5 for a harmonic solid, theorem of energy equipartition between all quadratic
degrees of freedom)."""
),
)
fcp_nraise: int | None = Field(
None,
json_schema_extra={"default_ref": "nraise"},
description=dedent(
"""\
if fcp_temperature == 'reduce-T' : every fcp_nraise steps the instantaneous temperature
is reduced by -fcp_delta_t (i.e. fcp_delta_t is added to the temperature) if
fcp_temperature == 'rescale-v' : every fcp_nraise steps the average temperature,
computed from the last fcp_nraise steps, is rescaled to fcp_tempw if fcp_temperature
== 'berendsen' : the 'rise time' parameter is given in units of the time step: tau =
fcp_nraise*dt, so dt/tau = 1/fcp_nraise if fcp_temperature == 'andersen' : the
'collision frequency' parameter is given as nu=1/tau defined above, so nu*dt =
1/fcp_nraise"""
),
)
freeze_all_atoms: bool = Field(
False,
description="If .TRUE., freeze all atoms to perform relaxation or dynamics only with FCP.",
)
[docs]
class RismNamelist(Namelist):
"""Pydantic model for the `RISM` namelist."""
nsolv: int = Field(
..., description="The number of solvents (i.e. molecular species) in the unit cell"
)
closure: Literal["kh", "hnc"] = Field(
"kh",
description=dedent(
"""\
Specify the type of closure equation:
- 'kh': The Kovalenko and Hirata's model. [A.Kovalenko, F.Hirata, JCP 110, 10095
(1999), doi:10.1063/1.478883 (https://doi.org/10.1063/1.478883)].
- 'hnc': The HyperNetted-Chain model, which is suitable only for solvents without
charge. [J.P.Hansen et al., Theory of simple liquids. Academic Press, London,
1990]."""
),
)
tempv: Annotated[float, Quantity(units="K", dimensionality="temperature")] = Field(
300.0, description="Temperature of solvents."
)
ecutsolv: Annotated[float | None, Quantity(units="Ry", dimensionality="energy")] = Field(
None,
json_schema_extra={"default_expr": "4 * ecutwfc"},
description=dedent(
"""\
Kinetic energy cutoff for solvent's correlation functions. If a solute is an isolated
system or slab, you may allowed to use default value. For a frameworked or porous
solute (e.g. Zeolite, MOF), it is desirable to apply a larger value. Solvents confined
in a framework often have a high frequency."""
),
)
starting1d: Literal["zero", "file", "fix"] = Field(
"zero",
description=dedent(
"""\
- 'zero': Starting correlation functions of 1D-RISM from zero. ( default for scf,
*relax, *md ).
- 'file': Start from existing '1d-rism_csvv_r.xml' file in the directory specified by
variables 'prefix' and 'outdir'.
- 'fix': Read from existing '1d-rism_csvv_r.xml' file in the directory specified by
variables 'prefix' and 'outdir', and never calculate 1D-RISM. For nscf and bands
calculation this is the default."""
),
)
starting3d: Literal["zero", "file"] = Field(
"zero",
description=dedent(
"""\
- 'zero': Starting correlation functions of 3D-RISM from zero. ( default for scf,
*relax, *md ).
- 'file': Start from existing '3d-rism_csuv_r.dat' file in the directory specified
by variables 'prefix' and 'outdir'. For nscf and bands calculation this is the
default."""
),
)
smear1d: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
2.0, description="Coulomb smearing radius for 1D-RISM."
)
smear3d: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
2.0, description="Coulomb smearing radius for 3D-RISM."
)
rism1d_maxstep: int = Field(
50000, description="Maximum number of iterations in a 1D-RISM step."
)
rism3d_maxstep: int = Field(5000, description="Maximum number of iterations in a 3D-RISM step.")
rism1d_conv_thr: float = Field(1e-08, description="Convergence threshold for 1D-RISM.")
rism3d_conv_thr: float | None = Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "lgcscf==.FALSE.", "value": "1e-05"},
{"when": None, "value": "5e-06"},
],
},
description="Convergence threshold for 3D-RISM.",
)
mdiis1d_size: int = Field(20, description="Size of Modified DIIS (MDIIS) for 1D-RISM.")
mdiis3d_size: int = Field(10, description="Size of Modified DIIS (MDIIS) for 3D-RISM.")
mdiis1d_step: float = Field(0.5, description="Step of Modified DIIS (MDIIS) for 1D-RISM.")
mdiis3d_step: float = Field(0.8, description="Step of Modified DIIS (MDIIS) for 3D-RISM.")
rism1d_bond_width: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Gaussian width of bonds to smear intra-molecular correlation for 1D-RISM. If 3D-RISM
calculation, default is 0. If Laue-RISM calculation, default is 2 / SQRT(ecutwfc)."""
),
)
rism1d_dielectric: float = Field(
-1.0,
description=dedent(
"""\
Dielectric constant for 1D-RISM. If rism1d_dielectric > 0, dielectrically consistent
RISM (DRISM) is performed. For details of DRISM, see: J.S.Perkyns and B.M.Pettitt, CPL
1992, 190, 626, doi:10.1016/0009-2614(92)85201-K
(https://doi.org/10.1016/0009-2614(92)85201-K)"""
),
)
rism1d_molesize: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
2.0,
description=dedent(
"""\
Size of solvent molecules for 1D-RISM. This is used only if rism1d_dielectric > 0. If
you have large molecules, you have to set ~ 20 a.u. ."""
),
)
rism1d_nproc: int = Field(128, description="Number of processes to calculate 1D-RISM.")
rism3d_conv_level: float | None = Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "laue_both_hands==.TRUE.", "value": "0.5"},
{"when": "lgcscf==.TRUE.", "value": "0.3"},
{"when": None, "value": "0.1"},
],
},
description="",
)
rism3d_planar_average: bool = Field(
False,
description=dedent(
"""\
If .TRUE., planar averages of solvent densities and potentials are calculated and
written to 'prefix.rism1'. For 3D-RISM, default is .FALSE. For Laue-RISM, default is
.TRUE."""
),
)
laue_nfit: int = Field(
4,
description=dedent(
"""\
The number of z-grid points for the polynomial fit along the cell edge. This is only
for Laue-RISM."""
),
)
laue_expand_right: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
-1.0,
description=dedent(
"""\
If positive value, set the ending position offset [in a.u.] of the solvent region on
right-hand side of the unit cell, measured relative to the unit cell edge. (the solvent
region ends at z = + [L_z/2 + laue_expand_right].) This is only for Laue-RISM."""
),
)
laue_expand_left: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
-1.0,
description=dedent(
"""\
If positive value, set the ending position offset [in a.u.] of the solvent region on
left-hand side of the unit cell, measured relative to the unit cell edge. (the solvent
region ends at z = - [L_z/2 + laue_expand_left].) This is only for Laue-RISM."""
),
)
laue_starting_right: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Set the starting position [in a.u.] of the solvent region on right-hand side of the
unit cell. Then the solvent region is defined as [ laue_starting_right , L_z/2 +
laue_expand_right ], where distribution functions are finite. This is only for
Laue-RISM."""
),
)
laue_starting_left: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Set the starting position [in a.u.] of the solvent region on left-hand side of the unit
cell. Then the solvent region is defined as [ -L_z/2 - laue_expand_left ,
laue_starting_left ], where distribution functions are finite. This is only for
Laue-RISM."""
),
)
laue_buffer_right: Annotated[float | None, Quantity(units="bohr", dimensionality="length")] = (
Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "laue_expand_right > 0.0", "value": "8.0"},
{"when": None, "value": "-1.0"},
],
},
description=dedent(
"""\
If positive value, set the buffering length [in a.u.] of the solvent region on
right-hand side of the unit cell. Then correlation functions are defined inside of
[ laue_starting_right - laue_buffer_right , L_z/2 + laue_expand_right ]. This is
only for Laue-RISM."""
),
)
)
laue_buffer_left: Annotated[float | None, Quantity(units="bohr", dimensionality="length")] = (
Field(
None,
json_schema_extra={
"conditional_default": [
{"when": "laue_expand_left > 0.0", "value": "8.0"},
{"when": None, "value": "-1.0"},
],
},
description=dedent(
"""\
If positive value, set the buffering length [in a.u.] of the solvent region on
left-hand side of the unit cell. Then correlation functions are defined inside of [
-L_z/2 - laue_expand_left , laue_starting_left + laue_buffer_left ]. This is only
for Laue-RISM."""
),
)
)
laue_both_hands: bool = Field(
False,
description=dedent(
"""\
If .TRUE., you can set different densities to the solvent regions of right-hand side
and left-hand side. See SOLVENTS card."""
),
)
laue_wall: Literal["none", "auto", "manual"] = Field(
"auto",
description=dedent(
"""\
Set the repulsive wall with (1/r)^12 term of Lennard-Jones potential. This is only for
Laue-RISM.
- 'none': The repulsive wall is not defined.
- 'auto': The repulsive wall is defined, whose edge position is set automatically. One
does not have to set laue_wall_z (the edge position).
- 'manual': The repulsive wall is defined, whose edge position is set manually. One
have to set laue_wall_z (the edge position)."""
),
)
laue_wall_z: Annotated[float, Quantity(units="bohr", dimensionality="length")] = Field(
0.0,
description=dedent(
"""\
Set the edge position [in a.u.] of the repulsive wall. If laue_expand_right > 0.0, the
repulsive wall is defined on [ -inf , laue_wall_z ]. If laue_expand_left > 0.0, the
repulsive wall is defined on [ laue_wall_z , inf ]. This is only for Laue-RISM and
laue_wall == 'manual' ."""
),
)
laue_wall_rho: Annotated[float, Quantity(units="bohr^-3", dimensionality="length^-3")] = Field(
0.01,
description=dedent(
"""\
The density (1/bohr^3) of the repulsive wall. This is only for Laue-RISM and laue_wall
/= 'none' ."""
),
)
laue_wall_epsilon: Annotated[float, Quantity(units="kcal mol^-1", dimensionality="energy")] = (
Field(
0.1,
description=dedent(
"""\
The Lennard-Jones potential of the repulsive wall. Here, you can set the parameter
'epsilon'. This is only for Laue-RISM and laue_wall /= 'none' ."""
),
)
)
laue_wall_sigma: Annotated[float, Quantity(units="angstrom", dimensionality="length")] = Field(
4.0,
description=dedent(
"""\
The Lennard-Jones potential of the repulsive wall. Here, you can set the parameter
'sigma'. This is only for Laue-RISM and laue_wall /= 'none' ."""
),
)
laue_wall_lj6: bool = Field(
False,
description=dedent(
"""\
If .TRUE., the attractive term -(1/r)^6 of Lennard-Jones potential is added. This is
only for Laue-RISM and laue_wall /= 'none' ."""
),
)
solute_lj: list[str] = Field(default_factory=list, description="(start = 1, end = ntyp)")
solute_epsilon: Annotated[
list[float] | None, Quantity(units="kcal mol^-1", dimensionality="energy")
] = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
The Lennard-Jones potential of solute on atomic type 'i'. Here, you can set the
parameter 'epsilon'. (start = 1, end = ntyp)"""
),
)
solute_sigma: Annotated[
list[float] | None, Quantity(units="angstrom", dimensionality="length")
] = Field(
None,
json_schema_extra={"computed_default": True},
description=dedent(
"""\
The Lennard-Jones potential of solute on atomic type 'i'. Here, you can set the
parameter 'sigma'. (start = 1, end = ntyp)"""
),
)