Skip to content

Commit a1d24d0

Browse files
committed
Merge branch 'release/1.0.9'
2 parents b88839d + 63b42d3 commit a1d24d0

20 files changed

+1258
-300
lines changed

qha/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
__credits__ = {'Renata M. M. Wentzcovitch': '[email protected]'}
1111
__date__ = 'Feb 17, 2018'
1212
__maintainer__ = 'Tian Qin, Qi Zhang'
13-
__version__ = '1.0.8'
13+
__version__ = '1.0.9'

qha/bmf.py

Lines changed: 0 additions & 164 deletions
This file was deleted.

qha/calculator.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
from qha.unit_conversion import gpa_to_ry_b3, ry_b3_to_gpa, b3_to_a3, ry_to_j_mol, ry_to_ev
3030
from qha.v2p import v2p
3131

32+
# ===================== What can be exported? =====================
33+
__all__ = ['Calculator', 'SamePhDOSCalculator', 'DifferentPhDOSCalculator']
34+
3235

3336
class Calculator:
3437
def __init__(self, user_settings: Dict[str, Any]):
@@ -350,8 +353,8 @@ def vib_ry(self):
350353
v = np.empty(self.temperature_array.shape)
351354

352355
for i, t in enumerate(self.temperature_array):
353-
v[i] = same_phonon_dos.FreeEnergy(t, self.volume_energy.as_matrix(), self.degeneracies,
354-
self.q_weights, self.frequencies).total
356+
v[i] = same_phonon_dos.FreeEnergy(t, self.degeneracies, self.q_weights, self.volume_energy.as_matrix(),
357+
self.frequencies).total
355358
return v
356359

357360

@@ -415,7 +418,7 @@ def read_input(self):
415418
@LazyProperty
416419
def vib_ry(self):
417420
# We grep all the arguments once since they are being invoked for thousands of times, and will be an overhead.
418-
args = self.static_energies, self.degeneracies, self.q_weights, self.frequencies, self._volumes, \
421+
args = self.degeneracies, self.q_weights, self.static_energies, self._volumes, self.frequencies, \
419422
self.settings['static_only']
420423

421424
mat = np.empty((self.temperature_array.size, self._volumes.shape[1]))

qha/fitting.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python3
2+
"""
3+
:mod: bmf_all_t
4+
================================
5+
6+
.. module bmf_all_t
7+
:platform: Unix, Windows, Mac, Linux
8+
:synopsis:
9+
.. moduleauthor:: Tian Qin <[email protected]>
10+
"""
11+
12+
from typing import Optional
13+
14+
import numpy as np
15+
from numpy.linalg import inv
16+
17+
# ===================== What can be exported? =====================
18+
__all__ = ['polynomial_least_square_fitting', 'birch_murnaghan_finite_strain_fitting']
19+
20+
21+
def polynomial_least_square_fitting(x, y, new_x, order: Optional[int] = 3):
22+
"""
23+
Equation of calculate the coefficients are from
24+
`Wolfram Mathworld <http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html>`_.
25+
26+
:param x: Eulerian strain of calculated volumes (sparse)
27+
:param y: Free energy of these calculated volumes (sparse)
28+
:param new_x: Eulerian strain at a greater dense vector
29+
:param order: orders to fit Birch Murnaghan EOS
30+
:return: Free energy at a denser strain vector (denser volumes vector)
31+
"""
32+
order += 1 # The order needed is 1 more than ``numpy.vander`` default value.
33+
X = np.vander(x, order, increasing=True) # This will make a Vandermonde matrix that will be used in BM fitting.
34+
X_T = X.T
35+
a = inv(X_T @ X) @ X_T @ y
36+
new_y = np.vander(new_x, order, increasing=True) @ a
37+
return a, new_y
38+
39+
40+
def birch_murnaghan_finite_strain_fitting(eulerian_strain, free_energy, strain, order: Optional[int] = 3):
41+
"""
42+
Calculate the F(T,V) for given strain.
43+
44+
:param eulerian_strain: Eulerian strain of calculated volumes (sparse)
45+
:param free_energy: Free energy of these calculated volumes (sparse)
46+
:param strain: Eulerian strain at a greater dense vector
47+
:param order: orders to fit Birch Murnaghan EOS
48+
:return: Free energy at a dense (T, V) grid.
49+
"""
50+
temperature_amount, _ = free_energy.shape
51+
dense_volume_amount = len(strain)
52+
f_v_t = np.empty((temperature_amount, dense_volume_amount)) # Initialize the F(T,V) array
53+
54+
for i in range(temperature_amount):
55+
_, f_i = polynomial_least_square_fitting(eulerian_strain, free_energy[i], strain, order)
56+
f_v_t[i] = f_i
57+
return f_v_t

qha/grid_interpolation.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from numba import vectorize, float64, jit, int64
1717
from numba.types import UniTuple
1818

19-
from qha.bmf import bmf_all_t, bmf
19+
from qha.fitting import polynomial_least_square_fitting, birch_murnaghan_finite_strain_fitting
2020
from qha.type_aliases import Vector, Matrix
2121
from qha.unit_conversion import gpa_to_ry_b3
2222

