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 write_input_files_to_path(self, structure, incar, kpoints, potcar, submission_script_file, wavecar_path, chargecar_path): """ Simply write files to path """ structure.to_poscar_file_path(Path.clean(self.path, 'POSCAR')) incar.write_to_path(Path.clean(self.path, 'INCAR')) if kpoints: kpoints.write_to_path(Path.clean(self.path, 'KPOINTS')) elif 'kspacing' not in incar: raise Exception("If no kpoints is provided, must have kspacing parameter in incar set") potcar.write_to_path(Path.clean(self.path, 'POTCAR')) submission_script_file.write_to_path(Path.clean(self.path, 'submit.sh')) if wavecar_path and Path.exists(wavecar_path): Path.copy(wavecar_path, self.get_extended_path('WAVECAR')) if chargecar_path and Path.exists(chargecar_path): Path.copy(chargecar_path, self.get_extended_path('CHARGECAR'))
def get_wavecar_path(self): """ If lwave of current run is true, returns path to wavecar of current run, else None """ if self.run_count == 0: return None current_run = self.get_current_vasp_run() if current_run.incar['lwave']: wavecar_path = current_run.get_extended_path('WAVECAR') return wavecar_path if Path.exists(wavecar_path) else None
def complete(self): for misfit_strain in self.misfit_strains_list: misfit_path = self.get_extended_path(str(misfit_strain).replace('-', 'n')) for i in range(10000): relax_path = Path.join(misfit_path, 'structure_' + str(i)) if not Path.exists(relax_path): return True else: relaxation = VaspRelaxation(path=relax_path) if not relaxation.complete: return False
def load(self): """ Loads the previously saved pickled instance of self at self.path. """ if not Path.exists(self.get_save_path()): raise Exception( "Cannot load individual: no instance saved to file.") file = open(self.get_save_path(), 'r') data_pickle = file.read() file.close() self.__dict__ = cPickle.loads(data_pickle)
def __init__(self, generation_directory_path=None, directory_to_individual_conversion_method=None): """ If generation_directory_path is not none, loads in existing individuals at this path. If generation_directory_path is None, population is initialized as empty. """ self.individuals = [] self.directory_to_individual_conversion_method = directory_to_individual_conversion_method if directory_to_individual_conversion_method else self.default_directory_to_individual_conversion_method if generation_directory_path: if not Path.exists(generation_directory_path): raise Exception("Generation directory path does not exist.") self.append_individuals_at_path(generation_directory_path)
def get_generation_count(self): """ Returns an integer in (0, 1, 2, 3, ...) representing how many generations have been created. """ i = 1 while True: if not Path.exists( self.get_extended_path( PopulationCollection.generation_prefix_string + str(i))): return i - 1 i += 1
def get_next_structure(self): """If first relax, return self.input_initial_structure, else, get the contcar from the current run""" if self.run_count == 0: return self.input_initial_structure current_contcar_path = self.get_current_vasp_run().get_extended_path('CONTCAR') if not Path.exists(current_contcar_path): raise Exception("Method get_next_structure called, but Contcar for current run doesn't exist") elif not self.get_current_vasp_run().complete: raise Exception("Method get_next_structure called, but current run is not yet complete") return Structure(current_contcar_path)
def get_parent_structures_list(self): structure_list = [] i = 0 while True: parent_path = self.get_extended_path('.parent_poscar_' + str(i) + '.vasp') if Path.exists(parent_path): structure_list.append(Structure(parent_path)) i += 1 else: break return structure_list
def structure_is_duplicate(self, structure, misfit_path): """ Returns true if this has been the initial structure for any previous relaxation """ for i in range(10000): relax_path = Path.join(misfit_path, 'structure_' + str(i)) if not Path.exists(relax_path): return False else: comparison_structure = Structure(file_path=Path.join(relax_path, 'original_initial_structure')) if structure.is_equivalent_to_structure(comparison_structure): print "FOUND DUPLICATE in epitaxial_relaxer.py" return True
def get_run_paths_list(self): """ Returns the a list of paths containing the vasp (static) force calculation run paths, i.e. [.../0, .../1, ...] """ run_paths_list = [] i = 0 while Path.exists(self.get_extended_path(str(i))): run_path = self.get_extended_path(str(i)) run_paths_list.append(run_path) i += 1 return run_paths_list
def load(self): """ Loads the previously saved pickled instance of self at self.path. self.path is not overwritted by the load in case the run has since been moved. """ if not Path.exists(self.get_save_path()): raise Exception( "Cannot load calculation set: no instance saved to file.") file = open(self.get_save_path(), 'r') data_pickle = file.read() file.close() previous_path = self.path self.__dict__ = cPickle.loads(data_pickle) self.path = previous_path #in case run is moved
def __init__(self, path, structure=None, incar=None, kpoints=None, potcar=None, submission_script_file=None, input_set=None, wavecar_path=None, chargecar_path=None): """ Cases for __init__: 1. path does not exist or is empty => make the directory, enforce input file arguments all exists, write out input files to directory 2. path exists and is not empty 1. path/.job_id does not exist 1. path has all 5 input files written to it already => do nothing if not all five input parameters exist, else overwrite current input files to directory 2. path does not have all 5 input files (has some subset or none) => enforce input file arguments all exists, write out input files to directory 2. path/.job_id exists => do nothing """ self.path = Path.clean(path) if input_set: structure = input_set.structure incar = input_set.incar kpoints = input_set.kpoints potcar = input_set.potcar submission_script_file = input_set.submission_script_file all_essential_input_parameters_exist = not bool(filter(lambda x: x == None, [structure, incar, potcar, submission_script_file])) if not Path.exists(self.path) or Path.is_empty(self.path): if not all_essential_input_parameters_exist: raise Exception("All five vasp input files must be input for run to be initialized.") else: Path.make(self.path) self.write_input_files_to_path(structure, incar, kpoints, potcar, submission_script_file, wavecar_path, chargecar_path) else: if self.job_id_string: pass else: if self.all_input_files_are_present(): #all input files are written to directory if all_essential_input_parameters_exist: #overwrite what's there self.write_input_files_to_path(structure, incar, kpoints, potcar, submission_script_file, wavecar_path, chargecar_path) else: pass #do nothing - don't have the necessary inputs to start a run else: #not all input files currently exist - must have necessary input params to overwrite if not all_essential_input_parameters_exist: raise Exception("All five vasp input files must be input for run with incomplete inputs at path to be initialized.") else: self.write_input_files_to_path(structure, incar, kpoints, potcar, submission_script_file, wavecar_path)
def get_current_dos_count(self): pre = 'hybrid_electronic_optimization_' current = 0 while Path.exists(Path.join(self.dos_path, pre + str(current + 1))): current += 1 if current == 0: return 0 else: run_path = Path.join(self.dos_path, pre + str(current)) current_dos_run = VaspRun(path=run_path) if current_dos_run.complete: return current + 1 else: return current
def calculations_list(self): calculations_list = [] for vasp_calculation_input_dictionary_parallel_group in self.list_of_vasp_calculation_input_dictionaries: sub_list = [] for vasp_calculation_input_dictionary in vasp_calculation_input_dictionary_parallel_group: calculation_path = vasp_calculation_input_dictionary['path'] if not Path.exists(calculation_path): vasp_calculation = None else: vasp_calculation = VaspCalculationGenerator( vasp_calculation_input_dictionary) sub_list.append(vasp_calculation) calculations_list.append(sub_list) return calculations_list
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 update(self): for misfit_strain in self.misfit_strains_list: misfit_path = self.get_extended_path(str(misfit_strain).replace('-', 'n')) for i in range(10000): relax_path = Path.join(misfit_path, 'structure_' + str(i)) if not Path.exists(relax_path): break relaxation = VaspRelaxation(path=relax_path) relaxation.update() print "Updating Epitaxial Relax run at " + relax_path + " Status is " + relaxation.get_status_string() if self.calculate_polarizations and relaxation.complete: self.update_polarization_run(relaxation)
def initialize_vasp_relaxations(self): """ """ for misfit_strain in self.misfit_strains_list: lattice_constant = self.reference_lattice_constant*(1.0+misfit_strain) misfit_path = self.get_extended_path(str(misfit_strain).replace('-', 'n')) Path.make(misfit_path) for i, initial_structure in enumerate(self.initial_structures_list): #if self.structure_is_duplicate(initial_structure, misfit_path): #####################FIX THIS AND PUT BACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # print "Duplicate structure found - skipping" # continue structure = copy.deepcopy(initial_structure) if abs(structure.lattice[0][1]) > 0.0 or abs(structure.lattice[0][2]) > 0.0 or abs(structure.lattice[1][0]) > 0.0 or abs(structure.lattice[1][2]) > 0.0: raise Exception("Current lattice is incompatible with (100) epitaxy: ", str(structure.lattice)) structure.lattice[0][0] = lattice_constant*self.supercell_dimensions_list[0] structure.lattice[1][1] = lattice_constant*self.supercell_dimensions_list[1] #break symmetry structure.randomly_displace_sites(max_displacement_magnitude=0.01) relax_path = Path.join(misfit_path, 'structure_' + str(i)) if not Path.exists(relax_path): print "Initializing epitaxial relaxation at " + relax_path relaxation = VaspRelaxation(path=relax_path, initial_structure=structure, input_dictionary=self.vasp_relaxation_inputs_dictionary) initial_structure.to_poscar_file_path(Path.join(relax_path, 'original_initial_structure'))
def incar(self): incar_path = Path.clean(self.path, 'INCAR') if Path.exists(incar_path): return Incar(incar_path) else: return None
def touch(file_path): """Same as unix command touch - creates empty file at file_path if file does not already exists""" if not Path.exists(file_path): file = File() file.write_to_path(file_path)
dfpt_force_run.update() 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)
def delete_wavecar_if_complete(self): if Path.exists(self.get_extended_path('WAVECAR')) and self.complete: Path.remove(self.get_extended_path('WAVECAR'))
def delete_big_vasp_files_if_complete(self): if self.complete: for file_name in ['WAVECAR', 'CHG', 'CHGCAR', 'vasprun.xml']: if Path.exists(self.get_extended_path(file_name)): Path.remove(self.get_extended_path(file_name))
def potcar(self): potcar_path = Path.clean(self.path, 'POTCAR') if Path.exists(potcar_path): return Potcar(potcar_path) else: return None
def outcar(self): outcar_path = Path.clean(self.path, 'OUTCAR') if Path.exists(outcar_path): return Outcar(outcar_path) else: return None
def kpoints(self): kpoints_path = Path.clean(self.path, 'KPOINTS') if Path.exists(kpoints_path): return Kpoints(kpoints_path) else: return None
def get_data_dictionaries_list(self, get_polarization=False): """ Starts at most negative misfit runs and goes to larger misfits finding the minimum energy data set. To encourage continuity, if two or more relaxations are within a small energy threshold of each other, the structure that is closest to the last chosen structure is chosen. The output of this function looks like [[-0.02, energy_1, [polarization_vector_1]], [-0.015, energy_2, [polarization_vector_2]], ...] """ output_data_dictionaries = [] spg_symprecs = [0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.001] for misfit_strain in self.misfit_strains_list: # print str(misfit_strain) data_dictionary = OrderedDict() data_dictionary['misfit_strain'] = misfit_strain misfit_path = self.get_extended_path(str(misfit_strain).replace('-', 'n')) minimum_energy = 10000000000 minimum_energy_relaxation = None for i in range(10000): relax_path = Path.join(misfit_path, 'structure_' + str(i)) if not Path.exists(relax_path): break relaxation = VaspRelaxation(path=relax_path) if not relaxation.complete: continue energy = relaxation.get_final_energy(per_atom=False) # print 'structure_' + str(i), energy if energy < minimum_energy: minimum_energy = energy minimum_energy_relaxation = relaxation # print # print "minimum E " + str(minimum_energy) # print if minimum_energy_relaxation == None: data_dictionary['structure'] = None data_dictionary['energy'] = None data_dictionary['polarization_vector'] = None for symprec in spg_symprecs: data_dictionary['spg_' + str(symprec)] = None data_dictionary['path'] = None else: structure = copy.deepcopy(minimum_energy_relaxation.final_structure) if get_polarization: polarization_vector = self.update_polarization_run(minimum_energy_relaxation) else: polarization_vector = None data_dictionary['structure'] = structure data_dictionary['energy'] = minimum_energy data_dictionary['polarization_vector'] = polarization_vector for symprec in spg_symprecs: data_dictionary['spg_' + str(symprec)] = structure.get_spacegroup_string(symprec) data_dictionary['path'] = Path.join(minimum_energy_relaxation.path, 'static') output_data_dictionaries.append(data_dictionary) return output_data_dictionaries
def get_final_structure(self): if Path.exists(self.get_extended_path('./CONTCAR')) and self.complete: return Structure(self.get_extended_path('./CONTCAR')) else: return None
def current_structure(self): if Path.exists(self.get_extended_path('./CONTCAR')): return Structure(self.get_extended_path('./CONTCAR')) else: return self.initial_structure
def poscar(self): if Path.exists(self.get_extended_path('./POSCAR')): return Structure(self.get_extended_path('./POSCAR')) else: return None