コード例 #1
0
    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  ', ''
        ])
コード例 #2
0
def get_sample(calculation_path):
    structure = Structure(file_path=Path.join(calculation_path, 'POSCAR'))
    structure.shift_sites_so_first_atom_is_at_origin()

    outcar = Outcar(file_path=Path.join(calculation_path, 'OUTCAR'))

    lattice_information = structure.get_magnitudes_and_angles()

    ideal_perovskite_structure = Perovskite(
        supercell_dimensions=[1, 1, 1],
        lattice=copy.deepcopy(structure.lattice),
        species_list=structure.get_species_list())

    displacement_vector = DisplacementVector.get_instance_from_displaced_structure_relative_to_reference_structure(
        reference_structure=ideal_perovskite_structure,
        displaced_structure=structure,
        coordinate_mode='Cartesian')

    energy = outcar.energy

    forces = outcar.final_forces_list

    stresses = outcar.final_stresses_list
    volume = structure.lattice.get_volume()  #in A^3

    for z in range(len(stresses)):
        stresses[z] /= volume

    row_of_data = lattice_information + displacement_vector.to_list() + [
        energy
    ] + forces + stresses

    output_string = ' '.join([str(x) for x in row_of_data])

    return row_of_data, output_string
コード例 #3
0
    def test_init(self):
        with self.assertRaises(IOError):
            file = File(Path.clean(self.data_path, 'file.txt'))

        file = File()
        self.assertEqual(file.lines, [])
        self.assertEqual(file.load_path, None)

        with self.assertRaises(IOError):
            file.write_to_path()

        file_path = Path.clean(self.data_path, 'file1.txt')
        file = File(file_path)
        self.assertEqual(file.lines[0], "This is a test file")
        self.assertEqual(file.lines[4], "line 5")
        self.assertEqual(file.lines[6], "end of testing file")
        with self.assertRaises(IndexError):
            file.lines[7]

        self.assertEqual(file.load_path, file_path)

        file_path = Path.clean(self.data_path, 'small_file.txt')
        file = File(file_path)
        self.assertEqual(file.lines, ['Small file', '  Very small  ', ''])

        file_path = Path.clean(self.data_path, 'empty.txt')
        file = File(file_path)
        self.assertEqual(file.lines, [])

        file_path = Path.clean(self.data_path, 'almost_empty.txt')
        file = File(file_path)  #this file contains: line 1: '\n' line 2: ''
        self.assertEqual(file.lines, [''])
コード例 #4
0
    def __init__(self,
                 path,
                 structures_list,
                 vasp_run_inputs_dictionary,
                 wavecar_path=None):
        """
		path should be the main path of the calculation set

		structures_list should be the set of structures for which forces are calculated.

		vasp_run_inputs_dictionary should look like:

		vasp_run_inputs_dictionary = {
			'kpoint_scheme': 'Monkhorst',
			'kpoint_subdivisions_list': [4, 4, 4],
			'encut': 800,
			'npar': 1 (optional)
		}

		wavecar_path should be the wavecar of a similar structure to the input structures of the structures_list.
		"""

        for structure in structures_list:
            Structure.validate(structure)

        self.path = path
        self.structures_list = structures_list
        self.vasp_run_inputs = copy.deepcopy(vasp_run_inputs_dictionary)
        self.wavecar_path = wavecar_path

        Path.make(path)

        self.initialize_vasp_runs()
コード例 #5
0
    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', ''
        ])
コード例 #6
0
def npar_converger(base_path, structure, npar_list, base_kpoints_scheme,
                   base_kpoints_subdivisions_list, base_ediff, base_encut,
                   node_count):
    """Takes in a structure, set of npars, and base params and runs set in base_path"""
    encut_convergence_set_path = Path.clean(base_path)
    Path.make(encut_convergence_set_path)

    for npar in npar_list:
        run_path = Path.join(encut_convergence_set_path, str(npar))

        input_dictionary = {
            'external_relaxation_count': 0,
            'kpoint_schemes_list': [base_kpoints_scheme],
            'kpoint_subdivisions_lists': [base_kpoints_subdivisions_list],
            'submission_script_modification_keys_list': ['100'],
            'submission_node_count_list': [node_count],
            'ediff': [base_ediff],
            'encut': [base_encut],
            'npar': [npar]
        }

        vasp_relaxation = VaspRelaxation(run_path,
                                         structure,
                                         input_dictionary,
                                         verbose=False)

        if vasp_relaxation.update():
            print "npar:", npar, "node_count:", node_count, round(
                vasp_relaxation.get_final_energy(True),
                5), round(vasp_relaxation.total_time, 2)
        else:
            pass
