1# Copyright (C) 2015 Atsushi Togo
2# All rights reserved.
3#
4# This file is part of phonopy.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# * Redistributions of source code must retain the above copyright
11#   notice, this list of conditions and the following disclaimer.
12#
13# * Redistributions in binary form must reproduce the above copyright
14#   notice, this list of conditions and the following disclaimer in
15#   the documentation and/or other materials provided with the
16#   distribution.
17#
18# * Neither the name of the phonopy project nor the names of its
19#   contributors may be used to endorse or promote products derived
20#   from this software without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33# POSSIBILITY OF SUCH DAMAGE.
34
35from phonopy.gruneisen import GruneisenMesh
36from phonopy.gruneisen import GruneisenBandStructure
37from phonopy.gruneisen import GruneisenThermalProperties
38
39
40class PhonopyGruneisen(object):
41    def __init__(self,
42                 phonon,
43                 phonon_plus,
44                 phonon_minus,
45                 delta_strain=None):
46        self._phonon = phonon
47        self._phonon_plus = phonon_plus
48        self._phonon_minus = phonon_minus
49        self._delta_strain = delta_strain
50
51        self._mesh = None
52        self._band_structure = None
53        self._thermal_properties = None
54
55    def get_phonon(self):
56        return self._phonon
57
58    def set_mesh(self,
59                 mesh,
60                 shift=None,
61                 is_time_reversal=True,
62                 is_gamma_center=False,
63                 is_mesh_symmetry=True):
64        for phonon in (self._phonon, self._phonon_plus, self._phonon_minus):
65            if phonon.get_dynamical_matrix() is None:
66                print("Warning: Dynamical matrix has not yet built.")
67                return False
68
69        symmetry = phonon.get_primitive_symmetry()
70        rotations = symmetry.get_pointgroup_operations()
71        self._mesh = GruneisenMesh(
72            self._phonon.get_dynamical_matrix(),
73            self._phonon_plus.get_dynamical_matrix(),
74            self._phonon_minus.get_dynamical_matrix(),
75            mesh,
76            delta_strain=self._delta_strain,
77            shift=shift,
78            is_time_reversal=is_time_reversal,
79            is_gamma_center=is_gamma_center,
80            is_mesh_symmetry=is_mesh_symmetry,
81            rotations=rotations,
82            factor=self._phonon.get_unit_conversion_factor())
83        return True
84
85    def get_mesh(self):
86        if self._mesh is None:
87            return None
88        else:
89            return (self._mesh.get_qpoints(),
90                    self._mesh.get_weights(),
91                    self._mesh.get_frequencies(),
92                    self._mesh.get_eigenvectors(),
93                    self._mesh.get_gruneisen())
94
95    def write_yaml_mesh(self):
96        self._mesh.write_yaml()
97
98    def write_hdf5_mesh(self):
99        self._mesh.write_hdf5()
100
101    def plot_mesh(self,
102                  cutoff_frequency=None,
103                  color_scheme=None,
104                  marker='o',
105                  markersize=None):
106        import matplotlib.pyplot as plt
107        fig, ax = plt.subplots()
108        ax.xaxis.set_ticks_position('both')
109        ax.yaxis.set_ticks_position('both')
110        ax.xaxis.set_tick_params(which='both', direction='in')
111        ax.yaxis.set_tick_params(which='both', direction='in')
112        self._mesh.plot(plt,
113                        cutoff_frequency=cutoff_frequency,
114                        color_scheme=color_scheme,
115                        marker=marker,
116                        markersize=markersize)
117        return plt
118
119    def set_band_structure(self, bands):
120        self._band_structure = GruneisenBandStructure(
121            bands,
122            self._phonon.get_dynamical_matrix(),
123            self._phonon_plus.get_dynamical_matrix(),
124            self._phonon_minus.get_dynamical_matrix(),
125            delta_strain=self._delta_strain,
126            factor=self._phonon.get_unit_conversion_factor())
127
128    def get_band_structure(self):
129        band = self._band_structure
130        return (band.get_qpoints(),
131                band.get_distances(),
132                band.get_frequencies(),
133                band.get_eigenvectors(),
134                band.get_gruneisen())
135
136    def write_yaml_band_structure(self):
137        self._band_structure.write_yaml()
138
139    def plot_band_structure(self,
140                            epsilon=1e-4,
141                            color_scheme=None):
142        import matplotlib.pyplot as plt
143        fig, axarr = plt.subplots(2, 1)
144        for ax in axarr:
145            ax.xaxis.set_ticks_position('both')
146            ax.yaxis.set_ticks_position('both')
147            ax.xaxis.set_tick_params(which='both', direction='in')
148            ax.yaxis.set_tick_params(which='both', direction='in')
149            self._band_structure.plot(axarr,
150                                      epsilon=epsilon,
151                                      color_scheme=color_scheme)
152        return plt
153
154    def set_thermal_properties(self,
155                               volumes,
156                               t_step=2,
157                               t_max=2004,
158                               t_min=0,
159                               cutoff_frequency=None):
160        self._thermal_properties  = GruneisenThermalProperties(
161            self._mesh,
162            volumes,
163            t_step=t_step,
164            t_max=t_max,
165            t_min=t_min,
166            cutoff_frequency=cutoff_frequency)
167
168    def get_thermal_properties(self):
169        return self._thermal_properties
170
171    def write_yaml_thermal_properties(self, filename='thermal_properties'):
172        self._thermal_properties.write_yaml(filename=filename)
173