def write_born_file(initial_structure, phonopy_inputs, dielectric_tensor, born_effective_charge_tensor, file_path): """ Creates the born file that phonopy needs for the non-analytical correction to be applied. """ phonon = get_initialized_phononopy_instance(initial_structure, phonopy_inputs) symm = Symmetry(cell=phonon.get_primitive(), symprec=phonopy_inputs['symprec']) independent_atom_indices_list = symm.get_independent_atoms() born_file = File() born_file += "14.400" flat_dielectric_list = misc.flatten_multi_dimensional_list( dielectric_tensor) born_file += " ".join(str(component) for component in flat_dielectric_list) print "Independent atom indices:", independent_atom_indices_list for atomic_bec_index in independent_atom_indices_list: atomic_bec = born_effective_charge_tensor[atomic_bec_index] flat_atomic_bec = misc.flatten_multi_dimensional_list(atomic_bec) born_file += " ".join(str(component) for component in flat_atomic_bec) born_file.write_to_path(file_path)
def print_eigenvalues_to_file(self, file_path): file = File() for i, eigen_pair in enumerate(self.get_sorted_hessian_eigen_pairs_list()): file += "u_" + str(i+1) + ": " + str(eigen_pair.eigenvalue) file.write_to_path(file_path)
def write_error_to_path(calculation_path, error_string): error_path = Path.join( calculation_path, QueueAdapter.error_path + "_" + su.get_time_stamp_string()) file = File() file[0] = error_string file.write_to_path(error_path)
def get_queue_view_file(): """ Returns a file that gives information of all jobs for this user. Looks something like like: 682554.fenrir.bw angsten default job 16794 1 -- -- 16:00 R 00:01 682555.fenrir.bw angsten default job 16794 1 -- -- 16:00 R 00:01 682557.fenrir.bw angsten default job 16794 1 -- -- 16:00 C 00:03 """ output_file = File() if QueueAdapter.host in ['Fenrir', 'Asathor']: queue_view_process = subprocess.Popen("qstat -a | grep " + QueueAdapter.user, shell=True, stdout=subprocess.PIPE) output, error = queue_view_process.communicate() if error: raise Exception("Error in getting view of queue: " + error) else: output_file += output #output is string with \n's built in - file class will handle this automatically output_file.trim_trailing_whitespace_only_lines( ) #otherwise empty output will lead to lines in out_file looking like [''] - errors out then elif QueueAdapter.host == 'Tom_hp': pass else: raise Exception("QueueAdapter.host not supported") return output_file
def __init__(self, file_path=None, elements_list=None, basenames_list=None, calculation_type='lda_paw', minimal_form=None): super(Potcar, self).__init__(file_path) if file_path: if self.get_lines_containing_string("PAW_PBE"): #be careful if potcars different than used to in future self.calculation_type = 'gga_paw_pbe' else: self.calculation_type = 'lda_paw' if minimal_form: calculation_type = minimal_form['calculation_type'] basenames_list = minimal_form['basenames'] if elements_list or basenames_list: self.calculation_type = calculation_type element_mapping_file = File(Potcar.element_mapping_path) element_mapping_string = str(element_mapping_file) potcar_dict = json.loads(element_mapping_string) base_path = potcar_dict[calculation_type]['path'] if elements_list: potcar_paths = [Path.clean(base_path, potcar_dict[calculation_type][element], 'POTCAR') for element in elements_list] elif basenames_list: potcar_paths = [Path.clean(base_path, basename, 'POTCAR') for basename in basenames_list] concatenated_file = File() for path in potcar_paths: concatenated_file = concatenated_file + File(path) self.lines = concatenated_file.lines
def test_add(self): file_path = Path.clean(self.data_path, 'small_file.txt') file = File(file_path) add_str = "string to add" right_full_str = file + add_str self.assertEqual(right_full_str, "Small file\n Very small \n\nstring to add") l_add_str = " left string to add" left_full_str = l_add_str + file self.assertEqual(left_full_str, " left string to addSmall file\n Very small \n\n") file_path_1 = Path.clean(self.data_path, 'small_file.txt') file_path_2 = Path.clean(self.data_path, 'small_file_2.txt') first_file = File(file_path_1) second_file = File(file_path_2) final_file = first_file + second_file self.assertEqual(final_file.lines, [ 'Small file', ' Very small ', '', '', 'Small file 2', ' Not as small ', '' ])
def write_parent_paths_to_file(self): if self.parent_paths_list: file = File() for path in self.parent_paths_list: file += path file.write_to_path(self.get_extended_path(".parent_paths"))
def print_eigen_components_to_file(self, file_path): file = File() for i, eigen_pair in enumerate(self.get_sorted_hessian_eigen_pairs_list()): file += "Index: " + str(i) + "\n" + str(eigen_pair) file += '' file.write_to_path(file_path)
def write_id_string_to_path(calculation_path, id_string): """ Writes id_string to the first line of the id file at id_path """ id_path = Path.join(calculation_path, QueueAdapter.id_path) file = File() file[0] = id_string file.write_to_path(id_path)
def test_write_to_path(self): file_path = Path.clean(self.data_path, 'small_file.txt') file = File(file_path) file[0] += " for line 0" file[3] = "line 3" file += "" file += "here\nand here" file += "" self.assertEqual(file.lines, [ 'Small file for line 0', ' Very small ', '', 'line 3', '', 'here', 'and here', '' ]) file.write_to_path( Path.clean(self.data_path, 'small_file_ammended.txt')) file_2 = File(Path.clean(self.data_path, 'small_file_ammended.txt')) file_2[2] = "no more" file_2.write_to_path() file_3 = File(Path.clean(self.data_path, 'small_file_ammended.txt')) self.assertEqual(file_3.lines, [ 'Small file for line 0', ' Very small ', 'no more', 'line 3', '', 'here', 'and here', '' ])
def get_submission_file(): if QueueAdapter.host in ['Fenrir', 'Asathor']: return File(Path.clean("/home/angsten/.submit.sh")) elif QueueAdapter.host == 'Tom_hp': file = File() file[0] = 'fake submit script' file[1] = 'nodes = 3' return file elif QueueAdapter.host == 'Savio': return File('/global/home/users/angsten/submit.sh')
def test_str(self): file = File(Path.clean(self.data_path, 'small_file.txt')) self.assertEqual(str(file), "Small file\n Very small \n\n") file = File(Path.clean(self.data_path, 'empty.txt')) self.assertEqual(str(file), "") file = File(Path.clean( self.data_path, 'almost_empty.txt')) #this file contains: line 1: '\n' line 2: '' self.assertEqual(str(file), "\n")
def print_selected_uniques_to_file(self, file_path): file = File() for unique_data_triplet in self.get_sorted_unique_relaxation_data_list( ): file += "Energy: " + str( unique_data_triplet[0].get_final_energy(per_atom=False)) file += "Final Chromosome:" file += misc.get_formatted_chromosome_string( unique_data_triplet[2]) file += "" file.write_to_path(file_path)
def print_mode_effective_charge_vectors_to_file(self, file_path, reference_structure): file = File() f = su.pad_decimal_number_to_fixed_character_length rnd = 4 pad = 7 for i, eigen_pair in enumerate(self.get_sorted_hessian_eigen_pairs_list()): index_string = str(i+1) while len(index_string) < 3: index_string += ' ' file += "u_" + index_string + ' ' + f(eigen_pair.eigenvalue, 2, pad) + ' ' + " ".join(f(x, rnd, pad) for x in self.get_mode_effective_charge_vector(eigen_pair.eigenvector, reference_structure)) #file += '' file.write_to_path(file_path)
def get_parent_paths_list(self): if Path.exists(self.get_extended_path(".parent_paths")): file = File(self.get_extended_path(".parent_paths")) paths_list = [line for line in file] return paths_list else: return None
def get_structure_creation_id_string(self): if not Path.exists(self.get_structure_creation_id_file_path()): return None else: file = File(self.get_structure_creation_id_file_path()) if len(file) < 1: return None else: return file[0]
def get_job_id_at_path(calculation_path): """ Looks in the .job_id file for an id. Returns id as a string if present, None if not present """ id_path = Path.join(calculation_path, QueueAdapter.id_path) if Path.exists(id_path): return File(id_path)[0] else: return None
def view(self, files_to_view=['Potcar', 'Kpoints', 'Incar', 'Poscar', 'Contcar', 'Submit.sh', '_JOB_OUTPUT.txt']): """ See printing of actual text input files written in directory, not internally stored input files. Useful for validating runs. files_to_view list is case insensitive - it will find 'POSCAR' file if you input 'poscar' for instance """ head_string = "==> " file_separator = 30*"-" output_string = "" output_string += "\n\n\n" + 30*"-" + "VaspRun View: Job ID is " + str(self.job_id_string) + 30*"-" + 55*"*" + "\n\n\n" output_string += head_string + "Path: " + self.path + "\n" for file_name in files_to_view: actual_file_name = Path.get_case_insensitive_file_name(self.path, file_name) #if Submit.sh is file_name, could find submit.sh for example if not actual_file_name: output_string += head_string + file_name + " file not present" + "\n" continue file_path = self.get_extended_path(actual_file_name) if actual_file_name.upper() == 'POTCAR': potcar = Potcar(file_path) file_string = " ".join(potcar.get_basenames_list()) + '\n' else: file = File(file_path) file_string = str(file) output_string += head_string + actual_file_name + ":\n" + file_separator + "\n" + file_string + file_separator + "\n\n" output_string += "\n\n" + 30*"-" + "End VaspRun View for Job ID " + str(self.job_id_string) + 30*"-" + "\n\n\n\n" print output_string, # def log(self, log_string, raise_exception=False): # """Tracks the output of the run, logging either to stdout or a local path file or both""" # log_string = log_string.rstrip('\n') + '\n' # log_string_with_time_stamp = su.get_time_stamp_string() + " || " + log_string # if not Path.exists(VaspRun.log_path): # File.touch(self.get_extended_path(VaspRun.log_path)) # log_file = File(self.get_extended_path(VaspRun.log_path)) # log_file.append(log_string_with_time_stamp) # log_file.write_to_path() # if raise_exception: # raise Exception(log_string)
def convert_phonopy_atoms_to_structure(phonopy_atoms_structure): """ Converts phonopy's representation of a structure to an instance of Structure. """ temporary_write_path = Path.get_temporary_path() Path.validate_does_not_exist(temporary_write_path) Path.validate_writeable(temporary_write_path) write_vasp(temporary_write_path, phonopy_atoms_structure) species_list = convert_phonopy_symbols_to_unique_species_list( phonopy_atoms_structure.symbols) structure_poscar_file = File(temporary_write_path) structure_poscar_file.insert( 5, " ".join(species_list)) #phonopy uses bad poscar format structure_poscar_file.write_to_path() final_structure = Structure(temporary_write_path) Path.remove(temporary_write_path) Structure.validate(final_structure) return final_structure
def quick_view(self): """ Gives queue properties, energy list, tail of _JOB_OUTPUT.txt file """ extend_count = 200 print "\n"*3 print "-"*extend_count print " Relaxation Run at " + self.path print "-"*extend_count if self.run_count == self.external_relaxation_count: run_str = "Static Run" else: run_str = "Relax_" + str(self.run_count) if self.run_count > 0: run = self.get_current_vasp_run() print run.path, '\n\n' print run.queue_properties, '\n\n' std_out_path = run.get_extended_path('_JOB_OUTPUT.txt') if Path.exists(std_out_path): std_out_file = File(run.get_extended_path('_JOB_OUTPUT.txt')) print "-"*140 print "\n".join(std_out_file[:40]) print " ." print " ." print " ." print " ." print " ." print "\n".join(std_out_file[-40:]) print "-"*140 else: print "No _JOB_OUTPUT.txt file found" print "\n"*3
def test_overrides(self): file = File() self.assertFalse(file) file[2] = ' inserted line ' self.assertEqual(file.lines, ['', '', ' inserted line ']) file[1] = 'add this line\n and this one where index 1 was' self.assertEqual(file.lines, [ '', 'add this line', ' and this one where index 1 was', ' inserted line ' ]) file[1] = 'replaced add this line' self.assertEqual(file.lines, [ '', 'replaced add this line', ' and this one where index 1 was', ' inserted line ' ]) self.assertEqual( file.lines[1:3], ['replaced add this line', ' and this one where index 1 was']) del file[1] del file[0:2] self.assertEqual(file.lines, [' inserted line ']) self.assertFalse("home is where the heart is" in file) self.assertTrue("line" in file) file += "new line added" self.assertEqual(file.lines, [' inserted line ', 'new line added']) file.insert(0, 'inserted at beginning') file.insert(2, 'right before new line added line') self.assertEqual(file.lines, [ 'inserted at beginning', ' inserted line ', 'right before new line added line', 'new line added' ]) self.assertTrue(file) self.assertEqual(len(file), 4) l = [ 'inserted at beginning', ' inserted line ', 'right before new line added line', 'new line added' ] for x, item in enumerate(file): self.assertEqual(item, l[x])
import numpy as np import matplotlib.mlab as mlab import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages from fpctoolkit.io.file import File import fpctoolkit.util.string_util as su file_path = 'C:\Users\Tom\Desktop\dos_5at_kvo' file = File(file_path) num_atoms = 5 def get_floats_list_from_string(line): return [float(x) for x in su.remove_extra_spaces(line.strip()).split(' ')] # print file tag_line = file[5] fermi_energy = get_floats_list_from_string(tag_line)[3] print "Fermi energy: " + str(fermi_energy) section_indices = [] for i, line in enumerate(file): if line == tag_line: section_indices.append(i)
elif exp == 1: exp_string = "*x" else: exp_string = "" fit_string += str(round(fitting_parameters[index], 3)) + exp_string + " + " return fit_string[:-2] data_file = File("C:/Users/Tom/Documents/Berkeley/research/scripts/fpctoolkit/data/derivative_plot_data_pretty") header_line = data_file[0] header_data = header_line.split(' ') #SrTiO3 a=3.79 encut=600eV kpoints=3x3x3M disp_step=0.01A u2 Energy pp = PdfPages('C:\Users\Tom\Desktop\derivative_fits/' + header_data[0] + "/" + header_data[1] + '.pdf') start_index = 1 end_index = None out_dict = {} j = 1
else: hessian = Hessian(dfpt_force_run.outcar) #hessian.print_eigen_components() hessian.print_eigenvalues() guessed_minima_data_path = Path.join(base_path, 'guessed_chromosomes') minima_path = Path.join(base_path, 'minima_tests') if Path.exists(guessed_minima_data_path): minima_file = File(guessed_minima_data_path) eigen_chromosome_energy_pairs_list = [] #[[predicted_energy_difference_1, [e1, e2, e3, e4, ...]], [predicted_energy_difference_2, [e1, ...]]] for line in minima_file: energy_difference = float((line.strip()).split(',')[0]) eigen_chromosome = [float(x) for x in (line.strip()).split(',')[1].split(' ')[1:]] eigen_chromosome_energy_pairs_list.append([energy_difference, eigen_chromosome]) minima_relaxer = MinimaRelaxer(path=minima_path, reference_structure=relaxed_structure, reference_completed_vasp_relaxation_run=relaxation, hessian=hessian, vasp_relaxation_inputs_dictionary=minima_relaxation_input_dictionary, eigen_chromosome_energy_pairs_list=eigen_chromosome_energy_pairs_list) minima_relaxer.update()
def get_table_chunk(misfit_strain, mode_count): output_string = "" mfit_str = str(misfit_strain) while len(mfit_str) < 5: mfit_str += " " file_path = Path.join( str(misfit_strain).replace('-', 'n'), "output_mode_effective_charge_vectors") file = File(file_path) eigen_values_list = [] untouched_eig_vals_list = [] polarizations_list = [] spg_list = [] glazers_list = ['N/A'] * mode_count glazer_tracker_dict = {} glazers = [ "$a^0_+b^0_0b^0_0$", "$a^0_0b^0_+a^0_0$", "$a^0_0a^0_0c^0_+$", "$a^-_0b^0_0b^0_0$", "$a^0_0b^-_0a^0_0$", "$a^0_0a^0_0c^-_0$", "$a^+_0b^0_0b^0_0$", "$a^0_0b^+_0a^0_0$", "$a^0_0a^0_0c^+_0$" ] for i in range(0, mode_count): line = file[i] line = su.remove_extra_spaces(line) parts = line.split(' ') eigen_value = parts[1] px = parts[2] py = parts[3] pz = parts[4] spg = parts[5] if spg == 'I4/mmm': #################################################### spg = 'P4/mbm' translational_mode = bool(spg == 'Pm-3m') spg_list.append(spg) if not spg in glazer_tracker_dict: glazer_tracker_dict[spg] = [[i, eigen_value]] else: glazer_tracker_dict[spg].append([i, eigen_value]) if not translational_mode: eigen_values_list.append(round_string(eigen_value)) polarizations_list.append('(' + round_string(px) + ' ' + round_string(py) + ' ' + round_string(pz) + ')') if spg == 'P4mm': if abs(float(px)) > 0.0: glazers_list[i] = glazers[0] elif abs(float(py)) > 0.0: glazers_list[i] = glazers[1] elif abs(float(pz)) > 0.0: glazers_list[i] = glazers[2] else: eigen_values_list.append('') polarizations_list.append('*') glazers_list[i] = '' untouched_eig_vals_list.append(eigen_value) for i in range(0, mode_count): glazer_string = "" spg = spg_list[i] current_eig_val = untouched_eig_vals_list[i] for entry in glazer_tracker_dict[spg]: index = entry[0] eig_val = entry[1] if index != i and eig_val == current_eig_val: if spg == 'I4/mcm': glazers_list[i] = glazers[3] if glazers[ 3] not in glazers_list else glazers[4] elif spg == 'P4/mbm': glazers_list[i] = glazers[6] if glazers[ 6] not in glazers_list else glazers[7] break if glazers_list[i] == 'N/A': if spg == 'I4/mcm': glazers_list[i] = glazers[5] elif spg == 'P4/mbm': glazers_list[i] = glazers[8] output_string += " & $\lambda_i$ & " + " & ".join( eigen_values_list) + '\\\\\n' output_string += mfit_str + " & $\\vec{Z}_i$ & " + " & ".join( polarizations_list) + ' \\\\\n' output_string += " & Modified Glazer & " + " & ".join( glazers_list) + "\\\\" return output_string
def update(self): file = File() file += ''.join(self.reference_structure.get_species_list( )) + '3' + ' a=' + str( round(self.reference_structure.lattice[0][0] / 2.0, 2) ) + 'A ediff=' + str( self.vasp_run_inputs_dictionary['ediff']) + ' encut=' + str( self.vasp_run_inputs_dictionary['encut']) + ' ' + 'x'.join( str(k) for k in self.vasp_run_inputs_dictionary['kpoint_subdivisions_list'] ) + self.vasp_run_inputs_dictionary['kpoint_scheme'][ 0] + ' disp_step=' + str( self.displacement_finite_differences_step_size) + 'A' Path.make(self.path) perturbation_magnitude_lists_dictionary = { 'displacement': [ self.perturbation_magnitudes_dictionary['displacement'] * i for i in range(0, 14) ], 'strain': [ self.perturbation_magnitudes_dictionary['strain'] * i for i in range(-15, 15 + 1) ] } total_variables_list = self.displacement_variables_list + self.strain_variables_list #u^2, u^4, and e^2 coefficients for variable in total_variables_list: variable_path = self.get_extended_path(str(variable)) Path.make(variable_path) print str(variable) file += str(variable) + ' Energy' perturbation_magnitudes_list = copy.deepcopy( perturbation_magnitude_lists_dictionary[variable.type_string]) if str(variable) in ['e_4', 'e_5']: perturbation_magnitudes_list = [-0.02, -0.01, 0.0, 0.01, 0.02] if str(variable) in self.variable_specialty_points_dictionary: for additional_perturbation_magnitude in self.variable_specialty_points_dictionary[ str(variable)]: perturbation_magnitudes_list.append( additional_perturbation_magnitude) perturbation_magnitudes_list = sorted(perturbation_magnitudes_list) print "Pert list is " + str(perturbation_magnitudes_list) energies_list = [] for perturbation_magnitude in perturbation_magnitudes_list: eigen_chromosome = [0.0] * ( 3 * self.reference_structure.site_count) if variable.type_string == 'displacement': add_index = 6 else: add_index = 0 eigen_chromosome[variable.index + add_index] = perturbation_magnitude energies_list.append( self.get_energy_of_eigen_chromosome( path=Path.join( variable_path, str(perturbation_magnitude).replace('-', 'n')), eigen_chromosome=eigen_chromosome)) if variable.type_string == 'displacement': #Due to centrosymmetry, we know the negative chromosomes have equal energy for i in range(len(energies_list) - 1, 0, -1): file += str( -1.0 * perturbation_magnitudes_list[i]) + " " + str( energies_list[i]) #file += "0.0 " + str(self.reference_completed_vasp_relaxation_run.get_final_energy(per_atom=False)) for i in range(len(energies_list)): file += str(perturbation_magnitudes_list[i]) + " " + str( energies_list[i]) file += '' #e*u^2 terms for strain_variable in self.strain_variables_list: for m, displacement_variable_1 in enumerate( self.displacement_variables_list): for j in range(m, len(self.displacement_variables_list)): if not j == m: continue if str(strain_variable) in [ 'e_4', 'e_5' ]: ##########################################temp remove!!!!!!!!!!!! continue displacement_variable_2 = self.displacement_variables_list[ j] print str(strain_variable) + ' d^2E/d' + str( displacement_variable_1) + 'd' + str( displacement_variable_2) file += str(strain_variable) + ' d^2E/d' + str( displacement_variable_1) + 'd' + str( displacement_variable_2) path = self.get_extended_path( str(strain_variable) + "_" + str(displacement_variable_1) + "_" + str(displacement_variable_2)) Path.make(path) for i in range(-3, 4): strain = i * 0.005 #self.perturbation_magnitudes_dictionary['strain']*0.5 calculation_path = Path.join( path, str(strain).replace('-', 'n')) eigen_chromosome = [0.0] * ( 3 * self.reference_structure.site_count) eigen_chromosome[strain_variable.index] = strain structure = self.get_distorted_structure_from_eigen_chromosome( eigen_chromosome) file += str(strain) + " " + str( self.get_displacement_second_derivative( calculation_path, structure, displacement_variable_1.index, displacement_variable_2.index)) file += '' file.write_to_path(self.status_file_path)
def run_misfit_strain(path, misfit_strain, input_dictionary, initial_relaxation_input_dictionary, dfpt_incar_settings, derivative_evaluation_vasp_run_inputs_dictionary, minima_relaxation_input_dictionary, epitaxial_relaxation_input_dictionary): Path.make(path) guessed_minima_data_path = Path.join(path, 'guessed_chromosomes') species_list = input_dictionary['species_list'] reference_lattice_constant = input_dictionary['reference_lattice_constant'] Nx = input_dictionary['supercell_dimensions_list'][0] Ny = input_dictionary['supercell_dimensions_list'][1] Nz = input_dictionary['supercell_dimensions_list'][2] displacement_finite_differences_step_size = input_dictionary[ 'displacement_finite_differences_step_size'] perturbation_magnitudes_dictionary = input_dictionary[ 'perturbation_magnitudes_dictionary'] a = reference_lattice_constant * (1.0 + misfit_strain) initial_structure = Perovskite( supercell_dimensions=[Nx, Ny, Nz], lattice=[[a * Nx, 0.0, 0.0], [0.0, a * Ny, 0.0], [ 0.0, 0.0, reference_lattice_constant * Nz * (1.0 + 0.3 * (1.0 - (a / reference_lattice_constant))) ]], species_list=species_list) relaxation = VaspRelaxation( path=Path.join(path, 'relaxation'), initial_structure=initial_structure, input_dictionary=initial_relaxation_input_dictionary) if not relaxation.complete: relaxation.update() return False relaxed_structure = relaxation.final_structure relaxed_structure_path = Path.join(path, 'output_relaxed_structure') relaxed_structure.to_poscar_file_path(relaxed_structure_path) force_calculation_path = Path.join(path, 'dfpt_force_calculation') kpoints = Kpoints(scheme_string=kpoint_scheme, subdivisions_list=kpoint_subdivisions_list) incar = IncarMaker.get_dfpt_hessian_incar(dfpt_incar_settings) input_set = VaspInputSet(relaxed_structure, kpoints, incar, auto_change_lreal=False, auto_change_npar=False) input_set.incar['lepsilon'] = True dfpt_force_run = VaspRun(path=force_calculation_path, input_set=input_set) if not dfpt_force_run.complete: dfpt_force_run.update() return False hessian = Hessian(dfpt_force_run.outcar) if input_dictionary['write_hessian_data']: hessian.print_eigenvalues_to_file( Path.join(path, 'output_eigen_values')) hessian.print_eigen_components_to_file( Path.join(path, 'output_eigen_components')) hessian.print_mode_effective_charge_vectors_to_file( Path.join(path, 'output_mode_effective_charge_vectors'), relaxed_structure) eigen_structure = EigenStructure(reference_structure=relaxed_structure, hessian=hessian) mode_structures_path = Path.join(path, 'mode_rendered_structures') Path.make(mode_structures_path) mode_charge_file = File( Path.join(path, 'output_mode_effective_charge_vectors')) sorted_eigen_pairs = hessian.get_sorted_hessian_eigen_pairs_list() for i, structure in enumerate( eigen_structure.get_mode_distorted_structures_list( amplitude=0.6)): if i > 30: break structure.to_poscar_file_path( Path.join( mode_structures_path, 'u' + str(i + 1) + '_' + str(round(sorted_eigen_pairs[i].eigenvalue, 2)) + '.vasp')) structure.lattice = Lattice([[8.0, 0.0, 0.0], [0.0, 8.0, 0.0], [0.0, 0.0, 8.0]]) mode_charge_file[i] += ' ' + structure.get_spacegroup_string( symprec=0.2) + ' ' + structure.get_spacegroup_string( symprec=0.1) + ' ' + structure.get_spacegroup_string( symprec=0.001) mode_charge_file.write_to_path() #sys.exit() ################################################### random structure searcher if True: rand_path = Path.join(path, 'random_trials') Path.make(rand_path) num_guesses = 1 num_modes = 12 max_amplitude = 0.6 if misfit_strain == 0.02: eigen_structure = EigenStructure( reference_structure=relaxed_structure, hessian=hessian) for i in range(num_guesses): trial_path = Path.join(rand_path, str(i)) if not Path.exists(trial_path): initial_structure_trial = eigen_structure.get_random_structure( mode_count_cutoff=num_modes, max_amplitude=max_amplitude) trial_relaxation = VaspRelaxation( path=trial_path, initial_structure=initial_structure_trial, input_dictionary=minima_relaxation_input_dictionary) else: trial_relaxation = VaspRelaxation(path=trial_path) print "Updating random trial relaxation at " + trial_relaxation.path + " Status is " + trial_relaxation.get_status_string( ) trial_relaxation.update() if trial_relaxation.complete: print "Trial " + str(i) print trial_relaxation.get_data_dictionary() return None ################################################### if not Path.exists(guessed_minima_data_path): variable_specialty_points_dictionary = input_dictionary[ 'variable_specialty_points_dictionary_set'][ misfit_strain] if input_dictionary.has_key( misfit_strain) else {} derivative_evaluation_path = Path.join( path, 'expansion_coefficient_calculations') derivative_evaluator = DerivativeEvaluator( path=derivative_evaluation_path, reference_structure=relaxed_structure, hessian=hessian, reference_completed_vasp_relaxation_run=relaxation, vasp_run_inputs_dictionary= derivative_evaluation_vasp_run_inputs_dictionary, perturbation_magnitudes_dictionary= perturbation_magnitudes_dictionary, displacement_finite_differences_step_size= displacement_finite_differences_step_size, status_file_path=Path.join(path, 'output_derivative_plot_data'), variable_specialty_points_dictionary= variable_specialty_points_dictionary, max_displacement_variables=input_dictionary[ 'max_displacement_variables']) derivative_evaluator.update() else: minima_path = Path.join(path, 'minima_relaxations') minima_relaxer = MinimaRelaxer( path=minima_path, reference_structure=relaxed_structure, reference_completed_vasp_relaxation_run=relaxation, hessian=hessian, vasp_relaxation_inputs_dictionary= minima_relaxation_input_dictionary, eigen_chromosome_energy_pairs_file_path=guessed_minima_data_path, log_base_path=path, max_minima=input_dictionary['max_minima']) minima_relaxer.update() minima_relaxer.print_status_to_file( Path.join(path, 'output_minima_relaxations_status')) if minima_relaxer.complete: print "Minima relaxer complete: sorting the relaxations to find the lowest energy structure." #minima_relaxer.print_selected_uniques_to_file(file_path=Path.join(path, 'output_selected_unique_minima_relaxations')) sorted_uniques = minima_relaxer.get_sorted_unique_relaxation_data_list( ) return sorted_uniques
if minima_relaxer.complete: print "Minima relaxer complete: sorting the relaxations to find the lowest energy structure." #minima_relaxer.print_selected_uniques_to_file(file_path=Path.join(path, 'output_selected_unique_minima_relaxations')) sorted_uniques = minima_relaxer.get_sorted_unique_relaxation_data_list( ) return sorted_uniques if __name__ == '__main__': ####################################################################################################### input_dictionary = {} input_dictionary['species_list'] = File( './system_formula')[0].strip().split(' ') print input_dictionary['species_list'] #which misfit strains to run expansion approximation scheme at misfit_strains_list = [-0.02, -0.01, 0.0, 0.01, 0.02] variable_specialty_points_dictionary_set = {} #variable_specialty_points_dictionary_set[-0.02] = { # 'u_2': [0.001, 0.2], # 'e_3': [0.45] # } lattice_constants_dictionary = {} lattice_constants_dictionary['SrTiO'] = 3.8610547 lattice_constants_dictionary['CaTiO'] = 3.81331597 lattice_constants_dictionary['SrHfO'] = 4.0680851
def print_status_to_file(self, file_path): print "in print_status_to_file" file = File() spg_symprecs = [0.1, 0.01, 0.001] file += "Complete: " + str(self.complete) file += "" reference_energy = self.reference_completed_vasp_relaxation_run.get_final_energy( per_atom=False) eigen_structure = EigenStructure( reference_structure=self.reference_structure, hessian=self.hessian) for i, vasp_relaxation in enumerate(self.vasp_relaxations_list): mx = len(self.vasp_relaxations_list) if (i % (mx / 10) == 0): mx = self.max_minima if self.max_minima else len( self.eigen_chromosomes_list) print str(i) + "/" + str(mx) file += '-' * 38 + " Structure Guess " + str(i) + ' ' + '-' * 38 file += '' if vasp_relaxation.complete: eigen_structure.set_strains_and_amplitudes_from_distorted_structure( vasp_relaxation.final_structure) eigen_structure_list_representation = eigen_structure.get_list_representation( ) self.completed_relaxations_data_list.append([ vasp_relaxation, self.eigen_chromosomes_list[i], eigen_structure_list_representation ]) file += "DFT Energy Change " + str( vasp_relaxation.get_final_energy(per_atom=False) - reference_energy) file += "Space Group " + " ".join([ vasp_relaxation.final_structure.get_spacegroup_string( symprec) for symprec in spg_symprecs ]) file += "Guessed Energy Change " + str( self.predicted_energies_list[i]) file += "Guessed Chromosome" file += misc.get_formatted_chromosome_string( self.eigen_chromosomes_list[i]) file += "Final Chromosome" file += misc.get_formatted_chromosome_string( eigen_structure_list_representation) else: file += "Guessed Energy Change " + str( self.predicted_energies_list[i]) file += "Guessed Chromosome" file += misc.get_formatted_chromosome_string( self.eigen_chromosomes_list[i]) file += "Incomplete" file += '' file.write_to_path(file_path) print "out of print_status_to_file\n"
def __init__(self, path, reference_structure, reference_completed_vasp_relaxation_run, hessian, vasp_relaxation_inputs_dictionary, eigen_chromosome_energy_pairs_file_path, log_base_path, max_minima=None): """ eigen_chromosome_energy_pairs_list should look like [[predicted energy change, guessed eigen_chromosome], [...],...] vasp_relaxation_inputs_dictionary should look like: vasp_relaxation_inputs_dictionary = { 'external_relaxation_count': 4, 'kpoint_schemes_list': ['Gamma'], 'kpoint_subdivisions_lists': [[1, 1, 1], [1, 1, 2], [2, 2, 4]], 'submission_script_modification_keys_list': ['100', 'standard', 'standard_gamma'], #optional - will default to whatever queue adapter gives 'submission_node_count_list': [1, 2], 'ediff': [0.001, 0.00001, 0.0000001], 'encut': [200, 400, 600, 800], 'isif' : [5, 2, 3] #any other incar parameters with value as a list } max_minima controls how many minima are relaxed. If None, all are relaxed """ minima_file = File(eigen_chromosome_energy_pairs_file_path) eigen_chromosome_energy_pairs_list = [ ] #[[predicted_energy_difference_1, [e1, e2, e3, e4, ...]], [predicted_energy_difference_2, [e1, ...]]] for line in minima_file: energy_difference = float((line.strip()).split(',')[0]) eigen_chromosome = [ float(x) for x in (line.strip()).split(',')[1].split(' ')[1:] ] eigen_chromosome_energy_pairs_list.append( [energy_difference, eigen_chromosome]) self.path = path self.reference_structure = reference_structure self.reference_completed_vasp_relaxation_run = reference_completed_vasp_relaxation_run self.hessian = hessian self.eigen_pairs_list = hessian.get_sorted_hessian_eigen_pairs_list() self.vasp_relaxation_inputs_dictionary = copy.deepcopy( vasp_relaxation_inputs_dictionary) self.max_minima = max_minima sorted_eigen_chromosome_energy_pairs_list = sorted( eigen_chromosome_energy_pairs_list, key=lambda x: x[0]) guesses_log_path = Path.join(log_base_path, 'output_guesses_log') if not Path.exists(guesses_log_path): file = File() sorted_hessian_eigen_pairs_list = hessian.get_sorted_hessian_eigen_pairs_list( ) total = len(sorted_eigen_chromosome_energy_pairs_list) eigen_structure = EigenStructure( reference_structure=self.reference_structure, hessian=self.hessian) for i, eigen_chromosome_energy_pair in enumerate( sorted_eigen_chromosome_energy_pairs_list): print "Writing guess log " + str(i + 1) + " of " + str(total) eigen_structure.set_eigen_chromosome( eigen_chromosome_energy_pair[1]) initial_structure = eigen_structure.get_distorted_structure() spg = initial_structure.get_spacegroup_string(0.001) file += str(eigen_chromosome_energy_pair[0] ) + ' ' + misc.get_formatted_chromosome_string( eigen_chromosome_energy_pair[1]) + ' ' + spg file.write_to_path(guesses_log_path) full_guesses_list_file = File( guesses_log_path ) #lines look like -0.550084 [ 0.000 0.000 -0.009 0.000 0.000 0.000 0.605 0.605 0.000 0.000 0.000 0.000 0.000 0.000 ] Amm2 (38) unique_guesses_file = File() final_pairs_list = [] energies_list = [] seen_before_dictionary = {} print 'Analyzing unique pairs in minima relax' for line in full_guesses_list_file: energy = float(su.remove_extra_spaces(line.split('[')[0])) chromosome = [ float(x) for x in su.remove_extra_spaces( line[line.find('[') + 1:line.find(']')]).split(' ') ] spg = su.remove_extra_spaces(line.split(']')[1]) key = str(energy) + '_' + spg if key in seen_before_dictionary: continue else: seen_before_dictionary[key] = True eigen_chromosome_energy_pair = [energy, chromosome] energies_list.append(eigen_chromosome_energy_pair[0]) final_pairs_list.append(eigen_chromosome_energy_pair) unique_guesses_file += str( eigen_chromosome_energy_pair[0] ) + ' ' + misc.get_formatted_chromosome_string( eigen_chromosome_energy_pair[1]) + ' ' + spg unique_guesses_file.write_to_path( Path.join(log_base_path, 'output_unique_guesses_log')) # #remove redundant energies from list # final_pairs_list = [] # energies_list = [] # for eigen_chromosome_energy_pair in sorted_eigen_chromosome_energy_pairs_list: # if eigen_chromosome_energy_pair[0] in energies_list: # continue # else: # energies_list.append(eigen_chromosome_energy_pair[0]) # final_pairs_list.append(eigen_chromosome_energy_pair) # print "Final pairs list: " # print final_pairs_list self.predicted_energies_list = [ eigen_chromosome_energy_pair[0] for eigen_chromosome_energy_pair in final_pairs_list ] self.eigen_chromosomes_list = [ eigen_chromosome_energy_pair[1] for eigen_chromosome_energy_pair in final_pairs_list ] self.completed_relaxations_data_list = [ ] #list of lists with each component like [relaxation, initial chromosome, final chromosome] self.vasp_relaxations_list = None Path.make(path) print "Initializing minima relaxation runs" self.initialize_relaxation_list()