elastic-ase 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. elastic_ase-0.0.1/LICENSE +10 -0
  2. elastic_ase-0.0.1/PKG-INFO +364 -0
  3. elastic_ase-0.0.1/README.md +332 -0
  4. elastic_ase-0.0.1/elastic_ase/__init__.py +32 -0
  5. elastic_ase-0.0.1/elastic_ase/_spglib.py +21 -0
  6. elastic_ase-0.0.1/elastic_ase/analysis.py +130 -0
  7. elastic_ase-0.0.1/elastic_ase/auto.py +233 -0
  8. elastic_ase-0.0.1/elastic_ase/average.py +82 -0
  9. elastic_ase-0.0.1/elastic_ase/calculator.py +906 -0
  10. elastic_ase-0.0.1/elastic_ase/cli.py +260 -0
  11. elastic_ase-0.0.1/elastic_ase/codes.py +153 -0
  12. elastic_ase-0.0.1/elastic_ase/deformations.py +20 -0
  13. elastic_ase-0.0.1/elastic_ase/orientation.py +108 -0
  14. elastic_ase-0.0.1/elastic_ase/plotting.py +35 -0
  15. elastic_ase-0.0.1/elastic_ase/properties.py +53 -0
  16. elastic_ase-0.0.1/elastic_ase/report.py +69 -0
  17. elastic_ase-0.0.1/elastic_ase/results.py +51 -0
  18. elastic_ase-0.0.1/elastic_ase/rundir.py +148 -0
  19. elastic_ase-0.0.1/elastic_ase/solvers.py +31 -0
  20. elastic_ase-0.0.1/elastic_ase/symmetry.py +152 -0
  21. elastic_ase-0.0.1/elastic_ase/systems.py +322 -0
  22. elastic_ase-0.0.1/elastic_ase.egg-info/PKG-INFO +364 -0
  23. elastic_ase-0.0.1/elastic_ase.egg-info/SOURCES.txt +30 -0
  24. elastic_ase-0.0.1/elastic_ase.egg-info/dependency_links.txt +1 -0
  25. elastic_ase-0.0.1/elastic_ase.egg-info/entry_points.txt +2 -0
  26. elastic_ase-0.0.1/elastic_ase.egg-info/requires.txt +10 -0
  27. elastic_ase-0.0.1/elastic_ase.egg-info/top_level.txt +1 -0
  28. elastic_ase-0.0.1/pyproject.toml +53 -0
  29. elastic_ase-0.0.1/setup.cfg +4 -0
  30. elastic_ase-0.0.1/tests/test_elastic.py +467 -0
  31. elastic_ase-0.0.1/tests/test_features.py +184 -0
  32. elastic_ase-0.0.1/tests/test_workflows.py +328 -0
