System Types

System type definitions and validation.

Canonical system-type definitions and validation helpers.

class scgo.system_types.AdsorbateDefinition[source]

Bases: TypedDict

Role and layout for *_adsorbate system types (gas or surface mobile region).

Both core_symbols and adsorbate_symbols must be set (use [] for the side that is empty). They must form an ordered partition of the run composition such that composition == core_symbols + adsorbate_symbols (list equality, same length and order for the mobile atoms). The slab, if any, is not part of composition.

Empty core (core_symbols=[]): all mobile atoms are in adsorbate_symbols.

Build a core cluster, place rigid fragment(s) with scgo.cluster_adsorbate.place_fragment_on_cluster() (one site per fragment), then (for surface) deposit. Pass adsorbates as list[Atoms] with one entry per fragment at the runner API; adsorbate_fragment_lengths must match.

core_symbols: list[str]
adsorbate_symbols: list[str]
adsorbate_fragment_lengths: list[int]
fragment_anchor_index: NotRequired[int]
fragment_bond_axis: NotRequired[list[int]]
class scgo.system_types.SystemPolicy(system_type, uses_surface, has_adsorbate, requires_slab_prefix_validation, needs_supported_deposit_validation, neb_force_mic, neb_disable_alignment, neb_surface_cell_remap, neb_surface_lattice_rotation, constrain_adsorbate_moves, adsorbate_move_scale, allow_composition_permutations)[source]

Bases: object

Behavior flags for a concrete system type.

system_type: Literal['gas_cluster', 'surface_cluster', 'gas_cluster_adsorbate', 'surface_cluster_adsorbate']
uses_surface: bool
has_adsorbate: bool
requires_slab_prefix_validation: bool
needs_supported_deposit_validation: bool
neb_force_mic: bool
neb_disable_alignment: bool
neb_surface_cell_remap: bool
neb_surface_lattice_rotation: bool
constrain_adsorbate_moves: bool
adsorbate_move_scale: float
allow_composition_permutations: bool
scgo.system_types.get_system_policy(system_type)[source]

Return centralized behavior policy for one explicit system type.

Return type:

SystemPolicy

scgo.system_types.resolve_connectivity_factor(connectivity_factor, *, cluster_adsorbate_config=None, surface_config=None)[source]

Resolve structure connectivity factor from explicit value or configs.

Return type:

float

scgo.system_types.validate_system_type_settings(*, system_type, surface_config=None)[source]

Validate system-type companion settings.

Return type:

None

scgo.system_types.uses_surface(system_type)[source]
Return type:

bool

scgo.system_types.validate_mobile_symbols_match_adsorbate_definition(atoms, n_slab, adsorbate_definition)[source]

Ensure atoms mobile slice matches core_symbols + adsorbate_symbols in order.

Return type:

None

scgo.system_types.validate_structure_for_system_type(atoms, *, system_type, surface_config=None, n_slab=None, adsorbate_definition=None, connectivity_factor=None, allow_cluster_fragmentation=False, allow_adsorbate_surface_detachment=False, enforce_adsorbate_subgraph_integrity=True)[source]

Apply system-type-specific structural validation.

When adsorbate_definition is set for a *_adsorbate system type, the mobile region must match core_symbols + adsorbate_symbols in order (after the slab prefix for surface systems).

Parameters:
  • atoms (Atoms) – The Atoms object to validate

  • system_type (Literal['gas_cluster', 'surface_cluster', 'gas_cluster_adsorbate', 'surface_cluster_adsorbate']) – The system type

  • surface_config (SurfaceSystemConfig | None) – Surface configuration (for surface systems)

  • n_slab (int | None) – Number of slab atoms (for surface systems)

  • adsorbate_definition (AdsorbateDefinition | None) – Adsorbate definition (for adsorbate systems)

  • connectivity_factor (float | None) – Connectivity factor to use for cluster connectivity validation. If None, defaults to CONNECTIVITY_FACTOR from config.

  • allow_cluster_fragmentation (bool) – For surface systems, allow multiple disconnected core-bearing mobile subgroups (each must touch the slab).

  • allow_adsorbate_surface_detachment (bool) – For surface systems, allow adsorbate-only mobile subgroups on the slab without cluster contact (requires exactly one core/mixed subgroup when fragmentation is disabled).

  • enforce_adsorbate_subgraph_integrity (bool) – When True, require each adsorbate fragment to remain internally connected.

Return type:

None

scgo.system_types.validate_composition_against_adsorbate(composition, adsorbate_definition, *, context='')[source]

Check ordered partition and return (core_list, ads_list) as list[str].

Both core_symbols and adsorbate_symbols must be present (use [] if empty). The run composition must equal core_symbols + adsorbate_symbols in order.

Raises:

ValueError – If keys are missing, both sides are empty for non-empty composition, or the ordered partition does not match composition.

