Skip to content

Commit e14d746

Browse files
committed
review comments
1 parent 8fb6d0e commit e14d746

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

examples/elastic_constants.jl

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# # Elastic constants
22

3-
# We compute *clamped-ion* elastic constants of a crystal using the algorithmic differentiation
4-
# density-functional perturbation theory (AD-DFPT) approach as introduced in [^SPH25].
3+
# We compute *clamped-ion* elastic constants of a crystal using
4+
# the algorithmic differentiation density-functional perturbation theory (AD-DFPT) approach
5+
# as introduced in [^SPH25].
56
#
67
# [^SPH25]:
78
# Schmitz, N. F., Ploumhans, B., & Herbst, M. F. (2025)
89
# *Algorithmic differentiation for plane-wave DFT: materials design, error control and learning model parameters.*
910
# [arXiv:2509.07785](https://arxiv.org/abs/2509.07785)
10-
11+
#
1112
# We consider a crystal in its equilibrium configuration, where all atomic forces
1213
# and stresses vanish. Homogeneous strains $η$ are then applied
1314
# relative to this relaxed structure.
@@ -24,8 +25,8 @@
2425
# and is tabulated in standard references (eg. Table 9 in [^Nye1985]).
2526
# This sparsity can be used a priori to reduce the number of strain patterns
2627
# that need to be probed to extract all independent components of $C$.
27-
# For example, cubic crystals have only three independent elastic constants $C_{11}$, $C_{12}$ and $C_{44}$,
28-
# with the pattern
28+
# For example, cubic crystals have only three independent elastic constants
29+
# $C_{11}$, $C_{12}$ and $C_{44}$, with the pattern
2930
# ```math
3031
# C = \begin{pmatrix}
3132
# C_{11} & C_{12} & C_{12} & 0 & 0 & 0 \\
@@ -84,7 +85,7 @@ function symmetries_from_strain(model0, voigt_strain)
8485
model.symmetries
8586
end
8687

87-
strain_pattern = [1., 0., 0., 1., 0., 0.]; # should yield [c11, c12, c12, c44, 0, 0] for cubic crystal
88+
strain_pattern = [1., 0., 0., 1., 0., 0.]; # recovers [c11, c12, c12, c44, 0, 0]
8889

8990
# For elastic constants beyond the bulk modulus, symmetry-breaking strains
9091
# are required. That is, the symmetry group of the crystal is reduced.
@@ -101,22 +102,31 @@ function stress_from_strain(model0, voigt_strain; symmetries, Ecut, kgrid, tol)
101102
DFTK.full_stress_to_voigt(compute_stresses_cart(scfres))
102103
end
103104

104-
stress_fn(voigt_strain) = stress_from_strain(model0, voigt_strain; symmetries=symmetries_strain, Ecut, kgrid, tol)
105-
stress, (dstress,) = value_and_pushforward(stress_fn, AutoForwardDiff(), zeros(6), (strain_pattern,));
106-
@show stress dstress;
105+
stress_fn(voigt_strain) = stress_from_strain(model0, voigt_strain;
106+
symmetries=symmetries_strain,
107+
Ecut, kgrid, tol)
108+
stress, (dstress,) = value_and_pushforward(stress_fn, AutoForwardDiff(),
109+
zeros(6), (strain_pattern,));
110+
111+
# We can inspect the stress to verify it is small (close to equilibrium):
112+
stress
107113

108-
c11 = uconvert(u"GPa", dstress[1] * u"hartree" / u"bohr"^3)
109-
c12 = uconvert(u"GPa", dstress[2] * u"hartree" / u"bohr"^3)
110-
c44 = uconvert(u"GPa", dstress[4] * u"hartree" / u"bohr"^3)
111-
@show c11 c12 c44;
114+
# The response of the stress to `strain_pattern` contains the elastic constants
115+
# in atomic units, with the expected pattern $(c11, c12, c12, c44, 0, 0)$:
116+
dstress
112117

113-
# These results can be compared directly to finite differences of the stress-strain relation:
118+
# Convert to GPa:
119+
println("C11: ", uconvert(u"GPa", dstress[1] * u"hartree" / u"bohr"^3))
120+
println("C12: ", uconvert(u"GPa", dstress[2] * u"hartree" / u"bohr"^3))
121+
println("C44: ", uconvert(u"GPa", dstress[4] * u"hartree" / u"bohr"^3))
122+
123+
# These results can be compared directly to finite differences of the stress_fn:
114124
h = 1e-3
115125
dstress_fd = (stress_fn(h * strain_pattern) - stress_fn(-h * strain_pattern)) / 2h
116-
c11_fd = uconvert(u"GPa", dstress_fd[1] * u"hartree" / u"bohr"^3)
117-
c12_fd = uconvert(u"GPa", dstress_fd[2] * u"hartree" / u"bohr"^3)
118-
c44_fd = uconvert(u"GPa", dstress_fd[4] * u"hartree" / u"bohr"^3)
119-
@show c11_fd c12_fd c44_fd;
126+
println("C11 (FD): ", uconvert(u"GPa", dstress_fd[1] * u"hartree" / u"bohr"^3))
127+
println("C12 (FD): ", uconvert(u"GPa", dstress_fd[2] * u"hartree" / u"bohr"^3))
128+
println("C44 (FD): ", uconvert(u"GPa", dstress_fd[4] * u"hartree" / u"bohr"^3))
129+
120130

121131
# Here are AD-DFPT results from increasing discretization parameters:
122132
#
@@ -127,7 +137,9 @@ c44_fd = uconvert(u"GPa", dstress_fd[4] * u"hartree" / u"bohr"^3)
127137
# | 24 | [8, 8, 8] | 153.26 | 56.82 | 99.97 |
128138
# | 24 | [14, 14, 14] | 153.03 | 56.71 | 100.09 |
129139
#
130-
# For comparison, Materials Project for PBE *relaxed-ion* elastic constants of silicon [mp-149](https://next-gen.materialsproject.org/materials/mp-149):
140+
# For comparison, Materials Project for PBE *relaxed-ion* elastic constants of
141+
# silicon [mp-149](https://next-gen.materialsproject.org/materials/mp-149):
131142
# c11 = 153 GPa, c12 = 57 GPa, c44 = 74 GPa.
132-
# Note the discrepancy in c44, which is due to us not yet including ionic relaxation in this example.
143+
# Note the discrepancy in c44, which is due to us not yet including
144+
# ionic relaxation in this example.
133145

0 commit comments

Comments
 (0)