@@ -0,0 +1,10 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pranav Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10
+
@@ -0,0 +1,364 @@
1
+ Metadata-Version: 2.4
2
+ Name: elastic-ase
3
+ Version: 0.0.1
4
+ Summary: Second-order elastic constants from energy-strain calculations with ASE calculators
5
+ Author: Pranav Kumar
6
+ License-Expression: MIT
7
+ Project-URL: Source, https://github.com/prnvrvs/elastic_ase
8
+ Project-URL: Documentation, https://prnvrvs.github.io/elastic_ase/
9
+ Project-URL: Issues, https://github.com/prnvrvs/elastic_ase/issues
10
+ Keywords: elastic constants,stiffness,ASE,DFT,VASP,Quantum ESPRESSO,materials science
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Physics
19
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: numpy
24
+ Requires-Dist: ase
25
+ Requires-Dist: spglib>=2.4
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest; extra == "test"
28
+ Provides-Extra: doc
29
+ Requires-Dist: sphinx; extra == "doc"
30
+ Requires-Dist: sphinx-book-theme; extra == "doc"
31
+ Dynamic: license-file
32
+
33
+ # elastic_ase
34
+
35
+ Second-order elastic constants ($C_{ij}$) from energy–strain calculations with ASE
36
+ calculators. elastic_ase is the ASE counterpart of
37
+ [elastic_vasp](https://github.com/prnvrvs/elastic_vasp): the same deformation tables and
38
+ analysis, with the energies from an ASE calculator (run in memory) or from DFT run folders
39
+ (VASP, Quantum ESPRESSO) that elastic_ase writes and reads back.
40
+
41
+ **Documentation:** https://prnvrvs.github.io/elastic_ase/
42
+
43
+ ## Features
44
+
45
+ - Symmetry detection with spglib and deformation tables for all crystal systems: cubic,
46
+ hexagonal, tetragonal (4/mmm and 4/m), trigonal (with $C_{14}$ and $C_{15}$),
47
+ orthorhombic, monoclinic, triclinic; an orientation-aware automatic mode.
48
+ - The structure is rotated rigidly into the standard setting (cell, atoms and per-atom data
49
+ unchanged); without rotation, an exact check warns when a table does not fit the
50
+ orientation.
51
+ - Energies from an ASE calculator (`calculate()`), or run folders for a DFT code with
52
+ done / failed / pending tracking and restarts (`code="vasp"` or `"qe"`, `write_inputs`,
53
+ `run_jobs`, `status`, `read_results`).
54
+ - Results: stiffness matrix, Born stability, Voigt–Reuss–Hill averages, sound velocities,
55
+ Debye temperature, residual pressure of the reference cell, energy–strain fit plots,
56
+ save/load; directional properties and plots with
57
+ [elastic-vis](https://github.com/prabhat7iitm/elastic-vis).
58
+ - Command line tool (`elastic-ase`) for EMT, GRACE or any calculator given as `-c module:function`.
59
+
60
+ ## What is tested
61
+
62
+ - All tables recover a known stiffness matrix exactly from a synthetic quadratic energy, and
63
+ they are identical to elastic_vasp's.
64
+ - With EMT: relaxed alloy structures of every crystal family give the same constants from
65
+ the named table, the full triclinic fit and the automatic mode on randomly rotated copies.
66
+ - VASP: reading 19 real VASP 6 OUTCARs of fcc Al reproduces elastic_vasp's result
67
+ ($C_{11}$ = 106.6, $C_{12}$ = 63.4, $C_{44}$ = 28.9 GPa).
68
+ - Quantum ESPRESSO: input writing and output reading/convergence checks are tested on files,
69
+ **not yet with a real pw.x run through elastic_ase**.
70
+ - **Not tested here:** GRACE, MACE, CHGNet or other ML potentials (they should work like any
71
+ ASE calculator), ASE's `Vasp` calculator writing full inputs, `run_jobs` with a real DFT
72
+ code (tested with a stand-in program), other DFT codes, magnetic systems.
73
+
74
+ Please report problems on the [issue tracker](https://github.com/prnvrvs/elastic_ase/issues).
75
+
76
+ ---
77
+
78
+ ## Installation
79
+
80
+ ```bash
81
+ pip install elastic-ase # from PyPI (once the first release is published)
82
+ pip install "git+https://github.com/prnvrvs/elastic_ase.git" # current version from GitHub
83
+ ```
84
+
85
+ Optional, for the directional plots and extremes:
86
+ [elastic-vis](https://github.com/prabhat7iitm/elastic-vis) is not on PyPI, so install it
87
+ separately:
88
+
89
+ ```bash
90
+ pip install "git+https://github.com/prabhat7iitm/elastic-vis.git"
91
+ ```
92
+
93
+ For development (editable mode):
94
+ ```bash
95
+ git clone https://github.com/prnvrvs/elastic_ase.git
96
+ cd elastic_ase
97
+ pip install -e ".[test]"
98
+ ```
99
+
100
+ Requires Python 3.10 or newer.
101
+
102
+ ---
103
+
104
+ ## Command-Line Interface (CLI)
105
+
106
+ Calculate elastic constants directly from any structure file (CIF, POSCAR, XYZ, etc.):
107
+
108
+ ```bash
109
+ # Quick test using ASE's built-in EMT calculator:
110
+ elastic-ase POSCAR -c emt
111
+
112
+ # Using GRACE machine learning foundation model:
113
+ elastic-ase POSCAR -c grace -m GRACE-2L-OAM
114
+
115
+ # Symmetry check without running calculations:
116
+ elastic-ase POSCAR --check
117
+
118
+ # Save output to JSON, CSV, or plain 6x6 text matrix:
119
+ elastic-ase structure.cif -c grace -m GRACE-2L-OAM -o results.json
120
+ elastic-ase structure.cif -c grace -m GRACE-2L-OAM -o results.csv
121
+ elastic-ase structure.cif -c grace -m GRACE-2L-OAM -o C.txt
122
+
123
+ # Calculate and generate 2D & 3D directional plots (via elastic-vis):
124
+ elastic-ase structure.cif -c grace -m GRACE-2L-OAM --plot --Young --Shear --2D --3D --format png
125
+ elastic-ase structure.cif -c grace -m GRACE-2L-OAM --plot --Poisson --LC --format pdf
126
+ ```
127
+
128
+ ### CLI Options
129
+ - `--check`: Instant symmetry and orientation check without calculations.
130
+ - `-c, --calculator`: `emt` (default), `grace`, or any ASE calculator as `module:function`, e.g. `ase.calculators.emt:EMT` (tested with EMT only).
131
+ - `-m, --model`: GRACE model name (default: `GRACE-2L-OAM`).
132
+ - `-s, --symmetry`: Crystal symmetry family (`auto`, `cubic`, `hexagonal`, `tetragonal_1`, `tetragonal_2`, `orthogonal`, `trigonal_1`, `trigonal_2`, `monoclinic`, `triclinic`).
133
+ - `--strains`: Comma-separated strain list (default: `-0.01,-0.005,0.0,0.005,0.01`).
134
+ - `-o, --output`: File path to export results (`.json`, `.csv`, or `.txt` for 6x6 matrix).
135
+ - `-q, --quiet`: Suppress verbose terminal logs.
136
+ - `--plot`: Enable anisotropic property visualization.
137
+ - `--Young`, `--Shear`, `--Poisson`, `--LC`: Property selection.
138
+ - `--2D`, `--3D`: Dimension selection.
139
+ - `--format`: Image format (`png`, `pdf`, `svg`).
140
+ - `--style`: Path to custom JSON styling configuration.
141
+
142
+ ---
143
+
144
+ ## Python API Quickstart
145
+
146
+ ### 1. Minimal Example (Instant with EMT)
147
+ ```python
148
+ from ase.build import bulk
149
+ from ase.calculators.emt import EMT
150
+ from elastic_ase import ElasticASE
151
+
152
+ # Setup structure and calculator
153
+ # Use the relaxed lattice constant of *your* calculator: a pre-stressed cell biases
154
+ # the constants. 3.9943 A is the EMT equilibrium of Al (a = 4.05 A would be under
155
+ # 1.6 GPa of tension with EMT).
156
+ al = bulk("Al", "fcc", a=3.9943, cubic=True)
157
+ al.calc = EMT()
158
+
159
+ # Run ElasticASE (symmetry auto-detected)
160
+ el = ElasticASE(al)
161
+ res = el.calculate()
162
+
163
+ print("C11:", res["stiffness_matrix"][0, 0], "GPa")
164
+ print("C12:", res["stiffness_matrix"][0, 1], "GPa")
165
+ print("C44:", res["stiffness_matrix"][3, 3], "GPa")
166
+ print("Bulk Modulus K_VRH:", res["polycrystalline_averages"]["K_VRH"], "GPa")
167
+ print("Stable?", res["is_stable"])
168
+ ```
169
+
170
+ ### 2. With GRACE Foundation Models
171
+
172
+ Not tested here (GRACE is not installed in our test setup); it should work like any ASE
173
+ calculator. Relax the structure with GRACE first.
174
+
175
+ ```python
176
+ from ase.build import bulk
177
+ from tensorpotential.calculator import grace_fm
178
+ from elastic_ase import ElasticASE
179
+
180
+ calc = grace_fm("GRACE-2L-OAM")
181
+ co = bulk("Co", "hcp", a=2.498, c=4.053)
182
+ co.calc = calc
183
+
184
+ el = ElasticASE(co, symmetry="hexagonal")
185
+ res = el.calculate()
186
+ ```
187
+
188
+ ---
189
+
190
+ ## DFT codes: VASP, Quantum ESPRESSO, ... (Python API)
191
+
192
+ The calculations are independent single-point runs (13 for a cubic crystal with 5 strains;
193
+ the unstrained cell is run once). With a DFT code there are two ways to run them.
194
+
195
+ ### A. Let ASE run them, with run folders and restart
196
+
197
+ The run folders, saved energies and restarts are tested with a stand-in file-based
198
+ calculator; running ASE's `Vasp` calculator itself through elastic_ase has not been tested yet.
199
+
200
+ ```python
201
+ from ase.calculators.vasp import Vasp
202
+
203
+ atoms.calc = Vasp(xc="PBE", encut=520, kpts=(12, 12, 12), ismear=1, sigma=0.1,
204
+ ediff=1e-7, isif=2, ibrion=-1) # your own converged settings
205
+ el = ElasticASE(atoms)
206
+ results = el.calculate(workdir="elastic_runs")
207
+ ```
208
+
209
+ Each run gets its own folder (`elastic_runs/C11_C12_I/strain_+0.005000/`, ...), so every
210
+ OUTCAR is kept, and each energy is saved to `elastic_runs/energies.json` as soon as it is
211
+ computed. A run that crashes, or whose SCF did not converge (ASE's `converged = False`), is
212
+ recorded as failed; the other runs still go ahead and the failed ones are listed at the end.
213
+
214
+ To check and repeat only what is missing:
215
+
216
+ ```python
217
+ el.status("elastic_runs") # done / failed (with reason) / pending
218
+ el.is_complete("elastic_runs") # True when every run has a usable energy
219
+ el.missing("elastic_runs") # the failed and pending runs
220
+ el.run_pending("elastic_runs") # run only those (or runs=[...] for a chosen few)
221
+ results = el.calculate(workdir="elastic_runs") # fits once complete; runs nothing already done
222
+ ```
223
+
224
+ ### B. Run folders for the DFT code itself (e.g. on a cluster)
225
+
226
+ Tell ElasticConstants once which code you use (and, if it should run the jobs, the command);
227
+ every later step then knows what to write, which output to read and check, and what to run:
228
+
229
+ ```python
230
+ from ase.io import read
231
+ from elastic_ase import ElasticConstants
232
+
233
+ ec = ElasticConstants(read("POSCAR"), code="vasp", command="mpirun -np 16 vasp_std")
234
+ ec.write_inputs("runs", files={"INCAR": "INCAR", "KPOINTS": "KPOINTS", "POTCAR": "POTCAR"})
235
+ # -> runs/<deformation>/strain_<value>/{POSCAR, INCAR, KPOINTS, POTCAR}
236
+
237
+ ec.run_jobs("runs") # runs the command in every folder without a usable OUTCAR
238
+ ec.status("runs") # done / failed (unconverged, unreadable, wrong cell) / pending
239
+ ec.is_complete("runs") # True when every run has a usable OUTCAR
240
+ ec.missing("runs") # the failed and pending runs
241
+ ec.run_jobs("runs") # call again after fixing a problem: only missing runs are repeated
242
+ results = ec.read_results("runs")
243
+ ```
244
+
245
+ `run_jobs` runs the folders one after the other (each command's screen output goes to
246
+ `elastic_ase_run.log` in its folder). On a cluster, submit the folders as separate jobs
247
+ instead, then use the same `status`, `missing` (for `write_inputs(..., runs=...)` to
248
+ resubmit) and `read_results`.
249
+
250
+ | `code=` | writes | reads and checks | default `command` |
251
+ |---|---|---|---|
252
+ | `"vasp"` | POSCAR + your `files` (or full input from an ASE `Vasp` calculator) | `OUTCAR` (electronic convergence) | `vasp_std` |
253
+ | `"qe"` | `espresso.pwi` from an ASE `Espresso` calculator | `espresso.pwo` (SCF convergence) | `pw.x -in espresso.pwi > espresso.pwo` |
254
+ | none | structure files (`format=`) + your `files` | `output=` (any file ASE reads) | `command=` |
255
+
256
+ `output="vasprun.xml"` reads another file than the code's default. The shortcuts
257
+ `vasp_input` / `vasp_status` / `vasp_output` and `qe_input` / `qe_status` / `qe_output` do the
258
+ same with the code fixed:
259
+
260
+ ```python
261
+ ec = ElasticConstants(read("POSCAR"))
262
+ ec.vasp_input("runs", incar="INCAR", kpoints="KPOINTS", potcar="POTCAR")
263
+ results = ec.vasp_output("runs")
264
+ ```
265
+
266
+ Your INCAR, KPOINTS and POTCAR are copied unchanged into every folder (use `ISIF = 2`,
267
+ `IBRION = -1` or a fixed-cell ionic relaxation); the POTCAR element order is checked against
268
+ the POSCAR. With an ASE `Vasp(...)` calculator attached and no files given, `vasp_input`
269
+ writes the full input from the calculator instead.
270
+
271
+ For Quantum ESPRESSO the input is written from an ASE `Espresso` calculator (its
272
+ pseudopotentials, k-points and `input_data` are used for every run):
273
+
274
+ ```python
275
+ from ase.calculators.espresso import Espresso, EspressoProfile
276
+
277
+ atoms.calc = Espresso(profile=EspressoProfile(command="pw.x", pseudo_dir="pseudo"),
278
+ pseudopotentials={"Al": "Al.pbe-n-kjpaw_psl.1.0.0.UPF"},
279
+ input_data={"system": {"ecutwfc": 60, "occupations": "smearing",
280
+ "smearing": "mv", "degauss": 0.02}},
281
+ kpts=(12, 12, 12))
282
+ ec = ElasticConstants(atoms, code="qe", command="mpirun -np 16 pw.x -in espresso.pwi > espresso.pwo")
283
+ ec.write_inputs("runs") # runs/<run>/espresso.pwi
284
+ ec.run_jobs("runs") # or submit the folders yourself
285
+ ec.status("runs") # done / failed (SCF not converged, unreadable) / pending
286
+ results = ec.read_results("runs") # read, check, fit, analyse
287
+ ```
288
+
289
+ Any other code ASE can read: `ElasticConstants(atoms, output="<output file>",
290
+ command="<command>")` with `write_inputs(workdir, format=..., files=...)`.
291
+
292
+ `read_results` checks that every output is readable, holds the strained cell its folder
293
+ expects (catches mixed-up folders) and, for VASP, that the electronic loop converged;
294
+ everything that is not usable is listed in one error. Use the same structure, symmetry and
295
+ strains for writing and reading.
296
+
297
+ Do your own convergence tests (cutoff, k-points, smearing): converge the elastic constants
298
+ themselves, not only the total energy, and use the same settings for every run. Relax the
299
+ reference structure first; with `optimizer=` (or `ISIF = 2` in VASP) the atoms are relaxed
300
+ inside each fixed strained cell.
301
+
302
+ ---
303
+
304
+ ## Results, checks and derived properties
305
+
306
+ `calculate()`, `vasp_output()`, `qe_output()` and `read_results()` all return the same
307
+ dictionary (also kept as `ec.results`):
308
+
309
+ | Key | Content |
310
+ |---|---|
311
+ | `stiffness_matrix` | 6×6 C in GPa (Cartesian frame, or standard setting with `frame="standard"`) |
312
+ | `independent_constants`, `standard_constants` | e.g. `C11`, `C12`, `C44` |
313
+ | `is_stable`, `stability_criteria` | Born stability (all eigenvalues of C positive) |
314
+ | `polycrystalline_averages` | Voigt/Reuss/Hill K, G, E, ν, Pugh ratio, Zener and universal anisotropy |
315
+ | `derived_properties` | density, longitudinal/transverse/mean sound velocity, Debye temperature (Anderson), Kleinman parameter (cubic), empirical Vickers hardness (Chen, Tian; rough) |
316
+ | `residual_stress` | residual pressure of the reference cell, from the linear terms of the fits |
317
+ | `directional_properties` | min/max of E, G, ν, linear compressibility (with elastic-vis) |
318
+ | `coefficients`, `r2_scores`, `energies` | fitted curvatures, fit quality, every energy |
319
+
320
+ Checks and tools:
321
+
322
+ - **Residual stress:** a reference cell that is not relaxed biases the constants by about the
323
+ same amount. ElasticASE estimates the residual pressure from the linear terms of the
324
+ energy–strain fits (no stress calculation needed, so it also works on OUTCARs) and warns
325
+ above 0.5 GPa. The linear term is taken from a cubic fit, so anharmonicity at large strains
326
+ does not show up as a fake pressure.
327
+ - **Look at the curves:** `ec.plot_fits("energy_strain.png")` plots every energy–strain curve
328
+ with its fit. Smooth parabolas are the first check; scatter or kinks point to unconverged
329
+ settings or a failed run.
330
+ - **Save and reload:** `ec.save("al.json")` stores the structure, settings and every energy
331
+ with the results; `ElasticASE.load("al.json")` redoes the whole analysis without running
332
+ anything.
333
+ - `ElasticConstants` is the same class under a more descriptive name:
334
+ `from elastic_ase import ElasticConstants; ec = ElasticConstants(atoms)`.
335
+
336
+ ---
337
+
338
+ ## Running Unit Tests
339
+
340
+ Run the test suite with standard `unittest`:
341
+ ```bash
342
+ python -m unittest discover -s tests
343
+ ```
344
+ Or with `pytest`:
345
+ ```bash
346
+ pytest tests/
347
+ ```
348
+
349
+ ---
350
+
351
+ ## Crystallographic Conventions & Common Pitfalls
352
+
353
+ Points where the orientation or setting of the crystal matters:
354
+
355
+ 1. **Trigonal Systems & "31m"-Type Groups ($P\bar{3}1m, P\bar{3}1c, P31m, P31c, P312, P3_1 12, P3_2 12$):**
356
+ - In standard settings with $a \parallel x$, the 2-fold axes in 31m-type groups are perpendicular to $a$, causing the stiffness matrix to have $C_{15}$ rather than $C_{14}$.
357
+ - **Solution in ElasticASE:** Automatic symmetry detection routes all trigonal crystals to `trigonal_2`. It fits both $C_{14}$ and $C_{15}$, so it does not depend on the in-plane orientation about $z$ (one extra deformation).
358
+
359
+ 2. **Orientation of the crystal (rotated cells, rhombohedral cells, monoclinic unique axis):**
360
+ - The named tables assume the crystal axes along fixed Cartesian directions: cubic and orthorhombic axes along $x, y, z$; the 3-, 4- or 6-fold axis along $z$; the monoclinic unique axis $b$ along $y$.
361
+ - **Default (`reorient=True`):** the structure is rigidly rotated into this standard setting. Only the orientation changes: your cell (primitive, conventional or supercell), the atoms and per-atom data (magnetic moments, charges, tags, constraints) are kept, so calculator settings such as the k-point mesh stay valid. A primitive rhombohedral cell stays primitive, with its 3-fold axis rotated onto $z$.
362
+ - **`reorient=False` with a named symmetry:** the crystal is used as given. ElasticASE checks exactly whether the chosen table can measure the crystal in this orientation and warns if not (the constants would be wrong).
363
+ - **`reorient=False` with `symmetry="auto"`:** the constants and deformations are derived from the crystal in its own orientation, so any orientation works.
364
+