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,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Temperature-regime (tregime) workflow for ReaxKit.
|
|
3
|
+
|
|
4
|
+
This workflow provides a utility for generating sample `tregime.in` files,
|
|
5
|
+
which define temperature schedules used in ReaxFF molecular dynamics
|
|
6
|
+
simulations.
|
|
7
|
+
|
|
8
|
+
It supports:
|
|
9
|
+
- Writing a correctly formatted `tregime.in` file with fixed-width columns.
|
|
10
|
+
- Controlling the number of temperature-regime rows written to the file.
|
|
11
|
+
- Automatically selecting a standardized output location when no explicit
|
|
12
|
+
output path is provided.
|
|
13
|
+
|
|
14
|
+
The workflow is intended to simplify creation of valid temperature-regime
|
|
15
|
+
input files for testing, prototyping, and reproducible simulation setup.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
from reaxkit.io.generators.tregime_generator import write_sample_tregime
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _task_generate(args: argparse.Namespace) -> int:
|
|
27
|
+
# Default output location: reaxkit_outputs/tregime/tregime.in
|
|
28
|
+
out_default = Path("reaxkit_outputs") / "tregime" / "tregime.in"
|
|
29
|
+
|
|
30
|
+
# Prefer your project resolver if available
|
|
31
|
+
out_path: Path
|
|
32
|
+
if args.out:
|
|
33
|
+
out_path = Path(args.out)
|
|
34
|
+
else:
|
|
35
|
+
try:
|
|
36
|
+
from reaxkit.utils.path import resolve_output_path # type: ignore
|
|
37
|
+
|
|
38
|
+
out_path = Path(
|
|
39
|
+
resolve_output_path(
|
|
40
|
+
kind="tregime",
|
|
41
|
+
out=args.out,
|
|
42
|
+
default_name="tregime.in",
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
except Exception:
|
|
46
|
+
out_path = out_default
|
|
47
|
+
|
|
48
|
+
write_sample_tregime(out_path, n_rows=args.rows)
|
|
49
|
+
|
|
50
|
+
print(f"[Done] Sample tregime generated in {out_path}")
|
|
51
|
+
return 0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def register_tasks(subparsers: argparse._SubParsersAction) -> None:
|
|
55
|
+
gen = subparsers.add_parser(
|
|
56
|
+
"gen",
|
|
57
|
+
help="Generate a sample tregime.in file (fixed-width columns).",
|
|
58
|
+
description=(
|
|
59
|
+
"Examples:\n"
|
|
60
|
+
" reaxkit tregime gen \n"
|
|
61
|
+
" reaxkit tregime gen --rows 5 \n"
|
|
62
|
+
),
|
|
63
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
64
|
+
)
|
|
65
|
+
gen.add_argument(
|
|
66
|
+
"--out",
|
|
67
|
+
default="reaxkit_generated_inputs/tregime.in",
|
|
68
|
+
help=(
|
|
69
|
+
"Output tregime filename or path. "
|
|
70
|
+
"If not provided, writes to reaxkit_outputs/tregime/tregime.in"
|
|
71
|
+
),
|
|
72
|
+
)
|
|
73
|
+
gen.add_argument(
|
|
74
|
+
"--rows",
|
|
75
|
+
type=int,
|
|
76
|
+
default=3,
|
|
77
|
+
help="Number of sample rows to write.",
|
|
78
|
+
)
|
|
79
|
+
gen.set_defaults(_run=_task_generate)
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Velocity and acceleration (vels) analysis workflow for ReaxKit.
|
|
3
|
+
|
|
4
|
+
This workflow provides tools for inspecting, visualizing, and exporting data
|
|
5
|
+
from ReaxFF velocity-related output files, including `vels`, `moldyn.vel`,
|
|
6
|
+
and `molsav`.
|
|
7
|
+
|
|
8
|
+
It supports:
|
|
9
|
+
- Extracting per-atom coordinates, velocities, accelerations, or previous-step
|
|
10
|
+
accelerations for all atoms or selected subsets.
|
|
11
|
+
- Printing extracted data to the console or exporting it to CSV.
|
|
12
|
+
- Visualizing scalar velocity or acceleration components (e.g. vx, vz, ax)
|
|
13
|
+
mapped onto atomic positions using 3D scatter plots.
|
|
14
|
+
- Generating 2D projected heatmaps (xy, xz, yz) of scalar quantities by spatial
|
|
15
|
+
binning and aggregation.
|
|
16
|
+
|
|
17
|
+
The workflow is designed for spatially resolved analysis of atomic motion and
|
|
18
|
+
dynamics in ReaxFF molecular dynamics simulations.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
from typing import Optional, Tuple, Union
|
|
26
|
+
|
|
27
|
+
import numpy as np
|
|
28
|
+
import pandas as pd
|
|
29
|
+
|
|
30
|
+
from reaxkit.io.handlers.vels_handler import VelsHandler
|
|
31
|
+
from reaxkit.analysis.per_file.vels_analyzer import get_vels_data
|
|
32
|
+
from reaxkit.utils.media.plotter import scatter3d_points, heatmap2d_from_3d
|
|
33
|
+
from reaxkit.utils.path import resolve_output_path
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# ------------------------- small parsers -------------------------
|
|
37
|
+
|
|
38
|
+
def _parse_atoms_1based(spec: Optional[str]) -> Optional[list[int]]:
|
|
39
|
+
"""
|
|
40
|
+
Parse atoms like:
|
|
41
|
+
"1,3,7" or "1 3 7" or "1-5" (inclusive) or "1-10,15,20-25"
|
|
42
|
+
Returns 1-based indices (as stored in vels dfs).
|
|
43
|
+
"""
|
|
44
|
+
if spec is None:
|
|
45
|
+
return None
|
|
46
|
+
s = spec.strip()
|
|
47
|
+
if not s:
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
out: list[int] = []
|
|
51
|
+
parts = s.replace(",", " ").split()
|
|
52
|
+
for p in parts:
|
|
53
|
+
if "-" in p:
|
|
54
|
+
a, b = p.split("-", 1)
|
|
55
|
+
if a.strip().isdigit() and b.strip().isdigit():
|
|
56
|
+
lo, hi = int(a), int(b)
|
|
57
|
+
if lo <= hi:
|
|
58
|
+
out.extend(list(range(lo, hi + 1)))
|
|
59
|
+
else:
|
|
60
|
+
out.extend(list(range(hi, lo + 1)))
|
|
61
|
+
else:
|
|
62
|
+
if p.isdigit():
|
|
63
|
+
out.append(int(p))
|
|
64
|
+
|
|
65
|
+
# unique, preserve order
|
|
66
|
+
seen = set()
|
|
67
|
+
uniq = []
|
|
68
|
+
for x in out:
|
|
69
|
+
if x not in seen:
|
|
70
|
+
uniq.append(x)
|
|
71
|
+
seen.add(x)
|
|
72
|
+
return uniq or None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _parse_bins(bins: str) -> Union[int, Tuple[int, int]]:
|
|
76
|
+
if "," in bins:
|
|
77
|
+
nx, ny = [int(x) for x in bins.split(",")]
|
|
78
|
+
return (nx, ny)
|
|
79
|
+
return int(bins)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _value_column_to_key(value_col: str) -> tuple[str, str]:
|
|
83
|
+
"""
|
|
84
|
+
Map a requested scalar column to the vels_get key + dataframe column name.
|
|
85
|
+
Examples:
|
|
86
|
+
vx/vy/vz -> ("velocities", "vx"/"vy"/"vz")
|
|
87
|
+
ax/ay/az -> ("accelerations", "ax"/"ay"/"az")
|
|
88
|
+
pax/pay/paz -> ("prev_accelerations", "ax"/"ay"/"az")
|
|
89
|
+
"""
|
|
90
|
+
v = value_col.strip().lower()
|
|
91
|
+
if v in {"vx", "vy", "vz"}:
|
|
92
|
+
return ("velocities", v)
|
|
93
|
+
if v in {"ax", "ay", "az"}:
|
|
94
|
+
return ("accelerations", v)
|
|
95
|
+
if v in {"pax", "pay", "paz"}:
|
|
96
|
+
# previous accels share ax/ay/az columns
|
|
97
|
+
return ("prev_accelerations", "a" + v[1:])
|
|
98
|
+
raise ValueError("value_col must be one of: vx,vy,vz, ax,ay,az, pax,pay,paz")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# ------------------------- common args -------------------------
|
|
102
|
+
|
|
103
|
+
def _add_common_vels_io_args(p: argparse.ArgumentParser) -> None:
|
|
104
|
+
p.add_argument("--file", default="vels", help="Path to vels/moldyn.vel/molsav file.")
|
|
105
|
+
p.add_argument("--atoms", default=None,
|
|
106
|
+
help='1-based atom indices (optional). Examples: "1,3,7" or "1-10,25".')
|
|
107
|
+
p.add_argument("--export", default=None, help="Path to export CSV data.")
|
|
108
|
+
p.add_argument("--print", action="store_true", help="Print output to console.")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _add_common_plot_args(p: argparse.ArgumentParser) -> None:
|
|
112
|
+
p.add_argument("--save", default=None, help="Path to save plot image (dir or full filename).")
|
|
113
|
+
p.add_argument("--vmin", type=float, default=None, help="Color scale min (auto if not set).")
|
|
114
|
+
p.add_argument("--vmax", type=float, default=None, help="Color scale max (auto if not set).")
|
|
115
|
+
p.add_argument("--cmap", default="coolwarm", help="Matplotlib colormap.")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# ------------------------- tasks -------------------------
|
|
119
|
+
|
|
120
|
+
def _get_task(args: argparse.Namespace) -> int:
|
|
121
|
+
h = VelsHandler(args.file)
|
|
122
|
+
|
|
123
|
+
atoms = _parse_atoms_1based(args.atoms)
|
|
124
|
+
|
|
125
|
+
out = get_vels_data(h, args.key, atoms=atoms)
|
|
126
|
+
|
|
127
|
+
# metadata
|
|
128
|
+
if isinstance(out, dict):
|
|
129
|
+
if args.print or (not args.export):
|
|
130
|
+
for k, v in out.items():
|
|
131
|
+
print(f"{k}: {v}")
|
|
132
|
+
if args.export:
|
|
133
|
+
export_path = resolve_output_path(args.export, workflow="vels")
|
|
134
|
+
# simple key/value csv
|
|
135
|
+
dfm = pd.DataFrame([{"key": k, "value": str(v)} for k, v in out.items()])
|
|
136
|
+
dfm.to_csv(export_path, index=False)
|
|
137
|
+
print(f"[Done] Requested data is exported to {export_path}")
|
|
138
|
+
return 0
|
|
139
|
+
|
|
140
|
+
# dataframe
|
|
141
|
+
df = out
|
|
142
|
+
if args.print or (not args.export):
|
|
143
|
+
# avoid flooding console; you can change this later
|
|
144
|
+
with pd.option_context("display.max_rows", 30, "display.width", 140):
|
|
145
|
+
print(df)
|
|
146
|
+
|
|
147
|
+
if args.export:
|
|
148
|
+
export_path = resolve_output_path(args.export, workflow="vels")
|
|
149
|
+
df.to_csv(export_path, index=False)
|
|
150
|
+
print(f"[Done] Requested data is exported to {export_path}")
|
|
151
|
+
|
|
152
|
+
return 0
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _plot3d_task(args: argparse.Namespace) -> int:
|
|
156
|
+
h = VelsHandler(args.file)
|
|
157
|
+
atoms = _parse_atoms_1based(args.atoms)
|
|
158
|
+
|
|
159
|
+
# coords
|
|
160
|
+
cdf = get_vels_data(h, "coordinates", atoms=atoms)
|
|
161
|
+
if cdf.empty:
|
|
162
|
+
raise ValueError("No coordinates to plot (empty selection).")
|
|
163
|
+
|
|
164
|
+
# scalar values from one of the sections
|
|
165
|
+
key, col = _value_column_to_key(args.value)
|
|
166
|
+
vdf = get_vels_data(h, key, atoms=atoms)
|
|
167
|
+
if vdf.empty:
|
|
168
|
+
raise ValueError(f"No data for {args.value} to plot (empty selection or missing section).")
|
|
169
|
+
|
|
170
|
+
merged = cdf.merge(vdf, on="atom_index", how="inner")
|
|
171
|
+
if merged.empty:
|
|
172
|
+
raise ValueError("No matching atom rows between coordinates and selected values.")
|
|
173
|
+
|
|
174
|
+
coords = merged[["x", "y", "z"]].to_numpy(float)
|
|
175
|
+
vals = merged[col].to_numpy(float)
|
|
176
|
+
|
|
177
|
+
m = np.isfinite(vals)
|
|
178
|
+
coords = coords[m]
|
|
179
|
+
vals = vals[m]
|
|
180
|
+
if coords.size == 0:
|
|
181
|
+
raise ValueError("All selected values are NaN/invalid; nothing to plot.")
|
|
182
|
+
|
|
183
|
+
title = f"{args.value}_3D"
|
|
184
|
+
scatter3d_points(
|
|
185
|
+
coords,
|
|
186
|
+
vals,
|
|
187
|
+
title=title,
|
|
188
|
+
s=args.size,
|
|
189
|
+
alpha=args.alpha,
|
|
190
|
+
cmap=args.cmap,
|
|
191
|
+
vmin=args.vmin,
|
|
192
|
+
vmax=args.vmax,
|
|
193
|
+
elev=args.elev,
|
|
194
|
+
azim=args.azim,
|
|
195
|
+
save=(resolve_output_path(args.save, workflow="vels") if args.save else None),
|
|
196
|
+
show_message=True,
|
|
197
|
+
)
|
|
198
|
+
return 0
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _heatmap2d_task(args: argparse.Namespace) -> int:
|
|
202
|
+
h = VelsHandler(args.file)
|
|
203
|
+
atoms = _parse_atoms_1based(args.atoms)
|
|
204
|
+
|
|
205
|
+
cdf = get_vels_data(h, "coordinates", atoms=atoms)
|
|
206
|
+
if cdf.empty:
|
|
207
|
+
raise ValueError("No coordinates to plot (empty selection).")
|
|
208
|
+
|
|
209
|
+
key, col = _value_column_to_key(args.value)
|
|
210
|
+
vdf = get_vels_data(h, key, atoms=atoms)
|
|
211
|
+
if vdf.empty:
|
|
212
|
+
raise ValueError(f"No data for {args.value} to plot (empty selection or missing section).")
|
|
213
|
+
|
|
214
|
+
merged = cdf.merge(vdf, on="atom_index", how="inner")
|
|
215
|
+
if merged.empty:
|
|
216
|
+
raise ValueError("No matching atom rows between coordinates and selected values.")
|
|
217
|
+
|
|
218
|
+
coords = merged[["x", "y", "z"]].to_numpy(float)
|
|
219
|
+
vals = merged[col].to_numpy(float)
|
|
220
|
+
m = np.isfinite(vals)
|
|
221
|
+
coords = coords[m]
|
|
222
|
+
vals = vals[m]
|
|
223
|
+
if coords.size == 0:
|
|
224
|
+
raise ValueError("All selected values are NaN/invalid; nothing to plot.")
|
|
225
|
+
|
|
226
|
+
bins = _parse_bins(args.bins)
|
|
227
|
+
title = f"{args.value}_{args.plane}_heatmap2d"
|
|
228
|
+
|
|
229
|
+
heatmap2d_from_3d(
|
|
230
|
+
coords,
|
|
231
|
+
vals,
|
|
232
|
+
plane=args.plane,
|
|
233
|
+
bins=bins,
|
|
234
|
+
agg=args.agg,
|
|
235
|
+
vmin=args.vmin,
|
|
236
|
+
vmax=args.vmax,
|
|
237
|
+
cmap=args.cmap,
|
|
238
|
+
title=title,
|
|
239
|
+
save=(resolve_output_path(args.save, workflow="vels") if args.save else None),
|
|
240
|
+
show_message=True,
|
|
241
|
+
)
|
|
242
|
+
return 0
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
# ------------------------- CLI registration -------------------------
|
|
246
|
+
|
|
247
|
+
def register_tasks(subparsers: argparse._SubParsersAction) -> None:
|
|
248
|
+
# ---------------- get ----------------
|
|
249
|
+
g = subparsers.add_parser(
|
|
250
|
+
"get",
|
|
251
|
+
help="Get vels data (coords/vels/accels/prev) for all or selected atoms.",
|
|
252
|
+
description=(
|
|
253
|
+
"Examples:\n"
|
|
254
|
+
" reaxkit vels get --key velocities --atoms 1,3,7 --print\n"
|
|
255
|
+
" reaxkit vels get --key coordinates --atoms 1-50 --export coords.csv\n"
|
|
256
|
+
" reaxkit vels get --key metadata --print\n"
|
|
257
|
+
),
|
|
258
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
259
|
+
)
|
|
260
|
+
_add_common_vels_io_args(g)
|
|
261
|
+
g.add_argument("--key", required=True,
|
|
262
|
+
choices=["metadata", "coordinates", "velocities", "accelerations", "prev_accelerations"],
|
|
263
|
+
help="Which dataset to return.")
|
|
264
|
+
g.set_defaults(_run=_get_task)
|
|
265
|
+
|
|
266
|
+
# ---------------- plot3d ----------------
|
|
267
|
+
p3 = subparsers.add_parser(
|
|
268
|
+
"plot3d",
|
|
269
|
+
help="3D scatter: color a scalar (vz, vx, ax, ...) on atomic positions.",
|
|
270
|
+
description=(
|
|
271
|
+
"Examples:\n"
|
|
272
|
+
" reaxkit vels plot3d --value vz --save vz_3d.png\n"
|
|
273
|
+
" reaxkit vels plot3d --value vz --atoms 1-500 --cmap coolwarm\n"
|
|
274
|
+
),
|
|
275
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
276
|
+
)
|
|
277
|
+
p3.add_argument("--file", default="vels", help="Path to vels/moldyn.vel/molsav file.")
|
|
278
|
+
p3.add_argument("--atoms", default=None,
|
|
279
|
+
help='1-based atom indices. Examples: "1,3,7" or "1-10,25".')
|
|
280
|
+
p3.add_argument("--value", required=True,
|
|
281
|
+
help="Scalar to plot: vx,vy,vz, ax,ay,az, pax,pay,paz.")
|
|
282
|
+
_add_common_plot_args(p3)
|
|
283
|
+
p3.add_argument("--size", type=float, default=8.0, help="Marker size.")
|
|
284
|
+
p3.add_argument("--alpha", type=float, default=0.9, help="Marker transparency.")
|
|
285
|
+
p3.add_argument("--elev", type=float, default=22.0, help="3D view elevation.")
|
|
286
|
+
p3.add_argument("--azim", type=float, default=38.0, help="3D view azimuth.")
|
|
287
|
+
p3.set_defaults(_run=_plot3d_task)
|
|
288
|
+
|
|
289
|
+
# ---------------- heatmap2d ----------------
|
|
290
|
+
h2 = subparsers.add_parser(
|
|
291
|
+
"heatmap2d",
|
|
292
|
+
help="2D heatmap: project positions to xy/xz/yz and bin/aggregate a scalar.",
|
|
293
|
+
description=(
|
|
294
|
+
"Examples:\n"
|
|
295
|
+
" reaxkit vels heatmap2d --value vz --plane xz --bins 60 --agg mean --save vz_xz.png\n"
|
|
296
|
+
" reaxkit vels heatmap2d --value vz --plane xy --bins 80,40 --agg max\n"
|
|
297
|
+
),
|
|
298
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
299
|
+
)
|
|
300
|
+
h2.add_argument("--file", default="vels", help="Path to vels/moldyn.vel/molsav file.")
|
|
301
|
+
h2.add_argument("--atoms", default=None,
|
|
302
|
+
help='1-based atom indices. Examples: "1,3,7" or "1-10,25".')
|
|
303
|
+
h2.add_argument("--value", required=True,
|
|
304
|
+
help="Scalar to plot: vx,vy,vz, ax,ay,az, pax,pay,paz.")
|
|
305
|
+
h2.add_argument("--plane", default="xy", choices=["xy", "xz", "yz"], help="Projection plane.")
|
|
306
|
+
h2.add_argument("--bins", default="50", help='Grid bins: "N" or "Nx,Ny" (e.g., "80,40").')
|
|
307
|
+
h2.add_argument("--agg", default="mean", help="Aggregation: mean|max|min|sum|count.")
|
|
308
|
+
_add_common_plot_args(h2)
|
|
309
|
+
h2.set_defaults(_run=_heatmap2d_task)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Volume-regime (vregime) workflow for ReaxKit.
|
|
3
|
+
|
|
4
|
+
This workflow provides a utility for generating sample `vregime.in` files,
|
|
5
|
+
which define volume or pressure control schedules used in ReaxFF simulations.
|
|
6
|
+
|
|
7
|
+
It supports:
|
|
8
|
+
- Writing a correctly formatted `vregime.in` file with fixed-width columns.
|
|
9
|
+
- Controlling the number of volume-regime rows written to the file.
|
|
10
|
+
- Automatically selecting a standardized output location when no explicit
|
|
11
|
+
output path is provided.
|
|
12
|
+
|
|
13
|
+
The workflow is intended to simplify creation of valid volume-regime input
|
|
14
|
+
files for testing, prototyping, and reproducible ReaxFF simulation setup.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from reaxkit.io.generators.vregime_generator import write_sample_vregime
|
|
23
|
+
|
|
24
|
+
def _task_generate(args: argparse.Namespace) -> int:
|
|
25
|
+
out_default = Path("reaxkit_outputs") / "vregime" / "vregime.in"
|
|
26
|
+
|
|
27
|
+
if args.out:
|
|
28
|
+
out_path = Path(args.out)
|
|
29
|
+
else:
|
|
30
|
+
# Prefer your project resolver if available
|
|
31
|
+
try:
|
|
32
|
+
from reaxkit.utils.path import resolve_output_path # type: ignore
|
|
33
|
+
|
|
34
|
+
out_path = Path(
|
|
35
|
+
resolve_output_path(
|
|
36
|
+
kind="vregime",
|
|
37
|
+
out=None,
|
|
38
|
+
default_name="vregime.in",
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
except Exception:
|
|
42
|
+
out_path = out_default
|
|
43
|
+
|
|
44
|
+
write_sample_vregime(out_path, n_rows=args.rows)
|
|
45
|
+
|
|
46
|
+
print(f"[Done] Sample vregime generated in {out_path}")
|
|
47
|
+
return 0
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def register_tasks(subparsers: argparse._SubParsersAction) -> None:
|
|
51
|
+
p = subparsers.add_parser(
|
|
52
|
+
"gen",
|
|
53
|
+
help="Generate a sample vregime.in file (Volume regimes).",
|
|
54
|
+
description=(
|
|
55
|
+
"Examples:\n"
|
|
56
|
+
" reaxkit vregime gen \n"
|
|
57
|
+
" reaxkit vregime gen --rows 3 \n"
|
|
58
|
+
),
|
|
59
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
60
|
+
)
|
|
61
|
+
p.add_argument(
|
|
62
|
+
"--out",
|
|
63
|
+
default="reaxkit_generated_inputs/vregime.in",
|
|
64
|
+
help=(
|
|
65
|
+
"Output vregime filename or path. "
|
|
66
|
+
"If not provided, writes to reaxkit_outputs/vregime/vregime.in"
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
p.add_argument(
|
|
70
|
+
"--rows",
|
|
71
|
+
type=int,
|
|
72
|
+
default=5,
|
|
73
|
+
help="Number of sample rows to write.",
|
|
74
|
+
)
|
|
75
|
+
p.set_defaults(_run=_task_generate)
|