def update_polarization_run(self, relaxation, structure_tag):

		if not relaxation.complete:
			return

		path = relaxation.path

		supercell_dimensions = inputs_dictionaries[structure_tag]['supercell_dimensions_list']

		polarization_reference_structure=Perovskite(supercell_dimensions=supercell_dimensions, lattice=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], species_list=relaxation.final_structure.get_species_list())

		distorted_structure = relaxation.final_structure
		polarization_reference_structure.lattice = copy.deepcopy(distorted_structure.lattice)

		vasp_run_inputs_dictionary = {
			'kpoint_scheme': relaxation.kpoint_schemes[100],
			'kpoint_subdivisions_list': relaxation.kpoint_subdivisions_lists[100],
			'isym': 0
		}

		for key, value_list in relaxation.incar_modifier_lists_dictionary:
			vasp_run_inputs_dictionary[key] = value_list[1000]


		polarization_run = VaspPolarizationRunSet(path, polarization_reference_structure, distorted_structure, vasp_run_inputs_dictionary)

		polarization_run.update()

		return polarization_run.get_change_in_polarization()
예제 #2
0
def get_fraction_of_displacements_for_nine_common_modes(distorted_structure):

    reference_structure = Perovskite(
        supercell_dimensions=[2, 2, 2],
        lattice=distorted_structure.lattice,
        species_list=distorted_structure.get_species_list())

    total_displacement_vector_instance = DisplacementVector.get_instance_from_displaced_structure_relative_to_reference_structure(
        reference_structure=reference_structure,
        displaced_structure=distorted_structure,
        coordinate_mode='Cartesian')

    total_displacement_vector = total_displacement_vector_instance.to_numpy_array(
    )

    total_displacement_magnitude = sum(
        [abs(x) for x in total_displacement_vector])

    print "Total displacement magnitude is " + str(
        total_displacement_magnitude) + " angstroms"

    for basis_vector in eigen_basis_vectors_list:
        projection = np.dot(basis_vector, total_displacement_vector)

        #contribution_vector = projection*basis_vector

        #basis_total_displacement_magnitude_contribution = np.linalg.norm(contribution_vector) #sum([abs(x) for x in contribution_vector])

        #fractions.append(float(basis_total_displacement_magnitude_contribution/total_displacement_magnitude))

        fractions.append(abs(projection) / total_displacement_magnitude)

    return fractions
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
예제 #4
0
def get_nine_common_amplitudes(distorted_structure):

    reference_structure = Perovskite(
        supercell_dimensions=[2, 2, 2],
        lattice=distorted_structure.lattice,
        species_list=distorted_structure.get_species_list())

    total_displacement_vector_instance = DisplacementVector.get_instance_from_displaced_structure_relative_to_reference_structure(
        reference_structure=reference_structure,
        displaced_structure=distorted_structure,
        coordinate_mode='Cartesian')

    total_displacement_vector = total_displacement_vector_instance.to_numpy_array(
    )

    for basis_vector in eigen_basis_vectors_list:
        projection = np.dot(basis_vector, total_displacement_vector)

        print str(round(projection, 4)) + '   ',
def get_random_structure():
    a = 15.16
    structure = Perovskite(supercell_dimensions=[4, 4, 1],
                           lattice=[[a, 0.0, 0.0], [0.0, a, 0.0],
                                    [0.0, 0.0, a / 4.0]],
                           species_list=['K', 'V', 'O'])

    shear_factor = 1.0
    structure.lattice.randomly_strain(
        stdev=0.08,
        mask_array=[[0.0, 0.0, 2.0 * shear_factor],
                    [0.0, 0.0, 2.0 * shear_factor], [0.0, 0.0,
                                                     1.0]])  #for (100) epitaxy

    mult = 2.4  #1.8
    min_atomic_distance = 1.5
    print structure.randomly_displace_site_positions(
        stdev=0.2 * mult,
        enforced_minimum_atomic_distance=min_atomic_distance,
        max_displacement_distance=0.3 * mult,
        mean=0.3,
        types_list=['K'])
    print structure.randomly_displace_site_positions(
        stdev=0.6 * mult,
        enforced_minimum_atomic_distance=min_atomic_distance,
        max_displacement_distance=0.6 * mult,
        mean=0.5,
        types_list=['V'])
    print structure.randomly_displace_site_positions(
        stdev=0.8 * mult,
        enforced_minimum_atomic_distance=min_atomic_distance,
        max_displacement_distance=1.2 * mult,
        mean=0.7,
        types_list=['O'])

    return structure