Return type:

tuple[list[str], list[str]]

scgo.system_types.validate_adsorbate_definition(*, system_type, composition, adsorbate_definition, context)[source]

Validate explicit adsorbate role definition for high-level runners.

Return type:

None

scgo.system_types.resolve_adsorbate_fragments(templates, adsorbate_definition, *, context='')[source]

Normalize fragment templates and validate them against the adsorbate definition.

Return type:

list[Atoms]

scgo.system_types.normalize_adsorbates_input(adsorbates, *, context)[source]
Return type:

list[Atoms]

scgo.system_types.flatten_adsorbate_symbols(adsorbates)[source]
Return type:

list[str]

scgo.system_types.combine_adsorbates_to_template(adsorbates)[source]
Return type:

Atoms

scgo.system_types.build_adsorbate_definition_from_inputs(*, system_type, composition, adsorbates, context)[source]
Return type:

tuple[AdsorbateDefinition | None, list[Atoms] | None, list[str]]

Available System Types

SCGO supports four explicit system types (SystemType is a Literal alias):

  1. gas_cluster: Gas-phase cluster (no slab, no adsorbates)

  2. surface_cluster: Cluster supported on a slab (surface_config required)

  3. gas_cluster_adsorbate: Gas-phase cluster with adsorbates

  4. surface_cluster_adsorbate: Supported cluster with adsorbates (surface_config required)

See SystemPolicy and AdsorbateDefinition in the module reference above.

NEB policy flags (via SystemPolicy)

Each system type sets defaults consumed by get_ts_search_params():

  • neb_force_mic — surface types use minimum-image path interpolation.

  • neb_disable_alignment — when False (default), neb_align_endpoints stays on in presets.

  • neb_surface_cell_remap / neb_surface_lattice_rotation — enabled for surface_cluster and surface_cluster_adsorbate; use lattice-compatible in-plane shifts and global rotation before NEB interpolation (not independent mobile-only rotations).

  • The remap search span is controlled at runtime by neb_surface_max_lattice_shift in TS presets (default 1 cell in each in-plane direction).

Surface mobile connectivity

validate_structure_for_system_type() delegates slab checks to validate_supported_cluster_deposit(). Two runtime flags (default False in GO and TS presets):

  • allow_cluster_fragmentation — multiple disconnected core/mixed mobile subgroups.

  • allow_adsorbate_surface_detachment — adsorbate-only mobile subgroups on the slab without cluster contact (with exactly one core/mixed subgroup when fragmentation is off).

For *_adsorbate types, n_core_mobile is inferred from adsorbate_definition['core_symbols']. The former allow_dissociative_adsorption parameter is removed; set both new flags to True for the old permissive behavior.

Adsorbate subgraph integrity

When enforce_adsorbate_subgraph_integrity=True (default in GO/TS presets), SCGO rejects disconnected adsorbate subgraphs.

  • With runner-style adsorbates=Atoms | list[Atoms] input, each input fragment must be connected and SCGO stores fragment boundaries for per-fragment checks.

  • For manual adsorbate_definition input, adsorbate_fragment_lengths is optional:

    • when provided, integrity is enforced per fragment;

    • when omitted, integrity is enforced on the full adsorbate block as one connected subgraph.

This design supports non-linear molecules without requiring a rigid fragment_bond_axis contract.

Adsorbate placement tuning

For *_adsorbate GO runs, optional placement and validation knobs live in go_params only:

  • connectivity_factor — primary threshold for structure validation (and fallback for hierarchical placement when no config is set).

  • cluster_adsorbate_config — optional ClusterAdsorbateConfig (fragment height range, max_placement_attempts, blmin_ratio, clash/connectivity checks). Fragment placement samples convex-hull vertex/edge/facet sites, ranks candidates by steric deficit, and relaxes placement thresholds on retry. Prefer connectivity_factor alone unless you need placement-specific overrides.

  • freeze_adsorbate_internal_geometry — Kabsch-restore fragments after mutations (strict template mode). Default False still preserves intra-fragment bonds via tag-rigid GA operators.

GA operators for adsorbate types

When SystemPolicy.has_adsorbate is true, the GA partitions the mobile region with ASE tags (core = 0, each fragment = 1..N):

  • Crossover splices the core only; adsorbate fragments inherit from parent 0.

  • Mutations use tag-rigid displacements for rattle, anisotropic rattle, and overlap relief so intra-fragment geometry is unchanged.

  • Rotational / mirror / flattening / breathing / in-plane slide use core-only or adsorbate-scoped variants (*_core, *_ads).

  • ``fragment_reposition`` re-places one adsorbate on fresh hull sites using the same placement engine as initialization.

Operator clash checks use build_blmin() (BLMIN_RATIO_DEFAULT = 0.7). Post-operator validation uses connectivity_factor (typically 1.4) via validate_structure_for_system_type().