def check_symmetry(phonon, optional_structure_info): # Assumed that primitive cell is the cell that user is interested in. print(_get_symmetry_yaml(phonon.primitive, phonon.primitive_symmetry, phonon.version)) if phonon.unitcell.magnetic_moments is None: base_fname = get_default_cell_filename(phonon.calculator) symprec = phonon.primitive_symmetry.get_symmetry_tolerance() (bravais_lattice, bravais_pos, bravais_numbers) = spglib.refine_cell(phonon.primitive, symprec) bravais = PhonopyAtoms(numbers=bravais_numbers, scaled_positions=bravais_pos, cell=bravais_lattice) filename = 'B' + base_fname print("# Symmetrized conventional unit cell is written into %s." % filename) trans_mat = guess_primitive_matrix(bravais, symprec=symprec) primitive = get_primitive(bravais, trans_mat, symprec=symprec) write_crystal_structure( filename, bravais, interface_mode=phonon.calculator, optional_structure_info=optional_structure_info) filename = 'P' + base_fname print("# Symmetrized primitive is written into %s." % filename) write_crystal_structure( filename, primitive, interface_mode=phonon.calculator, optional_structure_info=optional_structure_info)
def _get_error_message(optional_structure_info, interface_mode, fallback_reason, cell_filename, command_name): final_cell_filename = optional_structure_info[0] if fallback_reason is None: msg_list = [] if cell_filename != final_cell_filename: msg_list.append("Crystal structure file \"%s\" was not found." % cell_filename) msg_list.append("Crystal structure file \"%s\" was not found." % final_cell_filename) return "\n".join(msg_list) #################################### # Must be phonopy_yaml mode below. # #################################### msg_list = [] if fallback_reason in [ "default file not found", "read_vasp parsing failed" ]: if cell_filename: vasp_filename = cell_filename else: vasp_filename = get_default_cell_filename('vasp') if fallback_reason == "read_vasp parsing failed": msg_list.append( "Parsing crystal structure file of \"%s\" failed." % vasp_filename) else: msg_list.append("Crystal structure file of \"%s\" was not found." % vasp_filename) elif fallback_reason == "no supercell matrix given": msg_list.append("Supercell matrix (DIM or --dim) was not explicitly " "specified.") msg_list.append("By this reason, phonopy_yaml mode was invoked.") if final_cell_filename is None: # No phonopy*.yaml file was found. msg_list.append( "But \"%s\" and \"%s\" could not be found." % ("%s_disp.yaml" % command_name, "%s.yaml" % command_name)) return "\n".join(msg_list) phpy = optional_structure_info[1] if phpy is None: # Failed to parse phonopy*.yaml. msg_list.append("But parsing \"%s\" failed." % final_cell_filename) return "\n".join(msg_list)
def _poscar_failed(cell_filename): """Determine if fall back happens 1) read_vasp (parsing POSCAR-style file) is failed. --> fallback ValueError is raised by read_vasp when the POSCAR-style format is broken. By this way, we assume the input crystal structure is not in the POSCAR-style format and is in the phonopy.yaml type. 2) The file given by get_default_cell_filename('vasp') is not found at the current directory. --> fallback This is the trigger to look for the phonopy.yaml type file. 3) The given file with cell_filename is not found. --> not fallback This case will not invoke phonopy.yaml mode and here nothing is done, i.e., fallback_reason = None. This error will be caught in the following part again be handled properly (read_crystal_structure). """ fallback_reason = None try: if cell_filename is None: read_vasp(get_default_cell_filename('vasp')) else: read_vasp(cell_filename) except ValueError: # (1) see above fallback_reason = "read_vasp parsing failed" except FileNotFoundError: if cell_filename is None: # (2) see above fallback_reason = "default file not found" else: # (3) see above pass return fallback_reason
def _get_error_message(optional_structure_info, interface_mode, fallback_reason, cell_filename, phonopy_yaml_cls): final_cell_filename = optional_structure_info[0] if phonopy_yaml_cls is None: _phonopy_yaml_cls = PhonopyYaml else: _phonopy_yaml_cls = phonopy_yaml_cls if fallback_reason is None: msg_list = [] if cell_filename != final_cell_filename: msg_list.append("Crystal structure file \"%s\" was not found." % cell_filename) msg_list.append("Crystal structure file \"%s\" was not found." % final_cell_filename) return "\n".join(msg_list) #################################### # Must be phonopy_yaml mode below. # #################################### msg_list = [] if fallback_reason in ["default file not found", "read_vasp parsing failed"]: if cell_filename: vasp_filename = cell_filename else: vasp_filename = get_default_cell_filename('vasp') if fallback_reason == "read_vasp parsing failed": msg_list.append( "Parsing crystal structure file of \"%s\" failed." % vasp_filename) else: msg_list.append( "Crystal structure file of \"%s\" was not found." % vasp_filename) elif fallback_reason == "no supercell matrix given": msg_list.append("Supercell matrix (DIM or --dim) was not explicitly " "specified.") msg_list.append("By this reason, %s_yaml mode was invoked." % _phonopy_yaml_cls.command_name) if final_cell_filename is None: # No phonopy*.yaml file was found. filenames = ["\"%s\"" % name for name in _phonopy_yaml_cls.default_filenames] if len(filenames) == 1: text = filenames[0] elif len(filenames) == 2: text = " and ".join(filenames) else: tail = " and ".join(filenames[-2:]) head = ", ".join(filenames[:-2]) text = head + ", " + tail msg_list.append("But %s could not be found." % text) return "\n".join(msg_list) phpy = optional_structure_info[1] if phpy is None: # Failed to parse phonopy*.yaml. msg_list.append("But parsing \"%s\" failed." % final_cell_filename) return "\n".join(msg_list)
def collect_cell_info( supercell_matrix=None, primitive_matrix=None, interface_mode=None, cell_filename=None, chemical_symbols=None, enforce_primitive_matrix_auto=False, phonopy_yaml_cls=None, ): """Collect crystal structure information from inputs. Note ---- When the crystal structure is read from phonopy.yaml like file, ``supercell_matrix`` and ``primitive_matrix`` are ignored. Parameters ---------- supercell_matrix : array_like or None 3x3 transformation matrix or when it is a diagonal matrix, three diagonal elements. Default is None. See also shape_supercell_matrix. primitive_matrix : array_like, str, or None 3x3 transformation matrix or a character representing centring or None. Default is None. See also get_primitive_matrix. interface_mode : str or None Force calculator or crystal structure format name. cell_filename : str or None Input cell filename. chemical_symbols : list of str List of chemical symbols or unit cell. enforce_primitive_matrix_auto : bool Enforce primitive_matrix='auto' when True. Default is False. phonopy_yaml_cls : Class object PhonopyYaml like class name. This is used to return its instance when needed. Returns ------- dict : "unitcell": PhonopyAtoms Unit cell. "supercell_matrix": ndarray "primitive_matrix": ndarray "optional_structure_info": list See read_crystal_structure. "interface_mode": str Force calculator or crystal structure format name. "phonopy_yaml": None or instance of the class given by phonopy_yaml_cls Not None when crystal structure was read phonopy.yaml like file. "error_message" : str Unless error exists, this entry should not be in this dict. Otherwise, some error exists. The error message is storedin the string. """ # In some cases, interface mode falls back to phonopy_yaml mode. fallback_reason = _fallback_to_phonopy_yaml(supercell_matrix, interface_mode, cell_filename) if fallback_reason: _interface_mode = "phonopy_yaml" elif interface_mode is None: _interface_mode = None else: _interface_mode = interface_mode.lower() if phonopy_yaml_cls is None: _phonopy_yaml_cls = PhonopyYaml else: _phonopy_yaml_cls = phonopy_yaml_cls unitcell, optional_structure_info = read_crystal_structure( filename=cell_filename, interface_mode=_interface_mode, chemical_symbols=chemical_symbols, phonopy_yaml_cls=_phonopy_yaml_cls, ) # Error check if unitcell is None: err_msg = _get_error_message( optional_structure_info, fallback_reason, cell_filename, _phonopy_yaml_cls, ) return {"error_message": err_msg} # Retrieve more information on cells ( interface_mode_out, supercell_matrix_out, primitive_matrix_out, ) = _collect_cells_info( _interface_mode, optional_structure_info, interface_mode, supercell_matrix, primitive_matrix, ) err_msg = [] unitcell_filename = optional_structure_info[0] if supercell_matrix_out is None: err_msg.append( "Supercell matrix (DIM or --dim) information was not found.") if cell_filename is None and ( unitcell_filename == get_default_cell_filename(interface_mode_out)): err_msg += [ "", "Phonopy read the crystal structure from the file having the default " "filename ", "of each calculator. In this case, supercell matrix has to be " "specified.", "Because this is the old style way of using %s," % _phonopy_yaml_cls.command_name, ] filenames = [ '"%s"' % name for name in _phonopy_yaml_cls.default_filenames[:-1] ] err_msg += [ '"%s" was read being prefered to files such as ' % unitcell_filename, '%s, or "%s".' % (", ".join(filenames), _phonopy_yaml_cls.default_filenames[-1]), ] err_msg += [ "", 'If crystal structure is expected to be read from some "*.yaml" file,', 'Please rename "%s" to something else.' % unitcell_filename, ] if np.linalg.det(unitcell.cell) < 0.0: err_msg.append("Lattice vectors have to follow the right-hand rule.") if len(err_msg) > 0: err_msg = [ 'Crystal structure was read from "%s".' % unitcell_filename ] + err_msg return {"error_message": "\n".join(err_msg)} if enforce_primitive_matrix_auto: primitive_matrix_out = "auto" if _interface_mode == "phonopy_yaml": phpy_yaml: PhonopyYaml = optional_structure_info[1] else: phpy_yaml = None return { "unitcell": unitcell, "supercell_matrix": supercell_matrix_out, "primitive_matrix": primitive_matrix_out, "optional_structure_info": optional_structure_info, "interface_mode": interface_mode_out, "phonopy_yaml": phpy_yaml, }