GraphAtoms 2.0.0__tar.gz → 2.1.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.
- {graphatoms-2.0.0 → graphatoms-2.1.0}/PKG-INFO +36 -13
- {graphatoms-2.0.0 → graphatoms-2.1.0}/README.md +35 -8
- {graphatoms-2.0.0 → graphatoms-2.1.0}/pyproject.toml +1 -5
- {graphatoms-2.0.0 → graphatoms-2.1.0}/pyproject.toml.orig +1 -5
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/network/_metadata.py +9 -2
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/network/_recorder.py +1 -1
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/runner/_base.py +94 -69
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/runner/_helper.py +12 -1
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/runner/otfkmc.py +1 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/reaction/__init__.py +1 -2
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/reaction/_event.py +8 -0
- graphatoms-2.0.0/src/graphatoms/reaction/desorption.py → graphatoms-2.1.0/src/graphatoms/reaction/xxsorption.py +100 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/sysGas.py +1 -0
- graphatoms-2.0.0/src/graphatoms/reaction/adsorption.py +0 -99
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/LICENSE +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/arrayapi/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/arrayapi/compat.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/arrayapi/typing.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/dataclasses/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_numpydantic.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_pydantic2pyarrow.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_pydanticMixin.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_pydanticModel.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/dataclasses/graph.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/atoms/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/atoms/aseread.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/atoms/octahedron.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/bonds/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/bonds/raw.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/calculator/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/calculator/emt.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/calculator/nequip.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/example.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/run.yaml +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/network/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/network/_scheduler.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/parallel/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/parallel/_base.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/parallel/_dask.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/parallel/_executorlib.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/parallel/_ray.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/runner/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/runner/_errors.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/runner/rxngen.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/view.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/_bond_list.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/_distance_pairs.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/_inner_outer.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/_neighbor_list.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/mic.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/rotation.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/geometry/sample.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/reaction/reaction.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/atoms.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/bonds.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/database/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/database/abc.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/database/dict.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/database/dir.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/database/hdf5.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/database/sqliteASE.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/graph.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/sysCluster.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/system/system.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/__init__.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/adsorption.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/asetools.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/bytestool.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/logger.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/parser.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/rdutils.py +0 -0
- {graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/utils/subgraph.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphatoms
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: The Chemical Core Class for Graph Theory Analysis.
|
|
5
5
|
Keywords: chemistry,graph theory,reaction,event,KMC
|
|
6
6
|
Author: LiuGaoyong
|
|
@@ -29,12 +29,8 @@ Requires-Dist: python-snappy>=0.7.3
|
|
|
29
29
|
Requires-Dist: tomli ; python_full_version < '3.11'
|
|
30
30
|
Requires-Dist: tomli-w
|
|
31
31
|
Requires-Dist: typing-extensions
|
|
32
|
-
Requires-Dist: plotext
|
|
33
|
-
Requires-Dist: plotext-plus
|
|
34
|
-
Requires-Dist: matplotlib
|
|
35
32
|
Requires-Dist: executorlib
|
|
36
33
|
Requires-Dist: hydra-core
|
|
37
|
-
Requires-Dist: pipefunc
|
|
38
34
|
Requires-Dist: typer
|
|
39
35
|
Requires-Dist: loguru
|
|
40
36
|
Requires-Python: >=3.12
|
|
@@ -62,6 +58,14 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
|
|
|
62
58
|
- **Dataclasses**: Pydantic-based data models for type-safe data handling
|
|
63
59
|
- **Array API Compatibility**: Full support for array API standard for cross-framework compatibility (NumPy, PyTorch, JAX, CuPy, etc.)
|
|
64
60
|
- **Subgraph Operations**: Backend-agnostic subgraph extraction with relabeling support using array-api-compat and array-api-extra
|
|
61
|
+
- **CLI Entry Points**: Three console scripts for configuration, execution, and inspection:
|
|
62
|
+
- `graphatoms-config`: Resolve and print the Hydra/OmegaConf run configuration
|
|
63
|
+
- `graphatoms-run`: Launch a run
|
|
64
|
+
- `run_type=otfkmc` for on-the-fly kinetic Monte Carlo simulation
|
|
65
|
+
- `run_type=rxngen` for reaction network generation
|
|
66
|
+
- `graphatoms-network`: Inspect and visualize a stored reaction network
|
|
67
|
+
- **Hydra-driven Configuration**: Composable, override-friendly config via Hydra/OmegaConf with grouped groups (`atoms`, `bonds`, `calculator`)
|
|
68
|
+
- **Pluggable Parallel Backends**: Switch executors at the config level — `serial`, `multiprocessing`, `ray`, `dask`, `executorlib` — for distributed/on-the-fly KMC workflows
|
|
65
69
|
|
|
66
70
|
## Module Structure
|
|
67
71
|
|
|
@@ -69,18 +73,33 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
|
|
|
69
73
|
src/graphatoms/
|
|
70
74
|
├── arrayapi/ # Array API compatibility layer
|
|
71
75
|
├── dataclasses/ # Pydantic-based data models
|
|
76
|
+
├── enterpoint/ # Entry points: CLI, config, runners, network, parallel
|
|
77
|
+
│ ├── config/ # Hydra/OmegaConf configuration (atoms, bonds, calculator)
|
|
78
|
+
│ ├── network/ # Reaction network: scheduler, recorder, metadata
|
|
79
|
+
│ ├── parallel/ # Pluggable executors (serial, multiprocessing, ray, dask, executorlib)
|
|
80
|
+
│ ├── runner/ # Runners (otfkmc, rxngen) and helpers
|
|
81
|
+
│ ├── steps/ # Step primitives for runners
|
|
82
|
+
│ └── view.py # CLI viewer for reactions
|
|
72
83
|
├── geometry/ # Geometric operations
|
|
73
84
|
├── reaction/ # Reaction classes and KMC events
|
|
74
|
-
│ ├──
|
|
75
|
-
│ ├──
|
|
76
|
-
│
|
|
77
|
-
│ ├── mdwarpper/ # MD wrapper
|
|
78
|
-
│ └── network/ # Reaction network
|
|
85
|
+
│ ├── _event.py # Event base and event info
|
|
86
|
+
│ ├── reaction.py # Reaction class
|
|
87
|
+
│ └── xxsorption.py # Adsorption/Desorption events
|
|
79
88
|
├── system/ # Core system classes
|
|
80
|
-
│ ├── atoms
|
|
81
|
-
│ ├──
|
|
82
|
-
│
|
|
89
|
+
│ ├── atoms.py # Atomic structure handling
|
|
90
|
+
│ ├── bonds.py # Bond list operations
|
|
91
|
+
│ ├── graph.py # Graph-based system representation
|
|
92
|
+
│ ├── system.py # System abstract base
|
|
93
|
+
│ ├── sysCluster.py # Cluster system
|
|
94
|
+
│ ├── sysGas.py # Gas molecule system
|
|
95
|
+
│ └── database/ # Database storage backends (HDF5, SQLite, folder)
|
|
83
96
|
└── utils/ # Utility functions
|
|
97
|
+
├── adsorption.py # Adsorption site helper
|
|
98
|
+
├── asetools.py # ASE-related tools
|
|
99
|
+
├── bytestool.py # Byte-level helpers
|
|
100
|
+
├── logger.py # Logging setup
|
|
101
|
+
├── parser.py # Hydra argument parsing
|
|
102
|
+
├── rdutils.py # RDKit utilities
|
|
84
103
|
└── subgraph.py # Array API compatible subgraph operations
|
|
85
104
|
```
|
|
86
105
|
|
|
@@ -103,6 +122,10 @@ src/graphatoms/
|
|
|
103
122
|
- pydantic >= 2.10
|
|
104
123
|
- python-snappy >= 0.7.3
|
|
105
124
|
- loguru
|
|
125
|
+
- pandas >= 2
|
|
126
|
+
- scipy >= 1.10
|
|
127
|
+
- typer
|
|
128
|
+
- executorlib
|
|
106
129
|
|
|
107
130
|
## Installation
|
|
108
131
|
|
|
@@ -17,6 +17,14 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
|
|
|
17
17
|
- **Dataclasses**: Pydantic-based data models for type-safe data handling
|
|
18
18
|
- **Array API Compatibility**: Full support for array API standard for cross-framework compatibility (NumPy, PyTorch, JAX, CuPy, etc.)
|
|
19
19
|
- **Subgraph Operations**: Backend-agnostic subgraph extraction with relabeling support using array-api-compat and array-api-extra
|
|
20
|
+
- **CLI Entry Points**: Three console scripts for configuration, execution, and inspection:
|
|
21
|
+
- `graphatoms-config`: Resolve and print the Hydra/OmegaConf run configuration
|
|
22
|
+
- `graphatoms-run`: Launch a run
|
|
23
|
+
- `run_type=otfkmc` for on-the-fly kinetic Monte Carlo simulation
|
|
24
|
+
- `run_type=rxngen` for reaction network generation
|
|
25
|
+
- `graphatoms-network`: Inspect and visualize a stored reaction network
|
|
26
|
+
- **Hydra-driven Configuration**: Composable, override-friendly config via Hydra/OmegaConf with grouped groups (`atoms`, `bonds`, `calculator`)
|
|
27
|
+
- **Pluggable Parallel Backends**: Switch executors at the config level — `serial`, `multiprocessing`, `ray`, `dask`, `executorlib` — for distributed/on-the-fly KMC workflows
|
|
20
28
|
|
|
21
29
|
## Module Structure
|
|
22
30
|
|
|
@@ -24,18 +32,33 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
|
|
|
24
32
|
src/graphatoms/
|
|
25
33
|
├── arrayapi/ # Array API compatibility layer
|
|
26
34
|
├── dataclasses/ # Pydantic-based data models
|
|
35
|
+
├── enterpoint/ # Entry points: CLI, config, runners, network, parallel
|
|
36
|
+
│ ├── config/ # Hydra/OmegaConf configuration (atoms, bonds, calculator)
|
|
37
|
+
│ ├── network/ # Reaction network: scheduler, recorder, metadata
|
|
38
|
+
│ ├── parallel/ # Pluggable executors (serial, multiprocessing, ray, dask, executorlib)
|
|
39
|
+
│ ├── runner/ # Runners (otfkmc, rxngen) and helpers
|
|
40
|
+
│ ├── steps/ # Step primitives for runners
|
|
41
|
+
│ └── view.py # CLI viewer for reactions
|
|
27
42
|
├── geometry/ # Geometric operations
|
|
28
43
|
├── reaction/ # Reaction classes and KMC events
|
|
29
|
-
│ ├──
|
|
30
|
-
│ ├──
|
|
31
|
-
│
|
|
32
|
-
│ ├── mdwarpper/ # MD wrapper
|
|
33
|
-
│ └── network/ # Reaction network
|
|
44
|
+
│ ├── _event.py # Event base and event info
|
|
45
|
+
│ ├── reaction.py # Reaction class
|
|
46
|
+
│ └── xxsorption.py # Adsorption/Desorption events
|
|
34
47
|
├── system/ # Core system classes
|
|
35
|
-
│ ├── atoms
|
|
36
|
-
│ ├──
|
|
37
|
-
│
|
|
48
|
+
│ ├── atoms.py # Atomic structure handling
|
|
49
|
+
│ ├── bonds.py # Bond list operations
|
|
50
|
+
│ ├── graph.py # Graph-based system representation
|
|
51
|
+
│ ├── system.py # System abstract base
|
|
52
|
+
│ ├── sysCluster.py # Cluster system
|
|
53
|
+
│ ├── sysGas.py # Gas molecule system
|
|
54
|
+
│ └── database/ # Database storage backends (HDF5, SQLite, folder)
|
|
38
55
|
└── utils/ # Utility functions
|
|
56
|
+
├── adsorption.py # Adsorption site helper
|
|
57
|
+
├── asetools.py # ASE-related tools
|
|
58
|
+
├── bytestool.py # Byte-level helpers
|
|
59
|
+
├── logger.py # Logging setup
|
|
60
|
+
├── parser.py # Hydra argument parsing
|
|
61
|
+
├── rdutils.py # RDKit utilities
|
|
39
62
|
└── subgraph.py # Array API compatible subgraph operations
|
|
40
63
|
```
|
|
41
64
|
|
|
@@ -58,6 +81,10 @@ src/graphatoms/
|
|
|
58
81
|
- pydantic >= 2.10
|
|
59
82
|
- python-snappy >= 0.7.3
|
|
60
83
|
- loguru
|
|
84
|
+
- pandas >= 2
|
|
85
|
+
- scipy >= 1.10
|
|
86
|
+
- typer
|
|
87
|
+
- executorlib
|
|
61
88
|
|
|
62
89
|
## Installation
|
|
63
90
|
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "graphatoms"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.1.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
description = "The Chemical Core Class for Graph Theory Analysis."
|
|
10
10
|
license-files = ["src/LICENSE"]
|
|
@@ -42,12 +42,8 @@ dependencies = [
|
|
|
42
42
|
"tomli; python_version < '3.11'",
|
|
43
43
|
"tomli-w",
|
|
44
44
|
"typing-extensions",
|
|
45
|
-
"plotext",
|
|
46
|
-
"plotext-plus",
|
|
47
|
-
"matplotlib",
|
|
48
45
|
"executorlib",
|
|
49
46
|
"hydra-core",
|
|
50
|
-
"pipefunc",
|
|
51
47
|
"typer",
|
|
52
48
|
"loguru",
|
|
53
49
|
]
|
|
@@ -12,7 +12,7 @@ graphatoms-network = "graphatoms.enterpoint.view:main"
|
|
|
12
12
|
graphatoms-run = "graphatoms.enterpoint.runner:run"
|
|
13
13
|
[project]
|
|
14
14
|
name = "graphatoms"
|
|
15
|
-
version = "2.
|
|
15
|
+
version = "2.1.0"
|
|
16
16
|
readme = "README.md"
|
|
17
17
|
description = "The Chemical Core Class for Graph Theory Analysis."
|
|
18
18
|
authors = [{ name = "LiuGaoyong", email = "liugaoyong_88@163.com" }]
|
|
@@ -60,12 +60,8 @@ dependencies = [
|
|
|
60
60
|
"typing-extensions",
|
|
61
61
|
|
|
62
62
|
# Other
|
|
63
|
-
"plotext",
|
|
64
|
-
"plotext-plus",
|
|
65
|
-
"matplotlib",
|
|
66
63
|
"executorlib",
|
|
67
64
|
"hydra-core",
|
|
68
|
-
"pipefunc",
|
|
69
65
|
"typer",
|
|
70
66
|
"loguru",
|
|
71
67
|
]
|
|
@@ -110,6 +110,7 @@ class _MetaDataTable(BaseModel):
|
|
|
110
110
|
*,
|
|
111
111
|
cluster_key: str | None = None,
|
|
112
112
|
system_key: str | None = None,
|
|
113
|
+
exclude_gas: bool = False,
|
|
113
114
|
**kwargs,
|
|
114
115
|
) -> int:
|
|
115
116
|
if cluster_key is not None:
|
|
@@ -117,7 +118,10 @@ class _MetaDataTable(BaseModel):
|
|
|
117
118
|
[
|
|
118
119
|
self.count[i]
|
|
119
120
|
for i, ck in enumerate(self.for_cluster)
|
|
120
|
-
if
|
|
121
|
+
if (
|
|
122
|
+
ck == cluster_key
|
|
123
|
+
and ((not exclude_gas) or self.key_g[i] is None)
|
|
124
|
+
)
|
|
121
125
|
]
|
|
122
126
|
+ [0]
|
|
123
127
|
)
|
|
@@ -126,7 +130,10 @@ class _MetaDataTable(BaseModel):
|
|
|
126
130
|
[
|
|
127
131
|
self.count[i]
|
|
128
132
|
for i, sk in enumerate(self.for_system)
|
|
129
|
-
if
|
|
133
|
+
if (
|
|
134
|
+
sk == system_key
|
|
135
|
+
and ((not exclude_gas) or self.key_g[i] is None)
|
|
136
|
+
)
|
|
130
137
|
]
|
|
131
138
|
+ [0]
|
|
132
139
|
)
|
|
@@ -106,7 +106,7 @@ class _OldNewRecorder(OurBaseModel):
|
|
|
106
106
|
class Recorder(OurBaseModel):
|
|
107
107
|
system: set[str] = set()
|
|
108
108
|
cluster: dict[str, _OldNewRecorder] = defaultdict(_OldNewRecorder)
|
|
109
|
-
adsorption:
|
|
109
|
+
adsorption: dict[str, _OldNewRecorder] = defaultdict(_OldNewRecorder)
|
|
110
110
|
bulk: set[str] = set()
|
|
111
111
|
|
|
112
112
|
@override
|
|
@@ -164,6 +164,7 @@ class RunnerABC:
|
|
|
164
164
|
),
|
|
165
165
|
raise_when_fail=True,
|
|
166
166
|
allow_hash_change=False,
|
|
167
|
+
allow_not_connected=False,
|
|
167
168
|
run_vibration=True,
|
|
168
169
|
deep_copy=True,
|
|
169
170
|
)
|
|
@@ -370,6 +371,7 @@ class ExplorationABC(RunnerABC):
|
|
|
370
371
|
graph_label=label,
|
|
371
372
|
graph=sysgraph,
|
|
372
373
|
allow_hash_change=False,
|
|
374
|
+
allow_not_connected=False,
|
|
373
375
|
raise_when_fail=False,
|
|
374
376
|
)
|
|
375
377
|
)
|
|
@@ -441,10 +443,13 @@ class ExplorationABC(RunnerABC):
|
|
|
441
443
|
system_key=system_key,
|
|
442
444
|
)
|
|
443
445
|
if len(lst_4adsorption) > 0:
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
446
|
+
for cluster in lst_4adsorption:
|
|
447
|
+
for gas in self.gas_lst:
|
|
448
|
+
self._second_step_adsorption(
|
|
449
|
+
gas=gas,
|
|
450
|
+
cluster=cluster,
|
|
451
|
+
system_key=system_key,
|
|
452
|
+
)
|
|
448
453
|
if len(lst_4surface) > 0:
|
|
449
454
|
for cluster in lst_4surface:
|
|
450
455
|
self._second_step_surface(
|
|
@@ -579,6 +584,7 @@ class ExplorationABC(RunnerABC):
|
|
|
579
584
|
confidence=confidence,
|
|
580
585
|
min_found=self.network.metadata.table.get_minconut_for(
|
|
581
586
|
cluster_key=cluster_key,
|
|
587
|
+
exclude_gas=True,
|
|
582
588
|
),
|
|
583
589
|
):
|
|
584
590
|
msg = f"Finish exploration for {cluster_key} with "
|
|
@@ -588,103 +594,122 @@ class ExplorationABC(RunnerABC):
|
|
|
588
594
|
for future in futures:
|
|
589
595
|
self.executor.cancel(future)
|
|
590
596
|
break
|
|
591
|
-
|
|
592
597
|
self.network.persistence()
|
|
593
598
|
|
|
594
599
|
def _second_step_adsorption(
|
|
595
600
|
self,
|
|
596
|
-
|
|
601
|
+
gas: Gas,
|
|
602
|
+
cluster: Cluster,
|
|
597
603
|
system_key: str = "",
|
|
598
604
|
) -> None:
|
|
599
605
|
"""The second step for the on-the-fly KMC simulation."""
|
|
600
|
-
|
|
606
|
+
cluster_key = cluster.get_key_for_metadata(True)
|
|
607
|
+
gas_key = gas.get_key_for_metadata(False)
|
|
608
|
+
|
|
609
|
+
# ---------------------------------------------
|
|
610
|
+
# check if the adsorption has been explored
|
|
611
|
+
# ---------------------------------------------
|
|
612
|
+
graph_label = f"{cluster_key}_{gas_key}"
|
|
613
|
+
if graph_label in self.network.recorder.adsorption:
|
|
614
|
+
msg = f"The adsorption for {cluster_key} with "
|
|
615
|
+
msg += f"{gas_key} has been explored."
|
|
616
|
+
self.logger.info(self._reformat_message(msg))
|
|
617
|
+
return
|
|
618
|
+
|
|
619
|
+
# ---------------------------------------------
|
|
620
|
+
# build helper for adsorption
|
|
621
|
+
# ---------------------------------------------
|
|
622
|
+
assert cluster.ncore > 0, "graph must have core"
|
|
623
|
+
adsorption_helper = Helper(
|
|
624
|
+
atoms=cluster.to_ase(
|
|
625
|
+
exclude_bond_attibutes=True,
|
|
626
|
+
exclude_energetics=True,
|
|
627
|
+
).copy(),
|
|
628
|
+
adsorbate=gas,
|
|
629
|
+
core=np.unique(cluster.idx_core),
|
|
630
|
+
nfibonacci=int(self.config.exploration.nfibonacci),
|
|
631
|
+
use_direct=True,
|
|
632
|
+
use_raw=True,
|
|
633
|
+
)
|
|
634
|
+
|
|
635
|
+
# ---------------------------------------------
|
|
636
|
+
# submit adsorption tasks to executor
|
|
637
|
+
# ---------------------------------------------
|
|
601
638
|
futures: list = []
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
self.
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
exclude_bond_attibutes=True,
|
|
623
|
-
exclude_energetics=True,
|
|
624
|
-
).copy(),
|
|
625
|
-
adsorbate=gas,
|
|
626
|
-
core=np.unique(cluster.idx_core),
|
|
627
|
-
nfibonacci=int(self.config.exploration.nfibonacci),
|
|
628
|
-
use_direct=True,
|
|
629
|
-
use_raw=True,
|
|
630
|
-
)
|
|
631
|
-
# ---------------------------------------------
|
|
632
|
-
# submit adsorption tasks to executor
|
|
633
|
-
# ---------------------------------------------
|
|
634
|
-
self.network.recorder.adsorption.add(label)
|
|
635
|
-
nrun: int = adsorption_helper.nrun
|
|
636
|
-
nrun: int = min(nrun, self.config.exploration.maxtry)
|
|
637
|
-
for irun in range(nrun):
|
|
638
|
-
futures.append(
|
|
639
|
-
self.executor.submit(
|
|
640
|
-
helper_adsorption,
|
|
641
|
-
config=self.config,
|
|
642
|
-
graph=cluster,
|
|
643
|
-
gas=gas,
|
|
644
|
-
irun=irun,
|
|
645
|
-
graph_label=None,
|
|
646
|
-
allow_hash_change=True,
|
|
647
|
-
raise_when_fail=False,
|
|
648
|
-
deep_copy=True,
|
|
649
|
-
)
|
|
650
|
-
)
|
|
651
|
-
self.logger.info(
|
|
652
|
-
self._reformat_message(
|
|
653
|
-
f"Submit {nrun} adsorption tasks for "
|
|
654
|
-
f"{cluster_key} with {gas_key}"
|
|
655
|
-
)
|
|
639
|
+
start: float = perf_counter()
|
|
640
|
+
nrun: int = adsorption_helper.nrun
|
|
641
|
+
maxtry: int = self.config.exploration.maxtry
|
|
642
|
+
if nrun <= maxtry:
|
|
643
|
+
lst = np.asarray(range(nrun))
|
|
644
|
+
else:
|
|
645
|
+
lst = np.random.randint(nrun, size=maxtry)
|
|
646
|
+
np.random.shuffle(lst)
|
|
647
|
+
for irun in lst:
|
|
648
|
+
futures.append(
|
|
649
|
+
self.executor.submit(
|
|
650
|
+
helper_adsorption,
|
|
651
|
+
config=self.config,
|
|
652
|
+
graph=cluster,
|
|
653
|
+
gas=gas,
|
|
654
|
+
irun=irun,
|
|
655
|
+
graph_label=graph_label,
|
|
656
|
+
allow_hash_change=True,
|
|
657
|
+
raise_when_fail=False,
|
|
658
|
+
deep_copy=True,
|
|
656
659
|
)
|
|
657
|
-
|
|
660
|
+
)
|
|
658
661
|
self.logger.info(
|
|
659
662
|
self._reformat_message(
|
|
660
|
-
f"Submit {
|
|
663
|
+
f"Submit {nrun} adsorption tasks by "
|
|
661
664
|
f"{perf_counter() - start:.2f} seconds"
|
|
665
|
+
f" for {cluster_key} with {gas_key}"
|
|
662
666
|
)
|
|
663
667
|
)
|
|
664
668
|
|
|
665
669
|
# -----------------------------------------------------------
|
|
666
670
|
# wait for the adsorption tasks to finish
|
|
667
671
|
# -----------------------------------------------------------
|
|
672
|
+
old_new = self.network.recorder.adsorption[graph_label]
|
|
673
|
+
confidence = self.config.exploration.maxconfidence
|
|
668
674
|
while len(futures) > 0:
|
|
669
675
|
future_result, futures = self.executor.wait(futures) # type: ignore
|
|
670
|
-
event,
|
|
671
|
-
|
|
676
|
+
event, _, cost_time, _ = future_result
|
|
677
|
+
event_label = self.network.found(
|
|
672
678
|
event,
|
|
673
679
|
for_cluster=None,
|
|
674
680
|
for_system=system_key,
|
|
675
681
|
persist=True,
|
|
676
682
|
)
|
|
677
|
-
if
|
|
678
|
-
msg = f"Adsorption search {
|
|
683
|
+
if event_label.startswith("fail"):
|
|
684
|
+
msg = f"Adsorption search {event_label} by {cost_time:.2f}"
|
|
679
685
|
msg += f" seconds because of {event}"
|
|
680
686
|
self.logger.info(self._reformat_message(msg))
|
|
687
|
+
old_new.found_fail()
|
|
681
688
|
else:
|
|
682
689
|
msg = "Adsorption search successfully, and got "
|
|
683
|
-
msg += f"{
|
|
684
|
-
if str(event) not in
|
|
690
|
+
msg += f"{event_label} by {cost_time:.2f} seconds."
|
|
691
|
+
if str(event) not in event_label:
|
|
685
692
|
msg += f" Simplify original {event} by threshold "
|
|
686
693
|
msg += f"{self.config.event.simplified_threshold:.2f}"
|
|
687
694
|
self.logger.info(self._reformat_message(msg))
|
|
695
|
+
if "new" in event_label:
|
|
696
|
+
old_new.found_new()
|
|
697
|
+
else:
|
|
698
|
+
old_new.found_old()
|
|
699
|
+
if old_new.exploration_can_be_finished(
|
|
700
|
+
confidence=confidence,
|
|
701
|
+
min_found=self.network.metadata.table.get_minconut_for(
|
|
702
|
+
cluster_key=cluster_key,
|
|
703
|
+
exclude_gas=False,
|
|
704
|
+
),
|
|
705
|
+
):
|
|
706
|
+
msg = f"Finish exploration for {cluster_key} and {gas_key}"
|
|
707
|
+
msg += f"with confidence {confidence:.2f}. {len(futures)}"
|
|
708
|
+
msg += " adsorption tasks left. They will be canceled."
|
|
709
|
+
self.logger.info(self._reformat_message(msg))
|
|
710
|
+
for future in futures:
|
|
711
|
+
self.executor.cancel(future)
|
|
712
|
+
break
|
|
688
713
|
self.network.persistence()
|
|
689
714
|
|
|
690
715
|
def _second_step_bulk(
|
|
@@ -87,6 +87,7 @@ def helper_optimization(
|
|
|
87
87
|
*,
|
|
88
88
|
graph_label: Any | None = None,
|
|
89
89
|
allow_hash_change: bool = True,
|
|
90
|
+
allow_not_connected: bool = False,
|
|
90
91
|
raise_when_fail: bool = False,
|
|
91
92
|
run_vibration: bool = True,
|
|
92
93
|
deep_copy: bool = True,
|
|
@@ -152,6 +153,15 @@ def helper_optimization(
|
|
|
152
153
|
parse_bonds=config.bonds, # type: ignore
|
|
153
154
|
deep=deep_copy,
|
|
154
155
|
)
|
|
156
|
+
if (not allow_not_connected) and (not result.is_connected):
|
|
157
|
+
e = HelperException(
|
|
158
|
+
msg="graph is not connected after optimization",
|
|
159
|
+
label=graph_label,
|
|
160
|
+
)
|
|
161
|
+
if raise_when_fail:
|
|
162
|
+
raise e
|
|
163
|
+
else:
|
|
164
|
+
return str(e), graph_label, perf_counter() - start
|
|
155
165
|
if not allow_hash_change and graph.hash != result.hash:
|
|
156
166
|
e = HelperException(
|
|
157
167
|
msg="hash changed after optimization",
|
|
@@ -362,6 +372,7 @@ def helper_dimer(
|
|
|
362
372
|
# ------------------------------------------------------------
|
|
363
373
|
cost_time = perf_counter() - start
|
|
364
374
|
if not product_result.is_connected:
|
|
375
|
+
# TODO: parse Desorption
|
|
365
376
|
e = HelperException(
|
|
366
377
|
msg="product is not connected",
|
|
367
378
|
label=graph_label,
|
|
@@ -442,7 +453,7 @@ def helper_adsorption(
|
|
|
442
453
|
"""
|
|
443
454
|
if graph_label is None:
|
|
444
455
|
graph_label = graph.get_key_for_metadata()
|
|
445
|
-
|
|
456
|
+
graph_label += f"_{gas.get_key_for_metadata(False)}"
|
|
446
457
|
|
|
447
458
|
# -----------------------------------------
|
|
448
459
|
# call adsorption initial positions
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# ruff: noqa: F401
|
|
2
2
|
|
|
3
|
-
from graphatoms.reaction.adsorption import Adsorption
|
|
4
|
-
from graphatoms.reaction.desorption import Desorption
|
|
5
3
|
from graphatoms.reaction._event import EventBase, EventInfo
|
|
6
4
|
from graphatoms.reaction.reaction import ReactionER, ReactionLH
|
|
5
|
+
from graphatoms.reaction.xxsorption import Adsorption, Desorption
|
|
7
6
|
|
|
8
7
|
__all__ = [
|
|
9
8
|
"EventBase",
|
|
@@ -224,6 +224,10 @@ class RTGP(OurFrozenModel):
|
|
|
224
224
|
# print(f"geom_moved: {geom_moved}")
|
|
225
225
|
|
|
226
226
|
moved: np.ndarray = np.asarray(list(graph_node_moved), dtype=int)
|
|
227
|
+
nmax = max(len(self.R), len(self.P))
|
|
228
|
+
nmin = min(len(self.R), len(self.P))
|
|
229
|
+
gas_moved = list(range(nmin, nmax))
|
|
230
|
+
moved = np.setdiff1d(moved, gas_moved)
|
|
227
231
|
pos = self.R.positions[moved, :].reshape(-1, len(moved), 3)
|
|
228
232
|
v = self.R.positions[:, np.newaxis, :] - pos
|
|
229
233
|
d = np.linalg.norm(v, axis=-1).min(-1)
|
|
@@ -234,6 +238,10 @@ class RTGP(OurFrozenModel):
|
|
|
234
238
|
if i is None or isinstance(i, Gas):
|
|
235
239
|
rtgp.append(i)
|
|
236
240
|
elif isinstance(i, SysGraph):
|
|
241
|
+
if len(i) == nmax:
|
|
242
|
+
sub = np.append(sub, gas_moved)
|
|
243
|
+
else:
|
|
244
|
+
sub = np.setdiff1d(sub, gas_moved)
|
|
237
245
|
rtgp.append(
|
|
238
246
|
Cluster.select(
|
|
239
247
|
i,
|
|
@@ -9,6 +9,101 @@ from graphatoms.reaction._event import EventBase, h, kB
|
|
|
9
9
|
from graphatoms.system.system import System
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
class Adsorption(EventBase):
|
|
13
|
+
@model_validator(mode="after")
|
|
14
|
+
def __check_something(self) -> Self:
|
|
15
|
+
assert self.G is not None, "The gas must be not None."
|
|
16
|
+
assert self.T is None, "The transition state must be None."
|
|
17
|
+
assert len(self.P) == len(self.R) + len(self.G), (
|
|
18
|
+
"The product state must be the sum of the " #
|
|
19
|
+
"reactant state and the gas molecule."
|
|
20
|
+
)
|
|
21
|
+
return self
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
@override
|
|
25
|
+
def reversed(self) -> "Desorption":
|
|
26
|
+
return Desorption(R=self.P, G=self.G, T=self.T, P=self.R)
|
|
27
|
+
|
|
28
|
+
@override
|
|
29
|
+
def apply(
|
|
30
|
+
self,
|
|
31
|
+
atoms: System | Atoms,
|
|
32
|
+
*args,
|
|
33
|
+
matched_indxs: list[int] | np.ndarray | None = None,
|
|
34
|
+
**kwargs,
|
|
35
|
+
) -> tuple[Atoms, float]:
|
|
36
|
+
atoms, rmsd = super().apply(atoms, *args, matched_indxs, **kwargs)
|
|
37
|
+
patoms: Atoms = self.P.to_ase(exclude_energetics=True)
|
|
38
|
+
mask = np.arange(len(self.P)) >= len(self.R)
|
|
39
|
+
atoms.extend(patoms[mask])
|
|
40
|
+
return atoms, rmsd
|
|
41
|
+
|
|
42
|
+
@override
|
|
43
|
+
def get_Ea(self, *args, **kwargs) -> float: # type: ignore
|
|
44
|
+
"""The adsorption reaction does not have an activation energy.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
np.inf
|
|
48
|
+
"""
|
|
49
|
+
return np.inf
|
|
50
|
+
|
|
51
|
+
@override
|
|
52
|
+
def get_dE(
|
|
53
|
+
self,
|
|
54
|
+
temperature: float = 300.0,
|
|
55
|
+
*args,
|
|
56
|
+
pressure: float | None = None,
|
|
57
|
+
**kwargs,
|
|
58
|
+
) -> float:
|
|
59
|
+
assert self.G is not None, "The gas must be not None."
|
|
60
|
+
e_P = self.P.get_free_energy(fqmin=30.0, temp=temperature)
|
|
61
|
+
e_R = self.R.get_free_energy(fqmin=30.0, temp=temperature)
|
|
62
|
+
if pressure is None:
|
|
63
|
+
pressure = self.G.pressure
|
|
64
|
+
assert pressure is not None, "The pressure must be not None."
|
|
65
|
+
e_G = self.G.get_free_energy(
|
|
66
|
+
fqmin=30.0,
|
|
67
|
+
temp=temperature,
|
|
68
|
+
pressure=pressure,
|
|
69
|
+
)
|
|
70
|
+
return e_P - e_R - e_G
|
|
71
|
+
|
|
72
|
+
@override
|
|
73
|
+
def get_rate(
|
|
74
|
+
self,
|
|
75
|
+
temperature: float = 300.0,
|
|
76
|
+
*args,
|
|
77
|
+
pressure: float | None = None,
|
|
78
|
+
sticking: float | None = None,
|
|
79
|
+
**kwargs,
|
|
80
|
+
) -> float:
|
|
81
|
+
"""Get the rate of the reaction by the collision theory.
|
|
82
|
+
|
|
83
|
+
Ref: Dominic R. Alfonso; Kinetic Monte Carlo Simul-
|
|
84
|
+
ation of CO Adsorption on Sulfur-Covered Pd(100).
|
|
85
|
+
J. Phys. Chem. A 2014, 118, 7306-7313.
|
|
86
|
+
Eq:
|
|
87
|
+
S*A
|
|
88
|
+
rate = -------------------
|
|
89
|
+
sqrt(2*pi*m*kB*T)
|
|
90
|
+
"""
|
|
91
|
+
assert self.G is not None, "The gas must be not None."
|
|
92
|
+
kBT = kB * temperature
|
|
93
|
+
m = np.sum(MASS[self.G.numbers])
|
|
94
|
+
A = abs(self.G.area + self.R.area - self.P.area) / 2.0
|
|
95
|
+
|
|
96
|
+
if sticking is None:
|
|
97
|
+
sticking = self.G.sticking
|
|
98
|
+
assert sticking is not None, (
|
|
99
|
+
"The sticking coefficient must be not None."
|
|
100
|
+
)
|
|
101
|
+
if pressure is None:
|
|
102
|
+
pressure = self.G.pressure
|
|
103
|
+
assert pressure is not None, "The pressure must be not None."
|
|
104
|
+
return (sticking * A * pressure) / np.sqrt(2 * np.pi * m * kBT)
|
|
105
|
+
|
|
106
|
+
|
|
12
107
|
class Desorption(EventBase):
|
|
13
108
|
@model_validator(mode="after")
|
|
14
109
|
def __check_something(self) -> Self:
|
|
@@ -20,6 +115,11 @@ class Desorption(EventBase):
|
|
|
20
115
|
)
|
|
21
116
|
return self
|
|
22
117
|
|
|
118
|
+
@property
|
|
119
|
+
@override
|
|
120
|
+
def reversed(self) -> "Adsorption":
|
|
121
|
+
return Adsorption(R=self.P, G=self.G, T=self.T, P=self.R)
|
|
122
|
+
|
|
23
123
|
@override
|
|
24
124
|
def apply(
|
|
25
125
|
self,
|
|
@@ -179,6 +179,7 @@ class Gas(System):
|
|
|
179
179
|
with warnings.catch_warnings():
|
|
180
180
|
warnings.simplefilter("ignore")
|
|
181
181
|
return IdealGasThermo(
|
|
182
|
+
atoms=Atoms(self.numbers, self.positions),
|
|
182
183
|
vib_energies=evib, # type: ignore
|
|
183
184
|
geometry=self.__geometry_type,
|
|
184
185
|
symmetrynumber=self.nsymmetry,
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
from typing import Self, override
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from ase import Atoms
|
|
5
|
-
from ase.data import atomic_masses as MASS
|
|
6
|
-
from pydantic import model_validator
|
|
7
|
-
|
|
8
|
-
from graphatoms.reaction._event import EventBase, kB
|
|
9
|
-
from graphatoms.system.system import System
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Adsorption(EventBase):
|
|
13
|
-
@model_validator(mode="after")
|
|
14
|
-
def __check_something(self) -> Self:
|
|
15
|
-
assert self.G is not None, "The gas must be not None."
|
|
16
|
-
assert self.T is None, "The transition state must be None."
|
|
17
|
-
assert len(self.P) == len(self.R) + len(self.G), (
|
|
18
|
-
"The product state must be the sum of the " #
|
|
19
|
-
"reactant state and the gas molecule."
|
|
20
|
-
)
|
|
21
|
-
return self
|
|
22
|
-
|
|
23
|
-
@override
|
|
24
|
-
def apply(
|
|
25
|
-
self,
|
|
26
|
-
atoms: System | Atoms,
|
|
27
|
-
*args,
|
|
28
|
-
matched_indxs: list[int] | np.ndarray | None = None,
|
|
29
|
-
**kwargs,
|
|
30
|
-
) -> tuple[Atoms, float]:
|
|
31
|
-
atoms, rmsd = super().apply(atoms, *args, matched_indxs, **kwargs)
|
|
32
|
-
patoms: Atoms = self.P.to_ase(exclude_energetics=True)
|
|
33
|
-
mask = np.arange(len(self.P)) >= len(self.R)
|
|
34
|
-
atoms.extend(patoms[mask])
|
|
35
|
-
return atoms, rmsd
|
|
36
|
-
|
|
37
|
-
@override
|
|
38
|
-
def get_Ea(self, *args, **kwargs) -> float: # type: ignore
|
|
39
|
-
"""The adsorption reaction does not have an activation energy.
|
|
40
|
-
|
|
41
|
-
Returns:
|
|
42
|
-
np.inf
|
|
43
|
-
"""
|
|
44
|
-
return np.inf
|
|
45
|
-
|
|
46
|
-
@override
|
|
47
|
-
def get_dE(
|
|
48
|
-
self,
|
|
49
|
-
temperature: float = 300.0,
|
|
50
|
-
*args,
|
|
51
|
-
pressure: float | None = None,
|
|
52
|
-
**kwargs,
|
|
53
|
-
) -> float:
|
|
54
|
-
assert self.G is not None, "The gas must be not None."
|
|
55
|
-
e_P = self.P.get_free_energy(fqmin=30.0, temp=temperature)
|
|
56
|
-
e_R = self.R.get_free_energy(fqmin=30.0, temp=temperature)
|
|
57
|
-
if pressure is None:
|
|
58
|
-
pressure = self.G.pressure
|
|
59
|
-
assert pressure is not None, "The pressure must be not None."
|
|
60
|
-
e_G = self.G.get_free_energy(
|
|
61
|
-
fqmin=30.0,
|
|
62
|
-
temp=temperature,
|
|
63
|
-
pressure=pressure,
|
|
64
|
-
)
|
|
65
|
-
return e_P - e_R - e_G
|
|
66
|
-
|
|
67
|
-
@override
|
|
68
|
-
def get_rate(
|
|
69
|
-
self,
|
|
70
|
-
temperature: float = 300.0,
|
|
71
|
-
*args,
|
|
72
|
-
pressure: float | None = None,
|
|
73
|
-
sticking: float | None = None,
|
|
74
|
-
**kwargs,
|
|
75
|
-
) -> float:
|
|
76
|
-
"""Get the rate of the reaction by the collision theory.
|
|
77
|
-
|
|
78
|
-
Ref: Dominic R. Alfonso; Kinetic Monte Carlo Simul-
|
|
79
|
-
ation of CO Adsorption on Sulfur-Covered Pd(100).
|
|
80
|
-
J. Phys. Chem. A 2014, 118, 7306-7313.
|
|
81
|
-
Eq:
|
|
82
|
-
S*A
|
|
83
|
-
rate = -------------------
|
|
84
|
-
sqrt(2*pi*m*kB*T)
|
|
85
|
-
"""
|
|
86
|
-
assert self.G is not None, "The gas must be not None."
|
|
87
|
-
kBT = kB * temperature
|
|
88
|
-
m = np.sum(MASS[self.G.numbers])
|
|
89
|
-
A = abs(self.G.area + self.R.area - self.P.area) / 2.0
|
|
90
|
-
|
|
91
|
-
if sticking is None:
|
|
92
|
-
sticking = self.G.sticking
|
|
93
|
-
assert sticking is not None, (
|
|
94
|
-
"The sticking coefficient must be not None."
|
|
95
|
-
)
|
|
96
|
-
if pressure is None:
|
|
97
|
-
pressure = self.G.pressure
|
|
98
|
-
assert pressure is not None, "The pressure must be not None."
|
|
99
|
-
return (sticking * A * pressure) / np.sqrt(2 * np.pi * m * kBT)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/atoms/octahedron.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/calculator/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphatoms-2.0.0 → graphatoms-2.1.0}/src/graphatoms/enterpoint/config/calculator/nequip.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|