Skip to content

Commit 124cc2c

Browse files
Merge branch 'master' into fast_w_update
2 parents 952de96 + 120dea5 commit 124cc2c

43 files changed

Lines changed: 9985 additions & 731 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/python-testsuite.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ jobs:
4949
run: |
5050
export OMP_NUM_THREADS=1
5151
cd tests
52+
rm -rf __pycache__
5253
# Test excluding very long running tests
5354
pytest -v -m "not release"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# generated using pymatgen
2+
data_Au
3+
_symmetry_space_group_name_H-M 'P 1'
4+
_cell_length_a 2.94954603
5+
_cell_length_b 2.94954603
6+
_cell_length_c 2.94954603
7+
_cell_angle_alpha 60.00000000
8+
_cell_angle_beta 60.00000000
9+
_cell_angle_gamma 60.00000000
10+
_symmetry_Int_Tables_number 1
11+
_chemical_formula_structural Au
12+
_chemical_formula_sum Au1
13+
_cell_volume 18.14473112
14+
_cell_formula_units_Z 1
15+
loop_
16+
_symmetry_equiv_pos_site_id
17+
_symmetry_equiv_pos_as_xyz
18+
1 'x, y, z'
19+
loop_
20+
_atom_site_type_symbol
21+
_atom_site_label
22+
_atom_site_symmetry_multiplicity
23+
_atom_site_fract_x
24+
_atom_site_fract_y
25+
_atom_site_fract_z
26+
_atom_site_occupancy
27+
Au Au0 1 0.00000000 0.00000000 0.00000000 1
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Import the sscha code
2+
import sscha, sscha.Ensemble, sscha.SchaMinimizer, sscha.Relax, sscha.Utilities
3+
4+
# Import the cellconstructor library to manage phonons
5+
import cellconstructor as CC, cellconstructor.Phonons
6+
import cellconstructor.Structure, cellconstructor.calculators
7+
8+
# Import the force field of Gold
9+
import ase, ase.calculators
10+
from ase.calculators.emt import EMT
11+
12+
# Import numerical and general pourpouse libraries
13+
import numpy as np, matplotlib.pyplot as plt
14+
import sys, os
15+
16+
17+
18+
"""
19+
Here we load the primitive cell of Gold from a cif file.
20+
And we use CellConstructor to compute phonons from finite differences.
21+
The phonons are computed on a q-mesh 4x4x4
22+
"""
23+
24+
gold_structure = CC.Structure.Structure()
25+
gold_structure.read_generic_file("Au.cif")
26+
27+
# Get the force field for gold
28+
calculator = EMT()
29+
30+
# Relax the gold structure (useless since for symmetries it is already relaxed)
31+
relax = CC.calculators.Relax(gold_structure, calculator)
32+
gold_structure_relaxed = relax.static_relax()
33+
34+
# Compute the harmonic phonons
35+
# NOTE: if the code is run with mpirun, the calculation goes in parallel
36+
gold_harmonic_dyn = CC.Phonons.compute_phonons_finite_displacements(gold_structure_relaxed, calculator, supercell = (4,4,4))
37+
38+
# Impose the symmetries and
39+
# save the dynamical matrix in the quantum espresso format
40+
gold_harmonic_dyn.Symmetrize()
41+
gold_harmonic_dyn.save_qe("harmonic_dyn")
42+
43+
44+
# If the dynamical matrix has imaginary frequencies, remove them
45+
gold_harmonic_dyn.ForcePositiveDefinite()
46+
47+
"""
48+
gold_harmonic_dyn is ready to start the SSCHA calculation.
49+
50+
Now let us initialize the ensemble, and the calculation at 300 K.
51+
We will run a NVT calculation, using 100 configurations at each step
52+
"""
53+
54+
TEMPERATURE = 300
55+
N_CONFIGS = 50
56+
MAX_ITERATIONS = 20
57+
58+
# Initialize the random ionic ensemble
59+
ensemble = sscha.Ensemble.Ensemble(gold_harmonic_dyn, TEMPERATURE)
60+
61+
# Initialize the free energy minimizer
62+
minim = sscha.SchaMinimizer.SSCHA_Minimizer(ensemble)
63+
minim.set_minimization_step(0.01)
64+
65+
# Initialize the NVT simulation
66+
relax = sscha.Relax.SSCHA(minim, calculator, N_configs = N_CONFIGS,
67+
max_pop = MAX_ITERATIONS)
68+
69+
# Define the I/O operations
70+
# To save info about the free energy minimization after each step
71+
ioinfo = sscha.Utilities.IOInfo()
72+
ioinfo.SetupSaving("minim_info")
73+
relax.setup_custom_functions(custom_function_post = ioinfo.CFP_SaveAll)
74+
75+
76+
# Run the NVT simulation (save the stress to compute the pressure)
77+
relax.relax(get_stress = True)
78+
79+
# If instead you want to run a NPT simulation, use
80+
# The target pressure is given in GPa.
81+
#relax.vc_relax(target_press = 0)
82+
83+
# You can also run a mixed simulation (NVT) but with variable lattice parameters
84+
#relax.vc_relax(fix_volume = True)
85+
86+
# Now we can save the final dynamical matrix
87+
# And print in stdout the info about the minimization
88+
relax.minim.finalize()
89+
relax.minim.dyn.save_qe("sscha_T{}_dyn".format(TEMPERATURE))
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import cellconstructor as CC, cellconstructor.Phonons, cellconstructor.ForceTensor
2+
import ase, ase.dft.kpoints
3+
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
import matplotlib.cm as cm
7+
import matplotlib.colors as colors
8+
9+
import sys, os
10+
11+
NQIRR = 13
12+
#CMAP = "Spectral_r"
13+
PATH = "GXWXKGL"
14+
N_POINTS = 1000
15+
16+
SPECIAL_POINTS = {"G": [0,0,0],
17+
"X": [0, .5, .5],
18+
"L": [.5, .5, .5],
19+
"W": [.25, .75, .5],
20+
"K": [3/8., 3/4., 3/8.]}
21+
22+
# Load the harmonic and sscha phonons
23+
harmonic_dyn = CC.Phonons.Phonons('harmonic_dyn', NQIRR)
24+
sscha_dyn = CC.Phonons.Phonons('sscha_T300_dyn', NQIRR)
25+
26+
# Get the band path
27+
qpath, data = CC.Methods.get_bandpath(harmonic_dyn.structure.unit_cell,
28+
PATH,
29+
SPECIAL_POINTS,
30+
N_POINTS)
31+
xaxis, xticks, xlabels = data # Info to plot correclty the x axis
32+
33+
# Get the phonon dispersion along the path
34+
harmonic_dispersion = CC.ForceTensor.get_phonons_in_qpath(harmonic_dyn, qpath)
35+
sscha_dispersion = CC.ForceTensor.get_phonons_in_qpath(sscha_dyn, qpath)
36+
37+
nmodes = harmonic_dyn.structure.N_atoms * 3
38+
39+
# Plot the two dispersions
40+
plt.figure(dpi = 150)
41+
ax = plt.gca()
42+
43+
for i in range(nmodes):
44+
lbl=None
45+
lblsscha = None
46+
if i == 0:
47+
lbl = 'Harmonic'
48+
lblsscha = 'SSCHA'
49+
50+
ax.plot(xaxis, harmonic_dispersion[:,i], color = 'k', ls = 'dashed', label = lbl)
51+
ax.plot(xaxis, sscha_dispersion[:,i], color = 'r', label = lblsscha)
52+
53+
# Plot vertical lines for each high symmetry points
54+
for x in xticks:
55+
ax.axvline(x, 0, 1, color = "k", lw = 0.4)
56+
ax.axhline(0, 0, 1, color = 'k', ls = ':', lw = 0.4)
57+
58+
ax.legend()
59+
60+
# Set the x labels to the high symmetry points
61+
ax.set_xticks(xticks)
62+
ax.set_xticklabels(xlabels)
63+
64+
ax.set_xlabel("Q path")
65+
ax.set_ylabel("Phonons [cm-1]")
66+
67+
plt.tight_layout()
68+
plt.savefig("dispersion.png")
69+
plt.show()
70+
71+
72+
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import cellconstructor as CC, cellconstructor.Phonons
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
5+
import scipy, scipy.optimize
6+
7+
import sys, os
8+
9+
"""
10+
This simple scripts plot the thermal expansion.
11+
It either directly plots the file produced at the end of thermal_expansion.py
12+
or it processes the dynamical matrices generated throughout the minimization.
13+
14+
It also fits the V(T) cuve and estimates the volumetric thermal expansion coefficient
15+
16+
alpha = dV/dT / V
17+
18+
At 300 K
19+
"""
20+
21+
22+
# Load all the dynamical matrices and compute volume
23+
DIRECTORY = "thermal_expansion"
24+
FILE = os.path.join(DIRECTORY, "thermal_expansion.dat")
25+
26+
27+
# Check if the file with the thermal expansion data exists
28+
if not os.path.exists( FILE):
29+
# If the simulation is not ended, load the volume from the dynamical matrices
30+
31+
# Get the dynamical matrices
32+
all_dyn_files = [x for x in os.listdir(DIRECTORY) if "sscha" in x and x.endswith("dyn1")]
33+
temperatures = [float(x.split("_")[-2].replace("T", "")) for x in all_dyn_files]
34+
35+
# Now sort in order of temperature
36+
sortmask = np.argsort(temperatures)
37+
all_dyn_files = [all_dyn_files[x] for x in sortmask]
38+
temperatures = np.sort(temperatures)
39+
40+
volumes = np.zeros_like(temperatures)
41+
42+
for i, fname in enumerate(all_dyn_files):
43+
# Load the dynamical matrix
44+
# The full_name means that we specify the name including the tail 1
45+
dyn = CC.Phonons.Phonons(os.path.join(DIRECTORY, fname), full_name = True)
46+
volumes[i] = dyn.get_volumes()
47+
48+
else:
49+
# Load the data from the final data file
50+
temperatures, volumes = np.loadtxt(FILE, unpack = True)
51+
52+
53+
# Prepare the figure and plot the V(T) from the sscha data
54+
plt.figure(dpi = 150)
55+
plt.scatter(temperatures, volumes, label = "SSCHA data", color = 'r')
56+
57+
# Fit the data with a quadratic curve
58+
def parabola(x, a, b, c):
59+
return a + b*x + c*x**2
60+
def diff_parab(x, a, b, c):
61+
return b + 2*c*x
62+
63+
popt, pcov = scipy.optimize.curve_fit(parabola, temperatures, volumes,
64+
p0 = [0,0,0])
65+
66+
# Evaluate the volume thermal expansion
67+
vol_thermal_expansion = diff_parab(300, *popt) / parabola(300, *popt)
68+
print("Vol thermal expansion: {} x 10^6 K^-1".format(vol_thermal_expansion * 1e6))
69+
plt.text(0.6, 0.2, r"$\alpha_v = "+"{:.1f}".format(vol_thermal_expansion*1e6)+r"\times 10^6 $ K$^{-1}$",
70+
transform = plt.gca().transAxes)
71+
72+
73+
# Plot the fit
74+
_t_ = np.linspace(np.min(temperatures), np.max(temperatures), 1000)
75+
plt.plot(_t_, parabola(_t_, *popt), label = "Fit", color = 'k', zorder = 0)
76+
77+
# Adjust the plot adding labels, legend, and saving in eps
78+
plt.xlabel("Temperature [K]")
79+
plt.ylabel(r"Volume [$\AA^3$]")
80+
plt.legend()
81+
plt.tight_layout()
82+
plt.savefig("thermal_expansion.png")
83+
plt.show()
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Import the sscha code
2+
import sscha, sscha.Ensemble, sscha.SchaMinimizer, sscha.Relax, sscha.Utilities
3+
4+
# Import the cellconstructor library to manage phonons
5+
import cellconstructor as CC, cellconstructor.Phonons
6+
import cellconstructor.Structure, cellconstructor.calculators
7+
8+
# Import the force field of Gold
9+
import ase, ase.calculators
10+
from ase.calculators.emt import EMT
11+
12+
# Import numerical and general pourpouse libraries
13+
import numpy as np, matplotlib.pyplot as plt
14+
import sys, os
15+
16+
17+
"""
18+
You need first to run the
19+
get_gold_free_energy.py
20+
21+
Here we use NPT simulation to compute the gold thermal expansion.
22+
"""
23+
24+
# Define the temperature range (in K)
25+
T_START = 300
26+
T_END = 1000
27+
DT = 50
28+
29+
N_CONFIGS = 50
30+
MAX_ITERATIONS = 10
31+
32+
# Import the gold force field
33+
calculator = EMT()
34+
35+
# Import the starting dynamical matrix (final result of get_gold_free_energy.py)
36+
dyn = CC.Phonons.Phonons("sscha_T300_dyn", nqirr = 13)
37+
38+
# Create the directory on which to store the output
39+
DIRECTORY = "thermal_expansion"
40+
if not os.path.exists(DIRECTORY):
41+
os.makedirs("thermal_expansion")
42+
43+
# We cycle over several temperatures
44+
t = T_START
45+
46+
47+
volumes = []
48+
temperatures = []
49+
while t <= T_END:
50+
# Change the temperature
51+
ensemble = sscha.Ensemble.Ensemble(dyn, t)
52+
minim = sscha.SchaMinimizer.SSCHA_Minimizer(ensemble)
53+
minim.set_minimization_step(0.1)
54+
55+
relax = sscha.Relax.SSCHA(minim, calculator, N_configs = N_CONFIGS,
56+
max_pop = MAX_ITERATIONS)
57+
58+
# Setup the I/O
59+
ioinfo = sscha.Utilities.IOInfo()
60+
ioinfo.SetupSaving( os.path.join(DIRECTORY, "minim_t{}".format(t)))
61+
relax.setup_custom_functions( custom_function_post = ioinfo.CFP_SaveAll)
62+
63+
64+
# Run the NPT simulation
65+
relax.vc_relax(target_press = 0)
66+
67+
# Save the volume and temperature
68+
volumes.append(relax.minim.dyn.structure.get_volume())
69+
temperatures.append(t)
70+
71+
# Start the next simulation from the results
72+
relax.minim.dyn.save_qe( os.path.join(DIRECTORY, "sscha_T{}_dyn".format(t)))
73+
dyn = relax.minim.dyn
74+
relax.minim.finalize()
75+
76+
# Update the temperature
77+
t += DT
78+
79+
# Save the thermal expansion
80+
np.savetxt(os.path.join(DIRECTORY, "thermal_expansion.dat"),
81+
np.transpose([temperatures, volumes]),
82+
header = "Temperature [K]; Volume [A^3]")
83+
84+
85+
86+
87+
88+

0 commit comments

Comments
 (0)