vibesketch.inputs.neb

Reaction-path inputs from a sketched reaction: NEB-TS for ORCA, CI-NEB for vibe-qc (#29).

Draw a reaction, then write the inputs for a nudged elastic band between its reactants and its products. Three things must hold, and each is checked:

  • The atoms are paired. vibesketch.chem.mapping pairs every reactant atom with a product atom by the fewest bonds formed and broken. The pairing is shown before anything is written (reaction_mapping()), and the user can correct it by pinning atoms (m1:3=m3:5: reactant species m1’s atom 3 becomes product species m3’s atom 5). An ambiguous pairing is refused, never guessed.

  • The ends match. vibesketch.chem.endpoints builds the reactant and product complexes with their atoms in one order, the product turned onto the reactant so the band does not rotate.

  • The writer can say it. The ORCA writer reuses the keyword model of vibesketch.inputs.orca and adds NEB-TS (climbing-image NEB, then a transition-state optimisation from the climbing image), NEB-CI or NEB with a %neb block; the product geometry goes in its own XYZ file. vibe-qc’s run_neb has the climbing image but no transition-state refinement, so its writer writes neb-ci and neb and refuses neb-ts with that reason. Both optimise the two ends first, as the built complexes are no minima.

Reagents drawn at the arrow are not part of the path. A species takes part once per side; 2 A -> B is refused as unbalanced, since the drawing’s species list does not say how many molecules react.

Module Attributes

NEB_PROGRAMS

The programs this module writes reaction-path inputs for.

Functions

mapping_text(report)

The mapping report as lines a person reviews: pairs, bond changes, refusals.

neb_inputs(document, reaction, program, spec)

The reaction-path input files for reaction, and the mapping they rest on.

parse_pin(text)

m1:3=m3:5 as (reactant species, atom, product species, atom), atoms 1-based.

reaction_mapping(document, reaction[, pins])

The atom mapping of reaction as the user reviews it, with any refusal.

reaction_path(document, reaction[, pins])

Map reaction of document and build its two ends.

Classes

NebSpec(*[, kind, basis, aux_basis, ...])

What to compute along the path: the level of theory and the band.

ReactionPath(reaction, mapping, endpoints, ...)

A mapped reaction and, when the mapping is clear, its two ends.

vibesketch.inputs.neb.NEB_PROGRAMS = ('orca', 'vibeqc')

The programs this module writes reaction-path inputs for.

class vibesketch.inputs.neb.NebSpec(*, kind='neb-ts', method, basis=None, aux_basis=None, approximation=None, dispersion=None, solvent=None, resources=None, images=8, preopt_ends=True)[source]

Bases: BaseModel

What to compute along the path: the level of theory and the band.

kind is neb-ts (climbing-image NEB, then a transition-state optimisation; ORCA), neb-ci (climbing-image NEB) or neb (a plain band). images counts the images between the two ends.

Parameters:
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

kind: Literal['neb-ts', 'neb-ci', 'neb']
method: str
basis: str | None
aux_basis: str | None
approximation: str | None
dispersion: str | None
solvent: model.Solvent | None
resources: model.Resources | None
images: int
preopt_ends: bool

Optimise both ends before the band; the built complexes are no minima.

job()[source]

The level of theory as a job specification (an optimisation needs the same gradients).

Return type:

JobSpec

class vibesketch.inputs.neb.ReactionPath(reaction, mapping, endpoints, charge, multiplicity, refusals=(), canvas=<factory>)[source]

Bases: object

A mapped reaction and, when the mapping is clear, its two ends.

Parameters:
reaction: str
mapping: Any | None
endpoints: Any | None
charge: int
multiplicity: int
refusals: tuple[str, ...] = ()

Why no inputs can be written for this reaction, if any reason.

canvas: dict[tuple[str, int], tuple[float, float]]

Where each species’ heavy atoms are drawn on the canvas, for this reaction: (species, atom index in the species) -> KET coordinates.

report()[source]

The mapping as the user reviews it before anything is written.

Return type:

dict[str, Any]

vibesketch.inputs.neb.mapping_text(report)[source]

The mapping report as lines a person reviews: pairs, bond changes, refusals.

Parameters:

report (dict[str, Any])

Return type:

str

vibesketch.inputs.neb.neb_inputs(document, reaction, program, spec, pins=())[source]

The reaction-path input files for reaction, and the mapping they rest on.

Raises WriterRefusal with every reason when the reaction cannot be mapped clearly or the program cannot express spec, for a program without a reaction-path writer, and UnknownReference for a reaction or species the document lacks.

Parameters:
Return type:

tuple[InputBundle, dict[str, Any]]

vibesketch.inputs.neb.parse_pin(text)[source]

m1:3=m3:5 as (reactant species, atom, product species, atom), atoms 1-based.

Parameters:

text (str)

Return type:

tuple[str, int, str, int]

vibesketch.inputs.neb.reaction_mapping(document, reaction, pins=())[source]

The atom mapping of reaction as the user reviews it, with any refusal.

Parameters:
Return type:

dict[str, Any]

vibesketch.inputs.neb.reaction_path(document, reaction, pins=())[source]

Map reaction of document and build its two ends.

Raises UnknownReference for a reaction or pinned species the document lacks and ValueError for a malformed pin; everything else that stops the path is in ReactionPath.refusals.

Parameters:
Return type:

ReactionPath