Source code for scgo.cluster_adsorbate.config

"""Configuration for placing adsorbates on gas-phase metal clusters."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from scgo.exceptions import SCGOValidationError
from scgo.initialization.initialization_config import (
    CONNECTIVITY_FACTOR,
    MIN_DISTANCE_FACTOR_DEFAULT,
)
from scgo.utils.config_aliases import _UNSET, resolve_aliased_float
from scgo.utils.validation import validate_positive


[docs] @dataclass(frozen=True, init=False) class ClusterAdsorbateConfig: """Shared placement / relaxation settings for any small adsorbate fragment. Height may be set via ``height_*`` or alias ``adsorption_height_*``. """ height_min: float height_max: float max_placement_attempts: int blmin_ratio: float cell_margin: float random_spin_about_normal: bool validate_combined_structure: bool structure_min_distance_factor: float structure_connectivity_factor: float structure_check_clashes: bool structure_check_connectivity: bool def __init__( self, *, height_min: Any = _UNSET, height_max: Any = _UNSET, adsorption_height_min: Any = _UNSET, adsorption_height_max: Any = _UNSET, max_placement_attempts: int = 80, blmin_ratio: float = 0.7, cell_margin: float = 6.0, random_spin_about_normal: bool = True, validate_combined_structure: bool = True, structure_min_distance_factor: float = MIN_DISTANCE_FACTOR_DEFAULT, structure_connectivity_factor: float = CONNECTIVITY_FACTOR, structure_check_clashes: bool = True, structure_check_connectivity: bool = True, ) -> None: object.__setattr__( self, "height_min", resolve_aliased_float( "height_min", height_min, "adsorption_height_min", adsorption_height_min, 0.9, ), ) object.__setattr__( self, "height_max", resolve_aliased_float( "height_max", height_max, "adsorption_height_max", adsorption_height_max, 2.2, ), ) object.__setattr__(self, "max_placement_attempts", max_placement_attempts) object.__setattr__(self, "blmin_ratio", blmin_ratio) object.__setattr__(self, "cell_margin", cell_margin) object.__setattr__(self, "random_spin_about_normal", random_spin_about_normal) object.__setattr__( self, "validate_combined_structure", validate_combined_structure ) object.__setattr__( self, "structure_min_distance_factor", structure_min_distance_factor ) object.__setattr__( self, "structure_connectivity_factor", structure_connectivity_factor ) object.__setattr__(self, "structure_check_clashes", structure_check_clashes) object.__setattr__( self, "structure_check_connectivity", structure_check_connectivity ) self.__post_init__() @property def adsorption_height_min(self) -> float: """Alias for :attr:`height_min`.""" return self.height_min @property def adsorption_height_max(self) -> float: """Alias for :attr:`height_max`.""" return self.height_max def __post_init__(self) -> None: validate_positive("height_min", self.height_min, strict=True) validate_positive("height_max", self.height_max, strict=True) if self.height_max < self.height_min: raise SCGOValidationError("height_max must be >= height_min") if self.max_placement_attempts < 1: raise SCGOValidationError("max_placement_attempts must be positive") validate_positive("blmin_ratio", self.blmin_ratio, strict=True) validate_positive("cell_margin", self.cell_margin, strict=True) validate_positive( "structure_min_distance_factor", self.structure_min_distance_factor, strict=True, ) validate_positive( "structure_connectivity_factor", self.structure_connectivity_factor, strict=True, )
def resolve_cluster_adsorbate_config( config: ClusterAdsorbateConfig | None, ) -> ClusterAdsorbateConfig: """Return *config* or the package default (single allowed default site).""" if config is None: return ClusterAdsorbateConfig() return config