Skip to content

Commit f490494

Browse files
Add optional Voigt order output, test written output
1 parent 7c04f5b commit f490494

File tree

2 files changed

+106
-8
lines changed

2 files changed

+106
-8
lines changed

janus_core/calculations/elasticity.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class Elasticity(BaseCalculation):
7474
write_kwargs
7575
Keyword arguments to pass to ase.io.write to save generated structures.
7676
Default is {}.
77+
write_voigt
78+
Whether to write out in Voigt notation, Default is True.
7779
7880
Attributes
7981
----------
@@ -102,6 +104,7 @@ def __init__(
102104
write_results: bool = True,
103105
write_structures: bool = False,
104106
write_kwargs: OutputKwargs | None = None,
107+
write_voigt: bool = True,
105108
) -> None:
106109
"""
107110
Initialise class.
@@ -149,6 +152,8 @@ def __init__(
149152
write_kwargs
150153
Keyword arguments to pass to ase.io.write to save generated structures.
151154
Default is {}.
155+
write_voigt
156+
Whether to write out in Voigt notation, Default is True.
152157
"""
153158
read_kwargs, minimize_kwargs, write_kwargs = none_to_dict(
154159
read_kwargs, minimize_kwargs, write_kwargs
@@ -160,6 +165,7 @@ def __init__(
160165
self.write_results = write_results
161166
self.write_structures = write_structures
162167
self.write_kwargs = write_kwargs
168+
self.write_voigt = write_voigt
163169

164170
if (
165171
(self.minimize or self.minimize_all)
@@ -286,7 +292,13 @@ def run(self) -> ElasticTensor:
286292
"homogeneous_poisson",
287293
)
288294
]
289-
for cijkl in self.elastic_tensor.flatten():
295+
296+
vals = (
297+
self.elastic_tensor.voigt
298+
if self.write_voigt
299+
else self.elastic_tensor
300+
)
301+
for cijkl in vals.flatten():
290302
values.append(cijkl)
291303
print(" ".join(map(str, values)), file=out)
292304
return self.elastic_tensor
@@ -311,21 +323,18 @@ def _calculate_elasticity(self) -> None:
311323
]
312324
for i, deformed_structure in enumerate(self.deformed_structures):
313325
deformed_structure.calc = copy(self.struct.calc)
326+
progress = f"{i} / {len(self.deformed_structures)}"
314327
if self.minimize_all:
315328
if self.logger:
316329
self.logger.info(
317-
"Minimising deformed structure %u / %u",
318-
i,
319-
len(self.deformed_structures),
330+
"Calculating stress for deformed structure " + progress
320331
)
321332
optimizer = GeomOpt(deformed_structure, **self.minimize_kwargs)
322333
optimizer.run()
323334

324335
if self.logger:
325336
self.logger.info(
326-
"Calculating stress for deformed structure %u / %u",
327-
i,
328-
len(self.deformed_structures),
337+
"Calculating stress for deformed structure " + progress,
329338
)
330339

331340
# Always append first original structure

tests/test_elasticity.py

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,110 @@
55
from pathlib import Path
66

77
from ase.build import bulk
8+
import numpy as np
89
from pytest import approx
910

1011
from janus_core.calculations.elasticity import Elasticity
1112
from janus_core.helpers.mlip_calculators import choose_calculator
13+
from tests.utils import assert_log_contains
1214

1315
DATA_PATH = Path(__file__).parent / "data"
1416
MODEL_PATH = Path(__file__).parent / "models" / "mace_mp_small.model"
1517

1618

1719
def test_calc_elasticity(tmp_path):
1820
"""Test calculating elasticity for Aluminium."""
21+
elasticity_path = tmp_path / "elasticity-elastic_tensor.dat"
22+
log_file = tmp_path / "elasticity.log"
23+
1924
struct = bulk("Al", crystalstructure="fcc")
2025
struct.calc = choose_calculator(arch="mace_mp", model=MODEL_PATH)
2126

22-
elasticity = Elasticity(struct, file_prefix=tmp_path / "elasticity")
27+
elasticity = Elasticity(
28+
struct, file_prefix=tmp_path / "elasticity", log_kwargs={"filename": log_file}
29+
)
2330
elastic_tensor = elasticity.run()
2431

2532
assert elastic_tensor.k_reuss == approx(80.34637735135381, rel=1e-3)
33+
34+
# Check geometry optimization run by default
35+
assert_log_contains(
36+
log_file,
37+
includes=["Using filter", "Using optimizer", "Starting geometry optimization"],
38+
)
39+
40+
assert elasticity_path.exists()
41+
written_elasticity = np.loadtxt(elasticity_path)
42+
# Defaulting to 6x6 Voigt notation
43+
assert len(written_elasticity) == 45
44+
45+
for i, prop in enumerate(
46+
(
47+
"k_reuss",
48+
"k_voigt",
49+
"k_vrh",
50+
"g_reuss",
51+
"g_voigt",
52+
"g_vrh",
53+
"y_mod",
54+
"universal_anisotropy",
55+
"homogeneous_poisson",
56+
)
57+
):
58+
assert elastic_tensor.property_dict[prop] == approx(
59+
written_elasticity[i], rel=1e-3
60+
)
61+
62+
assert written_elasticity[9:] == approx(elastic_tensor.voigt.flatten(), rel=1e-3)
63+
64+
65+
def test_no_optimize_no_write_voigt(tmp_path):
66+
"""Test calculating elasticity for Aluminium without optimization."""
67+
elasticity_path = tmp_path / "elasticity-elastic_tensor.dat"
68+
log_file = tmp_path / "elasticity.log"
69+
70+
struct = bulk("Al", crystalstructure="fcc")
71+
struct.calc = choose_calculator(arch="mace_mp", model=MODEL_PATH)
72+
73+
elasticity = Elasticity(
74+
struct,
75+
file_prefix=tmp_path / "elasticity",
76+
log_kwargs={"filename": log_file},
77+
minimize=False,
78+
write_voigt=False,
79+
)
80+
elastic_tensor = elasticity.run()
81+
82+
assert elastic_tensor.k_reuss == approx(80.34637735135381, rel=1e-3)
83+
84+
# Check geometry optimization run by default
85+
assert_log_contains(
86+
log_file,
87+
excludes=["Using filter", "Using optimizer", "Starting geometry optimization"],
88+
)
89+
90+
assert elasticity_path.exists()
91+
written_elasticity = np.loadtxt(elasticity_path)
92+
# Selected to full tensor 3x3x3x3
93+
assert len(written_elasticity) == 90
94+
95+
assert written_elasticity[0] == approx(elastic_tensor.k_reuss, rel=1e-3)
96+
97+
for i, prop in enumerate(
98+
(
99+
"k_reuss",
100+
"k_voigt",
101+
"k_vrh",
102+
"g_reuss",
103+
"g_voigt",
104+
"g_vrh",
105+
"y_mod",
106+
"universal_anisotropy",
107+
"homogeneous_poisson",
108+
)
109+
):
110+
assert elastic_tensor.property_dict[prop] == approx(
111+
written_elasticity[i], rel=1e-3
112+
)
113+
114+
assert written_elasticity[9:] == approx(elastic_tensor.flatten(), rel=1e-3)

0 commit comments

Comments
 (0)