1# Copyright (C) 2018 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
35import numpy as np
36from phonopy.api_phonopy import Phonopy
37from phonopy.interface.phonopy_yaml import PhonopyYaml
38from phonopy.interface.calculator import get_default_physical_units
39import phonopy.cui.load_helper as load_helper
40from phonopy.structure.cells import get_primitive_matrix
41
42
43def load(phonopy_yaml=None,  # phonopy.yaml-like must be the first argument.
44         supercell_matrix=None,
45         primitive_matrix=None,
46         is_nac=True,
47         calculator=None,
48         unitcell=None,
49         supercell=None,
50         nac_params=None,
51         unitcell_filename=None,
52         supercell_filename=None,
53         born_filename=None,
54         force_sets_filename=None,
55         force_constants_filename=None,
56         fc_calculator=None,
57         fc_calculator_options=None,
58         factor=None,
59         frequency_scale_factor=None,
60         produce_fc=True,
61         is_symmetry=True,
62         symmetrize_fc=True,
63         is_compact_fc=True,
64         store_dense_svecs=False,
65         symprec=1e-5,
66         log_level=0):
67    """Create Phonopy instance from parameters and/or input files.
68
69    "phonopy_yaml"-like file is parsed unless crystal structure information
70    is given by unitcell_filename, supercell_filename, unitcell
71    (PhonopyAtoms-like), or supercell (PhonopyAtoms-like).
72    Even when "phonopy_yaml"-like file is parse, parameters except for
73    crystal structure can be overwritten.
74
75    Phonopy default files of 'FORCE_SETS' and 'BORN' are parsed when they
76    are found in current directory and those data are not yet provided by
77    other means.
78
79    Crystal structure
80    -----------------
81    Means to provide crystal structure(s) and their priority:
82        1. unitcell_filename (with supercell_matrix)
83        2. supercell_filename
84        3. unitcell (with supercell_matrix)
85        4. supercell.
86        5. phonopy_yaml
87
88    Force sets or force constants
89    -----------------------------
90    Optional. Means to provide information to generate force constants
91    and their priority:
92        1. force_constants_filename
93        2. force_sets_filename
94        3. phonopy_yaml if force constants are found in phonoy_yaml.
95        4. phonopy_yaml if forces are found in phonoy_yaml.dataset.
96        5. 'FORCE_CONSTANTS' is searched in current directory.
97        6. 'force_constants.hdf5' is searched in current directory.
98        7. 'FORCE_SETS' is searched in current directory.
99    When both of 3 and 4 are satisfied but not others, force constants and
100    dataset are stored in Phonopy instance, but force constants are not
101    produced from dataset.
102
103    Parameters for non-analytical term correctiion (NAC)
104    ----------------------------------------------------
105    Optional. Means to provide NAC parameters and their priority:
106        1. born_filename
107        2. nac_params
108        3. phonopy_yaml.nac_params if existed and is_nac=True.
109        4. 'BORN' is searched in current directory when is_nac=True.
110
111    Parameters
112    ----------
113    phonopy_yaml : str, optional
114        Filename of "phonopy.yaml"-like file. If this is given, the data
115        in the file are parsed. Default is None.
116    supercell_matrix : array_like, optional
117        Supercell matrix multiplied to input cell basis vectors.
118        shape=(3, ) or (3, 3), where the former is considered a diagonal
119        matrix. Default is the unit matrix.
120        dtype=int
121    primitive_matrix : array_like or str, optional
122        Primitive matrix multiplied to input cell basis vectors. Default is
123        None, which is equivalent to 'auto'.
124        For array_like, shape=(3, 3), dtype=float.
125        When 'F', 'I', 'A', 'C', or 'R' is given instead of a 3x3 matrix,
126        the primitive matrix for the character found at
127        https://spglib.github.io/spglib/definition.html
128        is used.
129    is_nac : bool, optional
130        If True, look for 'BORN' file. If False, NAS is turned off.
131        Default is True.
132    calculator : str, optional.
133        Calculator used for computing forces. This is used to switch the set
134        of physical units. Default is None, which is equivalent to "vasp".
135    unitcell : PhonopyAtoms, optional
136        Input unit cell. Default is None.
137    supercell : PhonopyAtoms, optional
138        Input supercell. With given, default value of primitive_matrix is set
139        to 'auto' (can be overwitten). supercell_matrix is ignored. Default is
140        None.
141    nac_params : dict, optional
142        Parameters required for non-analytical term correction. Default is
143        None.
144        {'born': Born effective charges
145                 (array_like, shape=(primitive cell atoms, 3, 3), dtype=float),
146         'dielectric': Dielectric constant matrix
147                       (array_like, shape=(3, 3), dtype=float),
148         'factor': unit conversion facotr (float)}
149    unitcell_filename : str, optional
150        Input unit cell filename. Default is None.
151    supercell_filename : str, optional
152        Input supercell filename. When this is specified, supercell_matrix is
153        ignored. Default is None.
154    born_filename : str, optional
155        Filename corresponding to 'BORN', a file contains non-analytical term
156        correction parameters.
157    force_sets_filename : str, optional
158        Filename of a file corresponding to 'FORCE_SETS', a file contains sets
159        of forces and displacements. Default is None.
160    force_constants_filename : str, optional
161        Filename of a file corresponding to 'FORCE_CONSTANTS' or
162        'force_constants.hdf5', a file contains force constants. Default is
163        None.
164    fc_calculator : str, optional
165        Force constants calculator. Currently only 'alm'. Default is None.
166    fc_calculator_options : str, optional
167        Optional parameters that are passed to the external fc-calculator.
168        This is given as one text string. How to parse this depends on the
169        fc-calculator. For alm, each parameter is splitted by comma ',',
170        and each set of key and value pair is written in 'key = value'.
171    factor : float, optional
172        Phonon frequency unit conversion factor. Unless specified, default
173        unit conversion factor for each calculator is used.
174    frequency_scale_factor : float, optional
175        Factor multiplied to calculated phonon frequency. Default is None,
176        i.e., effectively 1.
177    produce_fc : bool, optional
178        Setting False, force constants are not calculated from displacements
179        and forces. Default is True.
180    is_symmetry : bool, optional
181        Setting False, crystal symmetry except for lattice translation is not
182        considered. Default is True.
183    symmetrize_fc : bool, optional
184        Setting False, force constants are not symmetrized when creating
185        force constants from displacements and forces. Default is True.
186    is_compact_fc : bool, optional
187        Force constants are produced in the array whose shape is
188            True: (primitive, supecell, 3, 3)
189            False: (supercell, supecell, 3, 3)
190        where 'supercell' and 'primitive' indicate number of atoms in these
191        cells. Default is True.
192    store_dense_svecs : bool, optional
193        This is for the test use. Do not set True.
194        Default is False.
195    symprec : float, optional
196        Tolerance used to find crystal symmetry. Default is 1e-5.
197    log_level : int, optional
198        Verbosity control. Default is 0.
199
200    """
201
202    if (supercell is not None or
203        supercell_filename is not None or
204        unitcell is not None or
205        unitcell_filename is not None):  # noqa E129
206        cell, smat, pmat = load_helper.get_cell_settings(
207            supercell_matrix=supercell_matrix,
208            primitive_matrix=primitive_matrix,
209            unitcell=unitcell,
210            supercell=supercell,
211            unitcell_filename=unitcell_filename,
212            supercell_filename=supercell_filename,
213            calculator=calculator,
214            symprec=symprec,
215            log_level=log_level)
216        _calculator = calculator
217        _nac_params = nac_params
218        _dataset = None
219        _fc = None
220    elif phonopy_yaml is not None:
221        phpy_yaml = PhonopyYaml()
222        phpy_yaml.read(phonopy_yaml)
223        cell = phpy_yaml.unitcell
224        smat = phpy_yaml.supercell_matrix
225        if smat is None:
226            smat = np.eye(3, dtype='intc', order='C')
227        if primitive_matrix is not None:
228            pmat = get_primitive_matrix(primitive_matrix, symprec=symprec)
229        else:
230            pmat = phpy_yaml.primitive_matrix
231        if nac_params is not None:
232            _nac_params = nac_params
233        elif is_nac:
234            _nac_params = phpy_yaml.nac_params
235        else:
236            _nac_params = None
237        _dataset = phpy_yaml.dataset
238        _fc = phpy_yaml.force_constants
239        if calculator is None:
240            _calculator = phpy_yaml.calculator
241        else:
242            _calculator = calculator
243    else:
244        msg = ("Cell information could not found. "
245               "Phonopy instance loading failed.")
246        raise RuntimeError(msg)
247
248    if log_level and _calculator is not None:
249        print("Set \"%s\" mode." % _calculator)
250
251    # units keywords: factor, nac_factor, distance_to_A
252    units = get_default_physical_units(_calculator)
253    if factor is None:
254        _factor = units['factor']
255    else:
256        _factor = factor
257    phonon = Phonopy(cell,
258                     smat,
259                     primitive_matrix=pmat,
260                     factor=_factor,
261                     frequency_scale_factor=frequency_scale_factor,
262                     symprec=symprec,
263                     is_symmetry=is_symmetry,
264                     store_dense_svecs=store_dense_svecs,
265                     calculator=_calculator,
266                     log_level=log_level)
267
268    # NAC params
269    if born_filename is not None or _nac_params is not None or is_nac:
270        ret_nac_params = load_helper.get_nac_params(
271            primitive=phonon.primitive,
272            nac_params=_nac_params,
273            born_filename=born_filename,
274            is_nac=is_nac,
275            nac_factor=units['nac_factor'],
276            log_level=log_level)
277        if ret_nac_params is not None:
278            phonon.nac_params = ret_nac_params
279
280    # Displacements, forces, and force constants
281    load_helper.set_dataset_and_force_constants(
282        phonon,
283        _dataset,
284        _fc,
285        force_constants_filename=force_constants_filename,
286        force_sets_filename=force_sets_filename,
287        fc_calculator=fc_calculator,
288        fc_calculator_options=fc_calculator_options,
289        produce_fc=produce_fc,
290        symmetrize_fc=symmetrize_fc,
291        is_compact_fc=is_compact_fc,
292        log_level=log_level)
293
294    return phonon
295