<commit_before># Copyright (C) 2014 <NAME>
# All rights reserved.
#
# This file is part of phonopy.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the
#   distribution.
#
# * Neither the name of the phonopy project nor the names of its
#   contributors may be used to endorse or promote products derived
#   from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import numpy as np
from phonopy.structure.atoms import PhonopyAtoms
from phonopy.structure.cells import get_supercell, get_primitive
from phonopy.harmonic.force_constants import (
    distribute_force_constants_by_translations)
from phonopy.structure.cells import SNF3x3


def get_commensurate_points(supercell_matrix):  # wrt primitive cell
    """Commensurate q-points are returned.

    Parameters
    ----------
    supercell_matrix : array_like
        Supercell matrix with respect to primitive cell basis vectors.
        shape=(3, 3), dtype=int

    Returns
    -------
    commensurate_points : ndarray
        Commensurate points corresponding to supercell matrix.
        shape=(N, 3), dtype='double', order='C'
        where N = det(supercell_matrix)

    """

    smat = np.array(supercell_matrix, dtype=int)
    rec_primitive = PhonopyAtoms(numbers=[1],
                                 scaled_positions=[[0, 0, 0]],
                                 cell=np.diag([1, 1, 1]),
                                 pbc=True)
    rec_supercell = get_supercell(rec_primitive, smat.T)
    q_pos = rec_supercell.scaled_positions
    return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos),
                    dtype='double', order='C')


def get_commensurate_points_in_integers(supercell_matrix):
    """Commensurate q-points in integer representation are returned.

    A set of integer representation of lattice points is transformed to
    the equivalent set of lattice points in fractional coordinates with
    respect to supercell basis vectors by
        integer_lattice_points / det(supercell_matrix)

    Parameters
    ----------
    supercell_matrix : array_like
        Supercell matrix with respect to primitive cell basis vectors.
        shape=(3, 3)
        dtype=intc

    Returns
    -------
    lattice_points : ndarray
        Integer representation of lattice points in supercell.
        shape=(N, 3)

    """
    smat = np.array(supercell_matrix, dtype=int)
    snf = SNF3x3(smat.T)
    snf.run()
    D = snf.D.diagonal()
    b, c, a = np.meshgrid(range(D[1]), range(D[2]), range(D[0]))
    lattice_points = np.dot(np.c_[a.ravel() * D[1] * D[2],
                                  b.ravel() * D[0] * D[2],
                                  c.ravel() * D[0] * D[1]], snf.Q.T)
    lattice_points = np.array(lattice_points % np.prod(D),
                              dtype='intc', order='C')
    return lattice_points


def ph2fc(ph_orig, supercell_matrix):
    """Transform force constants in Phonopy instance to other shape

    For example, ph_orig.supercell_matrix is np.diag([2, 2, 2]) and
    supercell_matrix is np.diag([4, 4, 4]), force constants having the
    later shape are returned. This is considered useful when ph_orig
    has non-analytical correction (NAC). The effect of this correction
    is included in the returned force constants. Phonons before and after
    this operation at commensurate points of the later supercell_matrix
    should agree.

    """

    smat = supercell_matrix
    scell = get_supercell(ph_orig.unitcell, smat)
    pcell = get_primitive(
        scell,
        np.dot(np.linalg.inv(smat), ph_orig.primitive_matrix),
        positions_to_reorder=ph_orig.primitive.scaled_positions)
    d2f = DynmatToForceConstants(pcell, scell)
    ph_orig.run_qpoints(d2f.commensurate_points,
                        with_dynamical_matrices=True)
    ph_dict = ph_orig.get_qpoints_dict()
    d2f.dynamical_matrices = ph_dict['dynamical_matrices']
    d2f.run()
    return d2f.force_constants