コード例 #7
0
    def test_init(self):
        file_path = Path.clean(self.data_path, "kpt_1")

        kpoints = Kpoints(file_path)

        self.assertEqual(kpoints.scheme, 'Gamma')

        kpoints.scheme = "monkhorst"

        self.assertEqual(kpoints.scheme, 'Monkhorst')

        self.assertEqual(kpoints.subdivisions_list, [4, 2, 4])

        kpoints.subdivisions_list = [6, 6, 8]

        self.assertEqual(kpoints.subdivisions_list, [6, 6, 8])

        new_path = Path.clean(self.data_path, "new_kpt_1")
        kpoints.write_to_path(new_path)

        kpoints_2 = Kpoints(new_path)

        self.assertEqual(kpoints_2.subdivisions_list, [6, 6, 8])
        self.assertEqual(kpoints.scheme, 'Monkhorst')

        with self.assertRaises(Exception):
            kpoints_2.scheme = "Lonkhorst"

        with self.assertRaises(Exception):
            kpoints_2.subdivisions_list = ['2', '4', '5', '6']

        kpoints_3 = Kpoints(scheme_string="Gamma", subdivisions_list=[4, 6, 8])
        self.assertEqual(str(kpoints_3),
                         'Kpoints File\n0\nGamma\n4 6 8\n0 0 0\n')
コード例 #8
0
	def __init__(self, path, initial_structure=None, input_dictionary=None):
		"""
		Input dicitonary should look something like:
		{
			'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],
			'calculation_type': 'gga' #not needed - defaults to 'lda',
			'static_lwave': True #if set, lwave is left on for static run
			#any other incar parameters with value as a list
		}

		If no input_dictionary is provided, this class will attempt to load a saved pickled instance.
		"""

		self.path = Path.expand(path)

		if not input_dictionary:
			self.load()
		else:
			self.vasp_run_list = []
			self.input_initial_structure = initial_structure

			Path.make(self.path)

			self.unpack_input_dictionary_into_self(input_dictionary)
			self.save()

		self.initialize_run_list()
コード例 #9
0
ファイル: potcar.py プロジェクト: greenmountainguy/fpctoolkit
	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
コード例 #10
0
    def initialize_paths(self):
        """
		Creates the base path directory and the first generation's path if they don't already exist.
		"""

        if not Path.exists(self.path):
            Path.make(self.path)

        if self.get_generation_count() == 0:
            Path.make(self.get_next_generation_path())
コード例 #11
0
    def __init__(self,
                 path,
                 initial_structure=None,
                 relaxation_input_dictionary=None,
                 extra_dos_inputs=None):
        """
		Input dicitonary should look something like:
		{
			'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],
			'calculation_type': 'gga' #must be gga in this case
			#any other incar parameters with value as a list
		}

		extra_dos_inputs is optional and should look like:
		{
			HFSCREEN = 0.2 # sets the type of hybid - can give params for pbe0 here too
			NEDOS = 4001
			'kpoint_schemes_list': ['Gamma'],
			'kpoint_subdivisions_lists': [[2, 2, 4]], #for enhanced kpoints - can be up to three for each stage of the dos
			any other incar params for just dos part
		}

		If no relaxation_input_dictionary is provided, this class will attempt to load a saved pickled instance.
		"""

        self.path = Path.expand(path)
        self.relaxation_path = self.get_extended_path('relaxation')
        self.dos_path = self.get_extended_path('dos')
        self.extra_dos_inputs = extra_dos_inputs
        self.dos_runs_list = []

        if 'calculation_type' not in relaxation_input_dictionary or relaxation_input_dictionary[
                'calculation_type'] != 'gga':
            raise Exception(
                "Calculation type must be gga for hybrid calculations")

        if not relaxation_input_dictionary:
            self.load()
        else:

            Path.make(self.path)

            relaxation_input_dictionary['static_lwave'] = True
            self.relaxation = VaspRelaxation(
                path=self.relaxation_path,
                initial_structure=initial_structure,
                input_dictionary=relaxation_input_dictionary)
            self.save()
コード例 #12
0
    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")
コード例 #13
0
def get_structure_list(path):
    """loads in poscars at path and returns list of structures"""

    path = Path.clean(path)
    files = Path.get_list_of_files_at_path(path)
    structs = {}
    
    for file in files:
        structs[file] = Structure(Path.join(path, file))

    return structs
コード例 #14
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
コード例 #15
0
    def append_individuals_at_path(self, path):
        """
		Looks for individuals inside path (saved as directories like 'individual_1, individual_2, ...') and appends to self.individuals
		"""

        #put all valid basenames in list like like: [individual_1, individual_2, ...]
        elligible_directory_basenames = Path.get_list_of_directory_basenames_containing_string(
            path, Population.individual_prefix_string)

        for basename in elligible_directory_basenames:
            self.individuals.append(
                self.directory_to_individual_conversion_method(
                    Path.join(path, basename)))
