def begin(self): if not self._job: print "set_job has to be executed." raise self._overwrite_settings() self._status = "stage 1" if self._impose_symmetry: prim_cell = get_primitive(self._cell, tolerance=self._symmetry_tolerance) self._space_group = get_symmetry_dataset(prim_cell) task = self._get_next_task(prim_cell) else: if self._find_symmetry: self._space_group = get_symmetry_dataset( self._cell, self._symmetry_tolerance) task = self._get_next_task(self._cell) if self._space_group: self._comment = self._space_group['international_standard'] self._so_tasks = [task] self._tasks = [task] self._write_yaml()
def next(self): if self._status == "terminate": self._stress = None self._forces = None self._energy = None self._next_cell = None else: task = self._tasks[0] self._next_cell = task.get_current_cell() stress = task.get_stress() forces = task.get_forces() energy = task.get_energy() if not stress == None: self._stress = stress if not forces == None: self._forces = forces if not energy == None: self._energy = energy if self._status == "terminate" and self._traverse == "restart": self._traverse = False if self._stage > 2: self._stage -= 2 task = self._so_tasks.pop() task = self._so_tasks.pop() self._next_cell = task.get_cell() else: self._so_tasks = [] self._stage = 0 self._next_cell = self._cell self._status = "next" if self._next_cell: if self._impose_symmetry: self._next_cell = get_primitive(self._next_cell, tolerance=self._symmetry_tolerance) self._space_group = get_symmetry_dataset(self._next_cell) else: if self._find_symmetry: self._space_group = get_symmetry_dataset(self._next_cell, tolerance=self._symmetry_tolerance) if self._space_group: self._comment = self._space_group["international_standard"] if self._status == "done": if self._stage < self._min_iteration: self._status = "next" if self._status == "next": if self._stage == self._max_iteration: self._status = "max_iteration" else: self._set_next_task() self._write_yaml() if "stage" in self._status: return self._tasks else: self._tasks = [] raise StopIteration
def _set_stage1(self, cell): prim_cell = get_primitive_cell(cell, tolerance=self._symmetry_tolerance) sym_dataset = get_symmetry_dataset(prim_cell) self._space_group_type = sym_dataset['international'] spg_number = sym_dataset['number'] if (spg_number >= 143 and spg_number <= 194 and not self._space_group_type[0] == 'R'): # Hexagonal lattice self._supercell_dimensions = [[3, 3, 2], [2, 2, 2]] else: # Other cases self._supercell_dimensions = [[2, 2, 2]] # Long cell axis is not multiplied. for dimension in self._supercell_dimensions: for i, length in enumerate( get_lattice_parameters(prim_cell.get_lattice())): if length * dimension[i] > 20: dimension[i] = 1 self._tasks = [] for i, dimension in enumerate(self._supercell_dimensions): task = self._get_phonon_task(prim_cell, np.diag(dimension), "phonon-%d" % (i + 1)) self._phre_tasks.append(task) self._tasks.append(task)
def _analyze_phonon(self): for dimension, task in zip(self._supercell_dimensions, self._tasks): self._energy = task.get_energy() phonon = task.get_phonon() phonon.set_mesh(dimension, is_gamma_center=True) qpoints, weigths, frequencies, eigvecs = phonon.get_mesh() eigenvalues = frequencies ** 2 * np.sign(frequencies) if (eigenvalues < self._cutoff_eigenvalue).any(): imaginary_modes = [] qpoints_done = [imag_mode[1] for imag_mode in self._imaginary_modes] print("Modulation structure search, start") self._imaginary_modes += get_unstable_modulations( phonon, dimension, symmetry_tolerance=self._symmetry_tolerance, max_displacement=self._max_displacement, cutoff_eigenvalue=self._cutoff_eigenvalue, ndiv=self._num_sampling_points, excluded_qpoints=qpoints_done) print("Modulation structure search, done") sym_dataset = get_symmetry_dataset( self._tasks[0].get_cell()) self._space_group_type = sym_dataset['international']
def _run(self): self._set_best_arguments_of_vectors_and_supercell() max_num_op = 0 best_cells = [] points_on_sphere = [] for i, point in enumerate(self._get_all_points_on_sphere()): modcell = self._get_cell_with_modulation( self._get_modulation(point)) symmetry = get_symmetry_dataset(modcell, tolerance=self._symmetry_tolerance) if self._store_all: self._all_cells.append(modcell) refined_cell = get_crystallographic_cell( modcell, tolerance=self._symmetry_tolerance) num_op = len(symmetry['rotations']) if num_op > max_num_op: max_num_op = num_op best_cells = [refined_cell] points_on_sphere = [point.copy()] if num_op == max_num_op: is_found = True for bc in best_cells: if xtal_compare(bc, refined_cell, tolerance=self._symmetry_tolerance, angle_tolerance=1.0): is_found = False break if is_found: best_cells.append(refined_cell) points_on_sphere.append(point.copy()) self._points_on_sphere = points_on_sphere
def _set_stage0(self): self._tasks = [] task = self._get_equilibrium_task( cell=self._cell, impose_symmetry=True, symmetry_tolerance=self._symmetry_tolerance) symmetry = get_symmetry_dataset(self._cell, tolerance=self._symmetry_tolerance) self._space_group_type = symmetry['international_standard'] self._phre_tasks = [task] self._tasks = [task]
def begin(self): if not self._job: print("set_job has to be executed.") raise RuntimeError self._status = "stage 1" if self._impose_symmetry: prim_cell = get_primitive_cell(self._cell, tolerance=self._symmetry_tolerance) self._space_group = get_symmetry_dataset(prim_cell) task = self._get_next_task(prim_cell) else: if self._find_symmetry: self._space_group = get_symmetry_dataset(self._cell, self._symmetry_tolerance) task = self._get_next_task(self._cell) if self._space_group: self._comment = self._space_group["international"] self._all_tasks = [task] self._tasks = [task] self._write_yaml()
def begin(self): if not self._job: print("set_job has to be executed.") raise RuntimeError self._status = "stage 0" self._stage = 0 self._tasks = [] task = self._get_phonon_relax_element_task(self._cell) self._phr_tasks = [task] self._tasks = [task] space_group = get_symmetry_dataset(self._cell, tolerance=self._symmetry_tolerance) self._comment = space_group['international']
def begin(self): if not self._job: print "set_job has to be executed." raise self._overwrite_settings() self._status = "stage 0" self._stage = 0 self._tasks = [] task = self._get_phonon_relax_element_task(self._cell) self._phr_tasks = [task] self._tasks = [task] space_group = get_symmetry_dataset(self._cell, tolerance=self._symmetry_tolerance) self._comment = space_group['international_standard']
def get_primitive(cell, tolerance=1e-5): # spglib returns R-centred lattice for Rhombohedrals brv_cell = get_crystallographic_cell(cell, tolerance) sym_dataset = get_symmetry_dataset(brv_cell) spg_symbol = sym_dataset['international'][0] if spg_symbol == 'F': brv_cell = _fc2prim(brv_cell) elif spg_symbol == 'I': brv_cell = _bc2prim(brv_cell) elif spg_symbol == 'A': brv_cell = _abc2prim(brv_cell) elif spg_symbol == 'B': brv_cell = _bbc2prim(brv_cell) elif spg_symbol == 'C': brv_cell = _cbc2prim(brv_cell) return brv_cell
def get_primitive(cell, tolerance=1e-5): # spglib returns R-centred lattice for Rhombohedrals std_cell = get_crystallographic_cell(cell, tolerance) sym_dataset = get_symmetry_dataset(std_cell) spg_symbol = sym_dataset['international'][0] if spg_symbol == 'F': std_cell = _fc2prim(std_cell) elif spg_symbol == 'I': std_cell = _bc2prim(std_cell) elif spg_symbol == 'A': std_cell = _abc2prim(std_cell) elif spg_symbol == 'B': std_cell = _bbc2prim(std_cell) elif spg_symbol == 'C': std_cell = _cbc2prim(std_cell) return std_cell
def _write_yaml(self): w = open("%s.yaml" % self._directory, 'w') if self._lattice_tolerance is not None: w.write("lattice_tolerance: %f\n" % self._lattice_tolerance) if self._stress_tolerance is not None: w.write("stress_tolerance: %f\n" % self._stress_tolerance) w.write("pressure_target: %f\n" % self._pressure_target) w.write("force_tolerance: %f\n" % self._force_tolerance) if self._max_increase is None: w.write("max_increase: unset\n") else: w.write("max_increase: %f\n" % self._max_increase) w.write("max_iteration: %d\n" % self._max_iteration) w.write("min_iteration: %d\n" % self._min_iteration) w.write("symmetry_tolerance: %f\n" % self._symmetry_tolerance) w.write("max_displacement: %f\n" % self._max_displacement) w.write("cutoff_eigenvalue: %f\n" % self._cutoff_eigenvalue) w.write("stage: %d\n" % self._stage) w.write("status: %s\n" % self._status) if self._energy: w.write("electric_total_energy: %20.10f\n" % self._energy) if self._imaginary_modes: w.write("imaginary_modes:\n") for imag_mode in self._imaginary_modes: spg = get_symmetry_dataset(imag_mode[0], tolerance=self._symmetry_tolerance) q = imag_mode[1] freq = imag_mode[2] q_index = imag_mode[3] + 1 band_index = imag_mode[4] + 1 degeneracy = imag_mode[6] dimension = tuple(imag_mode[7]) w.write("- supercell_dimension: [ %d, %d, %d ]\n" % dimension) w.write(" qpoint: [ %6.4f, %6.4f, %6.4f ] # %d\n" % (q[0], q[1], q[2], q_index)) w.write(" band: %d\n" % band_index) w.write(" frequency: %10.5f\n" % (-freq)) w.write(" degeneracy: %d\n" % degeneracy) w.write(" space_group_type: %s\n" % spg['international']) w.write(" space_group_number: %s\n" % spg['number']) w.write("tasks:\n") for task in self._phre_tasks: if task.get_status(): w.write("- name: %s\n" % task.get_name()) w.write(" status: %s\n" % task.get_status()) w.close()
def _write_yaml(self): w = open("%s.yaml" % self._directory, 'w') if self._lattice_tolerance is not None: w.write("lattice_tolerance: %f\n" % self._lattice_tolerance) if self._stress_tolerance is not None: w.write("stress_tolerance: %f\n" % self._stress_tolerance) w.write("pressure_target: %f\n" % self._pressure_target) w.write("force_tolerance: %f\n" % self._force_tolerance) w.write("max_increase: %f\n" % self._max_increase) w.write("max_iteration: %d\n" % self._max_iteration) w.write("min_iteration: %d\n" % self._min_iteration) w.write("symmetry_tolerance: %f\n" % self._symmetry_tolerance) w.write("max_displacement: %f\n" % self._max_displacement) w.write("cutoff_eigenvalue: %f\n" % self._cutoff_eigenvalue) w.write("stage: %d\n" % self._stage) w.write("status: %s\n" % self._status) if self._energy: w.write("electric_total_energy: %20.10f\n" % self._energy) if self._imaginary_modes: w.write("imaginary_modes:\n") for imag_mode in self._imaginary_modes: spg = get_symmetry_dataset(imag_mode[0], tolerance=self._symmetry_tolerance) q = imag_mode[1] freq = imag_mode[2] q_index = imag_mode[3] + 1 band_index = imag_mode[4] + 1 degeneracy = imag_mode[6] dimension = tuple(imag_mode[7]) w.write("- supercell_dimension: [ %d, %d, %d ]\n" % dimension) w.write(" qpoint: [ %6.4f, %6.4f, %6.4f ] # %d\n" % (q[0], q[1], q[2], q_index)) w.write(" band: %d\n" % band_index) w.write(" frequency: %10.5f\n" % (-freq)) w.write(" degeneracy: %d\n" % degeneracy) w.write(" space_group_type: %s\n" % spg['international_standard']) w.write(" space_group_number: %s\n" % spg['number']) w.write("tasks:\n") for task in self._phre_tasks: if task.get_status(): w.write("- name: %s\n" % task.get_name()) w.write(" status: %s\n" % task.get_status()) w.close()
def _run(self): self._set_vectors_and_supercell() max_num_op = 0 best_cells = [] best_spacegroup_types = [] points_on_sphere = [] phase_shifts = self._get_phase_shifts_at_lattice_points() for point in self._get_phases(): modulation = self._get_modulation(point) for phase in phase_shifts: amplitude = self._get_normalize_amplitude(modulation / phase) modcell = self._get_cell_with_modulation( modulation / phase * amplitude) symmetry = get_symmetry_dataset( modcell, tolerance=self._symmetry_tolerance) num_op = len(symmetry['rotations']) if num_op > max_num_op: max_num_op = num_op best_cells = [modcell] best_spacegroup_types = [symmetry['number']] points_on_sphere = [[point, phase, amplitude]] elif num_op == max_num_op: if symmetry['number'] in best_spacegroup_types: cell_in_best_cells = False for bc in best_cells: if xtal_compare( bc, modcell, tolerance=self._symmetry_tolerance, angle_tolerance=1.0): cell_in_best_cells = True break if not cell_in_best_cells: best_cells.append(modcell) points_on_sphere.append([point, phase, amplitude]) else: best_cells.append(modcell) points_on_sphere.append([point, phase, amplitude]) best_spacegroup_types.append(symmetry['number']) self._points_on_sphere = points_on_sphere
def _run(self): self._set_vectors_and_supercell() max_num_op = 0 best_cells = [] best_spacegroup_types = [] points_on_sphere = [] phase_shifts = self._get_phase_shifts_at_lattice_points() for point in self._get_phases(): modulation = self._get_modulation(point) for phase in phase_shifts: amplitude = self._get_normalize_amplitude(modulation / phase) modcell = self._get_cell_with_modulation(modulation / phase * amplitude) symmetry = get_symmetry_dataset( modcell, tolerance=self._symmetry_tolerance) num_op = len(symmetry['rotations']) if num_op > max_num_op: max_num_op = num_op best_cells = [modcell] best_spacegroup_types = [symmetry['number']] points_on_sphere = [[point, phase, amplitude]] elif num_op == max_num_op: if symmetry['number'] in best_spacegroup_types: cell_in_best_cells = False for bc in best_cells: if xtal_compare(bc, modcell, tolerance=self._symmetry_tolerance, angle_tolerance=1.0): cell_in_best_cells = True break if not cell_in_best_cells: best_cells.append(modcell) points_on_sphere.append([point, phase, amplitude]) else: best_cells.append(modcell) points_on_sphere.append([point, phase, amplitude]) best_spacegroup_types.append(symmetry['number']) self._points_on_sphere = points_on_sphere
def next(self): if self._stage == 0: if self._status == "terminate": raise StopIteration cell = self._tasks[0].get_cell() tid = self._find_equivalent_crystal_structure(cell) if tid > 0: # Equivalent structure found self._status = "confluence with [%d]" % tid symmetry = get_symmetry_dataset( cell, tolerance=self._symmetry_tolerance) self._space_group_type = symmetry['international_standard'] raise StopIteration elif (self._traverse == "restart" and not os.path.exists("phonon-1")): # This condition means the structure optimization terminated # by that equivalent crystal strucutre was found. However # in restart mode, the order to parse directory tree can # be different from that in run time. So inequivalent # crystal structure can be found different point. # This condition indicates there should be an equivalent # crystal structure somewhere else. In this case, this # 'next' does nothing (restarting stage0) and waits for # until it will be found. self.begin() return self._tasks else: # No equivalent structure found, move to phonon calculation self._ancestral_cells[self._tid_parent] = cell self._set_stage1(cell) self._stage = 1 self._status = "stage 1" return self._tasks else: if self._status == "next": self._analyze_phonon() self._status = "done" raise StopIteration
def _analyze_phonon(self): for dimension, task in zip(self._supercell_dimensions, self._tasks): self._energy = task.get_energy() phonon = task.get_phonon() phonon.set_mesh(dimension, is_gamma_center=True) qpoints, weigths, frequencies, eigvecs = phonon.get_mesh() eigenvalues = frequencies**2 * np.sign(frequencies) if (eigenvalues < self._cutoff_eigenvalue).any(): imaginary_modes = [] qpoints_done = [ imag_mode[1] for imag_mode in self._imaginary_modes ] self._imaginary_modes += get_unstable_modulations( phonon, dimension, symmetry_tolerance=self._symmetry_tolerance, max_displacement=self._max_displacement, cutoff_eigenvalue=self._cutoff_eigenvalue, ndiv=self._num_sampling_points, excluded_qpoints=qpoints_done) sym_dataset = get_symmetry_dataset(self._tasks[0].get_cell()) self._space_group_type = sym_dataset['international_standard']
def estimate_supercell_matrix(cell, max_num_atoms=120, symprec=1e-5): """Estimate supercell matrix from conventional cell Supercell matrix is estimated from basis vector lengths and maximum number of atoms accepted. The input cell must be already standarized. For triclinic, monoclinic, and orthorhombic cells, basis vectors of a, b, c are freely multiplied, but for tetragonal and hexagonal cells, multiplicities of a and b are the same, and for cubic cell, those of a, b, c are to be found the same. The supercell matrix is always returned as a diagonal matrix. """ dataset = get_symmetry_dataset(cell) spg_num = dataset['number'] num_atoms = len(cell.get_numbers()) lengths_orig = get_lattice_parameters(cell.get_lattice()) lengths = get_lattice_parameters(dataset['std_lattice']) # assert (np.abs(lengths_orig - lengths) < symprec).all(), \ # "%s\n%s" % (cell.get_lattice(), dataset['std_lattice']) if spg_num <= 74: # Triclinic, monoclinic, and orthorhombic multi = _get_multiplicity_abc(num_atoms, lengths, max_num_atoms) elif spg_num <= 194: # Tetragonal and hexagonal multi = _get_multiplicity_ac(num_atoms, lengths, max_num_atoms) else: # Cubic multi = _get_multiplicity_a(num_atoms, lengths, max_num_atoms) smat = np.eye(3, dtype='intc') for i in range(3): smat[i, i] = multi[i] return smat
def _set_stage1(self, cell): prim_cell = get_primitive(cell, tolerance=self._symmetry_tolerance) sym_dataset = get_symmetry_dataset(prim_cell) self._space_group_type = sym_dataset['international_standard'] spg_number = sym_dataset['number'] if (spg_number >= 143 and spg_number <= 194 and not self._space_group_type[0] == 'R'): # Hexagonal lattice self._supercell_dimensions = [[3, 3, 2], [2, 2, 2]] else: # Other cases self._supercell_dimensions = [[2, 2, 2]] # Long cell axis is not multiplied. for dimension in self._supercell_dimensions: for i, length in enumerate( get_lattice_parameters(prim_cell.get_lattice())): if length * dimension[i] > 20: dimension[i] = 1 self._tasks = [] for i, dimension in enumerate(self._supercell_dimensions): task = self._get_phonon_task(prim_cell, np.diag(dimension), "phonon-%d" % (i + 1)) self._phre_tasks.append(task) self._tasks.append(task)
def _run(self): self._set_best_arguments_of_vectors_and_supercell() max_num_op = 0 best_cells = [] points_on_sphere = [] for i, point in enumerate(self._get_all_points_on_sphere()): modcell = self._get_cell_with_modulation( self._get_modulation(point)) symmetry = get_symmetry_dataset( modcell, tolerance=self._symmetry_tolerance) if self._store_all: self._all_cells.append(modcell) refined_cell = get_crystallographic_cell( modcell, tolerance=self._symmetry_tolerance) num_op = len(symmetry['rotations']) if num_op > max_num_op: max_num_op = num_op best_cells = [refined_cell] points_on_sphere = [point.copy()] if num_op == max_num_op: is_found = True for bc in best_cells: if xtal_compare(bc, refined_cell, tolerance=self._symmetry_tolerance, angle_tolerance=1.0): is_found = False break if is_found: best_cells.append(refined_cell) points_on_sphere.append(point.copy()) self._points_on_sphere = points_on_sphere
def symmetry(cell, tolerance=1e-5): """ """ return get_symmetry_dataset(cell, tolerance)
def next(self): if self._status == "terminate": self._stress = None self._forces = None self._energy = None self._next_cell = None else: task = self._tasks[0] self._next_cell = task.get_current_cell() stress = task.get_stress() forces = task.get_forces() energy = task.get_energy() if not stress == None: self._stress = stress if not forces == None: self._forces = forces if not energy == None: self._energy = energy if "terminate" in self._status and self._traverse == "restart": self._traverse = False if self._stage > 2: self._stage -= 2 task = self._so_tasks.pop() task = self._so_tasks.pop() self._next_cell = task.get_cell() else: self._so_tasks = [] self._stage = 0 self._next_cell = self._cell self._status = "next" if self._next_cell: if self._impose_symmetry: self._next_cell = get_primitive( self._next_cell, tolerance=self._symmetry_tolerance) self._space_group = get_symmetry_dataset(self._next_cell) else: if self._find_symmetry: self._space_group = get_symmetry_dataset( self._next_cell, tolerance=self._symmetry_tolerance) if self._space_group: self._comment = self._space_group['international_standard'] if self._status == "done": if self._stage < self._min_iteration: self._status = "next" if self._status == "next": if self._stage == self._max_iteration: self._status = "max_iteration" else: self._set_next_task() self._write_yaml() if "stage" in self._status: return self._tasks else: self._tasks = [] raise StopIteration