Source code for PyCD.material_run

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

import numpy as np
import yaml

from PyCD.core import Material, Neighbors, System, Run


def material_run(dst_path):
    # Load simulation parameters
    sim_param_file_name = 'simulation_parameters.yml'
    sim_param_file_path = dst_path / sim_param_file_name
    with open(sim_param_file_path, 'r') as stream:
        try:
            sim_params = yaml.load(stream)
        except yaml.YAMLError as exc:
            print(exc)

    # data type conversion:
    sim_params['system_size'] = np.asarray(sim_params['system_size'])
    sim_params['pbc'] = np.asarray(sim_params['pbc'])
    sim_params['species_count'] = np.asarray(sim_params[
                                                    'species_count'])

    # Load material parameters
    config_file_name = 'sys_config.yml'
    work_dir_depth = (sim_params['work_dir_depth'] + 1
                      if sim_params['compute_mode'] == 'parallel' else sim_params['work_dir_depth'])
    if work_dir_depth == 0:
        input_directory_path = (
                dst_path.resolve() / sim_params['input_file_directory_name'])
    else:
        input_directory_path = (
            dst_path.resolve().parents[work_dir_depth - 1]
            / sim_params['input_file_directory_name'])
    config_file_path = input_directory_path / config_file_name
    with open(config_file_path, 'r') as stream:
        try:
            params = yaml.load(stream)
        except yaml.YAMLError as exc:
            print(exc)

    input_coordinate_file_name = 'POSCAR'
    input_coord_file_location = input_directory_path.joinpath(
                                            input_coordinate_file_name)
    params.update({'input_coord_file_location':
                   input_coord_file_location})
    config_params = ReturnValues(params)

    # Build material object files
    material_info = Material(config_params)

    # Build neighbors object files
    material_neighbors = Neighbors(material_info,
                                   sim_params['system_size'],
                                   sim_params['pbc'])

    file_exists = 0
    if dst_path.joinpath('Run.log').exists():
        file_exists = 1
    if not file_exists or sim_params['over_write']:
        # Load input files to instantiate system class
        hop_neighbor_list_file_name = input_directory_path.joinpath(
                                            'hop_neighbor_list.npy')
        hop_neighbor_list = np.load(hop_neighbor_list_file_name, allow_pickle=True)[()]
        pairwise_min_image_vector_data_file_path = (
                            input_directory_path.joinpath(
                                'pairwise_min_image_vector_data.npy'))
        pairwise_min_image_vector_data = np.load(
                                pairwise_min_image_vector_data_file_path)
        precomputed_array_log_file_path = input_directory_path.joinpath(
                                            'precomputed_array.log')
        precomputed_array_log_file = open(precomputed_array_log_file_path, 'r')
        for line_index, line in enumerate(precomputed_array_log_file):
            if line_index == 3:
                alpha = float(line[7:16])

        r_cut = config_params.r_cut
        k_cut = config_params.k_cut
        precision_parameters = config_params.precision_parameters

        # Load step hop neighbor list if needed
        step_system_size_array = []
        step_hop_neighbor_master_list = []
        if 'doping' in sim_params:
            for map_index, insertion_type in enumerate(sim_params['doping']['insertion_type']):
                if insertion_type == 'gradient':
                    gradient_params = sim_params['doping']['gradient'][map_index]
                    ld = gradient_params['ld']
                    step_length_ratio = gradient_params['step_length_ratio']
                    sum_step_length_ratio = sum(step_length_ratio)
                    stepwise_num_dopants = gradient_params['stepwise_num_dopants']
                    if any(stepwise_num_dopants):
                        num_steps = len(step_length_ratio)
                    else:
                        num_steps = 0
                    for step_index in range(num_steps):
                        import_flag = 0
                        step_system_size = np.copy(sim_params['system_size'])
                        step_system_size[ld] *= step_length_ratio[step_index] / sum_step_length_ratio
                        if len(step_system_size_array) == 0:
                            step_system_size_array = step_system_size
                            import_flag = 1
                        elif len(step_system_size_array.shape) == 1:
                            if not np.array_equal(step_system_size_array,
                                                  step_system_size):
                                step_system_size_array = np.vstack((step_system_size_array,
                                                                    step_system_size))
                                import_flag = 1
                        else:
                            lookup_array = np.where((step_system_size_array == step_system_size).all(axis=1))[0]
                            if len(lookup_array) == 0:
                                step_system_size_array = np.vstack((step_system_size_array,
                                                                    step_system_size))
                                import_flag = 1
                        if import_flag:
                            step_work_dir_depth = (
                                sim_params['doping']['step_work_dir_depth'] + 1
                                if sim_params['compute_mode'] == 'parallel' else sim_params['doping']['step_work_dir_depth'])
                            step_input_directory_path = (
                                dst_path.resolve().parents[step_work_dir_depth - 1]
                                / ('SystemSize[' + ','.join(str(element) for element in step_system_size) + ']')
                                / sim_params['input_file_directory_name'])
                            step_hop_neighbor_list_file_name = step_input_directory_path.joinpath(
                                                                        'hop_neighbor_list.npy')
                            step_hop_neighbor_list = np.load(step_hop_neighbor_list_file_name)[()]
                            step_hop_neighbor_master_list.append(step_hop_neighbor_list)

        material_system = System(
            material_info, material_neighbors, hop_neighbor_list,
            pairwise_min_image_vector_data, alpha, r_cut, k_cut, precision_parameters,
            step_system_size_array, step_hop_neighbor_master_list)

        # Load precomputed array to instantiate run class
        precomputed_array_file_path = input_directory_path.joinpath(
                                            'precomputed_array.npy')
        precomputed_array = np.load(precomputed_array_file_path)
        material_run = Run(
            material_system, precomputed_array, sim_params['temp'],
            sim_params['ion_charge_type'],
            sim_params['species_charge_type'],
            1 if sim_params['compute_mode'] == 'parallel' else sim_params['n_traj'],
            sim_params['t_final'], sim_params['time_interval'],
            sim_params['species_count'], sim_params['initial_occupancy'],
            sim_params['relative_energies'], sim_params['external_field'],
            sim_params['doping'])
        material_run.do_kmc_steps(dst_path, sim_params['output_data'],
                                  sim_params['random_seed'],
                                  sim_params['compute_mode'])
    else:
        print('Simulation files already exists in '
              + 'the destination directory')
    return None


[docs]class ReturnValues(object): """dummy class to return objects from methods \ defined inside other classes""" def __init__(self, input_dict): for key, value in input_dict.items(): setattr(self, key, value)