예제 #6
0
    'external_relaxation_count': 3,
    'kpoint_schemes_list': [kpoint_scheme],
    'kpoint_subdivisions_lists': [kpoint_subdivisions_list],
    'submission_node_count': 1,
    'potim': [0.1, 0.2, 0.4],
    'isif': [21, 71, 161],
    'ediff': [1e-4, 1e-5, 1e-6],
    'encut': [encut],
    'submission_script_modification_keys_list': ['100'],
    'lwave': [True],
    'lreal': [False],
    'addgrid': [True]
}


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, a*Nz*1.02]], species_list=species_list)


relaxation = VaspRelaxation(path=Path.join(base_path, 'relaxation'), initial_structure=initial_structure, input_dictionary=initial_relaxation_input_dictionary)


if not relaxation.complete:
	relaxation.update()
else:
	
	relaxed_structure = relaxation.final_structure


	force_calculation_path = Path.join(base_path, 'dfpt_force_calculation')

	kpoints = Kpoints(scheme_string=kpoint_scheme, subdivisions_list=kpoint_subdivisions_list)
def term_acceptance_function(expansion_term):

	variables = expansion_term.get_active_variables()

	if not expansion_term.is_pure_type('strain')

	#remove all terms with in-plane strain variables in them - these are fixed to 0 for (100) epitaxy
	for variable in variables:
		if variable.type_string == 'strain' and variable.index in [0, 1, 5]:
			return False

	#assume no forces or stresses on the cell
	if expansion_term.order == 1: 
		return False

	#only expand to second order w.r.t. strain
	if expansion_term.is_pure_type('strain') and expansion_term.order > 2:
		return False

	#for perovskite structure under arbitrary homogeneous strain, displacement terms are centrosymmetric
	if expansion_term.is_centrosymmetric():
		return False

	#only go to fourth order in single variable dsiplacement terms - don't do fourth order cross terms
	if expansion_term.order == 4 and not expansion_term.has_single_variable():
		return False

	return True


taylor_expansion = TaylorExpansion(variables_list=variables, term_acceptance_function=term_acceptance_function)

print
print "Number of terms:", len(taylor_expansion)


print '\n\t\t',
print taylor_expansion
print '\n'*3




base_path = "./"


perturbation_magnitudes_dictionary = {'strain': 0.01, 'displacement': 0.2}


a = 3.79
Nx = 1
Ny = 1
Nz = 1

vasp_run_inputs_dictionary = {
	'kpoint_scheme': 'Monkhorst',
	'kpoint_subdivisions_list': [8, 8, 8],
	'encut': 900,
	'addgrid': True
}

relaxation_input_dictionary= {
    'external_relaxation_count': 3,
    'isif': [6],
    'kpoint_schemes_list': [vasp_run_inputs_dictionary['kpoint_scheme']],
    'kpoint_subdivisions_lists': [vasp_run_inputs_dictionary['kpoint_subdivisions_list']],
    'ediff': [0.00001, 1e-7, 1e-9],
    'encut': [vasp_run_inputs_dictionary['encut']],
    'submission_script_modification_keys_list': ['100'],
    'lwave': [True]
}


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, a*Nz*1.02]], species_list=['Sr', 'Ti', 'O'])


relaxation = VaspRelaxation(path=Path.join(base_path, 'relaxation'), initial_structure=initial_structure, input_dictionary=relaxation_input_dictionary)


