diff --git a/src/mindlessgen/generator/main.py b/src/mindlessgen/generator/main.py index 9364c51..7c74a75 100644 --- a/src/mindlessgen/generator/main.py +++ b/src/mindlessgen/generator/main.py @@ -8,12 +8,10 @@ from pathlib import Path import multiprocessing as mp import warnings -import numpy as np -from ..molecules import generate_random_molecule, Molecule, get_lanthanides +from ..molecules import generate_random_molecule, Molecule from ..qm import XTB, get_xtb_path, QMMethod, ORCA, get_orca_path, GP3, get_gp3_path from ..molecules import iterative_optimization, postprocess_mol -from ..molecules.miscellaneous import get_actinides from ..prog import ConfigManager from .. import __version__ @@ -59,31 +57,9 @@ def generator(config: ConfigManager) -> tuple[list[Molecule] | None, int]: if config.general.verbosity > 0: print(config) + config.check_config() - # lower number of the available cores and the configured parallelism num_cores = min(mp.cpu_count(), config.general.parallel) - if config.general.parallel > mp.cpu_count(): - warnings.warn( - f"Number of cores requested ({config.general.parallel}) is greater " - + f"than the number of available cores ({mp.cpu_count()})." - + f"Using {num_cores} cores instead." - ) - if config.general.verbosity > 0: - print(f"Running with {num_cores} cores.") - - if num_cores > 1 and config.general.verbosity > 0: - # raise warning that parallelization will disable verbosity - warnings.warn( - "Parallelization will disable verbosity during iterative search. " - + "Set '--verbosity 0' or '-P 1' to avoid this warning, or simply ignore it." - ) - if num_cores > 1 and config.postprocess.debug: - # raise warning that debugging of postprocessing will disable parallelization - warnings.warn( - "Debug output might seem to be redundant due to the parallel processes " - + "with possibly similar errors in parallel mode. " - + "Don't be confused!" - ) # Check if the file "mindless.molecules" exists. If yes, append to it. if Path(MINDLESS_MOLECULES_FILE).is_file(): @@ -242,16 +218,6 @@ def single_molecule_generator( if config.general.verbosity > 1: print("Postprocessing successful.") - if isinstance(refine_engine, XTB): - if np.any(np.isin(optimized_molecule.ati, get_lanthanides() + get_actinides())): - print(config.warnings.get_warning()[0]) - - if np.any(optimized_molecule.ati > 85): - print(config.warnings.get_warning()[1]) - - if postprocess_engine is None: - print(config.warnings.get_warning()[2]) - if not stop_event.is_set(): stop_event.set() # Signal other processes to stop return optimized_molecule diff --git a/src/mindlessgen/molecules/miscellaneous.py b/src/mindlessgen/molecules/miscellaneous.py index b020813..8ed4424 100644 --- a/src/mindlessgen/molecules/miscellaneous.py +++ b/src/mindlessgen/molecules/miscellaneous.py @@ -34,7 +34,7 @@ def set_random_charge(ati: np.ndarray, verbosity: int = 1) -> tuple[int, int]: ln_protons += ( atom - 3 + 1 ) # subtract 3 to get the number of protons in the Ln3+ ion - if atom in get_actinides(): + elif atom in get_actinides(): if atom < 96: uhf += atom - 88 else: diff --git a/src/mindlessgen/prog/config.py b/src/mindlessgen/prog/config.py index 26aa813..3feb513 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -6,6 +6,8 @@ from pathlib import Path from abc import ABC, abstractmethod +import warnings +import multiprocessing as mp import toml from ..molecules import PSE_NUMBERS @@ -716,25 +718,6 @@ def scf_cycles(self, max_scf_cycles: int): self._scf_cycles = max_scf_cycles -class WarningConfig: - """ - This class handles warnings related to xTB calculations. - """ - - def __init__(self) -> None: - self.warnings = [ - "WARNING: f-block elements are within the molecule. xTB does not treat f electrons explicitly. UHF is set to 0.", - "WARNING: Super heavy elements are within the molecule. xTB does not treat super havy elements. Atomic numbers are reduced by 32.", - "WARNING: Postproccessing is turned off the structure will not be relaxed.", - ] - - def get_warning(self) -> list[str]: - """ - Get the list of warnings. - """ - return self.warnings - - class ConfigManager: """ Overall configuration manager for the program. @@ -750,11 +733,65 @@ def __init__(self, config_file: str | Path | None = None): self.refine = RefineConfig() self.postprocess = PostProcessConfig() self.generate = GenerateConfig() - self.warnings = WarningConfig() if config_file: self.load_from_toml(config_file) + def check_config(self): + """ + Checks ConfigClass for any incompatibilities that are imaginable + """ + # lower number of the available cores and the configured parallelism + num_cores = min(mp.cpu_count(), self.general.parallel) + if self.general.parallel > mp.cpu_count(): + warnings.warn( + f"Number of cores requested ({self.general.parallel}) is greater " + + f"than the number of available cores ({mp.cpu_count()})." + + f"Using {num_cores} cores instead." + ) + if self.general.verbosity > 0: + print(f"Running with {num_cores} cores.") + + if num_cores > 1 and self.general.verbosity > 0: + # raise warning that parallelization will disable verbosity + warnings.warn( + "Parallelization will disable verbosity during iterative search. " + + "Set '--verbosity 0' or '-P 1' to avoid this warning, or simply ignore it." + ) + if num_cores > 1 and self.postprocess.debug: + # raise warning that debugging of postprocessing will disable parallelization + warnings.warn( + "Debug output might seem to be redundant due to the parallel processes " + + "with possibly similar errors in parallel mode. " + + "Don't be confused!" + ) + + # Check for f-block elements in forbidden elements + if self.generate.forbidden_elements: + f_block_elements = set(range(56, 70)) | set(range(88, 102)) + if any( + elem not in f_block_elements + for elem in self.generate.forbidden_elements + ): + warnings.warn( + "f-block elements could be within the molecule. xTB does not treat f electrons explicitly. In this case UHF is set to 0." + ) + + # Check for super heavy elements in forbidden elements + super_heavy_elements = set(range(86, 102)) + if self.generate.element_composition and any( + elem in super_heavy_elements for elem in self.generate.element_composition + ): + warnings.warn( + "Super heavy elements are within the molecule. xTB does not treat super heavy elements. Atomic numbers are reduced by 32." + ) + + # Check if postprocessing is turned off + if not self.general.postprocess: + warnings.warn( + "Postprocessing is turned off. The structure will not be relaxed." + ) + def get_all_identifiers(self): """ Returns the identifiers of all subconfiguration classes, e.g. "orca", "refinement", ... diff --git a/src/mindlessgen/qm/xtb.py b/src/mindlessgen/qm/xtb.py index 6eef671..f80d2be 100644 --- a/src/mindlessgen/qm/xtb.py +++ b/src/mindlessgen/qm/xtb.py @@ -90,7 +90,6 @@ def optimize( if super_heavy_elements: # Reset the atomic numbers to the original values before returning the optimized molecule. optimized_molecule.ati = ati_original - molecule.ati = ati_original optimized_molecule.atlist = molecule.atlist return optimized_molecule