From 2488a731de492772bede2d6efc23ab22e686faf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Fri, 11 Oct 2024 15:33:57 +0200 Subject: [PATCH 01/10] elements from 86 to 103 now accessible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- src/mindlessgen/generator/main.py | 15 ++++++++++- src/mindlessgen/molecules/miscellaneous.py | 22 +++++++++++---- src/mindlessgen/prog/config.py | 31 ++++++++++++++++++++++ src/mindlessgen/qm/xtb.py | 18 +++++++++++++ 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/mindlessgen/generator/main.py b/src/mindlessgen/generator/main.py index 237d1ec..62e6fdd 100644 --- a/src/mindlessgen/generator/main.py +++ b/src/mindlessgen/generator/main.py @@ -8,10 +8,12 @@ from pathlib import Path import multiprocessing as mp import warnings +import numpy as np -from ..molecules import generate_random_molecule, Molecule +from ..molecules import generate_random_molecule, Molecule, get_lanthanides 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__ @@ -209,6 +211,17 @@ def single_molecule_generator( config_refine=config.refine, verbosity=config.general.verbosity, ) + + # if np.any(np.isin(optimized_molecule.ati, get_lanthanides())): + # print(config.warnings.get_warning()[0]) + # elif np.any(np.isin(optimized_molecule.ati, get_actinides())): + # print(config.warnings.get_warning()[0]) + 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) and postprocess_engine is None: + print(config.warnings.get_warning()[1]) + except RuntimeError as e: if config.general.verbosity > 0: print(f"Refinement failed for cycle {cycle + 1}.") diff --git a/src/mindlessgen/molecules/miscellaneous.py b/src/mindlessgen/molecules/miscellaneous.py index a735eb8..b020813 100644 --- a/src/mindlessgen/molecules/miscellaneous.py +++ b/src/mindlessgen/molecules/miscellaneous.py @@ -16,14 +16,15 @@ def set_random_charge(ati: np.ndarray, verbosity: int = 1) -> tuple[int, int]: if verbosity > 1: print(f"Number of protons in molecule: {nel}") - if np.any(np.isin(ati, get_lanthanides())): - ### Special mode for lanthanides + if np.any(np.isin(ati, get_lanthanides() + get_actinides())): + ### Special mode for lanthanides and actinides # -> always high spin - # -> Divide the molecule into Ln3+ ions and negative "ligands" + # -> Divide the molecule into Ln3+/Ac3+ ions and negative "ligands" # -> The ligands are the remaining protons are assumed to be low spin uhf = 0 charge = 0 ln_protons = 0 + ac_protons = 0 for atom in ati: if atom in get_lanthanides(): if atom < 64: @@ -33,9 +34,20 @@ 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 - ligand_protons = nel - ln_protons + if atom in get_actinides(): + if atom < 96: + uhf += atom - 88 + else: + uhf += 102 - atom + ac_protons += ( + atom - 3 + 1 + ) # subtract 3 to get the number of protons in the Ln3+ ion + ligand_protons = nel - ln_protons - ac_protons if verbosity > 2: - print(f"Number of protons from Ln^3+ ions: {ln_protons}") + if np.any(np.isin(ati, get_lanthanides())): + print(f"Number of protons from Ln^3+ ions: {ln_protons}") + if np.any(np.isin(ati, get_actinides())): + print(f"Number of protons from Ac^3+ ions: {ac_protons}") print( f"Number of protons from ligands (assuming negative charge): {ligand_protons}" ) diff --git a/src/mindlessgen/prog/config.py b/src/mindlessgen/prog/config.py index 6bd0020..cced24e 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -716,6 +716,36 @@ 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. Postproccessing is turned off the structure will not be relaxed.", + ] + + def add_warning(self, warning: str) -> None: + """ + Add a warning to the list of warnings. + """ + self.warnings.append(warning) + + def get_warning(self) -> list[str]: + """ + Get the list of warnings. + """ + return self.warnings + + def clear_warning(self) -> None: + """ + Clear all warnings. + """ + self.warnings.clear() + + class ConfigManager: """ Overall configuration manager for the program. @@ -731,6 +761,7 @@ 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) diff --git a/src/mindlessgen/qm/xtb.py b/src/mindlessgen/qm/xtb.py index 5dedc36..556fd91 100644 --- a/src/mindlessgen/qm/xtb.py +++ b/src/mindlessgen/qm/xtb.py @@ -36,6 +36,12 @@ def optimize( """ Optimize a molecule using xtb. """ + super_heavy_elements = False + ati_original = molecule.ati.copy() + if np.any(molecule.ati > 85): + super_heavy_elements = True + molecule.ati[molecule.ati > 85] -= 32 + if np.any(np.isin(molecule.ati, get_lanthanides())): check_ligand_uhf(molecule.ati, molecule.charge) # Store the original UHF value and set uhf to 0 @@ -82,12 +88,21 @@ def optimize( if np.any(np.isin(molecule.ati, get_lanthanides())): # Reset the UHF value to the original value before returning the optimized molecule. optimized_molecule.uhf = uhf_original + 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 return optimized_molecule def singlepoint(self, molecule: Molecule, verbosity: int = 1) -> str: """ Perform a single-point calculation using xtb. """ + super_heavy_elements = False + ati_original = molecule.ati.copy() + if np.any(molecule.ati > 85): + super_heavy_elements = True + molecule.ati[molecule.ati > 85] -= 32 if np.any(np.isin(molecule.ati, get_lanthanides())): check_ligand_uhf(molecule.ati, molecule.charge) # Store the original UHF value and set uhf to 0 @@ -128,6 +143,9 @@ def singlepoint(self, molecule: Molecule, verbosity: int = 1) -> str: if np.any(np.isin(molecule.ati, get_lanthanides())): molecule.uhf = uhf_original + if super_heavy_elements: + # Reset the atomic numbers to the original values before returning the optimized molecule. + molecule.ati = ati_original return xtb_log_out def check_gap( From c8091152933e8f6806014a681279c2dca093ef8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Fri, 11 Oct 2024 15:47:28 +0200 Subject: [PATCH 02/10] Changelog now updated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- CHANGELOG.md | 1 + src/mindlessgen/generator/main.py | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e8dcb3..4d466b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the novel "g-xTB" method (working title: GP3-xTB) - A function which contracts the coordinates after the initial generation. - A function which is able to printout the xyz coordinates to the terminal similar to the `.xyz` layout. +- The elements 86 to 103 are now accessible via the element composition. ### Breaking Changes - Removal of the `dist_threshold` flag and in the `-toml` file. diff --git a/src/mindlessgen/generator/main.py b/src/mindlessgen/generator/main.py index 62e6fdd..22eb2f2 100644 --- a/src/mindlessgen/generator/main.py +++ b/src/mindlessgen/generator/main.py @@ -212,10 +212,6 @@ def single_molecule_generator( verbosity=config.general.verbosity, ) - # if np.any(np.isin(optimized_molecule.ati, get_lanthanides())): - # print(config.warnings.get_warning()[0]) - # elif np.any(np.isin(optimized_molecule.ati, get_actinides())): - # print(config.warnings.get_warning()[0]) if np.any(np.isin(optimized_molecule.ati, get_lanthanides() + get_actinides())): print(config.warnings.get_warning()[0]) From e29d04eaa440b17df1635d3c2f58d50280f5a6f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Mon, 14 Oct 2024 13:35:00 +0200 Subject: [PATCH 03/10] update on Changelog.md and final version of the warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- CHANGELOG.md | 2 +- src/mindlessgen/generator/main.py | 16 ++++++++++------ src/mindlessgen/prog/config.py | 15 ++------------- src/mindlessgen/qm/xtb.py | 2 +- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d466b4..e17aeeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the novel "g-xTB" method (working title: GP3-xTB) - A function which contracts the coordinates after the initial generation. - A function which is able to printout the xyz coordinates to the terminal similar to the `.xyz` layout. -- The elements 86 to 103 are now accessible via the element composition. +- Elements 86 to 103 are accessible via the element composition. If `xtb` is the engine, the elements will be replaced by their lighter homologues. ### Breaking Changes - Removal of the `dist_threshold` flag and in the `-toml` file. diff --git a/src/mindlessgen/generator/main.py b/src/mindlessgen/generator/main.py index 22eb2f2..9364c51 100644 --- a/src/mindlessgen/generator/main.py +++ b/src/mindlessgen/generator/main.py @@ -212,12 +212,6 @@ def single_molecule_generator( verbosity=config.general.verbosity, ) - 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) and postprocess_engine is None: - print(config.warnings.get_warning()[1]) - except RuntimeError as e: if config.general.verbosity > 0: print(f"Refinement failed for cycle {cycle + 1}.") @@ -248,6 +242,16 @@ 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/prog/config.py b/src/mindlessgen/prog/config.py index cced24e..26aa813 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -724,27 +724,16 @@ class WarningConfig: 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. Postproccessing is turned off the structure will not be relaxed.", + "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 add_warning(self, warning: str) -> None: - """ - Add a warning to the list of warnings. - """ - self.warnings.append(warning) - def get_warning(self) -> list[str]: """ Get the list of warnings. """ return self.warnings - def clear_warning(self) -> None: - """ - Clear all warnings. - """ - self.warnings.clear() - class ConfigManager: """ diff --git a/src/mindlessgen/qm/xtb.py b/src/mindlessgen/qm/xtb.py index 556fd91..6eef671 100644 --- a/src/mindlessgen/qm/xtb.py +++ b/src/mindlessgen/qm/xtb.py @@ -41,7 +41,6 @@ def optimize( if np.any(molecule.ati > 85): super_heavy_elements = True molecule.ati[molecule.ati > 85] -= 32 - if np.any(np.isin(molecule.ati, get_lanthanides())): check_ligand_uhf(molecule.ati, molecule.charge) # Store the original UHF value and set uhf to 0 @@ -92,6 +91,7 @@ def optimize( # 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 def singlepoint(self, molecule: Molecule, verbosity: int = 1) -> str: From 446282099733faca2c33fec1327c2dc75a3584e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Mon, 14 Oct 2024 14:04:04 +0200 Subject: [PATCH 04/10] Right element number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e17aeeb..d3d1a87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for the novel "g-xTB" method (working title: GP3-xTB) - A function which contracts the coordinates after the initial generation. - A function which is able to printout the xyz coordinates to the terminal similar to the `.xyz` layout. -- Elements 86 to 103 are accessible via the element composition. If `xtb` is the engine, the elements will be replaced by their lighter homologues. +- Elements 87 to 103 are accessible via the element composition. If `xtb` is the engine, the elements will be replaced by their lighter homologues. ### Breaking Changes - Removal of the `dist_threshold` flag and in the `-toml` file. From 2a46238699e7ee7f5536f3e785391104daaed66e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Tue, 15 Oct 2024 13:29:00 +0200 Subject: [PATCH 05/10] implemented the warnings at the right position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- src/mindlessgen/generator/main.py | 38 +---------- src/mindlessgen/molecules/miscellaneous.py | 2 +- src/mindlessgen/prog/config.py | 77 ++++++++++++++++------ src/mindlessgen/qm/xtb.py | 1 - 4 files changed, 60 insertions(+), 58 deletions(-) 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 From 28212a01fd016e32fe23ae6165199f60f16c1ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Wed, 16 Oct 2024 14:43:01 +0200 Subject: [PATCH 06/10] adding a test for the actinides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- src/mindlessgen/generator/main.py | 5 +- src/mindlessgen/prog/config.py | 65 ++++++++++++----------- test/test_molecules/test_miscellaneous.py | 16 +++++- 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/mindlessgen/generator/main.py b/src/mindlessgen/generator/main.py index 7c74a75..0997bde 100644 --- a/src/mindlessgen/generator/main.py +++ b/src/mindlessgen/generator/main.py @@ -57,9 +57,12 @@ def generator(config: ConfigManager) -> tuple[list[Molecule] | None, int]: if config.general.verbosity > 0: print(config) - config.check_config() + + config.check_config(verbosity=config.general.verbosity) num_cores = min(mp.cpu_count(), config.general.parallel) + if config.general.verbosity > 0: + print(f"Running with {num_cores} cores.") # Check if the file "mindless.molecules" exists. If yes, append to it. if Path(MINDLESS_MOLECULES_FILE).is_file(): diff --git a/src/mindlessgen/prog/config.py b/src/mindlessgen/prog/config.py index 3feb513..f43256e 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -737,10 +737,11 @@ def __init__(self, config_file: str | Path | None = None): if config_file: self.load_from_toml(config_file) - def check_config(self): + def check_config(self, verbosity: int = 1) -> None: """ 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(): @@ -749,15 +750,7 @@ def check_config(self): + 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( @@ -766,31 +759,43 @@ def check_config(self): + "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 - ): + if verbosity > 0: + if num_cores > 1: + # raise warning that parallelization will disable verbosity 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." + "Parallelization will disable verbosity during iterative search. " + + "Set '--verbosity 0' or '-P 1' to avoid this warning, or simply ignore it." ) - # 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 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 if postprocessing is turned off - if not self.general.postprocess: - warnings.warn( - "Postprocessing is turned off. The structure will not be relaxed." - ) + # 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( + "xTB does not treat super heavy elements. Approximation: atomic numbers are reduced by 32. MindlesGen terminates normally." + ) + + # Check if postprocessing is turned off + if not self.general.postprocess and any( + elem in super_heavy_elements + for elem in self.generate.element_composition + ): + warnings.warn( + "Postprocessing is turned off. The structure will not be relaxed." + ) def get_all_identifiers(self): """ diff --git a/test/test_molecules/test_miscellaneous.py b/test/test_molecules/test_miscellaneous.py index 68b68e5..3c6e328 100644 --- a/test/test_molecules/test_miscellaneous.py +++ b/test/test_molecules/test_miscellaneous.py @@ -37,7 +37,18 @@ 7, ), # Gd (64), C, C -> Lanthanide case, UHF = 7, CHRG = 1 (np.array([57, 7, 0]), [0], 1), # Ce (58), O, H -> Lanthanide case, UHF = 1 - (np.array([69, 7, 0]), [0], 1), # Ce (58), O, H -> Lanthanide case, UHF = 1 + (np.array([69, 7, 0]), [0], 1), # Yb (70), O, H -> Lanthanide case, UHF = 1 + (np.array([5, 7, 0, 98]), [0], 4), # Es(99), O, C, H -> Actinides case, UHF = 4 + ( + np.array([59, 92, 0, 0]), + [0], + 7, + ), # Nd(60), Np(93), H, H -> Lanthanide and Actinide case, UHF = 7 + ( + np.array([59, 91, 92, 5, 7, 0]), + [0], + 10, + ), # Nd(60), U(92), Np(93), H, H -> Lanthanide and Actinides case, UHF = 10 ], ids=[ "B-N-H (standard, odd)", @@ -49,6 +60,9 @@ "Gd-C-N (lanthanide)", "Ce-O-H (lanthanide)", "Yb-O-H (lanthanide)", + "Es-O-C-H (actinides)", + "Nd-Np-H-H (lanthanide and actinide)", + "Nd-Eu-Np-H-H (lanthanide and actinides)", ], ) def test_set_random_charge(atom_types, expected_charges, expected_uhf): From 878269e598054f5fa53be370c297888100984293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= <106986430+jonathan-schoeps@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:26:57 +0200 Subject: [PATCH 07/10] Update src/mindlessgen/generator/main.py Co-authored-by: Marcel Mueller --- src/mindlessgen/generator/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mindlessgen/generator/main.py b/src/mindlessgen/generator/main.py index 0997bde..e0c0df8 100644 --- a/src/mindlessgen/generator/main.py +++ b/src/mindlessgen/generator/main.py @@ -190,7 +190,6 @@ def single_molecule_generator( config_refine=config.refine, verbosity=config.general.verbosity, ) - except RuntimeError as e: if config.general.verbosity > 0: print(f"Refinement failed for cycle {cycle + 1}.") From cd149cb9d93c8ccf327d2d3272929f34b797b93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= <106986430+jonathan-schoeps@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:27:10 +0200 Subject: [PATCH 08/10] Update src/mindlessgen/prog/config.py Co-authored-by: Marcel Mueller --- src/mindlessgen/prog/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mindlessgen/prog/config.py b/src/mindlessgen/prog/config.py index f43256e..d4befbe 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -785,7 +785,7 @@ def check_config(self, verbosity: int = 1) -> None: for elem in self.generate.element_composition ): warnings.warn( - "xTB does not treat super heavy elements. Approximation: atomic numbers are reduced by 32. MindlesGen terminates normally." + "xTB does not treat super heavy elements. Atomic numbers are temporarily reduced by 32 to their lighter homologues and then replaced with the correct atom number." ) # Check if postprocessing is turned off From 73671600a8429bda99b01693cda6bda5ffc8128e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Thu, 17 Oct 2024 11:00:15 +0200 Subject: [PATCH 09/10] Changed the warnings and when they are printed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- src/mindlessgen/prog/config.py | 51 ++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/mindlessgen/prog/config.py b/src/mindlessgen/prog/config.py index d4befbe..7f534e3 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -759,40 +759,43 @@ def check_config(self, verbosity: int = 1) -> None: + "Don't be confused!" ) - if verbosity > 0: - if num_cores > 1: - # 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 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." + ) - # 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 + # Check for f-block elements in forbidden elements + if self.generate.forbidden_elements: + if verbosity > 0: + f_block_elements = set(range(56, 71)) | set(range(88, 103)) + if not all( + elem in self.generate.forbidden_elements + for elem in f_block_elements + ) or any( + elem in f_block_elements + for elem in self.generate.element_composition ): 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 - ): + # 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 + ): + if verbosity > 0: warnings.warn( "xTB does not treat super heavy elements. Atomic numbers are temporarily reduced by 32 to their lighter homologues and then replaced with the correct atom number." ) - # Check if postprocessing is turned off - if not self.general.postprocess and any( - elem in super_heavy_elements - for elem in self.generate.element_composition - ): + # Check if postprocessing is turned off + if not self.general.postprocess and any( + elem in super_heavy_elements for elem in self.generate.element_composition + ): + if verbosity > 0: warnings.warn( "Postprocessing is turned off. The structure will not be relaxed." ) From a15b964738b8e5587ad6dc4e955cc6cf204336ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Sch=C3=B6ps?= Date: Thu, 17 Oct 2024 13:33:12 +0200 Subject: [PATCH 10/10] changed the way how the warning for the lanthanides is called MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Schöps --- src/mindlessgen/prog/config.py | 65 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/mindlessgen/prog/config.py b/src/mindlessgen/prog/config.py index 7f534e3..2fd3457 100644 --- a/src/mindlessgen/prog/config.py +++ b/src/mindlessgen/prog/config.py @@ -744,14 +744,14 @@ def check_config(self, verbosity: int = 1) -> None: # 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(): + if self.general.parallel > mp.cpu_count() and verbosity > -1: 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 num_cores > 1 and self.postprocess.debug: + if num_cores > 1 and self.postprocess.debug and verbosity > -1: # raise warning that debugging of postprocessing will disable parallelization warnings.warn( "Debug output might seem to be redundant due to the parallel processes " @@ -766,39 +766,38 @@ def check_config(self, verbosity: int = 1) -> None: + "Set '--verbosity 0' or '-P 1' to avoid this warning, or simply ignore it." ) - # Check for f-block elements in forbidden elements - if self.generate.forbidden_elements: - if verbosity > 0: - f_block_elements = set(range(56, 71)) | set(range(88, 103)) - if not all( - elem in self.generate.forbidden_elements - for elem in f_block_elements - ) or any( - elem in f_block_elements - for elem in self.generate.element_composition - ): + if self.refine.engine == "xtb": + # Check for f-block elements in forbidden elements + if self.generate.forbidden_elements: + if verbosity > 0: + f_block_elements = set(range(56, 71)) | set(range(88, 103)) + lanthanides = set(range(56, 71)) + if not all( + elem in self.generate.forbidden_elements for elem in lanthanides + ) or any( + elem in f_block_elements + for elem in self.generate.element_composition + ): + 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 + ): + if verbosity > 0: 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." + "xTB does not treat super heavy elements. Atomic numbers are temporarily reduced by 32 to their lighter homologues and then replaced with the correct atom number." ) - - # 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 - ): - if verbosity > 0: - warnings.warn( - "xTB does not treat super heavy elements. Atomic numbers are temporarily reduced by 32 to their lighter homologues and then replaced with the correct atom number." - ) - - # Check if postprocessing is turned off - if not self.general.postprocess and any( - elem in super_heavy_elements for elem in self.generate.element_composition - ): - if verbosity > 0: - warnings.warn( - "Postprocessing is turned off. The structure will not be relaxed." - ) + # Check if postprocessing is turned off + if not self.general.postprocess: + if verbosity > 0: + warnings.warn( + "Postprocessing is turned off. The structure will not be relaxed." + ) def get_all_identifiers(self): """