@@ -83,7 +83,7 @@ def approaching_to_best_ratio(self, volumes: Vector, free_energies: Vector, init
8383
"""
8484
strains, finer_volumes = interpolate_volumes(volumes, self.ntv, initial_ratio)
8585
eulerian_strain = calc_eulerian_strain(volumes[0], volumes)
86-
f_v_tmax = bmf(eulerian_strain, free_energies, strains, self.option)
86+
_, f_v_tmax = polynomial_least_square_fitting(eulerian_strain, free_energies, strains, self.option)
8787
p_v_tmax = -np.gradient(f_v_tmax) / np.gradient(finer_volumes)
8888
p_desire = gpa_to_ry_b3(self.p_desire)
8989
# find the index of the first pressure value that slightly smaller than p_desire
@@ -97,8 +97,8 @@ def refine_grids(self, volumes: Vector, free_energies: Matrix,
9797
Get the appropriate volume grid for interpolation.
9898
Avoid to use a too large volume grid to obtain data, which might lose accuracy.
9999
:param free_energies: Calculated Helmholtz Free Energies for input volumes (sparse).
100-
:param volumes: olumes of these calculations were perform (sparse).
101-
:param ratio: This ratio is used to get a larger volume grid
100+
:param volumes: Volumes of these calculations were perform (sparse).
101+
:param ratio: This ratio is used to get a larger volume grid
102102
:return: volume, Helmholtz free energy at a denser vector, and the `ratio` used in this calculation
103103
"""
104104
if ratio is not None:
@@ -112,6 +112,5 @@ def refine_grids(self, volumes: Vector, free_energies: Matrix,
112112

113113
eulerian_strain = calc_eulerian_strain(volumes[0], volumes)
114114
strains, finer_volumes = interpolate_volumes(volumes, self.ntv, new_ratio)
115-
f_tv = bmf_all_t(eulerian_strain, free_energies, strains, self.option)
116-
117-
return finer_volumes, f_tv, new_ratio
115+
f_tv_bfm = birch_murnaghan_finite_strain_fitting(eulerian_strain, free_energies, strains, self.option)
116+
return finer_volumes, f_tv_bfm, new_ratio

qha/multi_configurations/different_phonon_dos.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
.. moduleauthor:: Qi Zhang <[email protected]>
1111
"""
1212

13+
from typing import Optional
14+
1315
import numpy as np
1416
from lazy_property import LazyProperty
1517
from scipy.constants import Boltzmann
1618
from scipy.special import logsumexp
1719

1820
import qha.settings
19-
from qha.bmf import bmf
21+
from qha.fitting import polynomial_least_square_fitting
2022
from qha.grid_interpolation import calc_eulerian_strain
2123
from qha.single_configuration import free_energy
2224
from qha.type_aliases import Array4D, Scalar, Vector, Matrix
@@ -33,8 +35,9 @@
3335

3436

3537
class PartitionFunction:
36-
def __init__(self, temperature: Scalar, static_energies: Matrix, degeneracies: Vector, q_weights: Matrix,
37-
frequencies: Array4D, volumes: Matrix, static_only: bool, precision: int = 500):
38+
def __init__(self, temperature: Scalar, degeneracies: Vector, q_weights: Matrix, static_energies: Matrix,
39+
volumes: Matrix, frequencies: Array4D, static_only: Optional[bool] = False,
40+
precision: Optional[int] = 500, order: Optional[int] = 3):
3841
if not np.all(np.greater_equal(degeneracies, 0)):
3942
raise ValueError('Degeneracies should all be greater equal than 0!')
4043
if not np.all(np.greater_equal(
@@ -59,7 +62,7 @@ def __init__(self, temperature: Scalar, static_energies: Matrix, degeneracies: V
5962
self.volumes = volumes
6063
self.static_only = static_only
6164
self.precision = int(precision)
62-
self.__ntv = 400
65+
self.order = int(order)
6366

6467
@LazyProperty
6568
def helmoholtz_configs(self):
@@ -79,7 +82,8 @@ def helmholtz_at_ref_v(self):
7982
# strains, finer_volumes[i, :] = interpolate_volumes(self.volumes[i], self.__ntv, 1.05)
8083
eulerian_strain = calc_eulerian_strain(self.volumes[i][0], self.volumes[i])
8184
strains = calc_eulerian_strain(self.volumes[i][0], self.volumes[0])
82-
helmholtz_fitted[i, :] = bmf(eulerian_strain, self.helmoholtz_configs[i], strains)
85+
_, helmholtz_fitted[i, :] = polynomial_least_square_fitting(eulerian_strain, self.helmoholtz_configs[i],
86+
strains, order=self.order)
8387
return helmholtz_fitted
8488

8589
@LazyProperty

qha/multi_configurations/same_phonon_dos.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
.. moduleauthor:: Qi Zhang <[email protected]>
1010
"""
1111

12+
from typing import Optional
13+
1214
import numpy as np
1315
from lazy_property import LazyProperty
1416
from scipy.constants import Boltzmann
@@ -30,8 +32,8 @@
3032

3133

3234
class PartitionFunction:
33-
def __init__(self, temperature: Scalar, static_energies: Matrix, degeneracies: Vector, q_weights: Vector,
34-
frequencies: Array3D, precision: int = 500):
35+
def __init__(self, temperature: Scalar, degeneracies: Vector, q_weights: Vector, static_energies: Matrix,
36+
frequencies: Array3D, precision: Optional[int] = 500):
3537

3638
if not np.all(np.greater_equal(degeneracies, 0)):
3739
raise ValueError('Degeneracies should all be integers greater equal than 0!')
@@ -88,7 +90,7 @@ def derive_free_energy(self):
8890

8991

9092
class FreeEnergy:
91-
def __init__(self, temperature: Scalar, static_energies: Matrix, degeneracies: Vector, q_weights: Vector,
93+
def __init__(self, temperature: Scalar, degeneracies: Vector, q_weights: Vector, static_energies: Matrix,
9294
frequencies: Array3D):
9395
if not np.all(np.greater_equal(degeneracies, 0)):
9496
raise ValueError('Degeneracies should all be integers greater equal than 0!')

0 commit comments

Comments
 (0)