lammpsparser 0.0.3__tar.gz → 0.0.5__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.
- lammpsparser-0.0.5/.gitignore +218 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/PKG-INFO +5 -3
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/pyproject.toml +4 -3
- lammpsparser-0.0.5/src/lammpsparser/_version.py +24 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/compatibility/calculate.py +52 -6
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/compatibility/constraints.py +55 -3
- lammpsparser-0.0.5/src/lammpsparser/compatibility/data.py +87 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/compatibility/file.py +115 -27
- lammpsparser-0.0.5/src/lammpsparser/compatibility/output.py +38 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/compatibility/structure.py +41 -20
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/output.py +124 -12
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/output_raw.py +98 -13
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/potential.py +153 -7
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/structure.py +125 -36
- lammpsparser-0.0.3/src/lammpsparser/_version.py +0 -34
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/LICENSE +0 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/README.md +0 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/__init__.py +0 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/compatibility/__init__.py +0 -0
- {lammpsparser-0.0.3 → lammpsparser-0.0.5}/src/lammpsparser/units.py +0 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lammpsparser
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: Vector-oriented LAMMPS interface to rapidly iterate over series of atomistic structures or interatomic potentials.
|
|
5
5
|
Project-URL: Homepage, https://github.com/pyiron/lammpsparser
|
|
6
6
|
Project-URL: Documentation, https://github.com/pyiron/lammpsparser
|
|
@@ -50,9 +50,11 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
50
50
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
51
51
|
Requires-Python: <3.15,>=3.9
|
|
52
52
|
Requires-Dist: ase<=3.28.0,>=3.22.1
|
|
53
|
-
Requires-Dist: numpy<=2.4.
|
|
54
|
-
Requires-Dist: pandas<=3.0.
|
|
53
|
+
Requires-Dist: numpy<=2.4.6,>=1.26.0
|
|
54
|
+
Requires-Dist: pandas<=3.0.3,>=2.0.3
|
|
55
55
|
Requires-Dist: scipy<=1.17.1,>=1.11.1
|
|
56
|
+
Provides-Extra: compatibility
|
|
57
|
+
Requires-Dist: structuretoolkit<=0.0.44,>=0.0.30; extra == 'compatibility'
|
|
56
58
|
Provides-Extra: h5md
|
|
57
59
|
Requires-Dist: h5py<=3.16.0,>=3.9.0; extra == 'h5md'
|
|
58
60
|
Description-Content-Type: text/markdown
|
|
@@ -5,7 +5,7 @@ requires = [
|
|
|
5
5
|
"h5py",
|
|
6
6
|
"pandas",
|
|
7
7
|
"scipy",
|
|
8
|
-
"hatchling==1.
|
|
8
|
+
"hatchling==1.30.1",
|
|
9
9
|
"hatch-vcs==0.5.0",
|
|
10
10
|
]
|
|
11
11
|
build-backend = "hatchling.build"
|
|
@@ -35,8 +35,8 @@ classifiers = [
|
|
|
35
35
|
]
|
|
36
36
|
dependencies = [
|
|
37
37
|
"ase>=3.22.1,<=3.28.0",
|
|
38
|
-
"numpy>=1.26.0,<=2.4.
|
|
39
|
-
"pandas>=2.0.3,<=3.0.
|
|
38
|
+
"numpy>=1.26.0,<=2.4.6",
|
|
39
|
+
"pandas>=2.0.3,<=3.0.3",
|
|
40
40
|
"scipy>=1.11.1,<=1.17.1",
|
|
41
41
|
]
|
|
42
42
|
dynamic = ["version"]
|
|
@@ -48,6 +48,7 @@ Repository = "https://github.com/pyiron/lammpsparser"
|
|
|
48
48
|
|
|
49
49
|
[project.optional-dependencies]
|
|
50
50
|
h5md = ["h5py>=3.9.0,<=3.16.0"]
|
|
51
|
+
compatibility = ["structuretoolkit>=0.0.30,<=0.0.44"]
|
|
51
52
|
|
|
52
53
|
[tool.hatch.build]
|
|
53
54
|
include = [
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.0.5'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 0, 5)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = None
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
+
from typing import Any, cast
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
4
5
|
from ase.atoms import Atoms
|
|
@@ -121,7 +122,7 @@ def calc_md(
|
|
|
121
122
|
"Target temperature for fix nvt/npt/nph cannot be 0 or negative"
|
|
122
123
|
)
|
|
123
124
|
|
|
124
|
-
force_skewed = False
|
|
125
|
+
# force_skewed = False
|
|
125
126
|
pressure = _pressure_to_lammps(
|
|
126
127
|
pressure=pressure, rotation_matrix=rotation_matrix, units=units
|
|
127
128
|
)
|
|
@@ -139,8 +140,8 @@ def calc_md(
|
|
|
139
140
|
pressure_string += " {0} {1} {1} {2}".format(
|
|
140
141
|
coord, value, pressure_damping_timescale
|
|
141
142
|
)
|
|
142
|
-
if ii > 2:
|
|
143
|
-
|
|
143
|
+
# if ii > 2:
|
|
144
|
+
# force_skewed = True
|
|
144
145
|
|
|
145
146
|
if langevin: # NPT(Langevin)
|
|
146
147
|
fix_ensemble_str = "fix ensemble all nph" + pressure_string
|
|
@@ -277,7 +278,7 @@ def calc_minimize(
|
|
|
277
278
|
pressure=pressure, rotation_matrix=rotation_matrix, units=units
|
|
278
279
|
)
|
|
279
280
|
if np.isscalar(pressure):
|
|
280
|
-
str_press = " iso {}".format(pressure)
|
|
281
|
+
str_press = " iso {}".format(float(cast(Any, pressure)))
|
|
281
282
|
else:
|
|
282
283
|
str_press = ""
|
|
283
284
|
for ii, (press, str_axis) in enumerate(
|
|
@@ -307,10 +308,31 @@ def calc_minimize(
|
|
|
307
308
|
|
|
308
309
|
|
|
309
310
|
def calc_static():
|
|
311
|
+
"""
|
|
312
|
+
Generate LAMMPS input commands for a single-point (static) energy calculation.
|
|
313
|
+
|
|
314
|
+
Configures thermodynamic output and runs zero MD steps so that LAMMPS
|
|
315
|
+
computes and prints forces, stresses, and energies for the current
|
|
316
|
+
configuration without moving any atoms.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
list[str]: LAMMPS input lines to append to the input script.
|
|
320
|
+
"""
|
|
310
321
|
return ["variable thermotime equal 1"] + _get_thermo() + ["run 0"]
|
|
311
322
|
|
|
312
323
|
|
|
313
324
|
def _get_thermo():
|
|
325
|
+
"""
|
|
326
|
+
Return the standard thermodynamic output commands used by all calc modes.
|
|
327
|
+
|
|
328
|
+
Writes step, temperature, potential energy, total energy, full pressure
|
|
329
|
+
tensor, and volume every ``${thermotime}`` steps. The ``${thermotime}``
|
|
330
|
+
variable must be defined before these lines are appended.
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
list[str]: Three LAMMPS input lines: ``thermo_style``,
|
|
334
|
+
``thermo_modify``, and ``thermo``.
|
|
335
|
+
"""
|
|
314
336
|
return [
|
|
315
337
|
"thermo_style custom step temp pe etotal pxx pxy pxz pyy pyz pzz vol",
|
|
316
338
|
"thermo_modify format float %20.15g",
|
|
@@ -319,6 +341,20 @@ def _get_thermo():
|
|
|
319
341
|
|
|
320
342
|
|
|
321
343
|
def _is_isotropic_hydrostatic(pressure):
|
|
344
|
+
"""
|
|
345
|
+
Return ``True`` when ``pressure`` describes an isotropic, hydrostatic state.
|
|
346
|
+
|
|
347
|
+
A pressure specification is considered isotropic and hydrostatic when the
|
|
348
|
+
three diagonal (axial) components are equal and the three off-diagonal
|
|
349
|
+
(shear) components are either all ``None`` or all equal to zero.
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
pressure (list): Six-element list ``[pxx, pyy, pzz, pxy, pxz, pyz]``
|
|
353
|
+
where ``None`` means "unconstrained".
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
bool: ``True`` if the pressure is isotropic hydrostatic.
|
|
357
|
+
"""
|
|
322
358
|
axial_all_alike = None not in pressure[:3] and np.allclose(
|
|
323
359
|
pressure[:3], pressure[0]
|
|
324
360
|
)
|
|
@@ -432,12 +468,22 @@ def _pressure_to_lammps(pressure, rotation_matrix, units="metal"):
|
|
|
432
468
|
|
|
433
469
|
def _get_rotation_matrix(structure, pressure):
|
|
434
470
|
"""
|
|
471
|
+
Derive the rotation matrix from the structure's prism and optionally perturb
|
|
472
|
+
the cell to support non-diagonal pressure components.
|
|
473
|
+
|
|
474
|
+
If the requested pressure includes shear components and the cell is not
|
|
475
|
+
already triclinic, a tiny cell perturbation is applied so that LAMMPS
|
|
476
|
+
permits the off-diagonal deformations.
|
|
435
477
|
|
|
436
478
|
Args:
|
|
437
|
-
|
|
479
|
+
structure (ase.atoms.Atoms): Current atomic structure.
|
|
480
|
+
pressure (float or list): Pressure specification (scalar or up to six
|
|
481
|
+
components).
|
|
438
482
|
|
|
439
483
|
Returns:
|
|
440
|
-
|
|
484
|
+
tuple:
|
|
485
|
+
- numpy.ndarray: 3×3 rotation matrix from the ASE to LAMMPS frame.
|
|
486
|
+
- ase.atoms.Atoms: Possibly perturbed structure.
|
|
441
487
|
"""
|
|
442
488
|
if structure is not None:
|
|
443
489
|
prism = UnfoldingPrism(structure.cell)
|
|
@@ -2,7 +2,28 @@ import numpy as np
|
|
|
2
2
|
from ase.atoms import Atoms
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def _get_fixed_atom_boolean_vector(structure: Atoms):
|
|
5
|
+
def _get_fixed_atom_boolean_vector(structure: Atoms) -> np.ndarray:
|
|
6
|
+
"""
|
|
7
|
+
Convert ASE constraints to a per-atom, per-direction boolean array.
|
|
8
|
+
|
|
9
|
+
Translates ASE :class:`~ase.constraints.FixAtoms` and
|
|
10
|
+
:class:`~ase.constraints.FixedPlane` constraints on ``structure`` into a
|
|
11
|
+
boolean array where ``True`` indicates that the corresponding degree of
|
|
12
|
+
freedom is frozen.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
structure (ase.atoms.Atoms): Structure whose ``constraints`` attribute
|
|
16
|
+
is inspected.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
numpy.ndarray: Boolean array of shape ``(N, 3)`` where ``True`` means
|
|
20
|
+
the atom's motion in that Cartesian direction is fixed.
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
ValueError: If a constraint type other than ``FixAtoms`` or
|
|
24
|
+
``FixedPlane`` is encountered, or if the ``FixedPlane`` direction
|
|
25
|
+
is not one of the supported axis combinations.
|
|
26
|
+
"""
|
|
6
27
|
fixed_atom_vector = np.array([[False, False, False]] * len(structure))
|
|
7
28
|
for c in structure.constraints:
|
|
8
29
|
c_dict = c.todict()
|
|
@@ -27,8 +48,39 @@ def _get_fixed_atom_boolean_vector(structure: Atoms):
|
|
|
27
48
|
return fixed_atom_vector
|
|
28
49
|
|
|
29
50
|
|
|
30
|
-
def set_selective_dynamics(structure: Atoms, calc_md: bool = False):
|
|
31
|
-
|
|
51
|
+
def set_selective_dynamics(structure: Atoms, calc_md: bool = False) -> dict[str, str]:
|
|
52
|
+
"""
|
|
53
|
+
Translate ASE constraints into LAMMPS ``group`` / ``fix setforce`` commands.
|
|
54
|
+
|
|
55
|
+
Groups atoms by their frozen degrees of freedom and generates the
|
|
56
|
+
corresponding LAMMPS commands to zero the force (and optionally the
|
|
57
|
+
velocity) on those atoms. Supports constraints on individual Cartesian
|
|
58
|
+
directions (x, y, z) as well as the combined xy, yz, and zx pairs.
|
|
59
|
+
|
|
60
|
+
The LAMMPS equivalent of ASE's ``FixAtoms`` is ``fix setforce 0.0 0.0 0.0``
|
|
61
|
+
and ``FixedPlane`` along an axis is ``fix setforce 0.0 NULL NULL`` (or the
|
|
62
|
+
appropriate permutation).
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
structure (ase.atoms.Atoms): Structure whose ``constraints`` are
|
|
66
|
+
mapped to LAMMPS commands.
|
|
67
|
+
calc_md (bool): If ``True``, also add ``velocity … set`` commands to
|
|
68
|
+
initialise constrained atoms with zero velocity (required for MD
|
|
69
|
+
to prevent initial kinetic energy in frozen directions).
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
dict[str, str]: Ordered mapping of LAMMPS command keyword to the rest
|
|
73
|
+
of the command line. For example::
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
"group constraintxyz": "id 1 2 3",
|
|
77
|
+
"fix constraintxyz": "constraintxyz setforce 0.0 0.0 0.0",
|
|
78
|
+
"velocity constraintxyz": "set 0.0 0.0 0.0", # only when calc_md=True
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
Returns an empty dict if the structure has no constraints.
|
|
82
|
+
"""
|
|
83
|
+
control_dict: dict[str, str] = {}
|
|
32
84
|
if len(structure.constraints) > 0:
|
|
33
85
|
sel_dyn = _get_fixed_atom_boolean_vector(structure=structure)
|
|
34
86
|
# Enter loop only if constraints present
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional, Union
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class CalcMDInput:
|
|
9
|
+
"""
|
|
10
|
+
Input parameters for a LAMMPS molecular-dynamics run via :func:`~lammpsparser.compatibility.calculate.calc_md`.
|
|
11
|
+
|
|
12
|
+
All time-like values (``time_step``, ``temperature_damping_timescale``,
|
|
13
|
+
``pressure_damping_timescale``) are given in femtoseconds and are
|
|
14
|
+
internally rescaled to the target LAMMPS unit system before being written
|
|
15
|
+
to the input script.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
temperature: Target temperature in K. Scalar for a fixed target, or
|
|
19
|
+
a two-element list ``[T_start, T_end]`` for a linear ramp. If
|
|
20
|
+
``None``, an NVE run is performed.
|
|
21
|
+
pressure: Target pressure in GPa. Scalar for isotropic, list of up
|
|
22
|
+
to 6 values for ``[xx, yy, zz, xy, xz, yz]`` components. ``None``
|
|
23
|
+
values leave the corresponding cell degree of freedom unconstrained.
|
|
24
|
+
If ``None``, no barostat is applied.
|
|
25
|
+
n_ionic_steps: Number of MD timesteps to run.
|
|
26
|
+
time_step: MD timestep in fs (default: ``1.0``).
|
|
27
|
+
n_print: Write thermo and dump output every this many steps.
|
|
28
|
+
temperature_damping_timescale: Nosé–Hoover thermostat coupling time
|
|
29
|
+
in fs (LAMMPS ``Tdamp``).
|
|
30
|
+
pressure_damping_timescale: Nosé–Hoover barostat coupling time in fs
|
|
31
|
+
(LAMMPS ``Pdamp``).
|
|
32
|
+
seed: Random seed for velocity initialisation and Langevin dynamics.
|
|
33
|
+
tloop: Optional ``tloop`` argument for the ``fix nvt/npt`` command.
|
|
34
|
+
initial_temperature: Temperature used to initialise velocities.
|
|
35
|
+
``None`` defaults to twice the target temperature. ``0`` skips
|
|
36
|
+
velocity initialisation.
|
|
37
|
+
langevin: Use Langevin dynamics instead of Nosé–Hoover.
|
|
38
|
+
delta_temp: Deprecated alias for ``temperature_damping_timescale``.
|
|
39
|
+
delta_press: Deprecated alias for ``pressure_damping_timescale``.
|
|
40
|
+
rotation_matrix: 3×3 rotation matrix from the ASE to LAMMPS coordinate
|
|
41
|
+
frame. Derived automatically when ``None``.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
temperature: Optional[Union[float, list]] = None
|
|
45
|
+
pressure: Optional[Union[float, list, np.ndarray]] = None
|
|
46
|
+
n_ionic_steps: int = 1
|
|
47
|
+
time_step: float = 1.0
|
|
48
|
+
n_print: int = 100
|
|
49
|
+
temperature_damping_timescale: float = 100.0
|
|
50
|
+
pressure_damping_timescale: float = 1000.0
|
|
51
|
+
seed: int = 80996
|
|
52
|
+
tloop: Optional[int] = None
|
|
53
|
+
initial_temperature: Optional[float] = None
|
|
54
|
+
langevin: bool = False
|
|
55
|
+
delta_temp: Optional[float] = None
|
|
56
|
+
delta_press: Optional[float] = None
|
|
57
|
+
rotation_matrix: Optional[Union[list, np.ndarray]] = None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass
|
|
61
|
+
class CalcMinimizeInput:
|
|
62
|
+
"""
|
|
63
|
+
Input parameters for a LAMMPS geometry optimisation via :func:`~lammpsparser.compatibility.calculate.calc_minimize`.
|
|
64
|
+
|
|
65
|
+
Attributes:
|
|
66
|
+
ionic_energy_tolerance: Convergence criterion on the energy change
|
|
67
|
+
between consecutive steps in eV (LAMMPS ``etol``). The
|
|
68
|
+
minimisation stops when ``|ΔE| ≤ ionic_energy_tolerance``.
|
|
69
|
+
ionic_force_tolerance: Convergence criterion on the global force
|
|
70
|
+
vector magnitude in eV/Å (LAMMPS ``ftol``).
|
|
71
|
+
max_iter: Maximum number of minimisation iterations.
|
|
72
|
+
pressure: Target pressure in GPa for cell relaxation. Scalar for
|
|
73
|
+
isotropic, list of up to 6 Voigt components. ``None`` means
|
|
74
|
+
fixed-volume relaxation.
|
|
75
|
+
n_print: Write thermo and dump output every this many steps.
|
|
76
|
+
style: LAMMPS ``min_style`` keyword (e.g. ``"cg"`` for conjugate
|
|
77
|
+
gradient, ``"sd"`` for steepest descent).
|
|
78
|
+
rotation_matrix: 3×3 rotation matrix from the ASE to LAMMPS frame.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
ionic_energy_tolerance: float = 0.0
|
|
82
|
+
ionic_force_tolerance: float = 1e-4
|
|
83
|
+
max_iter: int = 100000
|
|
84
|
+
pressure: Optional[Union[float, list, np.ndarray]] = None
|
|
85
|
+
n_print: int = 1
|
|
86
|
+
style: str = "cg"
|
|
87
|
+
rotation_matrix: Optional[Union[list, np.ndarray]] = None
|