mirror of https://github.com/phonopy/phonopy.git
To reuse atomic permutation map as much as possible, that for space group is put in Symmetry and that for only translation is put in Primitive. In Symmetry, it is generated on demand, but in Primitive, it is made at the initialization step.
This commit is contained in:
parent
f18d5ce240
commit
c7c720652e
|
@ -365,14 +365,12 @@ class Phonopy(object):
|
|||
if 'forces' not in disp:
|
||||
return False
|
||||
|
||||
s2p_map = self._primitive.get_supercell_to_primitive_map()
|
||||
p2s_map = self._primitive.get_primitive_to_supercell_map()
|
||||
|
||||
if calculate_full_force_constants:
|
||||
self._run_force_constants_from_forces(
|
||||
decimals=self._force_constants_decimals,
|
||||
computation_algorithm=computation_algorithm)
|
||||
else:
|
||||
p2s_map = self._primitive.get_primitive_to_supercell_map()
|
||||
self._run_force_constants_from_forces(
|
||||
distributed_atom_list=p2s_map,
|
||||
decimals=self._force_constants_decimals,
|
||||
|
@ -381,17 +379,13 @@ class Phonopy(object):
|
|||
if show_drift and self._log_level:
|
||||
show_drift_force_constants(self._force_constants,
|
||||
supercell=self._supercell,
|
||||
symmetry=self._symmetry,
|
||||
s2p_map=s2p_map,
|
||||
p2s_map=p2s_map)
|
||||
primitive=self._primitive)
|
||||
|
||||
self._set_dynamical_matrix()
|
||||
|
||||
return True
|
||||
|
||||
def symmetrize_force_constants(self, level=2, show_drift=True):
|
||||
s2p_map = self._primitive.get_supercell_to_primitive_map()
|
||||
p2s_map = self._primitive.get_primitive_to_supercell_map()
|
||||
if self._force_constants.shape[0] == self._force_constants.shape[1]:
|
||||
n_satom = self._supercell.get_number_of_atoms()
|
||||
fc = self._force_constants
|
||||
|
@ -401,17 +395,13 @@ class Phonopy(object):
|
|||
else:
|
||||
symmetrize_compact_force_constants(self._force_constants,
|
||||
self._supercell,
|
||||
self._symmetry,
|
||||
s2p_map,
|
||||
p2s_map,
|
||||
self._primitive,
|
||||
level=level)
|
||||
if show_drift and self._log_level:
|
||||
sys.stdout.write(" after symmetrization: ")
|
||||
show_drift_force_constants(self._force_constants,
|
||||
supercell=self._supercell,
|
||||
symmetry=self._symmetry,
|
||||
s2p_map=s2p_map,
|
||||
p2s_map=p2s_map,
|
||||
primitive=self._primitive,
|
||||
values_only=True)
|
||||
|
||||
self._set_dynamical_matrix()
|
||||
|
|
|
@ -33,16 +33,15 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import numpy as np
|
||||
from phonopy.structure.atoms import PhonopyAtoms as Atoms
|
||||
from phonopy.structure.symmetry import Symmetry
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
from phonopy.structure.cells import get_supercell
|
||||
from phonopy.harmonic.force_constants import distribute_force_constants
|
||||
|
||||
def get_commensurate_points(supercell_matrix): # wrt primitive cell
|
||||
rec_primitive = Atoms(numbers=[1],
|
||||
scaled_positions=[[0, 0, 0]],
|
||||
cell=np.diag([1, 1, 1]),
|
||||
pbc=True)
|
||||
rec_primitive = PhonopyAtoms(numbers=[1],
|
||||
scaled_positions=[[0, 0, 0]],
|
||||
cell=np.diag([1, 1, 1]),
|
||||
pbc=True)
|
||||
rec_supercell = get_supercell(rec_primitive, supercell_matrix.T)
|
||||
q_pos = rec_supercell.get_scaled_positions()
|
||||
return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos),
|
||||
|
@ -180,11 +179,10 @@ class DynmatToForceConstants(object):
|
|||
dtype='double', order='C')
|
||||
rotations = np.array([np.eye(3, dtype='intc')] * len(trans),
|
||||
dtype='intc', order='C')
|
||||
permutations = self._primitive.get_atomic_permutations()
|
||||
distribute_force_constants(self._fc,
|
||||
range(self._supercell.get_number_of_atoms()),
|
||||
p2s,
|
||||
lattice,
|
||||
positions,
|
||||
rotations,
|
||||
trans,
|
||||
1e-5)
|
||||
permutations)
|
||||
|
|
|
@ -36,7 +36,6 @@ import numpy as np
|
|||
import sys
|
||||
from phonopy.structure.cells import (get_reduced_bases,
|
||||
get_equivalent_smallest_vectors,
|
||||
compute_all_sg_permutations,
|
||||
compute_permutation_for_rotation)
|
||||
|
||||
def get_force_constants(set_of_forces,
|
||||
|
@ -88,19 +87,9 @@ def get_fc2(supercell,
|
|||
symmetry,
|
||||
computation_algorithm=computation_algorithm)
|
||||
|
||||
# Distribute non-equivalent force constants to those equivalent
|
||||
symprec = symmetry.get_symmetry_tolerance()
|
||||
rotations = symmetry.get_symmetry_operations()['rotations']
|
||||
trans = symmetry.get_symmetry_operations()['translations']
|
||||
positions = supercell.get_scaled_positions()
|
||||
lattice = np.array(supercell.get_cell().T, dtype='double', order='C')
|
||||
|
||||
permutations = compute_all_sg_permutations(positions,
|
||||
rotations,
|
||||
trans,
|
||||
lattice,
|
||||
symprec)
|
||||
|
||||
permutations = symmetry.get_atomic_permutations()
|
||||
if atom_list is None:
|
||||
distribute_force_constants(force_constants,
|
||||
range(supercell.get_number_of_atoms()),
|
||||
|
@ -167,9 +156,7 @@ def symmetrize_force_constants(force_constants, iteration=1):
|
|||
|
||||
def symmetrize_compact_force_constants(force_constants,
|
||||
supercell,
|
||||
symmetry,
|
||||
s2p_map,
|
||||
p2s_map,
|
||||
primitive,
|
||||
level=2):
|
||||
"""Symmetry force constants by translational and permutation symmetries.
|
||||
|
||||
|
@ -185,7 +172,9 @@ def symmetrize_compact_force_constants(force_constants,
|
|||
|
||||
"""
|
||||
|
||||
permutations = _get_translational_permutations(supercell, symmetry)
|
||||
s2p_map = primitive.get_supercell_to_primitive_map()
|
||||
p2s_map = primitive.get_primitive_to_supercell_map()
|
||||
permutations = primitive.get_atomic_permutations()
|
||||
|
||||
try:
|
||||
import phonopy._phonopy as phonoc
|
||||
|
@ -200,27 +189,6 @@ def symmetrize_compact_force_constants(force_constants,
|
|||
import sys
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def _get_translational_permutations(supercell, symmetry):
|
||||
rotations = []
|
||||
trans = []
|
||||
identity = np.eye(3, dtype='intc')
|
||||
|
||||
for r, t in zip(symmetry.get_symmetry_operations()['rotations'],
|
||||
symmetry.get_symmetry_operations()['translations']):
|
||||
if (r == identity).all():
|
||||
rotations.append(r)
|
||||
trans.append(t)
|
||||
|
||||
permutations = compute_all_sg_permutations(
|
||||
supercell.get_scaled_positions(),
|
||||
np.array(rotations, dtype='intc', order='C'),
|
||||
np.array(trans, dtype='double'),
|
||||
np.array(supercell.get_cell().T, dtype='double', order='C'),
|
||||
symmetry.get_symmetry_tolerance())
|
||||
|
||||
return permutations
|
||||
|
||||
def distribute_force_constants(force_constants,
|
||||
atom_list,
|
||||
atom_list_done,
|
||||
|
@ -387,14 +355,13 @@ def set_tensor_symmetry(force_constants,
|
|||
|
||||
assert num_equiv_atoms * num_sitesym == len(rotations)
|
||||
|
||||
permutations = symmetry.get_atomic_permutations()
|
||||
distribute_force_constants(fc_new,
|
||||
range(len(positions)),
|
||||
indep_atoms,
|
||||
lattice,
|
||||
positions,
|
||||
rotations,
|
||||
translations,
|
||||
symprec)
|
||||
permutations)
|
||||
|
||||
force_constants[:] = fc_new
|
||||
|
||||
|
@ -548,9 +515,7 @@ def similarity_transformation(rot, mat):
|
|||
|
||||
def show_drift_force_constants(force_constants,
|
||||
supercell=None,
|
||||
symmetry=None,
|
||||
s2p_map=None,
|
||||
p2s_map=None,
|
||||
primitive=None,
|
||||
name="force constants",
|
||||
values_only=False):
|
||||
if force_constants.shape[0] == force_constants.shape[1]:
|
||||
|
@ -569,7 +534,9 @@ def show_drift_force_constants(force_constants,
|
|||
maxval2 = val2
|
||||
jk2 = [j, k]
|
||||
else:
|
||||
permutations = _get_translational_permutations(supercell, symmetry)
|
||||
s2p_map = primitive.get_supercell_to_primitive_map()
|
||||
p2s_map = primitive.get_primitive_to_supercell_map()
|
||||
permutations = primitive.get_atomic_permutations()
|
||||
try:
|
||||
import phonopy._phonopy as phonoc
|
||||
phonoc.transpose_compact_fc(force_constants,
|
||||
|
|
|
@ -290,9 +290,11 @@ class Primitive(PhonopyAtoms):
|
|||
self._p2p_map = None
|
||||
self._smallest_vectors = None
|
||||
self._multiplicity = None
|
||||
self._atomic_permutations = None
|
||||
self._primitive_cell(supercell)
|
||||
self._map_atomic_indices(supercell.get_scaled_positions())
|
||||
self._set_smallest_vectors(supercell)
|
||||
self._set_atomic_permutations(supercell)
|
||||
|
||||
def get_primitive_matrix(self):
|
||||
return self._primitive_matrix
|
||||
|
@ -309,6 +311,9 @@ class Primitive(PhonopyAtoms):
|
|||
def get_smallest_vectors(self):
|
||||
return self._smallest_vectors, self._multiplicity
|
||||
|
||||
def get_atomic_permutations(self):
|
||||
return self._atomic_permutations
|
||||
|
||||
def _primitive_cell(self, supercell):
|
||||
trimmed_cell_ = _trim_cell(self._primitive_matrix,
|
||||
supercell,
|
||||
|
@ -355,6 +360,20 @@ class Primitive(PhonopyAtoms):
|
|||
self._smallest_vectors, self._multiplicity = _get_smallest_vectors(
|
||||
supercell, self, self._symprec)
|
||||
|
||||
def _set_atomic_permutations(self, supercell):
|
||||
positions = supercell.get_scaled_positions()
|
||||
diff = positions - positions[self._p2s_map[0]]
|
||||
trans = np.array(diff[np.where(self._s2p_map == self._p2s_map[0])[0]],
|
||||
dtype='double', order='C')
|
||||
rotations = np.array([np.eye(3, dtype='intc')] * len(trans),
|
||||
dtype='intc', order='C')
|
||||
self._atomic_permutations = compute_all_sg_permutations(
|
||||
positions,
|
||||
rotations,
|
||||
trans,
|
||||
np.array(supercell.get_cell().T, dtype='double', order='C'),
|
||||
self._symprec)
|
||||
|
||||
def _trim_cell(relative_axes, cell, symprec):
|
||||
"""Trim overlapping atoms
|
||||
|
||||
|
|
|
@ -134,7 +134,8 @@ class Symmetry(object):
|
|||
def get_atomic_permutations(self):
|
||||
if self._atomic_permutations is None:
|
||||
positions = self._cell.get_scaled_positions()
|
||||
lattice = np.array(self._cell.get_cell().T, dtype='double', order='C')
|
||||
lattice = np.array(self._cell.get_cell().T,
|
||||
dtype='double', order='C')
|
||||
rotations = self._symmetry_operations['rotations']
|
||||
translations = self._symmetry_operations['translations']
|
||||
self._atomic_permutations = compute_all_sg_permutations(
|
||||
|
|
Loading…
Reference in New Issue