コード例 #16
0
	def initialize_vasp_runs(self):
		"""
		Creates any force calculation vasp runs (static force calculations at .../0, .../1, ...) that do not already exist.
		"""

		if Path.exists(self.get_extended_path('0')): #we don't want to write more runs if any already exist
			return

		for i, structure in enumerate(self.structures_list):
			run_path = self.get_extended_path(str(i))

			if not Path.exists(run_path):
				self.create_new_vasp_run(run_path, structure)
コード例 #17
0
    def update(self):
        """
		Main update method - create individuals until quota is reached, update the individuals in the current generation, create next generation path if current generation is complete.
		"""

        self.populate_current_generation()

        generation_complete = self.update_all_individuals_of_current_generation(
        )

        if generation_complete and (
                self.population_collection.get_generation_count() <
                self.ga_driver.get_max_number_of_generations()):
            Path.make(self.population_collection.get_next_generation_path())
コード例 #18
0
	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
コード例 #19
0
    def get_next_available_individual_path(self, generation_directory_path):

        if not Path.exists(generation_directory_path):
            raise Exception("Generation path does not exist")

        i = 1
        while True:
            individual_path = Path.join(
                generation_directory_path,
                Population.individual_prefix_string + str(i))
            if not Path.exists(individual_path):
                return individual_path

            i += 1
コード例 #20
0
	def initialize_run_list(self):
		"""sets self.vasp_run_list based on directories present"""

		self.vasp_run_list = []

		for i in range(self.external_relaxation_count):
			run_path = self.get_extended_path(VaspRelaxation.external_relax_basename_string + str(i+1))
			if Path.exists(run_path):
				self.vasp_run_list.append(VaspRun(run_path))
			else:
				return

		static_path = self.get_extended_path(VaspRelaxation.static_basename_string)
		if Path.exists(static_path):
			self.vasp_run_list.append(VaspRun(static_path))
コード例 #21
0
	def update(self):

		Path.make(self.path)

		self.vasp_static_run_sets_list = []

		for expansion_term in self.taylor_expansion.expansion_terms_list:

			vasp_static_run_set = self.get_vasp_static_run_set(expansion_term)

			if vasp_static_run_set.complete:
				self.set_taylor_coefficient(vasp_static_run_set, expansion_term)
				vasp_static_run_set.delete_wavecars_of_completed_runs()
			else:
				vasp_static_run_set.update()
コード例 #22
0
    def __init__(self,
                 path,
                 reference_structure=None,
                 distorted_structure=None,
                 vasp_run_inputs_dictionary=None):
        """
		reference_structure should be a Structure instance with the same lattice as distorted structure. Usually this reference is chosen to be centrosymmetry (like ideal perovskite) so that 
		absolute polarizations of the distorted structure can be caluclated.

		distorted_structure should be a Structure instance with the same lattice as the reference structure, but some of the atoms shifted to cause a change in polarization.

		vasp_run_inputs_dictionary should look like:

		vasp_run_inputs_dictionary = {
			'kpoint_scheme': 'Monkhorst',
			'kpoint_subdivisions_list': [4, 4, 4],
			'encut': 800,
		}

		"""

        self.path = Path.expand(path)

        if (reference_structure
                == None) or (distorted_structure
                             == None) or (vasp_run_inputs_dictionary == None):
            self.load()
        else:

            Structure.validate(reference_structure)
            Structure.validate(distorted_structure)

            if not reference_structure.lattice.equals(
                    distorted_structure.lattice):
                raise Exception(
                    "Warning: It's very difficult to interpret polarization results when the lattices of the reference and distorted structures are not equal. This is likely an error.",
                    reference_structure.lattice, distorted_structure.lattice)

            self.reference_structure = reference_structure
            self.distorted_structure = distorted_structure
            self.vasp_run_inputs = copy.deepcopy(vasp_run_inputs_dictionary)
            self.vasp_run_list = []

            self.save()

        Path.make(path)

        self.initialize_vasp_runs()
コード例 #23
0
 def write_parent_structures_to_poscar_files(self):
     if self.parent_structures_list and (not Path.exists(
             self.get_extended_path(".parent_paths"))):
         for i, parent_structure in enumerate(self.parent_structures_list):
             parent_structure.to_poscar_file_path(
                 self.get_extended_path('.parent_poscar_' + str(i) +
                                        '.vasp'))
コード例 #24
0
 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)
