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:
Atsushi Togo 2018-04-24 00:19:41 +09:00
parent f18d5ce240
commit c7c720652e
5 changed files with 43 additions and 68 deletions

View File

@ -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()

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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(