if not relaxation.complete:
	relaxation.update()
else:
	
	relaxed_structure = relaxation.final_structure

	force_calculation_path = Path.join(base_path, 'dfpt_force_calculation')

	kpoints = Kpoints(scheme_string=vasp_run_inputs_dictionary['kpoint_scheme'], subdivisions_list=vasp_run_inputs_dictionary['kpoint_subdivisions_list'])
	incar = IncarMaker.get_dfpt_hessian_incar({'encut': vasp_run_inputs_dictionary['encut']})

	input_set = VaspInputSet(relaxed_structure, kpoints, incar, auto_change_lreal=False, auto_change_npar=False)

	dfpt_force_run = VaspRun(path=force_calculation_path, input_set=input_set)

	if not dfpt_force_run.complete:
		dfpt_force_run.update()
	else:

		hessian = Hessian(dfpt_force_run.outcar)

		eigen_structure = EigenStructure(reference_structure=relaxed_structure, hessian=hessian)
		eigen_structure.print_eigen_components()



		de_path = Path.join(base_path, 'term_coefficient_calculations')
		derivative_evaluator = DerivativeEvaluator(path=de_path, reference_structure=relaxed_structure, hessian=hessian, taylor_expansion=taylor_expansion, 
			reference_completed_vasp_relaxation_run=relaxation, vasp_run_inputs_dictionary=vasp_run_inputs_dictionary, perturbation_magnitudes_dictionary=perturbation_magnitudes_dictionary)

		derivative_evaluator.update()

		print derivative_evaluator.taylor_expansion
from fpctoolkit.io.file import File
from fpctoolkit.structure.site import Site
from fpctoolkit.structure.lattice import Lattice
from fpctoolkit.structure.structure import Structure
from fpctoolkit.structure.perovskite import Perovskite
from fpctoolkit.structure.site_collection import SiteCollection
from fpctoolkit.io.vasp.outcar import Outcar
from fpctoolkit.workflow.vasp_run import VaspRun
from fpctoolkit.io.vasp.vasp_input_set import VaspInputSet
from fpctoolkit.io.vasp.incar_maker import IncarMaker
from fpctoolkit.workflow.vasp_relaxation import VaspRelaxation

if __name__ == "__main__":

    path = './relaxation_BTO_2'
    initial_structure = Perovskite(supercell_dimensions=[1, 1, 1],
                                   lattice=[[4.1, 0.1, 0.0], [0.0, 4.0, 0.0],
                                            [0.0, 0.1, 3.9]],
                                   species_list=['Ba', 'Ti', 'O'])
    input_dictionary = {
        'external_relaxation_count': 2,
        'kpoint_schemes_list': ['Monkhorst'],
        'kpoint_subdivisions_lists': [[2, 2, 2], [4, 4, 4], [6, 6, 6]],
        'ediff': [0.001, 0.0001, 0.00001],
        'encut': [400, 600]
    }

    relax = VaspRelaxation(path, initial_structure, input_dictionary)
    relax.update()
    relax.view(['poscar', 'contcar'])
예제 #9
0
relaxation_input_dictionary = {
    'external_relaxation_count':
    4,
    'isif': [6],
    'kpoint_schemes_list': [vasp_run_inputs_dictionary['kpoint_scheme']],
    'kpoint_subdivisions_lists':
    [vasp_run_inputs_dictionary['kpoint_subdivisions_list']],
    'ediff': [0.00001, 1e-7, 1e-9, 1e-10],
    'encut': [vasp_run_inputs_dictionary['encut']],
    'submission_script_modification_keys_list': ['100'],
    'lwave': [True],
    'lreal': [False]
}

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, a * Nz * 1.02]],
                               species_list=['Sr', 'Ti', 'O'])

relaxation = VaspRelaxation(path=Path.join(base_path, 'relaxation'),
                            initial_structure=initial_structure,
                            input_dictionary=relaxation_input_dictionary)

if not relaxation.complete:
    relaxation.update()