コード例 #25
0
    def test_init(self):
        file_path = Path.clean(self.data_path, "poscar_small")
        poscar = Poscar(file_path)

        self.assertEqual(poscar.species_list, ['Si', 'O'])
        self.assertEqual(poscar.lines, [
            'Poscar', '1.0', '5.0 0.2 0.1', '0.4\t 6.0   0.7',
            '-0.2   0.0  7.7    ', 'Si   O', '2  1', 'Direct',
            '0.11 0.22 0.33', '0.33 0.22 0.11', '0.22 0.33 0.11  '
        ])
        self.assertEqual(poscar.species_count_list, [2, 1])
        self.assertEqual(poscar.coordinate_mode, 'Direct')
        self.assertEqual(
            poscar.coordinates,
            [[0.11, 0.22, 0.33], [0.33, 0.22, 0.11], [0.22, 0.33, 0.11]])

        lattice = [[2.2, 2.3, 2.1], [1.2, 3.3, 0.0], [-1.2, -2.2, 4.4]]
        species_list = ['K', 'V', 'O']
        species_count_list = [1, 2, 3]
        coordinate_mode = 'cart'
        coordinates = [[0.2, 0.3, 0.4], [0.5, 0.5, 0.1], [-0.01, 0.1, 0.01],
                       [2.33, 6.5, 3.2], [0.0, 0.1, -0.1], [0.1, 0.5, 0.5]]
        poscar = Poscar(None, lattice, species_list, species_count_list,
                        coordinate_mode, coordinates)

        self.assertEqual(poscar.species_list, ['K', 'V', 'O'])
        self.assertEqual(poscar.lines, [
            'Poscar', '1.0', '2.2 2.3 2.1', '1.2 3.3 0.0', '-1.2 -2.2 4.4',
            'K V O', '1 2 3', 'Cartesian', '0.2 0.3 0.4', '0.5 0.5 0.1',
            '-0.01 0.1 0.01', '2.33 6.5 3.2', '0.0 0.1 -0.1', '0.1 0.5 0.5'
        ])
        self.assertEqual(poscar.species_count_list, [1, 2, 3])
        self.assertEqual(poscar.coordinate_mode, 'Cartesian')
        self.assertEqual(poscar.coordinates, coordinates)
コード例 #26
0
	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
コード例 #27
0
    def validate_constructor_arguments(file_path, lattice, sites):

        Path.validate(path=file_path, allow_none=True)

        if file_path == None:
            if lattice == None:
                raise Exception("A lattice must be specified.")
            else:
                Lattice.validate_lattice_representation(lattice)

            if not sites:
                raise Exception(
                    "A sites list or SiteColleciton instance must be specified."
                )
            else:
                SiteCollection.validate_sites(sites)
コード例 #28
0
    def __init__(self,
                 path=None,
                 calculation_set=None,
                 structure_creation_id_string=None,
                 parent_structures_list=None,
                 parent_paths_list=None):

        if not calculation_set:
            if not path:
                raise Exception(
                    "Path must be given if no calculation set is provided.")

            self.path = Path.expand(path)
            self.load()
        else:
            self.path = calculation_set.path
            self.calculation_set = calculation_set

            self.structure_creation_id_string = structure_creation_id_string if structure_creation_id_string else self.get_structure_creation_id_string(
            )
            self.parent_structures_list = parent_structures_list if parent_structures_list else self.get_parent_structures_list(
            )
            self.parent_paths_list = parent_paths_list if parent_paths_list else self.get_parent_paths_list(
            )

            self.write_structure_creation_id_string_to_file(
            )  #store how this individual was made
            self.write_parent_structures_to_poscar_files()
            self.write_parent_paths_to_file()

            self.save()
コード例 #29
0
	def __init__(self, path, initial_structures_list, reference_structure, vasp_relaxation_inputs_dictionary, reference_lattice_constant, misfit_strains_list, supercell_dimensions_list, calculate_polarizations=False):
		"""
		path should be the main path of the calculation set

		initial_structures_list should be the set of structures that are relaxed at each misfit strain

		reference structure can have any lattice but its atom positions must be in direct coords as the positions to compare polarizations to (choose a centrosymmetric structure if possible)

		vasp_relaxation_inputs_dictionary should look something like:
		{
			'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
		}

		reference_lattice_constant should be the lattice constant a0 which, when multiplied by the list of misfit strains, generates the new in-plane lattice constant at those strains.

		For each lattice constant and each structure, a relaxation is performed. Then, the lowest energy structures at each misfit strain can be determined, and a convex hull results.
		"""

		for structure in initial_structures_list:
			Structure.validate(structure)

		basic_validators.validate_real_number(reference_lattice_constant)

		for misfit_strain in misfit_strains_list:
			basic_validators.validate_real_number(misfit_strain)


		self.path = path
		self.initial_structures_list = initial_structures_list
		self.reference_structure = reference_structure
		self.vasp_relaxation_inputs_dictionary = vasp_relaxation_inputs_dictionary
		self.reference_lattice_constant = reference_lattice_constant
		self.misfit_strains_list = misfit_strains_list
		self.supercell_dimensions_list = supercell_dimensions_list
		self.calculate_polarizations = calculate_polarizations

		Path.make(path)

		self.initialize_vasp_relaxations()
コード例 #30
0
	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)