class DynmatToForceConstants(object):
    """Transforms eigensolutions to force constants

    This is the inverse transform of force constants to eigensolutions.
    Eigenvalue-eigenvector pairs of dynamical matrices are transformed to
    force constants by this class. Optionally, dynamical matrices
    (not the DynamicalMatrix class instance, but the calculated matrices)
    can be used instead of above pairs.

    The eigensolutions have to be those calculated at commensurate q-points
    of supercell matrix. The commensurate q-points are obtained by the
    attribute ``commensurate_points``. This set of commensurate points can be
    also given by setter of it.<commit_msg>Minor upate of ph2fc<commit_after># Copyright (C) 2014 <NAME>
# All rights reserved.
#
# This file is part of phonopy.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the
#   distribution.
#
# * Neither the name of the phonopy project nor the names of its
#   contributors may be used to endorse or promote products derived
#   from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import numpy as np
from phonopy.structure.atoms import PhonopyAtoms
from phonopy.structure.cells import (get_supercell, get_primitive,
                                     shape_supercell_matrix, SNF3x3)
from phonopy.harmonic.force_constants import (
    distribute_force_constants_by_translations)


def get_commensurate_points(supercell_matrix):  # wrt primitive cell
    """Commensurate q-points are returned.

    Parameters
    ----------
    supercell_matrix : array_like
        Supercell matrix with respect to primitive cell basis vectors.
        shape=(3, 3), dtype=int

    Returns
    -------
    commensurate_points : ndarray
        Commensurate points corresponding to supercell matrix.
        shape=(N, 3), dtype='double', order='C'
        where N = det(supercell_matrix)

    """

    smat = np.array(supercell_matrix, dtype=int)
    rec_primitive = PhonopyAtoms(numbers=[1],
                                 scaled_positions=[[0, 0, 0]],
                                 cell=np.diag([1, 1, 1]),
                                 pbc=True)
    rec_supercell = get_supercell(rec_primitive, smat.T)
    q_pos = rec_supercell.scaled_positions
    return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos),
                    dtype='double', order='C')


def get_commensurate_points_in_integers(supercell_matrix):
    """Commensurate q-points in integer representation are returned.

    A set of integer representation of lattice points is transformed to
    the equivalent set of lattice points in fractional coordinates with
    respect to supercell basis vectors by
        integer_lattice_points / det(supercell_matrix)

    Parameters
    ----------
    supercell_matrix : array_like
        Supercell matrix with respect to primitive cell basis vectors.
        shape=(3, 3)
        dtype=intc

    Returns
    -------
    lattice_points : ndarray
        Integer representation of lattice points in supercell.
        shape=(N, 3)

    """
    smat = np.array(supercell_matrix, dtype=int)
    snf = SNF3x3(smat.T)
    snf.run()
    D = snf.D.diagonal()
    b, c, a = np.meshgrid(range(D[1]), range(D[2]), range(D[0]))
    lattice_points = np.dot(np.c_[a.ravel() * D[1] * D[2],
                                  b.ravel() * D[0] * D[2],
                                  c.ravel() * D[0] * D[1]], snf.Q.T)
    lattice_points = np.array(lattice_points % np.prod(D),
                              dtype='intc', order='C')
    return lattice_points


def ph2fc(ph_orig, supercell_matrix):
    """Transform force constants in Phonopy instance to other shape

    For example, ph_orig.supercell_matrix is np.diag([2, 2, 2]) and
    supercell_matrix is np.diag([4, 4, 4]), force constants having the
    later shape are returned. This is considered useful when ph_orig
    has non-analytical correction (NAC). The effect of this correction
    is included in the returned force constants. Phonons before and after
    this operation at commensurate points of the later supercell_matrix
    should agree.

    """

    smat = shape_supercell_matrix(supercell_matrix)
    scell = get_supercell(ph_orig.unitcell, smat)
    pcell = get_primitive(
        scell,
        np.dot(np.linalg.inv(smat), ph_orig.primitive_matrix),
        positions_to_reorder=ph_orig.primitive.scaled_positions)
    d2f = DynmatToForceConstants(pcell, scell)
    ph_orig.run_qpoints(d2f.commensurate_points,
                        with_dynamical_matrices=True)
    ph_dict = ph_orig.get_qpoints_dict()
    d2f.dynamical_matrices = ph_dict['dynamical_matrices']
    d2f.run()
    return d2f.force_constants


class DynmatToForceConstants(object):
    """Transforms eigensolutions to force constants

    This is the inverse transform of force constants to eigensolutions.
    Eigenvalue-eigenvector pairs of dynamical matrices are transformed to
    force constants by this class. Optionally, dynamical matrices
    (not the DynamicalMatrix class instance, but the calculated matrices)
    can be used instead of above pairs.

    The eigensolutions have to be those calculated at commensurate q-points
    of supercell matrix. The commensurate q-points are obtained by the
    attribute ``commensurate_points``. This set of commensurate points can be
    also given by setter of it.
{'fraction_non_alphanumeric': 0.07611570953152999, 'fraction_numerical': 0.008106493728133799, 'mean_word_length': 3.107956536978619, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3808685', 'n_tokens_mistral': 3462, 'n_tokens_neox': 3218, 'n_words': 1176}