else:

    relaxed_structure = relaxation.final_structure

    force_calculation_path = Path.join(base_path, 'dfpt_force_calculation')

    kpoints = Kpoints(
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
    #for now, just arrange super list of [relaxation, chromosome] and print out energy and first few of chromosome - inspect these to see how diverse they are, sort by energy first

    #maybe don't run this until all structures have been determined
    if (len(initial_epitaxial_structures_list) > 0) or update_eptiaxy_only:
        print "Updating Epitaxial Relaxations"

        Path.make(epitaxial_path)

        a = 1.0  #doesn't matter
        Nx = input_dictionary['supercell_dimensions_list'][0]
        Ny = input_dictionary['supercell_dimensions_list'][1]
        Nz = input_dictionary['supercell_dimensions_list'][2]

        reference_structure = Perovskite(
            supercell_dimensions=[Nx, Ny, Nz],
            lattice=[[a * Nx, 0.0, 0.0], [0.0, a * Ny, 0.0], [0.0, 0.0, a]],
            species_list=input_dictionary['species_list'])

        epitaxial_relaxer = EpitaxialRelaxer(
            path=epitaxial_path,
            initial_structures_list=initial_epitaxial_structures_list,
            reference_structure=reference_structure,
            vasp_relaxation_inputs_dictionary=
            epitaxial_relaxation_input_dictionary,
            reference_lattice_constant=input_dictionary[
                'reference_lattice_constant'],
            misfit_strains_list=epitaxial_relaxations_misfit_strains_list,
            supercell_dimensions_list=input_dictionary[
                'supercell_dimensions_list'],
            calculate_polarizations=calculate_polarizations)
    def get_mated_perovskite_structure(structure_1, structure_2,
                                       supercell_dimensions_list):

        #validation: check that species are the same in each structure
        #########need to add min atomic distance check!!!!!!!!!!!!!!!!!!!!!!!!!!!

        Na = supercell_dimensions_list[0]
        Nb = supercell_dimensions_list[1]
        Nc = supercell_dimensions_list[2]

        parent_structures_list = [structure_1, structure_2]

        #everything below should be factored out into a function that takes in two structures (and interpolators) and returns one

        site_mapping_collections_list = []

        for i, parent_structure in enumerate(parent_structures_list):
            print "Parent structure " + str(i + 1)

            perovskite_reference_structure = Perovskite(
                supercell_dimensions=supercell_dimensions_list,
                lattice=parent_structure.lattice,
                species_list=parent_structure.get_species_list())

            perovskite_reference_structure.convert_sites_to_direct_coordinates(
            )
            parent_structure.convert_sites_to_direct_coordinates()

            parent_structure.sites.shift_direct_coordinates([
                random.uniform(-0.5, 0.5),
                random.uniform(-0.5, 0.5),
                random.uniform(-0.5, 0.5)
            ])

            #This aligns the lattices - sloppy but it works...figure out a better way later
            for align_try_count in range(21):
                if align_try_count == 20:
                    raise Exception(
                        "Cannot align crystal to perfect perovskite")

                site_mapping_collection = SiteMappingCollection(
                    perovskite_reference_structure.sites,
                    parent_structure.sites,
                    lattice=parent_structure.lattice)
                average_displacement_vector = site_mapping_collection.get_average_displacement_vector(
                )
                print average_displacement_vector
                site_mapping_collection.shift_sites_to_minimize_average_distance(
                )  #this shifts parent_struct's sites too because sites passed by reference

                converged = True
                for j in range(3):
                    if abs(average_displacement_vector[j]) > 0.00001:
                        converged = False

                if converged:
                    break

            site_mapping_collections_list.append(site_mapping_collection)

        #This should be a separately inputted block controlling how interpolation is run##################
        if Na == 2:
            discrete_interpolation_values = [
                1.0, 1.0, 0.0, 0.0
            ]  #one for each plane of perov atoms
        if Na == 4:
            discrete_interpolation_values = [
                1.0, 1.0, 1.0, 0.8, 0.0, 0.0, 0.0, 0.2
            ]

        def interpolation_function_da(da, db, dc):
            transition_increment = 0.5 / Na  #distance between perf perov planes in a direction
            transition_index = int(da / transition_increment)

            return discrete_interpolation_values[transition_index]

        def interpolation_function_db(da, db, dc):
            return interpolation_function_da(db, da, dc)

        def interpolation_function_dc(da, db, dc):
            return interpolation_function_da(dc, da, db)

        if random.uniform(0.0, 1.0) >= 0.5:
            interpolation_function_1 = interpolation_function_da
        else:
            interpolation_function_1 = interpolation_function_db

        if Na == 2 and Nc == 2:
            if random.uniform(0.0, 1.0) >= 0.66666:
                interpolation_function_1 = interpolation_function_dc

        def interpolation_function_2(da, db, dc):
            return 1.0 - interpolation_function_1(da, db, dc)

        ###################################################################################

        #make this a randomly weighted-average at some point
        averaged_lattice = Lattice.average(parent_structures_list[0].lattice,
                                           parent_structures_list[1].lattice)

        interpolated_sites_1 = site_mapping_collections_list[
            0].get_interpolated_site_collection(
                perovskite_reference_structure.sites, interpolation_function_1)
        interp_struct_1 = Structure(sites=interpolated_sites_1,
                                    lattice=averaged_lattice)

        interpolated_sites_2 = site_mapping_collections_list[
            1].get_interpolated_site_collection(interpolated_sites_1,
                                                interpolation_function_2)

        interp_struct_2 = Structure(sites=interpolated_sites_2,
                                    lattice=averaged_lattice)

        return interp_struct_2
예제 #13
0
    def get_random_structure(self, population_of_last_generation):

        self.structure_creation_id_string = 'random'
        self.parent_structures_list = None
        self.parent_paths_list = None

        return self.random_structure_creation_function()

        A_type = self.ga_input_dictionary['species_list'][0]
        B_type = self.ga_input_dictionary['species_list'][1]
        X_type = self.ga_input_dictionary['species_list'][2]

        Nx = self.ga_input_dictionary['supercell_dimensions_list'][0]
        Ny = self.ga_input_dictionary['supercell_dimensions_list'][1]
        Nz = self.ga_input_dictionary['supercell_dimensions_list'][2]

        a = self.ga_input_dictionary['epitaxial_lattice_constant']
        unit_cell_a = a / Nx

        c = (
            unit_cell_a * Nz
        )  ##############################eventually base c off of a good volume

        lattice = [[a, 0.0, 0.0], [0.0, a, 0.0], [0.0, 0.0, c]]

        structure = Perovskite(
            supercell_dimensions=self.
            ga_input_dictionary['supercell_dimensions_list'],
            lattice=lattice,
            species_list=self.ga_input_dictionary['species_list'])

        def envelope_function(curvature_parameter,
                              max_displacement_distance,
                              bell=True):
            """
			for bell == True:
				Get a curve that is high at 0, lower as you get away from 0
				curvature_parameter: closer to 0 means sharper peak at 0, closer to 3 or more, very constant until sharp drop to 0 at max_disp_dist
			for bell == False:
				Curve is 0 at 0, highest at max_disp_dist
				curvature_parameter: closer to 0 means curve gets to large value faster (less of an abyss around 0), larger means sharp increase near max_disp
			"""

            if bell:
                offset = 1.0
                sign = -1.0
            else:
                offset = 0.0
                sign = 1.0

            if max_displacement_distance == 0:
                return lambda x: 1.0
            else:
                return lambda x: offset + sign * (
                    (x**curvature_parameter) /
                    (max_displacement_distance**curvature_parameter))

        strain_probabilities_list = [0.5, 0.3, 0.2]
        random_selector = RandomSelector(strain_probabilities_list)
        event_index = random_selector.get_event_index()

        if event_index == 0:
            shear_factor = 0.1
            strain_stdev = 0.1
        elif event_index == 1:
            shear_factor = 0.25
            strain_stdev = 0.12
        elif event_index == 2:
            shear_factor = 0.6
            strain_stdev = 0.16
        """
		Basic random
		"""

        A_site_curvature_parameter = 1.4
        A_site_max_displacement = 0.35 * unit_cell_a
        A_bell = True

        B_site_curvature_parameter = 2.5
        B_site_max_displacement = 0.6 * unit_cell_a
        B_bell = True

        X_site_curvature_parameter = 3.0
        X_site_max_displacement = 0.75 * unit_cell_a
        X_bell = True

        AA_minimum_distance = 1.2
        AB_minimum_distance = 0.8
        BB_minimum_distance = 0.8
        AX_minimum_distance = 0.6
        BX_minimum_distance = 0.6
        XX_minimum_distance = 0.6

        A_site_vector_magnitude_distribution_function = Distribution(
            envelope_function(A_site_curvature_parameter,
                              A_site_max_displacement, A_bell), 0.0,
            A_site_max_displacement).get_random_value
        B_site_vector_magnitude_distribution_function = Distribution(
            envelope_function(B_site_curvature_parameter,
                              B_site_max_displacement, B_bell), 0.0,
            B_site_max_displacement).get_random_value
        X_site_vector_magnitude_distribution_function = Distribution(
            envelope_function(X_site_curvature_parameter,
                              X_site_max_displacement, X_bell), 0.0,
            X_site_max_displacement).get_random_value

        A_site_vector_distribution_function = VectorDistribution(
            Vector.get_random_unit_vector,
            A_site_vector_magnitude_distribution_function)
        B_site_vector_distribution_function = VectorDistribution(
            Vector.get_random_unit_vector,
            B_site_vector_magnitude_distribution_function)
        X_site_vector_distribution_function = VectorDistribution(
            Vector.get_random_unit_vector,
            X_site_vector_magnitude_distribution_function)

        displacement_vector_distribution_function_dictionary_by_type = {
            A_type: A_site_vector_distribution_function.get_random_vector,
            B_type: B_site_vector_distribution_function.get_random_vector,
            X_type: X_site_vector_distribution_function.get_random_vector
        }

        minimum_atomic_distances_nested_dictionary_by_type = {
            A_type: {
                A_type: AA_minimum_distance,
                B_type: AB_minimum_distance,
                X_type: AX_minimum_distance
            },
            B_type: {
                A_type: AB_minimum_distance,
                B_type: BB_minimum_distance,
                X_type: BX_minimum_distance
            },
            X_type: {
                A_type: AX_minimum_distance,
                B_type: BX_minimum_distance,
                X_type: XX_minimum_distance
            }
        }

        e33_average = 1.0
        e33_spread = 0.2
        min_e33 = e33_average - e33_spread
        max_e33 = e33_average + e33_spread
        e33_distribution_function = lambda x: (e33_spread - (
            abs(e33_average - x
                )))**0.4  #very broad bell shape max at 1.0, 0.0 at edges
        e33_distribution = Distribution(e33_distribution_function, min_e33,
                                        max_e33)

        e13_average = 0.0
        e13_spread = 0.2
        min_e13 = e13_average - e13_spread
        max_e13 = e13_average + e13_spread
        e13_distribution_function = lambda x: (e13_spread - (
            abs(e13_average - x
                )))**0.8  #somewhat broad bell shape max at 0.0, 0.0 at edges
        e13_distribution = Distribution(e13_distribution_function, min_e13,
                                        max_e13)

        e23_average = 0.0
        e23_spread = 0.2
        min_e23 = e23_average - e23_spread
        max_e23 = e23_average + e23_spread
        e23_distribution_function = lambda x: (e23_spread - (
            abs(e23_average - x
                )))**0.8  #somewhat broad bell shape max at 0.0, 0.0 at edges
        e23_distribution = Distribution(e23_distribution_function, min_e23,
                                        max_e23)

        zero_function = lambda: 0.0
        unity_function = lambda: 1.0

        distribution_function_array = [
            [unity_function, zero_function, e13_distribution.get_random_value],
            [zero_function, unity_function, e23_distribution.get_random_value],
            [zero_function, zero_function, e33_distribution.get_random_value]
        ]

        structure.lattice.randomly_strain(
            distribution_function_array=distribution_function_array)

        StructureManipulator.displace_site_positions_with_minimum_distance_constraints(
            structure,
            displacement_vector_distribution_function_dictionary_by_type,
            minimum_atomic_distances_nested_dictionary_by_type)

        self.structure_creation_id_string = 'random'
        self.parent_structures_list = None
        self.parent_paths_list = None

        return structure
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)

    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_differrences_step_size = input_dictionary[
        'displacement_finite_differrences_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)

    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)
    hessian.print_eigenvalues_to_file(Path.join(path, 'output_eigen_values'))
    hessian.print_eigen_components_to_file(
        Path.join(path, 'output_eigen_components'))

    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_differrences_step_size=
        displacement_finite_differrences_step_size,
        status_file_path=Path.join(path, 'output_derivative_plot_data'),
        variable_specialty_points_dictionary=
        variable_specialty_points_dictionary)
    derivative_evaluator.update()

    guessed_minima_data_path = Path.join(path, 'guessed_chromosomes')
    minima_path = Path.join(path, 'minima_relaxations')

    if Path.exists(guessed_minima_data_path):
        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)

        minima_relaxer.update()
        minima_relaxer.print_status_to_file(
            Path.join(path, 'output_minima_relaxations_status'))

        if minima_relaxer.complete:
            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
