gpuma 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. gpuma-0.5.0/LICENSE.md +21 -0
  2. gpuma-0.5.0/MANIFEST.in +11 -0
  3. gpuma-0.5.0/PKG-INFO +146 -0
  4. gpuma-0.5.0/README.md +109 -0
  5. gpuma-0.5.0/examples/config.json +25 -0
  6. gpuma-0.5.0/examples/example_ensemble_optimization.py +99 -0
  7. gpuma-0.5.0/examples/example_input_xyzs/butene_singlet.xyz +14 -0
  8. gpuma-0.5.0/examples/example_input_xyzs/butene_triplet.xyz +14 -0
  9. gpuma-0.5.0/examples/example_input_xyzs/butene_triplet_multi.xyz +56 -0
  10. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (1).xyz +20 -0
  11. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (10).xyz +20 -0
  12. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (11).xyz +20 -0
  13. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (12).xyz +20 -0
  14. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (13).xyz +20 -0
  15. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (14).xyz +20 -0
  16. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (15).xyz +20 -0
  17. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (16).xyz +20 -0
  18. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (17).xyz +20 -0
  19. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (18).xyz +20 -0
  20. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (19).xyz +20 -0
  21. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (2).xyz +20 -0
  22. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (20).xyz +20 -0
  23. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (21).xyz +20 -0
  24. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (22).xyz +20 -0
  25. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (23).xyz +20 -0
  26. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (24).xyz +20 -0
  27. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (25).xyz +20 -0
  28. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (26).xyz +20 -0
  29. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (27).xyz +20 -0
  30. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (28).xyz +20 -0
  31. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (3).xyz +20 -0
  32. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (4).xyz +20 -0
  33. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (5).xyz +20 -0
  34. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (6).xyz +20 -0
  35. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (7).xyz +20 -0
  36. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (8).xyz +20 -0
  37. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_dir/input (9).xyz +20 -0
  38. gpuma-0.5.0/examples/example_input_xyzs/multi_xyz_file.xyz +80 -0
  39. gpuma-0.5.0/examples/example_input_xyzs/single_xyz_file.xyz +20 -0
  40. gpuma-0.5.0/examples/example_single_optimization.py +91 -0
  41. gpuma-0.5.0/pyproject.toml +72 -0
  42. gpuma-0.5.0/setup.cfg +4 -0
  43. gpuma-0.5.0/src/gpuma/__init__.py +65 -0
  44. gpuma-0.5.0/src/gpuma/api.py +280 -0
  45. gpuma-0.5.0/src/gpuma/cli.py +629 -0
  46. gpuma-0.5.0/src/gpuma/config.py +341 -0
  47. gpuma-0.5.0/src/gpuma/decorators.py +33 -0
  48. gpuma-0.5.0/src/gpuma/io_handler.py +390 -0
  49. gpuma-0.5.0/src/gpuma/logging_utils.py +30 -0
  50. gpuma-0.5.0/src/gpuma/models.py +164 -0
  51. gpuma-0.5.0/src/gpuma/mol_utils.py +165 -0
  52. gpuma-0.5.0/src/gpuma/optimizer.py +338 -0
  53. gpuma-0.5.0/src/gpuma/structure.py +55 -0
  54. gpuma-0.5.0/src/gpuma.egg-info/PKG-INFO +146 -0
  55. gpuma-0.5.0/src/gpuma.egg-info/SOURCES.txt +64 -0
  56. gpuma-0.5.0/src/gpuma.egg-info/dependency_links.txt +1 -0
  57. gpuma-0.5.0/src/gpuma.egg-info/entry_points.txt +2 -0
  58. gpuma-0.5.0/src/gpuma.egg-info/requires.txt +21 -0
  59. gpuma-0.5.0/src/gpuma.egg-info/top_level.txt +1 -0
  60. gpuma-0.5.0/tests/test_api.py +92 -0
  61. gpuma-0.5.0/tests/test_cli.py +121 -0
  62. gpuma-0.5.0/tests/test_config.py +114 -0
  63. gpuma-0.5.0/tests/test_io.py +99 -0
  64. gpuma-0.5.0/tests/test_models.py +77 -0
  65. gpuma-0.5.0/tests/test_optimizer.py +97 -0
  66. gpuma-0.5.0/tests/test_structure.py +36 -0
