reaxkit 1.0.0__py3-none-any.whl
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.
- reaxkit/__init__.py +0 -0
- reaxkit/analysis/__init__.py +0 -0
- reaxkit/analysis/composed/RDF_analyzer.py +560 -0
- reaxkit/analysis/composed/__init__.py +0 -0
- reaxkit/analysis/composed/connectivity_analyzer.py +706 -0
- reaxkit/analysis/composed/coordination_analyzer.py +144 -0
- reaxkit/analysis/composed/electrostatics_analyzer.py +687 -0
- reaxkit/analysis/per_file/__init__.py +0 -0
- reaxkit/analysis/per_file/control_analyzer.py +165 -0
- reaxkit/analysis/per_file/eregime_analyzer.py +108 -0
- reaxkit/analysis/per_file/ffield_analyzer.py +305 -0
- reaxkit/analysis/per_file/fort13_analyzer.py +79 -0
- reaxkit/analysis/per_file/fort57_analyzer.py +106 -0
- reaxkit/analysis/per_file/fort73_analyzer.py +61 -0
- reaxkit/analysis/per_file/fort74_analyzer.py +65 -0
- reaxkit/analysis/per_file/fort76_analyzer.py +191 -0
- reaxkit/analysis/per_file/fort78_analyzer.py +154 -0
- reaxkit/analysis/per_file/fort79_analyzer.py +83 -0
- reaxkit/analysis/per_file/fort7_analyzer.py +393 -0
- reaxkit/analysis/per_file/fort99_analyzer.py +411 -0
- reaxkit/analysis/per_file/molfra_analyzer.py +359 -0
- reaxkit/analysis/per_file/params_analyzer.py +258 -0
- reaxkit/analysis/per_file/summary_analyzer.py +84 -0
- reaxkit/analysis/per_file/trainset_analyzer.py +84 -0
- reaxkit/analysis/per_file/vels_analyzer.py +95 -0
- reaxkit/analysis/per_file/xmolout_analyzer.py +528 -0
- reaxkit/cli.py +181 -0
- reaxkit/count_loc.py +276 -0
- reaxkit/data/alias.yaml +89 -0
- reaxkit/data/constants.yaml +27 -0
- reaxkit/data/reaxff_input_files_contents.yaml +186 -0
- reaxkit/data/reaxff_output_files_contents.yaml +301 -0
- reaxkit/data/units.yaml +38 -0
- reaxkit/help/__init__.py +0 -0
- reaxkit/help/help_index_loader.py +531 -0
- reaxkit/help/introspection_utils.py +131 -0
- reaxkit/io/__init__.py +0 -0
- reaxkit/io/base_handler.py +165 -0
- reaxkit/io/generators/__init__.py +0 -0
- reaxkit/io/generators/control_generator.py +123 -0
- reaxkit/io/generators/eregime_generator.py +341 -0
- reaxkit/io/generators/geo_generator.py +967 -0
- reaxkit/io/generators/trainset_generator.py +1758 -0
- reaxkit/io/generators/tregime_generator.py +113 -0
- reaxkit/io/generators/vregime_generator.py +164 -0
- reaxkit/io/generators/xmolout_generator.py +304 -0
- reaxkit/io/handlers/__init__.py +0 -0
- reaxkit/io/handlers/control_handler.py +209 -0
- reaxkit/io/handlers/eregime_handler.py +122 -0
- reaxkit/io/handlers/ffield_handler.py +812 -0
- reaxkit/io/handlers/fort13_handler.py +123 -0
- reaxkit/io/handlers/fort57_handler.py +143 -0
- reaxkit/io/handlers/fort73_handler.py +145 -0
- reaxkit/io/handlers/fort74_handler.py +155 -0
- reaxkit/io/handlers/fort76_handler.py +195 -0
- reaxkit/io/handlers/fort78_handler.py +142 -0
- reaxkit/io/handlers/fort79_handler.py +227 -0
- reaxkit/io/handlers/fort7_handler.py +264 -0
- reaxkit/io/handlers/fort99_handler.py +128 -0
- reaxkit/io/handlers/geo_handler.py +224 -0
- reaxkit/io/handlers/molfra_handler.py +184 -0
- reaxkit/io/handlers/params_handler.py +137 -0
- reaxkit/io/handlers/summary_handler.py +135 -0
- reaxkit/io/handlers/trainset_handler.py +658 -0
- reaxkit/io/handlers/vels_handler.py +293 -0
- reaxkit/io/handlers/xmolout_handler.py +174 -0
- reaxkit/utils/__init__.py +0 -0
- reaxkit/utils/alias.py +219 -0
- reaxkit/utils/cache.py +77 -0
- reaxkit/utils/constants.py +75 -0
- reaxkit/utils/equation_of_states.py +96 -0
- reaxkit/utils/exceptions.py +27 -0
- reaxkit/utils/frame_utils.py +175 -0
- reaxkit/utils/log.py +43 -0
- reaxkit/utils/media/__init__.py +0 -0
- reaxkit/utils/media/convert.py +90 -0
- reaxkit/utils/media/make_video.py +91 -0
- reaxkit/utils/media/plotter.py +812 -0
- reaxkit/utils/numerical/__init__.py +0 -0
- reaxkit/utils/numerical/extrema_finder.py +96 -0
- reaxkit/utils/numerical/moving_average.py +103 -0
- reaxkit/utils/numerical/numerical_calcs.py +75 -0
- reaxkit/utils/numerical/signal_ops.py +135 -0
- reaxkit/utils/path.py +55 -0
- reaxkit/utils/units.py +104 -0
- reaxkit/webui/__init__.py +0 -0
- reaxkit/webui/app.py +0 -0
- reaxkit/webui/components.py +0 -0
- reaxkit/webui/layouts.py +0 -0
- reaxkit/webui/utils.py +0 -0
- reaxkit/workflows/__init__.py +0 -0
- reaxkit/workflows/composed/__init__.py +0 -0
- reaxkit/workflows/composed/coordination_workflow.py +393 -0
- reaxkit/workflows/composed/electrostatics_workflow.py +587 -0
- reaxkit/workflows/composed/xmolout_fort7_workflow.py +343 -0
- reaxkit/workflows/meta/__init__.py +0 -0
- reaxkit/workflows/meta/help_workflow.py +136 -0
- reaxkit/workflows/meta/introspection_workflow.py +235 -0
- reaxkit/workflows/meta/make_video_workflow.py +61 -0
- reaxkit/workflows/meta/plotter_workflow.py +601 -0
- reaxkit/workflows/per_file/__init__.py +0 -0
- reaxkit/workflows/per_file/control_workflow.py +110 -0
- reaxkit/workflows/per_file/eregime_workflow.py +267 -0
- reaxkit/workflows/per_file/ffield_workflow.py +390 -0
- reaxkit/workflows/per_file/fort13_workflow.py +86 -0
- reaxkit/workflows/per_file/fort57_workflow.py +137 -0
- reaxkit/workflows/per_file/fort73_workflow.py +151 -0
- reaxkit/workflows/per_file/fort74_workflow.py +88 -0
- reaxkit/workflows/per_file/fort76_workflow.py +188 -0
- reaxkit/workflows/per_file/fort78_workflow.py +135 -0
- reaxkit/workflows/per_file/fort79_workflow.py +314 -0
- reaxkit/workflows/per_file/fort7_workflow.py +592 -0
- reaxkit/workflows/per_file/fort83_workflow.py +60 -0
- reaxkit/workflows/per_file/fort99_workflow.py +223 -0
- reaxkit/workflows/per_file/geo_workflow.py +554 -0
- reaxkit/workflows/per_file/molfra_workflow.py +577 -0
- reaxkit/workflows/per_file/params_workflow.py +135 -0
- reaxkit/workflows/per_file/summary_workflow.py +161 -0
- reaxkit/workflows/per_file/trainset_workflow.py +356 -0
- reaxkit/workflows/per_file/tregime_workflow.py +79 -0
- reaxkit/workflows/per_file/vels_workflow.py +309 -0
- reaxkit/workflows/per_file/vregime_workflow.py +75 -0
- reaxkit/workflows/per_file/xmolout_workflow.py +678 -0
- reaxkit-1.0.0.dist-info/METADATA +128 -0
- reaxkit-1.0.0.dist-info/RECORD +130 -0
- reaxkit-1.0.0.dist-info/WHEEL +5 -0
- reaxkit-1.0.0.dist-info/entry_points.txt +2 -0
- reaxkit-1.0.0.dist-info/licenses/AUTHORS.md +20 -0
- reaxkit-1.0.0.dist-info/licenses/LICENSE +21 -0
- reaxkit-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"""
|
|
2
|
+
fort.99 force-field training analysis workflow for ReaxKit.
|
|
3
|
+
|
|
4
|
+
This workflow provides tools for analyzing ReaxFF `fort.99` files, which contain
|
|
5
|
+
energy-error data used during force-field training and validation.
|
|
6
|
+
|
|
7
|
+
It supports:
|
|
8
|
+
- Extracting and sorting ENERGY error tables from `fort.99` files, with optional
|
|
9
|
+
CSV export for downstream analysis.
|
|
10
|
+
- Constructing energy–volume (EOS) relationships by combining `fort.99` and
|
|
11
|
+
`fort.74` data, enabling comparison between force-field and QM reference energies.
|
|
12
|
+
- Visualizing EOS curves and exporting the underlying data.
|
|
13
|
+
- Computing bulk moduli using a Vinet equation-of-state fit, based on selected
|
|
14
|
+
energy identifiers and data sources.
|
|
15
|
+
|
|
16
|
+
The workflow is intended to support force-field development, validation, and
|
|
17
|
+
benchmarking by bridging ReaxFF training outputs with physically meaningful
|
|
18
|
+
material properties.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
import argparse
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
from reaxkit.io.handlers.fort99_handler import Fort99Handler
|
|
27
|
+
from reaxkit.analysis.per_file import fort99_analyzer
|
|
28
|
+
from reaxkit.utils.media.plotter import single_plot
|
|
29
|
+
from reaxkit.utils.alias import normalize_choice
|
|
30
|
+
from reaxkit.io.handlers.fort74_handler import Fort74Handler
|
|
31
|
+
from reaxkit.utils.path import resolve_output_path
|
|
32
|
+
|
|
33
|
+
# ---------- tasks ----------
|
|
34
|
+
|
|
35
|
+
def _fort99_get_task(args: argparse.Namespace) -> int:
|
|
36
|
+
handler = Fort99Handler(args.file)
|
|
37
|
+
sortby = normalize_choice(args.sort, domain="sort")
|
|
38
|
+
|
|
39
|
+
df = fort99_analyzer.get_fort99_data(
|
|
40
|
+
handler,
|
|
41
|
+
sortby=sortby,
|
|
42
|
+
ascending=args.ascending,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if df.empty:
|
|
47
|
+
print("[Warning] fort.99 result is empty.")
|
|
48
|
+
return 0
|
|
49
|
+
|
|
50
|
+
workflow_name = args.kind
|
|
51
|
+
if args.export:
|
|
52
|
+
out = resolve_output_path(args.export, workflow_name)
|
|
53
|
+
df.to_csv(out, index=False)
|
|
54
|
+
print(f"[Done] Exported fort.99 table to {out}")
|
|
55
|
+
else:
|
|
56
|
+
# If no export requested, just print to stdout
|
|
57
|
+
print(df.to_string(index=False))
|
|
58
|
+
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _fort99_eos_task(args: argparse.Namespace) -> int:
|
|
63
|
+
"""
|
|
64
|
+
Steps:
|
|
65
|
+
1) Run fort99_energy_vs_volume to obtain:
|
|
66
|
+
iden1, iden2, ffield_value, qm_value, V_iden2
|
|
67
|
+
2) Filter by --iden (either 'all' or a specific iden1)
|
|
68
|
+
3) Optionally flip energy sign using --flip
|
|
69
|
+
4) For each iden1 group, plot single_plot (both lines on same axes)
|
|
70
|
+
5) Optionally export table
|
|
71
|
+
"""
|
|
72
|
+
fort99_handler = Fort99Handler(args.fort99)
|
|
73
|
+
|
|
74
|
+
# Guess fort.74 path if not provided
|
|
75
|
+
fort74_path = (Path(args.fort99).with_name("fort.74")
|
|
76
|
+
if args.fort74 is None else Path(args.fort74))
|
|
77
|
+
fort74_handler = Fort74Handler(str(fort74_path))
|
|
78
|
+
|
|
79
|
+
df = fort99_analyzer.fort99_energy_vs_volume(
|
|
80
|
+
fort99_handler=fort99_handler,
|
|
81
|
+
fort74_handler=fort74_handler,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if df.empty:
|
|
85
|
+
print("[Warning] No ENERGY vs volume data found.")
|
|
86
|
+
return 0
|
|
87
|
+
|
|
88
|
+
# Filter by iden1
|
|
89
|
+
if args.iden.lower() != "all":
|
|
90
|
+
df = df[df["iden1"] == args.iden]
|
|
91
|
+
if df.empty:
|
|
92
|
+
print(f"[Warning] No rows found for iden1 == {args.iden!r}.")
|
|
93
|
+
return 0
|
|
94
|
+
|
|
95
|
+
workflow_name = args.kind
|
|
96
|
+
# Export table
|
|
97
|
+
if args.export:
|
|
98
|
+
out = resolve_output_path(args.export, workflow_name)
|
|
99
|
+
df.to_csv(out, index=False)
|
|
100
|
+
print(f"[Done] Exported ENERGY vs volume table to {out}")
|
|
101
|
+
|
|
102
|
+
# No plot/save = nothing else to do
|
|
103
|
+
do_plot = args.plot or args.save
|
|
104
|
+
if not do_plot:
|
|
105
|
+
return 0
|
|
106
|
+
|
|
107
|
+
save_dir = None
|
|
108
|
+
if args.save:
|
|
109
|
+
save_dir = resolve_output_path(args.save, workflow_name)
|
|
110
|
+
|
|
111
|
+
# ----------- PLOTTING -------------
|
|
112
|
+
for iden1, g in df.groupby("iden1"):
|
|
113
|
+
# Sort by volume for proper curve ordering
|
|
114
|
+
g = g.sort_values("V_iden2")
|
|
115
|
+
|
|
116
|
+
# Flip sign if requested
|
|
117
|
+
if args.flip:
|
|
118
|
+
g["ffield_value"] = -g["ffield_value"]
|
|
119
|
+
g["qm_value"] = -g["qm_value"]
|
|
120
|
+
|
|
121
|
+
x = g["V_iden2"]
|
|
122
|
+
y_ff = g["ffield_value"]
|
|
123
|
+
y_qm = g["qm_value"]
|
|
124
|
+
|
|
125
|
+
single_plot(
|
|
126
|
+
series=[
|
|
127
|
+
{"x": x, "y": y_ff, "label": "Force-field"},
|
|
128
|
+
{"x": x, "y": y_qm, "label": "QM"},
|
|
129
|
+
],
|
|
130
|
+
title="",
|
|
131
|
+
xlabel="Volume",
|
|
132
|
+
ylabel="Relative Energy (kcal/mole)",
|
|
133
|
+
save=save_dir,
|
|
134
|
+
legend=True,
|
|
135
|
+
figsize=(6,4),
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return 0
|
|
139
|
+
|
|
140
|
+
def _task_bulk_modulus(args) -> None:
|
|
141
|
+
"""
|
|
142
|
+
Compute and print the bulk modulus from ENERGY vs volume data
|
|
143
|
+
using a Vinet equation-of-state fit.
|
|
144
|
+
"""
|
|
145
|
+
from reaxkit.analysis.per_file.fort99_analyzer import get_fort99_bulk_modulus
|
|
146
|
+
fort99_handler_to_use = Fort99Handler(args.fort99)
|
|
147
|
+
fort74_handler_to_use = Fort74Handler(args.fort74)
|
|
148
|
+
|
|
149
|
+
res = get_fort99_bulk_modulus(
|
|
150
|
+
fort99_handler=fort99_handler_to_use,
|
|
151
|
+
fort74_handler=fort74_handler_to_use,
|
|
152
|
+
iden=args.iden,
|
|
153
|
+
source=args.source,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
print("\nBulk modulus (Vinet EOS fit)")
|
|
157
|
+
print("-" * 40)
|
|
158
|
+
print(f"Identifier : {res['iden']}")
|
|
159
|
+
print(f"Source : {res['source']}")
|
|
160
|
+
print(f"Points : {res['n_points']}")
|
|
161
|
+
print(f"V0 : {res['V0_A3']:.4f} Å^3")
|
|
162
|
+
print(f"K0 : {res['K0_GPa']:.2f} GPa")
|
|
163
|
+
print(f"C : {res['C']:.3f}")
|
|
164
|
+
|
|
165
|
+
# ---------- registration ----------
|
|
166
|
+
|
|
167
|
+
def register_tasks(subparsers: argparse._SubParsersAction) -> None:
|
|
168
|
+
|
|
169
|
+
# ---- fort99 get ----
|
|
170
|
+
p_get = subparsers.add_parser(
|
|
171
|
+
"get",
|
|
172
|
+
help="Compute fort.99 ENERGY errors and sort/export the table \n",
|
|
173
|
+
description=(
|
|
174
|
+
"Examples:\n"
|
|
175
|
+
" reaxkit fort99 get --sort error --ascending --export fort99_sorted_data.csv \n"
|
|
176
|
+
),
|
|
177
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
178
|
+
)
|
|
179
|
+
p_get.add_argument("--file", default="fort.99", help="Path to fort.99 file")
|
|
180
|
+
p_get.add_argument("--sort", default="error", help="Column to sort by (e.g., error, ffield_value, qm_value)")
|
|
181
|
+
p_get.add_argument("--ascending", action="store_true", help="Sort ascending (default: descending)")
|
|
182
|
+
p_get.add_argument("--export", default=None, help="CSV file to export the sorted table (optional)")
|
|
183
|
+
p_get.set_defaults(_run=_fort99_get_task)
|
|
184
|
+
|
|
185
|
+
# ---- fort99 eos ----
|
|
186
|
+
p_eos = subparsers.add_parser(
|
|
187
|
+
"eos", help="Energy vs volume (EOS) plots from fort.99 + fort.74 \n",
|
|
188
|
+
description=(
|
|
189
|
+
"Examples:\n"
|
|
190
|
+
" reaxkit fort99 eos --iden all --save reaxkit_outputs/fort99/eos_plots/ --flip --export eos_plots.csv \n"
|
|
191
|
+
" reaxkit fort99 eos --iden bulk_0 --save eos_bulk_0.png --export eos_bulk0.csv"
|
|
192
|
+
),
|
|
193
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
194
|
+
)
|
|
195
|
+
p_eos.add_argument("--fort99", default="fort.99", help="Path to fort.99 file")
|
|
196
|
+
p_eos.add_argument("--fort74.md", default='fort.74', help="Path to fort.74 (default: same directory as fort.99)")
|
|
197
|
+
p_eos.add_argument("--iden", default="all", help="iden1 to include ('all' or specific e.g. bulk_0)")
|
|
198
|
+
p_eos.add_argument("--plot", action="store_true", help="Show plots interactively")
|
|
199
|
+
p_eos.add_argument("--save", default=None, help="Directory to save plots as <iden1>.png")
|
|
200
|
+
p_eos.add_argument("--export", default=None, help="CSV file to export ENERGY vs volume table")
|
|
201
|
+
p_eos.add_argument("--flip", action="store_true",
|
|
202
|
+
help="Flip the sign of both QM and force-field energies before plotting")
|
|
203
|
+
p_eos.set_defaults(_run=_fort99_eos_task)
|
|
204
|
+
|
|
205
|
+
# ---- fort99 bulk modulus calculator ----
|
|
206
|
+
bulk = subparsers.add_parser(
|
|
207
|
+
"bulk",
|
|
208
|
+
help="Compute bulk modulus from ENERGY vs volume (Vinet EOS)",
|
|
209
|
+
description=(
|
|
210
|
+
"Examples:\n"
|
|
211
|
+
" reaxkit fort99 bulk --iden 'Al2N2_w_opt2' \n"
|
|
212
|
+
" reaxkit fort99 bulk --iden Al2N2_w_opt2 --source qm\n"
|
|
213
|
+
),
|
|
214
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
215
|
+
)
|
|
216
|
+
bulk.add_argument("--fort99", default="fort.99", help="fort.99 file to use")
|
|
217
|
+
bulk.add_argument("--fort74.md", default="fort.74", help="fort.74 file to use")
|
|
218
|
+
bulk.add_argument("--iden", required=True, help="ENERGY identifier (iden1) to use for EOS fitting")
|
|
219
|
+
bulk.add_argument("--source", default="ffield", choices=["ffield", "qm"],
|
|
220
|
+
help="Energy source to use (ffield or qm)",
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
bulk.set_defaults(_run=_task_bulk_modulus)
|