예제 #15
0
	def get_random_perovskite_structure(species_list=None, primitive_cell_lattice_constant=None, supercell_dimensions_list=None, strain_distribution_function_array=None):
		"""
		Returns a random perovskite structure with species_list as its atom types and supercell_dimensions as
		its supercell dimensions. 

		primitive_cell_lattice_constant is length (in Angstroms) of the perovskite cubic lattice vector in a 5-atom unit cell
		"""

		(Nx, Ny, Nz) = supercell_dimensions_list

		(a, b, c) = (primitive_cell_lattice_constant*Nx, primitive_cell_lattice_constant*Ny, primitive_cell_lattice_constant*Nz)

		


		##############Move this chunk somewhere else - this func should just take in the strain distribution function array#####################################

		e33_average = 1.0
		e33_spread = 0.2
		min_e33 = e33_average - e33_spread
		max_e33 = e33_average + e33_spread
		e33_distribution_function = lambda x: (e33_spread - (abs(e33_average-x)))**0.4 #very broad bell shape max at 1.0, 0.0 at edges
		e33_distribution = Distribution(e33_distribution_function, min_e33, max_e33)


		e13_average = 0.0
		e13_spread = 0.2
		min_e13 = e13_average - e13_spread
		max_e13 = e13_average + e13_spread
		e13_distribution_function = lambda x: (e13_spread - (abs(e13_average-x)))**0.8 #somewhat broad bell shape max at 0.0, 0.0 at edges
		e13_distribution = Distribution(e13_distribution_function, min_e13, max_e13)


		e23_average = 0.0
		e23_spread = 0.2
		min_e23 = e23_average - e23_spread
		max_e23 = e23_average + e23_spread
		e23_distribution_function = lambda x: (e23_spread - (abs(e23_average-x)))**0.8 #somewhat broad bell shape max at 0.0, 0.0 at edges
		e23_distribution = Distribution(e23_distribution_function, min_e23, max_e23)

		zero_function = lambda : 0.0
		unity_function = lambda : 1.0

		strain_distribution_function_array = [
			[unity_function, zero_function, e13_distribution.get_random_value], 
			[zero_function, unity_function, e23_distribution.get_random_value], 
			[zero_function, zero_function, e33_distribution.get_random_value]
			]

		###################################################################################################################################################


		lattice = Lattice([[a, 0.0, 0.0], [0.0, b, 0.0], [0.0, 0.0, c]])
		structure = Perovskite(supercell_dimensions=supercell_dimensions_list, lattice=lattice, species_list=species_list)
		structure.lattice.randomly_strain(distribution_function_array=strain_distribution_function_array)


		##############################################################this stuff as well should be factored out - also take in 
		#displacement_vector_distribution_function_dictionary_by_type and minimum_atomic_distances_nested_dictionary_by_type

		def envelope_function(curvature_parameter, max_displacement_distance, bell=True):
			"""
			for bell == True:
				Get a curve that is high at 0, lower as you get away from 0
				curvature_parameter: closer to 0 means sharper peak at 0, closer to 3 or more, very constant until sharp drop to 0 at max_disp_dist
			for bell == False:
				Curve is 0 at 0, highest at max_disp_dist
				curvature_parameter: closer to 0 means curve gets to large value faster (less of an abyss around 0), larger means sharp increase near max_disp
			"""

			if bell:
				offset = 1.0
				sign = -1.0
			else:
				offset = 0.0
				sign = 1.0


			if max_displacement_distance == 0:
				return lambda x: 1.0
			else:
				return lambda x: offset + sign*((x**curvature_parameter)/(max_displacement_distance**curvature_parameter))


		A_type = species_list[0]
		B_type = species_list[1]
		X_type = species_list[2]


		A_site_curvature_parameter = 1.4
		A_site_max_displacement = 0.35*primitive_cell_lattice_constant
		A_bell = True

		B_site_curvature_parameter = 2.5
		B_site_max_displacement = 0.6*primitive_cell_lattice_constant
		B_bell = True

		X_site_curvature_parameter = 3.0
		X_site_max_displacement = 0.75*primitive_cell_lattice_constant
		X_bell = True

		AA_minimum_distance = 1.2
		AB_minimum_distance = 0.8
		BB_minimum_distance = 0.8
		AX_minimum_distance = 0.6
		BX_minimum_distance = 0.6
		XX_minimum_distance = 0.6


		A_site_vector_magnitude_distribution_function = Distribution(envelope_function(A_site_curvature_parameter, A_site_max_displacement, A_bell), 0.0, A_site_max_displacement).get_random_value
		B_site_vector_magnitude_distribution_function = Distribution(envelope_function(B_site_curvature_parameter, B_site_max_displacement, B_bell), 0.0, B_site_max_displacement).get_random_value
		X_site_vector_magnitude_distribution_function = Distribution(envelope_function(X_site_curvature_parameter, X_site_max_displacement, X_bell), 0.0, X_site_max_displacement).get_random_value

		A_site_vector_distribution_function = VectorDistribution(Vector.get_random_unit_vector, A_site_vector_magnitude_distribution_function)
		B_site_vector_distribution_function = VectorDistribution(Vector.get_random_unit_vector, B_site_vector_magnitude_distribution_function)
		X_site_vector_distribution_function = VectorDistribution(Vector.get_random_unit_vector, X_site_vector_magnitude_distribution_function)

		displacement_vector_distribution_function_dictionary_by_type = {
			A_type: A_site_vector_distribution_function.get_random_vector,
			B_type: B_site_vector_distribution_function.get_random_vector,
			X_type: X_site_vector_distribution_function.get_random_vector
		}

		minimum_atomic_distances_nested_dictionary_by_type = {
			A_type: {A_type: AA_minimum_distance, B_type: AB_minimum_distance, X_type: AX_minimum_distance},
			B_type: {A_type: AB_minimum_distance, B_type: BB_minimum_distance, X_type: BX_minimum_distance},
			X_type: {A_type: AX_minimum_distance, B_type: BX_minimum_distance, X_type: XX_minimum_distance}
		}


		##########################################################################################################################


		StructureManipulator.displace_site_positions_with_minimum_distance_constraints(structure, displacement_vector_distribution_function_dictionary_by_type, minimum_atomic_distances_nested_dictionary_by_type)

		return structure