gpuma-0.5.0/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Niklas Hölter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,11 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+
5
+ recursive-include examples *.py *.json *.xyz
6
+
7
+ # Exclude build and cache artifacts
8
+ prune build
9
+ prune dist
10
+ prune .pytest_cache
11
+ prune **/__pycache__
gpuma-0.5.0/PKG-INFO ADDED
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: gpuma
3
+ Version: 0.5.0
4
+ Summary: GPUMA - Geometry optimization toolkit using Fairchem UMA models and Torch-Sim
5
+ Author-email: Niklas Hölter <niklas.hoelter@uni-muenster.de>
6
+ License-Expression: MIT
7
+ Keywords: chemistry,geometry-optimization,uma,fairchem,ase,mlip,gpuma
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
13
+ Classifier: Topic :: Scientific/Engineering :: Physics
14
+ Requires-Python: >=3.12
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE.md
17
+ Requires-Dist: ase==3.27.0
18
+ Requires-Dist: torch-sim-atomistic==0.5.1
19
+ Requires-Dist: fairchem-core<2.10,>=2.7
20
+ Requires-Dist: morfeus-ml>=0.7
21
+ Requires-Dist: rdkit>=2022.9.5
22
+ Requires-Dist: tables>=3.10.2
23
+ Requires-Dist: scipy<1.15.0
24
+ Requires-Dist: hf_xet
25
+ Provides-Extra: yaml
26
+ Requires-Dist: pyyaml>=6.0; extra == "yaml"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=9.0.0; extra == "dev"
29
+ Requires-Dist: build>=1.2.1; extra == "dev"
30
+ Requires-Dist: twine>=5.0.0; extra == "dev"
31
+ Requires-Dist: pip-tools>=7.5.2; extra == "dev"
32
+ Requires-Dist: ruff>=0.14.14; extra == "dev"
33
+ Requires-Dist: mkdocs>=1.6.1; extra == "dev"
34
+ Requires-Dist: mkdocs-material>=9.7.1; extra == "dev"
35
+ Requires-Dist: mkdocstrings[python]>=1.0.2; extra == "dev"
36
+ Dynamic: license-file
37
+
38
+ # GPUMA
39
+
40
+ <div align="center">
41
+ <img src="docs/logo_bg.png" alt="GPUMA Logo"/>
42
+ </div>
43
+
44
+ ---
45
+
46
+ GPUMA is a minimalist Python toolkit for facile and rapid high-throughput molecular geometry optimization
47
+ based on the [UMA/OMol25 machine-learning interatomic potential](https://arxiv.org/abs/2505.08762).
48
+
49
+ GPUMA is especially designed for batch optimizations of many structures (conformer ensembles, datasets) on GPU,
50
+ ensuring efficient parallelization and maximum GPU utilization by leveraging the [torch-sim library](https://arxiv.org/abs/2508.06628).
51
+ It wraps Fairchem UMA models and torch-sim functionality to provide both a simple command-line
52
+ interface (CLI) and a small but expressive Python API for single- and multi-structure optimizations.
53
+
54
+ If conformer sampling is desired, GPUMA can generate conformer ensembles on the fly from SMILES strings
55
+ using the [morfeus library](https://digital-chemistry-laboratory.github.io/morfeus/). Alternative input formats
56
+ are described in the CLI section below.
57
+
58
+ Feedback and improvements are always welcome!
59
+
60
+ ## Installation
61
+
62
+ ### Option 1: Install from PyPI (recommended)
63
+
64
+ ```bash
65
+ pip install gpuma
66
+ ```
67
+
68
+ This installs `gpuma` together with its core dependencies. Make sure you are using
69
+ Python 3.12 or newer.
70
+
71
+ > ⚠️ **Required for UMA models:**</br>
72
+ > To access the UMA models on Hugging Face, **you must provide a token** either via the `HUGGINGFACE_TOKEN` environment variable or via the config (direct token string or path to a file containing the token).
73
+
74
+ ### Option 2: Install from source
75
+
76
+ ```bash
77
+ # clone the repository
78
+ git clone https://github.com/niklashoelter/gpuma.git
79
+ cd gpuma
80
+
81
+ # install using (uv) pip
82
+ uv pip install .
83
+ # or, without uv:
84
+ pip install .
85
+ ```
86
+
87
+ ## Documentation
88
+
89
+ Full documentation is available at [https://niklashoelter.github.io/gpuma/](https://niklashoelter.github.io/gpuma/).
90
+
91
+ For local browsing of the Markdown sources, see in particular:
92
+ - [docs/index.md](docs/index.md) – overview and getting started
93
+ - [docs/install.md](docs/install.md) – installation details
94
+ - [docs/cli.md](docs/cli.md) – CLI options and input formats
95
+ - [docs/config.md](docs/config.md) – configuration file schema and examples
96
+ - [docs/reference.md](docs/reference.md) – API and configuration reference
97
+
98
+ Using a configuration file is highly recommended for reproducibility and ease of use.
99
+
100
+ Also check the [examples/](examples) folder in the repository for sample config files and usage examples:
101
+ - [examples/config.json](examples/config.json) – minimal example configuration
102
+ - [examples/example_single_optimization.py](examples/example_single_optimization.py) – single-structure optimization from Python
103
+ - [examples/example_ensemble_optimization.py](examples/example_ensemble_optimization.py) – ensemble/multi-structure optimization from Python
104
+
105
+ ## CLI Usage
106
+
107
+ The CLI is provided via the command `gpuma`. For best results, create a
108
+ config file (JSON or YAML) and reference it in all CLI calls (see [examples/config.json](examples/config.json) for a minimal example).
109
+
110
+ ### Examples: Batch optimization of multiple XYZ structures
111
+
112
+ Optimize all XYZ files in a directory (each file containing a single structure):
113
+
114
+ ```bash
115
+ gpuma optimize --config examples/config.json --xyz-dir examples/example_input_xyzs/multi_xyz_dir/
116
+ ```
117
+
118
+ Optimize multiple structures contained in a single multi-XYZ file:
119
+
120
+ ```bash
121
+ gpuma optimize --config examples/config.json --xyz examples/example_input_xyzs/multi_xyz_file.xyz
122
+ ```
123
+
124
+ Refer to the [CLI documentation](docs/cli.md) for details on configuration options, supported input formats (SMILES, XYZ, directories, multi-XYZ files), and additional CLI examples.
125
+
126
+ ## Python API
127
+
128
+ A minimalistic and high-level Python API is provided for easy integration into custom scripts and workflows.
129
+
130
+ For example usage, see:
131
+ - [examples/example_single_optimization.py](examples/example_single_optimization.py)
132
+ - [examples/example_ensemble_optimization.py](examples/example_ensemble_optimization.py)
133
+
134
+ Please refer to the documentation and examples for detailed usage examples and API reference.
135
+
136
+ ## Known limitations
137
+
138
+ When a run is started from SMILES, an RDKit force field (via the morfeus library) is used to generate an initial structure. Spin is not taken into account during this step, so the initial estimated geometries can be incorrect. When the UMA/Omol25 models are applied subsequently, the structure can sometimes be optimized to a maximum rather than a minimum because the model is not provided with Hessian matrices. This behavior only affects runs originating from SMILES; it does not occur with better starting geometries (e.g., when starting from XYZ files).
139
+
140
+ ## Troubleshooting
141
+ - Missing libraries: install optional dependencies like `pyyaml` if you use YAML configs.
142
+ - Fairchem/UMA: ensure network access for model downloads and optionally set or provide
143
+ `huggingface_token` (e.g., via a token file) to access the UMA model family.
144
+
145
+ ## License
146
+ MIT License (see LICENSE)
gpuma-0.5.0/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # GPUMA
2
+
3
+ <div align="center">
4
+ <img src="docs/logo_bg.png" alt="GPUMA Logo"/>
5
+ </div>
6
+
7
+ ---
8
+
9
+ GPUMA is a minimalist Python toolkit for facile and rapid high-throughput molecular geometry optimization
10
+ based on the [UMA/OMol25 machine-learning interatomic potential](https://arxiv.org/abs/2505.08762).
11
+
12
+ GPUMA is especially designed for batch optimizations of many structures (conformer ensembles, datasets) on GPU,
13
+ ensuring efficient parallelization and maximum GPU utilization by leveraging the [torch-sim library](https://arxiv.org/abs/2508.06628).
14
+ It wraps Fairchem UMA models and torch-sim functionality to provide both a simple command-line
15
+ interface (CLI) and a small but expressive Python API for single- and multi-structure optimizations.
16
+
17
+ If conformer sampling is desired, GPUMA can generate conformer ensembles on the fly from SMILES strings
18
+ using the [morfeus library](https://digital-chemistry-laboratory.github.io/morfeus/). Alternative input formats
19
+ are described in the CLI section below.
20
+
21
+ Feedback and improvements are always welcome!
22
+
23
+ ## Installation
24
+
25
+ ### Option 1: Install from PyPI (recommended)
26
+
27
+ ```bash
28
+ pip install gpuma
29
+ ```
30
+
31
+ This installs `gpuma` together with its core dependencies. Make sure you are using
32
+ Python 3.12 or newer.
33
+
34
+ > ⚠️ **Required for UMA models:**</br>
35
+ > To access the UMA models on Hugging Face, **you must provide a token** either via the `HUGGINGFACE_TOKEN` environment variable or via the config (direct token string or path to a file containing the token).
36
+
37
+ ### Option 2: Install from source
38
+
39
+ ```bash
40
+ # clone the repository
41
+ git clone https://github.com/niklashoelter/gpuma.git
42
+ cd gpuma
43
+
44
+ # install using (uv) pip
45
+ uv pip install .
46
+ # or, without uv:
47
+ pip install .
48
+ ```
49
+
50
+ ## Documentation
51
+
52
+ Full documentation is available at [https://niklashoelter.github.io/gpuma/](https://niklashoelter.github.io/gpuma/).
53
+
54
+ For local browsing of the Markdown sources, see in particular:
55
+ - [docs/index.md](docs/index.md) – overview and getting started
56
+ - [docs/install.md](docs/install.md) – installation details
57
+ - [docs/cli.md](docs/cli.md) – CLI options and input formats
58
+ - [docs/config.md](docs/config.md) – configuration file schema and examples
59
+ - [docs/reference.md](docs/reference.md) – API and configuration reference
60
+
61
+ Using a configuration file is highly recommended for reproducibility and ease of use.
62
+
63
+ Also check the [examples/](examples) folder in the repository for sample config files and usage examples:
64
+ - [examples/config.json](examples/config.json) – minimal example configuration
65
+ - [examples/example_single_optimization.py](examples/example_single_optimization.py) – single-structure optimization from Python
66
+ - [examples/example_ensemble_optimization.py](examples/example_ensemble_optimization.py) – ensemble/multi-structure optimization from Python
67
+
68
+ ## CLI Usage
69
+
70
+ The CLI is provided via the command `gpuma`. For best results, create a
71
+ config file (JSON or YAML) and reference it in all CLI calls (see [examples/config.json](examples/config.json) for a minimal example).
72
+
73
+ ### Examples: Batch optimization of multiple XYZ structures
74
+
75
+ Optimize all XYZ files in a directory (each file containing a single structure):
76
+
77
+ ```bash
78
+ gpuma optimize --config examples/config.json --xyz-dir examples/example_input_xyzs/multi_xyz_dir/
79
+ ```
80
+
81
+ Optimize multiple structures contained in a single multi-XYZ file:
82
+
83
+ ```bash
84
+ gpuma optimize --config examples/config.json --xyz examples/example_input_xyzs/multi_xyz_file.xyz
85
+ ```
86
+
87
+ Refer to the [CLI documentation](docs/cli.md) for details on configuration options, supported input formats (SMILES, XYZ, directories, multi-XYZ files), and additional CLI examples.
88
+
89
+ ## Python API
90
+
91
+ A minimalistic and high-level Python API is provided for easy integration into custom scripts and workflows.
92
+
93
+ For example usage, see:
94
+ - [examples/example_single_optimization.py](examples/example_single_optimization.py)
95
+ - [examples/example_ensemble_optimization.py](examples/example_ensemble_optimization.py)
96
+
97
+ Please refer to the documentation and examples for detailed usage examples and API reference.
98
+
99
+ ## Known limitations
100
+
101
+ When a run is started from SMILES, an RDKit force field (via the morfeus library) is used to generate an initial structure. Spin is not taken into account during this step, so the initial estimated geometries can be incorrect. When the UMA/Omol25 models are applied subsequently, the structure can sometimes be optimized to a maximum rather than a minimum because the model is not provided with Hessian matrices. This behavior only affects runs originating from SMILES; it does not occur with better starting geometries (e.g., when starting from XYZ files).
102
+
103
+ ## Troubleshooting
104
+ - Missing libraries: install optional dependencies like `pyyaml` if you use YAML configs.
105
+ - Fairchem/UMA: ensure network access for model downloads and optionally set or provide
106
+ `huggingface_token` (e.g., via a token file) to access the UMA model family.
107
+
108
+ ## License
109
+ MIT License (see LICENSE)
@@ -0,0 +1,25 @@
1
+ {
2
+ "optimization": {
3
+
4
+ "batch_optimization_mode": "batch",
5
+ "batch_optimizer": "fire",
6
+ "max_num_conformers": 20,
7
+ "conformer_seed": 42,
8
+
9
+ "charge": 0,
10
+ "multiplicity": 1,
11
+
12
+ "force_convergence_criterion": 5e-2,
13
+ "energy_convergence_criterion": null,
14
+
15
+ "model_name": "uma-s-1p1",
16
+ "model_path": null,
17
+ "model_cache_dir": "/mnt/share/models/cache",
18
+ "device": "cuda",
19
+
20
+ "huggingface_token": null,
21
+ "huggingface_token_file": null,
22
+
23
+ "logging_level": "DEBUG"
24
+ }
25
+ }
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """Example: Ensemble and Batch Optimization with GPUMA.
3
+
4
+ This example demonstrates how to optimize SMILES-generated conformer ensembles
5
+ and how to batch-optimize general structures from multi-XYZ files or directories
6
+ using the GPUMA API.
7
+ """
8
+
9
+ import os
10
+ import sys
11
+
12
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
13
+
14
+ import gpuma
15
+ from gpuma.config import default_config, load_config_from_file
16
+
17
+ OUTPUT_DIR = os.path.join(os.path.dirname(__file__), "example_output")
18
+ os.makedirs(OUTPUT_DIR, exist_ok=True)
19
+
20
+
21
+ def example_ensemble_from_smiles():
22
+ """Example 1: Generate and optimize a conformer ensemble from SMILES."""
23
+ print("=== Example 1: Ensemble optimization from SMILES ===")
24
+
25
+ smiles = "CCC(CC)CCOOC(CC)CCOC" # Example SMILES
26
+ config = default_config
27
+ config.optimization.max_num_conformers = 50
28
+ config.optimization.force_convergence_criterion = 5e-1
29
+ print(f"Generating conformers for {smiles} and optimizing...")
30
+
31
+ output_file = os.path.join(OUTPUT_DIR, "python_ensemble_from_smiles_optimized.xyz")
32
+
33
+ results = gpuma.optimize_ensemble_smiles(
34
+ smiles=smiles,
35
+ output_file=output_file,
36
+ config=config
37
+ )
38
+
39
+ print("✓ Ensemble optimization successful!")
40
+ print(f" Generated conformers: {len(results)}")
41
+ for i, s in enumerate(results):
42
+ print(f" Conformer {i + 1}: {s.energy:.6f} eV")
43
+ print(f" Output saved to: {output_file}")
44
+
45
+
46
+ def example_batch_from_multi_xyz():
47
+ """Example 2: Batch optimize structures from a multi-structure XYZ file."""
48
+ print("\n=== Example 2: Batch optimization from multi-XYZ file ===")
49
+
50
+ input_file = "example_input_xyzs/butene_triplet_multi.xyz"
51
+ output_file = os.path.join(OUTPUT_DIR, "python_batch_from_multi_xyz_optimized.xyz")
52
+
53
+ config = load_config_from_file("config.json")
54
+ config.optimization.multiplicity = 3
55
+ results = gpuma.optimize_batch_multi_xyz_file(
56
+ input_file=input_file,
57
+ output_file=output_file,
58
+ config=config
59
+ )
60
+
61
+ print("✓ Batch optimization successful!")
62
+ print(f" Successfully optimized: {len(results)}")
63
+ for i, s in enumerate(results):
64
+ print(f" Structure {i + 1}: {s.energy:.6f} eV")
65
+ print(f" Output saved to: {output_file}")
66
+
67
+
68
+ def example_batch_from_xyz_directory():
69
+ """Example 3: Batch optimize structures from a directory of XYZ files."""
70
+ print("\n=== Example 3: Batch optimization from XYZ directory ===")
71
+
72
+ input_dir = "example_input_xyzs/multi_xyz_dir"
73
+ output_file = os.path.join(OUTPUT_DIR, "python_batch_from_directory_optimized.xyz")
74
+
75
+ results = gpuma.optimize_batch_xyz_directory(
76
+ input_directory=input_dir,
77
+ output_file=output_file
78
+ )
79
+
80
+ comments = [f"Optimized structure {i + 1} from directory" for i in range(len(results))]
81
+ gpuma.save_multi_xyz(results, output_file, comments)
82
+
83
+ print("✓ Batch optimization successful!")
84
+ print(f" Successfully optimized: {len(results)}")
85
+ for i, s in enumerate(results):
86
+ print(f" Structure {i + 1}: {s.energy:.6f} eV")
87
+ print(f" Output saved to: {output_file}")
88
+
89
+
90
+ if __name__ == "__main__":
91
+ print("GPUMA - Ensemble and Batch Optimization Examples")
92
+ print("=" * 70)
93
+
94
+ example_ensemble_from_smiles()
95
+ example_batch_from_multi_xyz()
96
+ example_batch_from_xyz_directory()
97
+
98
+ print("\n" + "=" * 70)
99
+ print("Examples completed! Check the generated XYZ files.")
@@ -0,0 +1,14 @@
1
+ 12
2
+ Optimized from SMILES: CC=CC | Energy: -4273.493688 eV | Charge: 0 | Multiplicity: 3
3
+ C -1.900595 0.450216 -0.639234
4
+ C -0.526495 0.530608 -0.103370
5
+ C 0.528262 -0.527150 -0.461806
6
+ C 1.900195 -0.451000 0.080194
7
+ H -2.657543 0.379571 0.153486
8
+ H -2.016685 -0.421879 -1.284155
9
+ H -2.169206 1.336974 -1.229126
10
+ H -0.235907 1.334041 0.559052
11
+ H 0.235625 -1.334592 -1.118427
12
+ H 2.168355 -1.336798 0.671650
13
+ H 2.016868 0.422236 0.723465
14
+ H 2.657128 -0.382228 -0.712767
@@ -0,0 +1,14 @@
1
+ 12
2
+ Optimized from SMILES: CC=CC | Energy: -4273.493688 eV | Charge: 0 | Multiplicity: 3
3
+ C -1.9005950000 0.4502160000 -0.6392340000
4
+ C -0.5264950000 0.5306080000 -0.1033700000
5
+ C 0.4954239479 -0.7881417480 -0.2154229594
6
+ C 1.9308878903 -0.4499872239 -0.2982345951
7
+ H -2.6575430000 0.3795710000 0.1534860000
8
+ H -2.0166850000 -0.4218790000 -1.2841550000
9
+ H -2.1692060000 1.3369740000 -1.2291260000
10
+ H -0.2359070000 1.3340410000 0.5590520000
11
+ H 0.0942915852 -1.2946010127 0.6513768880
12
+ H 2.2566221436 0.2044912910 0.5214745924
13
+ H 2.1576011119 0.0590031239 -1.2360411962
14
+ H 2.5716063212 -1.3402964303 -0.2408437298
@@ -0,0 +1,56 @@
1
+ 12
2
+ Optimized from SMILES: CC=CC | Energy: -4273.493688 eV | Charge: 0 | Multiplicity: 3
3
+ C -1.9005950000 0.4502160000 -0.6392340000
4
+ C -0.5264950000 0.5306080000 -0.1033700000
5
+ C 0.4954239479 -0.7881417480 -0.2154229594
6
+ C 1.9308878903 -0.4499872239 -0.2982345951
7
+ H -2.6575430000 0.3795710000 0.1534860000
8
+ H -2.0166850000 -0.4218790000 -1.2841550000
9
+ H -2.1692060000 1.3369740000 -1.2291260000
10
+ H -0.2359070000 1.3340410000 0.5590520000
11
+ H 0.0942915852 -1.2946010127 0.6513768880
12
+ H 2.2566221436 0.2044912910 0.5214745924
13
+ H 2.1576011119 0.0590031239 -1.2360411962
14
+ H 2.5716063212 -1.3402964303 -0.2408437298
15
+ 12
16
+ Optimized from SMILES: CC=CC | Energy: -4273.493688 eV | Charge: 0 | Multiplicity: 3
17
+ C -1.9005950000 0.4502160000 -0.6392340000
18
+ C -0.5264950000 0.5306080000 -0.1033700000
19
+ C 0.4954239479 -0.7881417480 -0.2154229594
20
+ C 1.9308878903 -0.4499872239 -0.2982345951
21
+ H -2.6575430000 0.3795710000 0.1534860000
22
+ H -2.0166850000 -0.4218790000 -1.2841550000
23
+ H -2.1692060000 1.3369740000 -1.2291260000
24
+ H -0.2359070000 1.3340410000 0.5590520000
25
+ H 0.0942915852 -1.2946010127 0.6513768880
26
+ H 2.2566221436 0.2044912910 0.5214745924
27
+ H 2.1576011119 0.0590031239 -1.2360411962
28
+ H 2.5716063212 -1.3402964303 -0.2408437298
29
+ 12
30
+ Optimized from SMILES: CC=CC | Energy: -4273.493688 eV | Charge: 0 | Multiplicity: 3
31
+ C -1.9005950000 0.4502160000 -0.6392340000
32
+ C -0.5264950000 0.5306080000 -0.1033700000
33
+ C 0.4954239479 -0.7881417480 -0.2154229594
34
+ C 1.9308878903 -0.4499872239 -0.2982345951
35
+ H -2.6575430000 0.3795710000 0.1534860000
36
+ H -2.0166850000 -0.4218790000 -1.2841550000
37
+ H -2.1692060000 1.3369740000 -1.2291260000
38
+ H -0.2359070000 1.3340410000 0.5590520000
39
+ H 0.0942915852 -1.2946010127 0.6513768880
40
+ H 2.2566221436 0.2044912910 0.5214745924
41
+ H 2.1576011119 0.0590031239 -1.2360411962
42
+ H 2.5716063212 -1.3402964303 -0.2408437298
43
+ 12
44
+ Optimized from SMILES: CC=CC | Energy: -4273.493688 eV | Charge: 0 | Multiplicity: 3
45
+ C -1.9005950000 0.4502160000 -0.6392340000
46
+ C -0.5264950000 0.5306080000 -0.1033700000
47
+ C 0.4954239479 -0.7881417480 -0.2154229594
48
+ C 1.9308878903 -0.4499872239 -0.2982345951
49
+ H -2.6575430000 0.3795710000 0.1534860000
50
+ H -2.0166850000 -0.4218790000 -1.2841550000
51
+ H -2.1692060000 1.3369740000 -1.2291260000
52
+ H -0.2359070000 1.3340410000 0.5590520000
53
+ H 0.0942915852 -1.2946010127 0.6513768880
54
+ H 2.2566221436 0.2044912910 0.5214745924
55
+ H 2.1576011119 0.0590031239 -1.2360411962
56
+ H 2.5716063212 -1.3402964303 -0.2408437298
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.551519736116
3
+ C -2.66062083976099 0.42178070263873 0.32320893307161
4
+ C -2.23790785032690 -0.55578771434406 -0.57736610844602
5
+ C -0.89063200209219 -0.90649968387654 -0.64549222422337
6
+ C 0.04788273649760 -0.28481048538367 0.18408020593902
7
+ C 1.49357028286238 -0.64248526930580 0.07660951215001
8
+ C 2.51842509141474 0.37149980061321 -0.30242372300699
9
+ N 2.39888606370255 -0.08899217739450 1.06586985302084
10
+ C -0.38198105382051 0.68986026096678 1.09029681299470
11
+ C -1.72898631302756 1.04137213098080 1.15676712471904
12
+ H -3.71509091084008 0.69647925279893 0.37859486963206
13
+ H -2.96136977963007 -1.04925615954480 -1.22850937344232
14
+ H -0.56166161680450 -1.67385694172772 -1.35051262268228
15
+ H 1.68272827957072 -1.66153503648733 -0.27798776877240
16
+ H 2.19384707878237 1.40118316770369 -0.47720027470562
17
+ H 3.36733429498554 0.04026932471951 -0.90748331382187
18
+ H 3.13295275865208 -0.75092606284559 1.30632320005423
19
+ H 0.35815188608546 1.15089287293532 1.74672078785138
20
+ H -2.05552910110378 1.80081203342835 1.86932411243042
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.549730217798
3
+ C -2.60252439229563 0.34816901517186 0.31130410379019
4
+ C -1.81619706753138 0.36723383006089 -0.84114176363625
5
+ C -0.43478749993316 0.21906194158022 -0.74950221699111
6
+ C 0.18764857468375 0.04868482301169 0.49432764325631
7
+ C 1.66623135860957 -0.11688012674397 0.61764186318717
8
+ C 2.40988884007991 -0.91234874642310 -0.39886011249545
9
+ N 2.56875388667993 0.52302365233375 -0.32437463832906
10
+ C -0.61034880946021 0.03520063670998 1.64275835222599
11
+ C -1.99391513445871 0.18140408768218 1.55381410761823
12
+ H -3.68461744559101 0.46515525510861 0.23967462232967
13
+ H -2.28212452724624 0.49817783645742 -1.81904425493374
14
+ H 0.16268086528061 0.23424811117128 -1.66550812031091
15
+ H 2.02913183524751 -0.12599094610884 1.64979348744112
16
+ H 1.81109302291314 -1.34774044945859 -1.20534339501041
17
+ H 3.28248345818731 -1.50017932433231 -0.10225722946821
18
+ H 2.04234073038285 1.00325231660204 -1.05321533919576
19
+ H -0.13688412948152 -0.08887918008010 2.61894454473068
20
+ H -2.59885456621162 0.16840726196522 2.46180833267868
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.549730217798
3
+ C -2.60252439229563 0.34816901517186 0.31130410379019
4
+ C -1.81619706753138 0.36723383006089 -0.84114176363625
5
+ C -0.43478749993316 0.21906194158022 -0.74950221699111
6
+ C 0.18764857468375 0.04868482301169 0.49432764325631
7
+ C 1.66623135860957 -0.11688012674397 0.61764186318717
8
+ C 2.40988884007991 -0.91234874642310 -0.39886011249545
9
+ N 2.56875388667993 0.52302365233375 -0.32437463832906
10
+ C -0.61034880946021 0.03520063670998 1.64275835222599
11
+ C -1.99391513445871 0.18140408768218 1.55381410761823
12
+ H -3.68461744559101 0.46515525510861 0.23967462232967
13
+ H -2.28212452724624 0.49817783645742 -1.81904425493374
14
+ H 0.16268086528061 0.23424811117128 -1.66550812031091
15
+ H 2.02913183524751 -0.12599094610884 1.64979348744112
16
+ H 1.81109302291314 -1.34774044945859 -1.20534339501041
17
+ H 3.28248345818731 -1.50017932433231 -0.10225722946821
18
+ H 2.04234073038285 1.00325231660204 -1.05321533919576
19
+ H -0.13688412948152 -0.08887918008010 2.61894454473068
20
+ H -2.59885456621162 0.16840726196522 2.46180833267868
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.549730217798
3
+ C -2.60252439229563 0.34816901517186 0.31130410379019
4
+ C -1.81619706753138 0.36723383006089 -0.84114176363625
5
+ C -0.43478749993316 0.21906194158022 -0.74950221699111
6
+ C 0.18764857468375 0.04868482301169 0.49432764325631
7
+ C 1.66623135860957 -0.11688012674397 0.61764186318717
8
+ C 2.40988884007991 -0.91234874642310 -0.39886011249545
9
+ N 2.56875388667993 0.52302365233375 -0.32437463832906
10
+ C -0.61034880946021 0.03520063670998 1.64275835222599
11
+ C -1.99391513445871 0.18140408768218 1.55381410761823
12
+ H -3.68461744559101 0.46515525510861 0.23967462232967
13
+ H -2.28212452724624 0.49817783645742 -1.81904425493374
14
+ H 0.16268086528061 0.23424811117128 -1.66550812031091
15
+ H 2.02913183524751 -0.12599094610884 1.64979348744112
16
+ H 1.81109302291314 -1.34774044945859 -1.20534339501041
17
+ H 3.28248345818731 -1.50017932433231 -0.10225722946821
18
+ H 2.04234073038285 1.00325231660204 -1.05321533919576
19
+ H -0.13688412948152 -0.08887918008010 2.61894454473068
20
+ H -2.59885456621162 0.16840726196522 2.46180833267868
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.549730217798
3
+ C -2.60252439229563 0.34816901517186 0.31130410379019
4
+ C -1.81619706753138 0.36723383006089 -0.84114176363625
5
+ C -0.43478749993316 0.21906194158022 -0.74950221699111
6
+ C 0.18764857468375 0.04868482301169 0.49432764325631
7
+ C 1.66623135860957 -0.11688012674397 0.61764186318717
8
+ C 2.40988884007991 -0.91234874642310 -0.39886011249545
9
+ N 2.56875388667993 0.52302365233375 -0.32437463832906
10
+ C -0.61034880946021 0.03520063670998 1.64275835222599
11
+ C -1.99391513445871 0.18140408768218 1.55381410761823
12
+ H -3.68461744559101 0.46515525510861 0.23967462232967
13
+ H -2.28212452724624 0.49817783645742 -1.81904425493374
14
+ H 0.16268086528061 0.23424811117128 -1.66550812031091
15
+ H 2.02913183524751 -0.12599094610884 1.64979348744112
16
+ H 1.81109302291314 -1.34774044945859 -1.20534339501041
17
+ H 3.28248345818731 -1.50017932433231 -0.10225722946821
18
+ H 2.04234073038285 1.00325231660204 -1.05321533919576
19
+ H -0.13688412948152 -0.08887918008010 2.61894454473068
20
+ H -2.59885456621162 0.16840726196522 2.46180833267868
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.549730217798
3
+ C -2.60252439229563 0.34816901517186 0.31130410379019
4
+ C -1.81619706753138 0.36723383006089 -0.84114176363625
5
+ C -0.43478749993316 0.21906194158022 -0.74950221699111
6
+ C 0.18764857468375 0.04868482301169 0.49432764325631
7
+ C 1.66623135860957 -0.11688012674397 0.61764186318717
8
+ C 2.40988884007991 -0.91234874642310 -0.39886011249545
9
+ N 2.56875388667993 0.52302365233375 -0.32437463832906
10
+ C -0.61034880946021 0.03520063670998 1.64275835222599
11
+ C -1.99391513445871 0.18140408768218 1.55381410761823
12
+ H -3.68461744559101 0.46515525510861 0.23967462232967
13
+ H -2.28212452724624 0.49817783645742 -1.81904425493374
14
+ H 0.16268086528061 0.23424811117128 -1.66550812031091
15
+ H 2.02913183524751 -0.12599094610884 1.64979348744112
16
+ H 1.81109302291314 -1.34774044945859 -1.20534339501041
17
+ H 3.28248345818731 -1.50017932433231 -0.10225722946821
18
+ H 2.04234073038285 1.00325231660204 -1.05321533919576
19
+ H -0.13688412948152 -0.08887918008010 2.61894454473068
20
+ H -2.59885456621162 0.16840726196522 2.46180833267868
@@ -0,0 +1,20 @@
1
+ 18
2
+ Coordinates from ORCA-job input E -364.547402520645
3
+ C -2.60115214273393 0.33276863076483 0.36743375216779
4
+ C -1.96251600704807 0.91187680185847 -0.73064256981145
5
+ C -0.57280047357360 0.89502755065857 -0.81749503375967
6
+ C 0.19971218921904 0.29699214936305 0.18741001804816
7
+ C 1.69167361333968 0.29361408716731 0.05690087184968
8
+ C 2.48988796034250 -0.87545070736772 0.48996666940890
9
+ N 2.32663079419270 -0.57872950994346 -0.92518842388708
10
+ C -0.44977584535880 -0.27629392403882 1.28477159064398
11
+ C -1.84234779489292 -0.25936374466470 1.37493492108870
12
+ H -3.68990601445353 0.34561744756658 0.43704749186311
13
+ H -2.55134669974352 1.37850159255334 -1.52199096186768
14
+ H -0.07079464037619 1.34804637753673 -1.67574310723363
15
+ H 2.15692788247398 1.28425776157197 0.11517259227131
16
+ H 1.94766145243800 -1.72708224764122 0.91089012053767
17
+ H 3.49694156085537 -0.73112727913793 0.88829839382341
18
+ H 1.62407716243719 -1.19775628668261 -1.32989054696702
19
+ H 0.14250686156748 -0.73175097674972 2.08072376448463
20
+ H -2.33538085353852 -0.70914772281467 2.23822046539342