Exemplo n.º 1
0
def main(*args):    
    """Main function for running calculation"""

    #Read in parameters from input file
    with open(args[0]) as f:
        input_dict = iprPy.calculation_read_input(__calc_type__, f, *args[1:])
        
    #Read in potential
    potential = lmp.Potential(input_dict['potential'], input_dict['potential_dir'])            
    
    #Get axes info
    axes = np.array([input_dict['x-axis'], input_dict['y-axis'], input_dict['z-axis']])
    
    #Perform crss calculation
    results_dict = crss(input_dict['lammps_command'], input_dict['initial_system'], 
                        potential, input_dict['symbols'], input_dict['C'], 
                        mpi_command=input_dict['mpi_command'], 
                        chi=input_dict['chi_angle'], sigma=input_dict['sigma'], 
                        tau_1=input_dict['tau_1'], tau_2=input_dict['tau_2'], 
                        press=input_dict['press'], rss_steps=input_dict['rss_steps'],
                        axes=axes)
    
    #Save data model of results 
    results = iprPy.calculation_data_model(__calc_type__, input_dict, results_dict)
    with open('results.json', 'w') as f:
        results.json(fp=f, indent=4)    
Exemplo n.º 2
0
def isymbolscombos(prototype, potential):
    
    symbols = lmp.Potential(potential.content).symbols
    natypes = prototype.todict()['natypes']
            
    for ivals in iterbox(len(symbols), natypes):
        yield list(np.asarray(symbols)[ivals])
Exemplo n.º 3
0
    def interpret(self, input_dict):
        """
        Interprets calculation parameters.
        
        Parameters
        ----------
        input_dict : dict
            Dictionary containing input parameter key-value pairs.
        """

        # Set default keynames
        keymap = self.keymap

        # Extract input values and assign default values
        potential_file = input_dict[keymap['potential_file']]
        potential_dir = input_dict.get(keymap['potential_dir'], '')
        potential_content = input_dict.get(keymap['potential_content'], None)

        # Use potential_content instead of potential_file if given
        if potential_content is not None:
            potential_file = potential_content

        # Save processed terms
        input_dict[keymap['potential_dir']] = potential_dir
        input_dict[keymap['potential']] = lmp.Potential(
            potential_file, potential_dir)
Exemplo n.º 4
0
    def load_parameters(self, input_dict):
        """
        Interprets calculation parameters.
        
        Parameters
        ----------
        input_dict : dict
            Dictionary containing input parameter key-value pairs.
        """

        # Set default keynames
        keymap = self.keymap
    
        # Extract input values and assign default values
        potential_file = input_dict[keymap['potential_file']]
        potential_kim_id = input_dict.get(keymap['potential_kim_id'], None)
        potential_kim_potid = input_dict.get(keymap['potential_kim_potid'], None)
        potential_dir = input_dict.get(keymap['potential_dir'], None)
        potential_content = input_dict.get(keymap['potential_content'], None)

        # Use potential_content instead of potential_file if given
        if potential_content is not None:
            potential_file = potential_content
        
        # Read potential
        self.potential = lmp.Potential(potential_file, pot_dir=potential_dir, 
                                       kim_id=potential_kim_id, potid=potential_kim_potid)
Exemplo n.º 5
0
def interpret_input(input_dict):
    with open(input_dict['potential_file']) as f:
        input_dict['potential'] = lmp.Potential(f, os.path.abspath(input_dict['potential_dir']))
        
    iprPy.input.system_family(input_dict)
    
    iprPy.input.ucell(input_dict)
    
    iprPy.input.initialsystem(input_dict)
Exemplo n.º 6
0
def main(*args):
    """Main function for running calculation"""

    #Read in parameters from input file
    with open(args[0]) as f:
        input_dict = iprPy.calculation_read_input(__calc_type__, f, *args[1:])

    #Read in potential
    potential = lmp.Potential(input_dict['potential'],
                              input_dict['potential_dir'])

    #Save data model of results
    results = iprPy.calculation_data_model(__calc_type__, input_dict,
                                           results_dict)
    with open('results.json', 'w') as f:
        results.json(fp=f, indent=4)
Exemplo n.º 7
0
def lammps_potential(input_dict, **kwargs):
    """
    Interprets calculation parameters associated with a potential-LAMMPS
    record.
    
    The input_dict keys used by this function (which can be renamed using the
    function's keyword arguments):
    
    - **'potential_file'** the potential-LAMMPS model to load.
    - **'potential_dir'** the directory containing all of the potential's
      artifacts.
    - **'potential_content'** alternate file or content to load instead of
      specified potential_file. This is used by prepare functions.
    - **'potential'** the atomman.lammps.Potential object created.
       
    Parameters
    ----------
    input_dict : dict
        Dictionary containing input parameter key-value pairs.
    potential_file : str
        Replacement parameter key name for 'potential_file'.
    potential_dir : str
        Replacement parameter key name for 'potential_dir'.
    potential : str
        Replacement parameter key name for 'potential'.
    """

    # Set default keynames
    keynames = [
        'potential_file', 'potential_dir', 'potential_content', 'potential'
    ]
    for keyname in keynames:
        kwargs[keyname] = kwargs.get(keyname, keyname)

    # Extract input values and assign default values
    potential_file = input_dict[kwargs['potential_file']]
    potential_dir = input_dict.get(kwargs['potential_dir'], '')
    potential_content = input_dict.get(kwargs['potential_content'], None)

    # Use potential_content instead of potential_file if given
    if potential_content is not None:
        potential_file = potential_content

    # Save processed terms
    input_dict[kwargs['potential_dir']] = potential_dir
    input_dict[kwargs['potential']] = lmp.Potential(potential_file,
                                                    potential_dir)
def main(*args):
    """Main function for running calculation"""

    # Read input file in as dictionary
    with open(args[0]) as f:
        input_dict = iprPy.input.parse(f, allsingular=True)

    # Interpret and process input parameters
    process_input(input_dict, *args[1:])

    #Read in potential
    potential = lmp.Potential(input_dict['potential'],
                              input_dict['potential_dir'])

    #Get axes info
    axes = np.array(
        [input_dict['x-axis'], input_dict['y-axis'], input_dict['z-axis']])

    # Perform crss calculation
    results_dict = crss(input_dict['lammps_command'],
                        input_dict['initial_system'],
                        potential,
                        input_dict['C'],
                        mpi_command=input_dict['mpi_command'],
                        chi=input_dict['chi_angle'],
                        sigma=input_dict['sigma'],
                        tau_1=input_dict['tau_1'],
                        tau_2=input_dict['tau_2'],
                        press=input_dict['press'],
                        rss_steps=input_dict['rss_steps'],
                        axes=axes)

    # Build and save data model of results
    record = iprPy.load_record(record_style)
    record.buildcontent(input_dict, results_dict)
    with open('results.json', 'w') as f:
        record.content.json(fp=f, indent=4)
Exemplo n.º 9
0
def relaxed(database_name, crystal_match_file, all_crystals_file, unique_crystals_file):
    # !!!!!!!!!!!!!!!!!!!!!!!!!!!!! Load records !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    database = load_database(database_name)

    # Load potential_LAMMPS records
    pot_records = database.get_records_df(style='potential_LAMMPS')
    print(f'{len(pot_records)} potential records found', flush=True)

    # Load crystal_prototype records
    proto_records = database.get_records_df(style='crystal_prototype')
    print(f'{len(proto_records)} prototype records found', flush=True)

    # Load reference_crystal records
    ref_records = database.get_records_df(style='reference_crystal')
    print(f'{len(ref_records)} reference records found', flush=True)

    # Get key lists for relax_* calculations
    raw_df = database.get_records_df(style='calculation_relax_box',
                                    full=False, flat=True)
    print(f'{len(raw_df)} calculation_relax_box records found', flush=True)
    try:
        box_keys = raw_df.key.tolist()
    except:
        box_keys = []

    raw_df = database.get_records_df(style='calculation_relax_static',
                                    full=False, flat=True)
    print(f'{len(raw_df)} calculation_relax_static records found', flush=True)
    try:
        static_keys = raw_df.key.tolist()
    except:
        static_keys = []

    raw_df = database.get_records_df(style='calculation_relax_dynamic',
                                    full=False, flat=True)
    print(f'{len(raw_df)} calculation_relax_dynamic records found', flush=True)
    try:
        dynamic_keys = raw_df.key.tolist()
    except:
        dynamic_keys = []
    print()

    # Get space group results
    spg_records = database.get_records_df(style='calculation_crystal_space_group',
                                        full=True, flat=False, status='finished')
    print(f'{len(spg_records)} calculation_crystal_space_group records found',
        flush=True)

    if len(spg_records) == 0:
        print('Stopping as no calculations to process')
        return

    # Separate records by branch
    prototype_records = spg_records[spg_records.branch == 'prototype']
    reference_records = spg_records[spg_records.branch == 'reference']
    family_records = spg_records[(spg_records.branch == 'prototype') 
                                |(spg_records.branch == 'reference')]
    print(f' -{len(prototype_records)} are for prototypes', flush=True)
    print(f' -{len(reference_records)} are for references', flush=True)

    calc_records = spg_records[spg_records.branch == 'relax'].reset_index(drop=True)
    print(f' -{len(calc_records)} are for calculations', flush=True)
    print()

    if len(calc_records) == 0:
        print('Stopping as no calculations to process')
        return

    if len(family_records) == 0:
        print('Stopping as prototype/reference records needed')
        return

    # !!!!!!!!!!!!!!!!!!!!!!!!!! Load saved results !!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    try:
        ref_proto_match = pd.read_csv(crystal_match_file)
    except:
        columns = ['reference', 'prototype', 'composition']
        ref_proto_match = pd.DataFrame(columns=columns)
    print(f'{len(ref_proto_match)} references matched to prototypes', flush=True)

    try:
        results = pd.read_csv(all_crystals_file)
    except:
        columns = ['calc_key', 'potential_LAMMPS_key', 'potential_LAMMPS_id',
                'potential_key', 'potential_id', 'composition', 'prototype',
                'family', 'method', 'transformed', 'E_coh', 'a', 'b', 'c',
                    'alpha', 'beta', 'gamma']
        results = pd.DataFrame(columns=columns)
    print(f'{len(results)} previous results found', flush=True)

    try:
        unique = pd.read_csv(unique_crystals_file)
    except:
        columns = ['calc_key', 'potential_LAMMPS_key', 'potential_LAMMPS_id',
                'potential_key', 'potential_id', 'composition', 'prototype',
                'family', 'method', 'transformed', 'E_coh', 'a', 'b', 'c',
                    'alpha', 'beta', 'gamma']
        unique = pd.DataFrame(columns=columns)
    print(f'{len(unique)} previous unique results found', flush=True)

    print()

    # !!!!!!!!!!!!!!!!!!!!!!!!! Process new results !!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    newresults = []
    old_keys = results.calc_key.values
    for series in calc_records.itertuples():
        if series.key in old_keys:
            continue
            
        results_dict = {}
        
        # Copy over values in series    
        results_dict['calc_key'] = series.key
        results_dict['composition'] = series.composition
        results_dict['family'] = series.family
        results_dict['a'] = series.ucell.box.a
        results_dict['b'] = series.ucell.box.b
        results_dict['c'] = series.ucell.box.c
        results_dict['alpha'] = series.ucell.box.alpha
        results_dict['beta'] = series.ucell.box.beta
        results_dict['gamma'] = series.ucell.box.gamma
        
        # Identify prototype
        try:
            results_dict['prototype'] = ref_proto_match[ref_proto_match.reference==series.family].prototype.values[0]
        except:
            results_dict['prototype'] = series.family
        else:
            if pd.isnull(results_dict['prototype']):
                results_dict['prototype'] = series.family
        
        # Check if structure has transformed relative to reference
        family_series = family_records[family_records.family == series.family].iloc[0]
        results_dict['transformed'] = (not (family_series.spacegroup_number == series.spacegroup_number
                                    and family_series.pearson_symbol == series.pearson_symbol))
        
        # Extract info from parent calculations
        for parent in database.get_parent_records(name=series.key):
            
            parent_dict = parent.todict()

            if parent_dict['key'] in box_keys:
                results_dict['method'] = 'box'
                results_dict['E_coh'] = parent_dict['E_cohesive']
                results_dict['potential_LAMMPS_key'] = parent_dict['potential_LAMMPS_key']
                continue

            elif parent_dict['key'] in dynamic_keys:
                results_dict['method'] = 'dynamic'
                continue

            elif parent_dict['key'] in static_keys:
                results_dict['method'] = 'static'
                results_dict['E_coh'] = parent_dict['E_cohesive']
                results_dict['potential_LAMMPS_key'] = parent_dict['potential_LAMMPS_key']

        pot_record = pot_records[pot_records.key == results_dict['potential_LAMMPS_key']].iloc[0]
        results_dict['potential_id'] = pot_record.pot_id
        results_dict['potential_key'] = pot_record.pot_key
        results_dict['potential_LAMMPS_id'] = pot_record.id
        
        newresults.append(results_dict)

    print(f'{len(newresults)} new results added')
    if len(newresults) > 0:
        results = results.append(newresults, ignore_index=True)
        results.to_csv(all_crystals_file, index=False)

    # !!!!!!!!!!!!!!!!!!!!!!!!! Find unique results !!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    new_unique = pd.DataFrame(columns=results.columns)

    # Loop over all potential implementations
    for implememtation_key in np.unique(results.potential_LAMMPS_key):
        imp_results = results[results.potential_LAMMPS_key == implememtation_key]
        
        # Loop over all compositions
        for composition in np.unique(results.composition):
            comp_unique = unique[unique.composition == composition].reset_index(drop=True)
            comp_results = imp_results[imp_results.composition == composition]
            
            # Loop over all prototypes
            for prototype in np.unique(comp_results.prototype):
                proto_results = comp_results[comp_results.prototype == prototype]
                
                # Loop over calculation methods from most robust to least
                for method in ['dynamic', 'static', 'box']:
                    
                    # First try matching results where prototype == family
                    for i, series in proto_results[(proto_results.prototype == proto_results.family)
                                                &(proto_results.method == method)
                                                &(~proto_results.transformed)].iterrows():
                        try:
                            matches = comp_unique[(np.isclose(comp_unique.E_coh, series.E_coh))
                                                &(np.isclose(comp_unique.a, series.a))
                                                &(np.isclose(comp_unique.b, series.b))
                                                &(np.isclose(comp_unique.c, series.c))
                                                &(np.isclose(comp_unique.alpha, series.alpha))
                                                &(np.isclose(comp_unique.beta, series.beta))
                                                &(np.isclose(comp_unique.gamma, series.gamma))]
                        except:
                            matches = []
                        if len(matches) == 0:
                            comp_unique = comp_unique.append(series)
                            new_unique = new_unique.append(series)
                            
                    # Next try matching results where prototype != family
                    for i, series in proto_results[(proto_results.prototype != proto_results.family)
                                                &(proto_results.method == method)
                                                &(~proto_results.transformed)].iterrows():
                        try:
                            matches = comp_unique[(np.isclose(comp_unique.E_coh, series.E_coh))
                                                &(np.isclose(comp_unique.a, series.a))
                                                &(np.isclose(comp_unique.b, series.b))
                                                &(np.isclose(comp_unique.c, series.c))
                                                &(np.isclose(comp_unique.alpha, series.alpha))
                                                &(np.isclose(comp_unique.beta, series.beta))
                                                &(np.isclose(comp_unique.gamma, series.gamma))]
                        except:
                            matches = []
                        if len(matches) == 0:
                            comp_unique = comp_unique.append(series)
                            new_unique = new_unique.append(series)
                            
    print(f'{len(new_unique)} new unique results added')       
    if len(new_unique) > 0:
        unique = unique.append(new_unique)
        unique.to_csv(unique_crystals_file, index=False)

    # !!!!!!!!!!!!!!!!!!! Generate relaxed_crystal records !!!!!!!!!!!!!!!!!!!!!! #

    for row in new_unique.itertuples():
        
        crystal_terms = {}
        crystal_terms['key'] = str(uuid.uuid4())
        crystal_terms['method'] = row.method
        crystal_terms['family'] = row.family
        crystal_terms['length_unit'] = 'angstrom'
        
        pot_record = database.get_record(name = pot_records[pot_records.key == row.potential_LAMMPS_key].id)
        crystal_terms['potential'] = lmp.Potential(pot_record.content)
        
        c_record = calc_records[calc_records.key == row.calc_key].iloc[0]
        
        # Use spg crystals for ref and α-As
        if (row.prototype[:3] == 'mp-' or
            row.prototype[:4] == 'mvc-' or
            row.prototype[:5] == 'oqmd-' or
            row.prototype == 'A7--alpha-As'):
            crystal_terms['ucell'] = c_record.ucell
        
        # Use scaled prototype crystals for the rest
        else:
            p_record = proto_records[proto_records.id == row.prototype].iloc[0]
            crystal_terms['ucell'] = p_record.ucell
            crystal_terms['ucell'].symbols = c_record.symbols
            crystal_terms['ucell'].box_set(a=row.a, b=row.b, c=row.c, alpha=row.alpha, beta=row.beta, gamma=row.gamma, scale=True)
        
        relaxrecord = load_record('relaxed_crystal')
        relaxrecord.buildcontent('b', crystal_terms)
        relaxrecord.name = crystal_terms['key']
        
        database.add_record(relaxrecord)
Exemplo n.º 10
0
def prepare(inline_terms, global_variables):
    """This is the prepare method for the calculation"""

    working_dir = os.getcwd()

    #Read in the calc_template
    calc_template = __calc_name__ + '.template'
    with open(os.path.join(__calc_dir__, 'calc_files', calc_template)) as f:
        template = f.read()

    #Identify the contents of calc_files
    calc_files = os.listdir(os.path.join(__calc_dir__, 'calc_files'))
    calc_files.remove(calc_template)

    #prepare_variables -- keywords used by this prepare function and the associated value lists given in inline_terms and global_variables
    #calculation_variables -- keywords in the calculation's template file. Empty and singular values filled in here, iterated values later
    prepare_variables, calculation_variables = __initial_setup(
        inline_terms, global_variables)

    #Loop over all potentials
    for potential_file, potential_dir in zip(
            prepare_variables.aslist('potential_file'),
            prepare_variables.aslist('potential_dir')):

        #Loop over all load systems
        for load, load_options, load_elements, box_parameters, elastic_constants_model in zip(
                prepare_variables.aslist('load'),
                prepare_variables.aslist('load_options'),
                prepare_variables.aslist('load_elements'),
                prepare_variables.aslist('box_parameters'),
                prepare_variables.aslist('elastic_constants_model')):

            #Loop over all size_mults
            for size_mults in prepare_variables.aslist('size_mults'):

                #Loop over all dislocation data models
                for dislocation_model in global_variables.aslist(
                        'dislocation_model'):

                    #Add iterated values to calculation_variables
                    calculation_variables['potential_file'] = potential_file
                    calculation_variables['potential_dir'] = potential_dir
                    calculation_variables['load'] = load
                    calculation_variables['load_options'] = load_options
                    calculation_variables['box_parameters'] = box_parameters
                    calculation_variables['size_mults'] = size_mults
                    calculation_variables['symbols'] = ''
                    calculation_variables[
                        'dislocation_model'] = dislocation_model
                    calculation_variables[
                        'elastic_constants_model'] = elastic_constants_model

                    #Fill in template using calculation_variables values, and build input_dict
                    calc_in = fill_template(template, calculation_variables,
                                            '<', '>')
                    input_dict = read_input(calc_in)

                    #Extract info from input dict
                    potential = lmp.Potential(input_dict['potential'])
                    system_family = input_dict['system_family']
                    dislocation_id = input_dict['dislocation_model'][
                        'dislocation-monopole-parameters']['dislocation']['id']

                    #Check if disl_model's system_family matches the load_file's system_family
                    if system_family != input_dict['dislocation_model'][
                            'dislocation-monopole-parameters']['system-family']:
                        continue

                    #Loop over all symbols combinations
                    for symbols in atomman_input.yield_symbols(
                            load, load_options, load_elements,
                            global_variables, potential):

                        #Define directory path for the record
                        record_dir = os.path.join(
                            calculation_variables['lib_directory'],
                            str(potential), '-'.join(symbols), system_family,
                            __calc_type__)
                        #record_dir = os.path.join(calculation_variables['lib_directory'], str(potential), '-'.join(symbols), system_family, __calc_type__, dislocation_id)

                        #Add symbols to input_dict and build incomplete record
                        input_dict['symbols'] = list(symbols)
                        record = data_model(input_dict)

                        #Check if record already exists
                        if __is_new_record(record_dir, record):

                            UUID = str(uuid.uuid4())
                            calculation_variables['symbols'] = ' '.join(
                                symbols)

                            #Create calculation run folder
                            sim_dir = os.path.join(
                                calculation_variables['run_directory'], UUID)
                            os.makedirs(sim_dir)

                            #Copy calc_files to run folder
                            for fname in calc_files:
                                shutil.copy(
                                    os.path.join(__calc_dir__, 'calc_files',
                                                 fname), sim_dir)

                            #Copy potential and load files to run directory and shorten paths
                            if calculation_variables['copy_files']:

                                #Divy up the load information
                                load_terms = load.split()
                                load_style = load_terms[0]
                                load_file = ' '.join(load_terms[1:])

                                #Copy loose files
                                shutil.copy(potential_file, sim_dir)
                                shutil.copy(load_file, sim_dir)
                                shutil.copy(dislocation_model, sim_dir)

                                #Copy potential_dir and contents to run folder
                                os.mkdir(
                                    os.path.join(
                                        sim_dir,
                                        os.path.basename(potential_dir)))
                                for fname in glob.iglob(
                                        os.path.join(potential_dir, '*')):
                                    shutil.copy(
                                        fname,
                                        os.path.join(
                                            sim_dir,
                                            os.path.basename(potential_dir)))

                                #Shorten file paths to be relative
                                calculation_variables[
                                    'potential_file'] = os.path.basename(
                                        potential_file)
                                calculation_variables[
                                    'potential_dir'] = os.path.basename(
                                        potential_dir)
                                calculation_variables['load'] = ' '.join(
                                    [load_style,
                                     os.path.basename(load_file)])
                                calculation_variables[
                                    'dislocation_model'] = os.path.basename(
                                        dislocation_model)

                            #Create calculation input file by filling in template with calculation_variables terms
                            os.chdir(sim_dir)
                            calc_in = fill_template(template,
                                                    calculation_variables, '<',
                                                    '>')
                            input_dict = read_input(calc_in, UUID)
                            with open(__calc_name__ + '.in', 'w') as f:
                                f.write('\n'.join(calc_in))
                            os.chdir(working_dir)

                            #Save the record to the library
                            with open(os.path.join(record_dir, UUID + '.json'),
                                      'w') as f:
                                record.json(fp=f, indent=2)
Exemplo n.º 11
0
def prepare(terms, variable):
    """This is the prepare method for the calculation"""

    working_dir = os.getcwd()

    #Identify the necessary run files in the calculation directory
    calc_template = os.path.join(__calc_dir__, __calc_name__ + '.template')
    calc_py = os.path.join(__calc_dir__, __calc_name__ + '.py')
    min_template = os.path.join(__calc_dir__, 'min.template')

    #Read in the calc_template
    with open(calc_template) as f:
        template = f.read()

    #Interpret and check terms and variables
    run_directory, lib_directory, v_dict = __initial_setup(terms, variable)

    #Loop over all potentials
    for potential_file, potential_dir in zip(variable.aslist('potential_file'),
                                             variable.aslist('potential_dir')):

        #Load potential
        with open(potential_file) as f:
            potential = lmp.Potential(f)

        #Pass potential's file and directory info to v_dict
        v_dict['potential_file'] = os.path.basename(potential_file)
        v_dict['potential_dir'] = os.path.basename(potential_dir)

        #Loop over all systems
        for load, load_options, load_elements, box_parameters in zip(
                variable.aslist('load'), variable.aslist('load_options'),
                variable.aslist('load_elements'),
                variable.aslist('box_parameters')):

            #Divy up the load information
            load_terms = load.split()
            load_style = load_terms[0]
            load_file = ' '.join(load_terms[1:])
            load_base = os.path.basename(load_file)

            #Check for system_model fields from previous simulations
            if load_style == 'system_model':
                with open(load_file) as f:
                    model = DM(f)

                #Skip if load relaxed with a different potential
                try:
                    pot_key = model.find('potential')['key']
                    if pot_key != potential.uuid:
                        continue
                except:
                    pass

                #Get or make the load artifact family name
                try:
                    system_family = model.find(
                        'system-info')['artifact']['family']
                except:
                    system_family = os.path.splitext(load_base)[0]
            else:
                system_family = os.path.splitext(load_base)[0]

            #Loop over all point defect data models
            for ptd_model in variable.aslist('ptd_model'):

                #Check if ptd_model's system_family matches the load_file's system_family
                with open(ptd_model) as f:
                    ptd = DM(f)
                if system_family != ptd['point-defect']['system-family']:
                    continue

                #Pass system's file, options and box parameters to v_dict
                v_dict['load'] = ' '.join([load_terms[0], load_base])
                v_dict['load_options'] = load_options
                v_dict['box_parameters'] = box_parameters

                #Pass defect model to v_dict
                ptd_file = os.path.basename(ptd_model)
                v_dict['ptd_model'] = ptd_file
                v_dict['ptd_name'] = ptd['point-defect']['identifier']['name']

                #Loop over all symbols combinations
                for symbols in atomman_input.yield_symbols(
                        load, load_options, load_elements, variable,
                        potential):

                    #Pass symbols to v_dict
                    v_dict['symbols'] = ' '.join(symbols)

                    #Define directory path for the record
                    record_dir = os.path.join(lib_directory, str(potential),
                                              '-'.join(symbols), system_family,
                                              __calc_type__)

                    #Loop over all size_mults
                    for size_mults in variable.aslist('size_mults'):
                        v_dict['size_mults'] = size_mults
                        #Check if record already exists
                        if __is_new_record(record_dir, v_dict):
                            UUID = str(uuid.uuid4())

                            #Create calculation run folder
                            sim_dir = os.path.join(run_directory, UUID)
                            os.makedirs(sim_dir)

                            #Copy files to run folder
                            shutil.copy(calc_py, sim_dir)
                            shutil.copy(min_template, sim_dir)
                            shutil.copy(potential_file, sim_dir)
                            shutil.copy(load_file, sim_dir)
                            shutil.copy(ptd_model, sim_dir)

                            #Copy potential_dir and contents to run folder
                            os.mkdir(
                                os.path.join(sim_dir,
                                             os.path.basename(potential_dir)))
                            for fname in glob.iglob(
                                    os.path.join(potential_dir, '*')):
                                shutil.copy(
                                    fname,
                                    os.path.join(
                                        sim_dir,
                                        os.path.basename(potential_dir)))

                            #Create calculation input file by filling in template with v_dict terms
                            os.chdir(sim_dir)
                            calc_in = fill_template(template, v_dict, '<', '>')
                            input_dict = calc.input(calc_in, UUID)
                            with open(__calc_name__ + '.in', 'w') as f:
                                f.write('\n'.join(calc_in))
                            os.chdir(working_dir)

                            #Save the incomplete record
                            model = calc.data_model(input_dict)
                            with open(os.path.join(record_dir, UUID + '.json'),
                                      'w') as f:
                                model.json(fp=f, indent=2)
Exemplo n.º 12
0
def main(*args):
    calculation = iprPy.Calculation(__calc_style__)

    with open(args[0]) as f:
        prepare_dict = read_input(f)

    #open database
    dbase = iprPy.database_fromdict(prepare_dict)

    #Build record_df
    record_df = build_record_df(dbase, __record_style__)

    #Loop over all potentials
    for pot_record in iprPy.prepare.ipotentials(
            dbase,
            element=prepare_dict['potential_element'],
            name=prepare_dict['potential_name'],
            pair_style=prepare_dict['potential_pair_style']):
        potential = lmp.Potential(pot_record.content)
        pot_tar = dbase.get_tar(pot_record)

        #Loop over all prototypes
        for proto_record in iprPy.prepare.iprototypes(
                dbase,
                natypes=prepare_dict['prototype_natypes'],
                name=prepare_dict['prototype_name'],
                spacegroup=prepare_dict['prototype_spacegroup'],
                crystalfamily=prepare_dict['prototype_crystalfamily'],
                pearson=prepare_dict['prototype_Pearsonsymbol']):

            #Iterate over all combinations of potentials, prototypes and symbols
            for symbols in iprPy.prepare.isymbolscombos(
                    proto_record, pot_record):

                #Create calc_key
                calc_key = str(uuid.uuid4())

                #Define values for calc_*.in file
                calc_dict = {}
                calc_dict['lammps_command'] = prepare_dict['lammps_command']
                calc_dict['mpi_command'] = prepare_dict['mpi_command']
                calc_dict['potential_file'] = pot_record.name + '.xml'
                calc_dict['potential_dir'] = pot_record.name
                calc_dict[
                    'load'] = 'system_model ' + proto_record.name + '.xml'
                calc_dict['load_options'] = ''
                calc_dict['symbols'] = ' '.join(symbols)
                calc_dict['box_parameters'] = ''
                calc_dict['x_axis'] = ''
                calc_dict['y_axis'] = ''
                calc_dict['z_axis'] = ''
                calc_dict['atomshift'] = ''
                calc_dict['sizemults'] = prepare_dict['sizemults']
                calc_dict['length_unit'] = prepare_dict['length_unit']
                calc_dict['pressure_unit'] = prepare_dict['pressure_unit']
                calc_dict['energy_unit'] = prepare_dict['energy_unit']
                calc_dict['force_unit'] = prepare_dict['force_unit']
                calc_dict['minimum_r'] = prepare_dict['minimum_r']
                calc_dict['maximum_r'] = prepare_dict['maximum_r']
                calc_dict['number_of_steps_r'] = prepare_dict[
                    'number_of_steps_r']

                #Build inputfile by filling in calculation's template
                inputfile = iprPy.tools.filltemplate(calculation.template,
                                                     calc_dict, '<', '>')

                #Read inputfile to build input_dict
                input_dict = calculation.read_input(inputfile, calc_key)

                #Define additional input_dict terms
                input_dict['potential'] = potential
                input_dict['load_file'] = proto_record.content
                iprPy.input.system_family(input_dict)

                #Build incomplete record
                new_record = iprPy.Record(
                    name=calc_key,
                    content=calculation.data_model(input_dict).xml(),
                    style=__record_style__)

                #Check if record is new
                if is_new(record_df, new_record):

                    #Add record to database
                    dbase.add_record(record=new_record)

                    #Generate calculation folder
                    calc_directory = os.path.join(
                        prepare_dict['run_directory'], calc_key)
                    os.makedirs(calc_directory)

                    #Save inputfile to calculation folder
                    with open(
                            os.path.join(calc_directory,
                                         'calc_' + __calc_style__ + '.in'),
                            'w') as f:
                        f.write(inputfile)

                    #Add calculation files to calculation folder
                    for calc_file in calculation.files:
                        shutil.copy(calc_file, calc_directory)

                    #Add potential record file to calculation folder
                    with open(
                            os.path.join(calc_directory,
                                         pot_record.name + '.xml'), 'w') as f:
                        f.write(pot_record.content)

                    #Extract potential's tar files to calculation folder
                    pot_tar.extractall(calc_directory)

                    #Add prototype record file to calculation folder
                    with open(
                            os.path.join(calc_directory,
                                         proto_record.name + '.xml'),
                            'w') as f:
                        f.write(proto_record.content)
Exemplo n.º 13
0
def atomicreference(database, keys, lib_directory=None, elements=None, **kwargs):
    
    # Get potentials
    if 'potential_file' in keys:
        potential_kwargs = {}
        for key in list(kwargs.keys()):
            if key[:10] == 'potential_':
                potential_kwargs[key[10:]] = kwargs.pop(key)
        
        pot_inputs = interatomicpotential(database, **potential_kwargs)
        
        potentials = {}
        potsymbols = {}
        for i in range(len(pot_inputs['potential_dir'])):
            potentials[pot_inputs['potential_dir'][i]] = pot_inputs['potential_content'][i]
            potsymbols[pot_inputs['potential_dir'][i]] = lmp.Potential(pot_inputs['potential_content'][i]).symbols
    else:
        potentials = {'empty': ''}
        potsymbols = None
    
    if lib_directory is None:
        lib_directory = os.path.join(os.path.dirname(rootdir), 'library')
    
    if elements is not None:
        elements = aslist(elements)
        allelements = set()
        for i in range(len(elements)):
            e = elements[i].split()
            allelements.update(e)
            e.sort()
            elements[i] = '-'.join(e)
    
    if potsymbols is None:
        if elements is not None:
            potsymbols = {'empty': list(allelements)}
        else:
            potsymbols = {'empty': ['*']}
    
    inputs = {}
    for key in keys:
        inputs[key] = []
    
    # Get reference file names for searching
    names = aslist(kwargs.get('name', '*'))
    
    for potential_name in potentials:
        potential_content = potentials[potential_name]
        allsymbols = potsymbols[potential_name]
        allsymbols.sort()
        
        for symbols in subsets(allsymbols):
            symbol_str = '-'.join(symbols)
            if elements is not None and symbol_str != '*'  and symbol_str not in elements:
                continue
            for name in names:
                for fname in glob.iglob(os.path.join(lib_directory, 'ref', symbol_str, name)):
                    load_file = os.path.basename(fname)
                    load_name, load_ext = os.path.splitext(load_file)
                    with open(fname) as f:
                        load_content = f.read()
                    
                    load_style = load_ext[1:]
                    if load_style in ['xml', 'json']: load_style = 'system_model'
                    elif load_style == 'dump': load_style = 'atom_dump'
                    elif load_style == 'dat': load_style = 'atom_data'
                    
                    for key in keys:
                        if key == 'potential_file':
                            inputs['potential_file'].append(potential_name + '.json')
                        elif key == 'potential_content':
                            inputs['potential_content'].append(potential_content)
                        elif key == 'potential_dir':
                            inputs['potential_dir'].append(potential_name)
                        elif key == 'load_file':
                            inputs['load_file'].append(load_file)
                        elif key == 'load_content':
                            inputs['load_content'].append('file ' + os.path.abspath(fname))
                        elif key == 'load_style':
                            inputs['load_style'].append(load_style)
                        elif key == 'family':
                            inputs['family'].append(load_name)
                        else:
                            inputs[key].append('')
    
    return inputs
def bain_run_calcs(input_dict, __calc_type__, step):

    #-------------------SETS UP THE SYSTEM--------------------

    #Read in potential
    potential = lmp.Potential(
        input_dict['potential'],
        input_dict['potential_dir'])  #reads the potential filename
    system = input_dict['initial_system']

    #if initial step, set up system to find difference in cohesive energy. this step is skipped when a and c values change.
    if step == 'initial':
        a_scale = 1
        c_scale = 1
    elif step == 'bain':
        a_scale = input_dict['bain_a_scale']
        c_scale = input_dict['bain_c_scale']

    #scale box and atoms simultaneously
    system.box_set(a=a_scale * system.box.a,
                   b=a_scale * system.box.b,
                   c=c_scale * system.box.c,
                   scale=True)

    #ensure all atoms are within the box
    system.wrap()

    #-------------------RUN LAMMPS AND SAVE RESULTS------------------
    #use above information to generate system_info and pair_info for LAMMPS
    system_info = am.lammps.atom_data.dump('bain.dat',
                                           system,
                                           units=potential.units,
                                           atom_style=potential.atom_style)
    pair_info = potential.pair_info(
        input_dict['symbols']
    )  #pulls the potential info when given which element the calculation is running on

    #write the LAMMPS input script
    with open('bain.in', 'w') as f:
        f.write(
            bain_relax_script('min.template',
                              system_info,
                              pair_info,
                              etol=input_dict['energy_tolerance'],
                              ftol=input_dict['force_tolerance'],
                              maxiter=input_dict['maximum_iterations'],
                              maxeval=input_dict['maximum_evaluations']))
    #run LAMMPS
    output = lmp.run(input_dict['lammps_command'], 'bain.in',
                     input_dict['mpi_command'])

    atom_last = 'atom.%i' % output.finds('Step')[
        -1]  #prints number of iterations (?)

    #save results into results_dict
    if step == 'initial':
        try:
            os.rename(atom_last, 'initial.dump')
        except:
            os.remove('initial.dump')
            os.rename(atom_last, 'initial.dump')
        os.remove('atom.0')
        d_system = lmp.atom_dump.load('initial.dump')

    elif step == 'bain':
        try:
            os.rename(atom_last, 'bain.dump')
        except:
            os.remove('bain.dump')
            os.rename(atom_last, 'bain.dump')
        os.remove('atom.0')
        d_system = lmp.atom_dump.load('bain.dump')

    results_dict = {}
    results_dict['potential_energy'] = float(output.finds('PotEng')[-1])

    #return values
    return results_dict['potential_energy']
Exemplo n.º 15
0
def main(*args):
    calculation = iprPy.Calculation(__calc_style__)

    with open(args[0]) as f:
        prepare_dict = read_input(f)

    #open database
    dbase = iprPy.database_fromdict(prepare_dict)

    #Build record_df
    record_df = build_record_df(dbase, __record_style__)

    #Build potential dictionaries (single dbase access)
    pot_record_dict = {}
    pot_tar_dict = {}
    for pot_record in dbase.iget_records(style='LAMMPS-potential'):
        pot_record_dict[pot_record.name] = pot_record

    #Load E_vs_r_scan records
    for parent_record in iprPy.prepare.icalculations(
            dbase,
            record_style='calculation-cohesive-energy-relation',
            symbol=prepare_dict['symbol_name'],
            prototype=prepare_dict['prototype_name'],
            potential=prepare_dict['potential_name']):
        parent_dict = parent_record.todict()

        #Load potential
        pot_record = pot_record_dict[parent_dict['potential_id']]
        potential = lmp.Potential(pot_record.content)

        #Get pot_tar from dbase only once per potential
        if parent_dict['potential_id'] in pot_tar_dict:
            pot_tar = pot_tar_dict[parent_dict['potential_id']]
        else:
            pot_tar = dbase.get_tar(pot_record)
            pot_tar_dict[parent_dict['potential_id']] = pot_tar

        #Loop over number_min_states
        for i in xrange(parent_dict['number_min_states']):
            if i == 0:
                load_options = 'key minimum-atomic-system'
            else:
                load_options = 'key minimum-atomic-system index ' + str(i)

            #Loop over strainrange values
            for strain in iprPy.tools.iaslist(prepare_dict['strainrange']):

                #Create calc_key
                calc_key = str(uuid.uuid4())

                #Define values for calc_*.in file
                calc_dict = {}

                calc_dict['lammps_command'] = prepare_dict['lammps_command']
                calc_dict['mpi_command'] = prepare_dict['mpi_command']
                calc_dict['potential_file'] = pot_record.name + '.xml'
                calc_dict['potential_dir'] = pot_record.name
                calc_dict[
                    'load'] = 'system_model ' + parent_record.name + '.xml'
                calc_dict['load_options'] = load_options
                calc_dict['symbols'] = ''
                calc_dict['box_parameters'] = ''
                calc_dict['x_axis'] = ''
                calc_dict['y_axis'] = ''
                calc_dict['z_axis'] = ''
                calc_dict['atomshift'] = ''
                calc_dict['sizemults'] = prepare_dict['sizemults']
                calc_dict['length_unit'] = prepare_dict['length_unit']
                calc_dict['pressure_unit'] = prepare_dict['pressure_unit']
                calc_dict['energy_unit'] = prepare_dict['energy_unit']
                calc_dict['force_unit'] = prepare_dict['force_unit']
                calc_dict['strainrange'] = strain
                calc_dict['energytolerance'] = prepare_dict['energytolerance']
                calc_dict['forcetolerance'] = prepare_dict['forcetolerance']
                calc_dict['maxiterations'] = prepare_dict['maxiterations']
                calc_dict['maxevaluations'] = prepare_dict['maxevaluations']
                calc_dict['maxatommotion'] = prepare_dict['maxatommotion']

                #Build inputfile by filling in calculation's template
                inputfile = iprPy.tools.filltemplate(calculation.template,
                                                     calc_dict, '<', '>')

                #Read inputfile to build input_dict
                input_dict = calculation.read_input(inputfile, calc_key)

                #Define additional input_dict terms
                input_dict['potential'] = potential
                input_dict['load_file'] = parent_record.content
                iprPy.input.system_family(input_dict)

                #Build incomplete record
                new_record = iprPy.Record(
                    name=calc_key,
                    content=calculation.data_model(input_dict).xml(),
                    style=__record_style__)

                #Check if record is new
                if is_new(record_df, new_record):

                    #Add record to database
                    dbase.add_record(record=new_record)

                    #Generate calculation folder
                    calc_directory = os.path.join(
                        prepare_dict['run_directory'], calc_key)
                    os.makedirs(calc_directory)

                    #Save inputfile to calculation folder
                    with open(
                            os.path.join(calc_directory,
                                         'calc_' + __calc_style__ + '.in'),
                            'w') as f:
                        f.write(inputfile)

                    #Add calculation files to calculation folder
                    for calc_file in calculation.files:
                        shutil.copy(calc_file, calc_directory)

                    #Add potential record file to calculation folder
                    with open(
                            os.path.join(calc_directory,
                                         pot_record.name + '.xml'), 'w') as f:
                        f.write(pot_record.content)

                    #Extract potential's tar files to calculation folder
                    pot_tar.extractall(calc_directory)

                    #Add parent record file to calculation folder
                    with open(
                            os.path.join(calc_directory,
                                         parent_record.name + '.xml'),
                            'w') as f:
                        f.write(parent_record.content)
Exemplo n.º 16
0
def crystalprototype(database,
                     keys,
                     record='crystal_prototype',
                     query=None,
                     **kwargs):

    # Get potentials
    if 'potential_file' in keys:
        potential_kwargs = {}
        for key in list(kwargs.keys()):
            if key[:10] == 'potential_':
                potential_kwargs[key[10:]] = kwargs.pop(key)

        pot_inputs = interatomicpotential(database, **potential_kwargs)

        potentials = {}
        potsymbols = {}
        for i in range(len(pot_inputs['potential_dir'])):
            potentials[pot_inputs['potential_dir']
                       [i]] = pot_inputs['potential_content'][i]
            potsymbols[pot_inputs['potential_dir'][i]] = lmp.Potential(
                pot_inputs['potential_content'][i]).symbols

    else:
        potentials = {'empty': ''}
        potsymbols = {'empty': None}

    prototypes, prototype_df = database.get_records(style=record,
                                                    return_df=True,
                                                    query=query,
                                                    **kwargs)

    inputs = {}
    for key in keys:
        inputs[key] = []

    for i, prototype_info in prototype_df.iterrows():
        prototype = prototypes[i]
        natypes = prototype_info.natypes

        for potential_name in potentials:
            potential_content = potentials[potential_name]
            allsymbols = potsymbols[potential_name]

            for symbols in itersymbols(allsymbols, natypes):
                for key in keys:
                    if key == 'potential_file':
                        inputs['potential_file'].append(potential_name +
                                                        '.json')
                    elif key == 'potential_content':
                        inputs['potential_content'].append(potential_content)
                    elif key == 'potential_dir':
                        inputs['potential_dir'].append(potential_name)
                    elif key == 'load_file':
                        inputs['load_file'].append(prototype.name + '.json')
                    elif key == 'load_content':
                        inputs['load_content'].append('record ' +
                                                      prototype.name)
                    elif key == 'load_style':
                        inputs['load_style'].append('system_model')
                    elif key == 'family':
                        inputs['family'].append(prototype.name)
                    elif key == 'symbols':
                        inputs['symbols'].append(' '.join(symbols).strip())
                    else:
                        inputs[key].append('')

    return inputs
Exemplo n.º 17
0
def relaxed(database_name, crystal_match_file, all_crystals_file,
            unique_crystals_file):

    # !!!!!!!!!!!!!!!!!!!!!!!!!!!!! Load records !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    database = load_database(database_name)

    # Load potential_LAMMPS records
    pot_records = database.get_records_df(style='potential_LAMMPS')
    print(f'{len(pot_records)} potential records found', flush=True)

    # Load crystal_prototype records
    proto_records = database.get_records_df(style='crystal_prototype')
    print(f'{len(proto_records)} prototype records found', flush=True)

    # Load reference_crystal records
    ref_records = database.get_records_df(style='reference_crystal')
    print(f'{len(ref_records)} reference records found', flush=True)

    # Load relax_box records
    raw_df = database.get_records_df(style='calculation_relax_box',
                                     full=True,
                                     flat=True)
    print(f'{len(raw_df)} calculation_relax_box records found', flush=True)

    if len(raw_df) > 0:
        box_df = raw_df[raw_df.branch == 'main'].reset_index(drop=True)
        box_df['method'] = 'box'
        print(f" - {len(box_df)} are branch main", flush=True)
    else:
        box_df = pd.DataFrame()

    # Load relax_static records
    raw_df = database.get_records_df(style='calculation_relax_static',
                                     full=True,
                                     flat=True)
    print(f'{len(raw_df)} calculation_relax_static records found', flush=True)

    if len(raw_df) > 0:
        static_df = raw_df[raw_df.branch == 'main'].reset_index(drop=True)
        static_df['method'] = 'static'
        print(f" - {len(static_df)} are branch main", flush=True)
        dynamic_df = raw_df[raw_df.branch == 'from_dynamic'].reset_index(
            drop=True)
        dynamic_df['method'] = 'dynamic'
        print(f" - {len(dynamic_df)} are branch from_dynamic", flush=True)
    else:
        static_df = pd.DataFrame()
        dynamic_df = pd.DataFrame()

    parent_df = pd.concat([box_df, static_df, dynamic_df],
                          ignore_index=True,
                          sort=False)

    # Get space group results
    spg_records = database.get_records_df(
        style='calculation_crystal_space_group',
        full=True,
        flat=False,
        status='finished')
    print(f'{len(spg_records)} calculation_crystal_space_group records found',
          flush=True)

    if len(spg_records) > 0:

        # Separate records using branch
        prototype_records = spg_records[spg_records.branch == 'prototype']
        print(f' - {len(prototype_records)} are for prototypes', flush=True)

        reference_records = spg_records[spg_records.branch == 'reference']
        print(f' - {len(reference_records)} are for references', flush=True)

        family_records = spg_records[(spg_records.branch == 'prototype')
                                     | (spg_records.branch == 'reference')]

        calc_records = spg_records[spg_records.branch == 'relax'].reset_index(
            drop=True)
        print(f' - {len(calc_records)} are for calculations', flush=True)

    else:
        print('Stopping as no calculations to process')

    if len(calc_records) == 0:
        print('Stopping as no calculations to process')

    if len(family_records) == 0:
        print('Stopping as prototype/reference records needed')

    # Get existing relaxed_records
    relaxed_records = database.get_records_df(style='relaxed_crystal',
                                              full=True,
                                              flat=False)
    print(len(relaxed_records), 'relaxed records found')
    print(
        f' - {len(relaxed_records[relaxed_records.standing=="good"])} good and unique'
    )

    # !!!!!!!!!!!!!!!!!!!!!!!!!! Load saved results !!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    # Load crystal_match_file
    try:
        ref_proto_match = pd.read_csv(crystal_match_file)
    except:
        columns = ['reference', 'prototype', 'composition']
        ref_proto_match = pd.DataFrame(columns=columns)
    print(f'{len(ref_proto_match)} references matched to prototypes',
          flush=True)

    # !!!!!!!!!!!!!!! Merge DataFrames and extract  results !!!!!!!!!!!!!!!!!!!!! #

    # Get parent keys (relax_*) for space_group calculations
    def get_parent(series):
        return series.load_file.split('/')[0]

    calc_records['parent'] = calc_records.apply(get_parent, axis=1)

    # Merge calc_records, family_records and ref_proto_match
    merged_df = pd.merge(pd.merge(pd.merge(calc_records,
                                           parent_df,
                                           left_on='parent',
                                           right_on='key',
                                           suffixes=('', '_parent'),
                                           validate='one_to_one'),
                                  family_records,
                                  on='family',
                                  suffixes=('', '_family'),
                                  validate="many_to_one"),
                         ref_proto_match,
                         how='left',
                         left_on='family',
                         right_on='reference',
                         suffixes=('', '_ref'))

    # Direct copy values from merged_df to results
    results = {}
    results['calc_key'] = merged_df.key
    results['potential_LAMMPS_key'] = merged_df.potential_LAMMPS_key
    results['potential_LAMMPS_id'] = merged_df.potential_LAMMPS_id
    results['potential_key'] = merged_df.potential_key
    results['potential_id'] = merged_df.potential_id
    results['composition'] = merged_df.composition
    results['family'] = merged_df.family
    results['method'] = merged_df.method
    results['parent_key'] = merged_df.parent
    results['E_coh'] = merged_df.E_cohesive
    results['prototype'] = merged_df.prototype
    results['ucell'] = merged_df.ucell
    results['ucell_family'] = merged_df.ucell_family

    # Identify transformed structures by comparing spacegroup info before/after relax
    def get_transformed(series):
        return (
            not (series.spacegroup_number_family == series.spacegroup_number
                 and series.pearson_symbol_family == series.pearson_symbol))

    results['transformed'] = merged_df.apply(get_transformed, axis=1)

    # Set prototype as prototype (if given) or family
    def get_prototype(series):
        # Identify prototype
        if pd.isnull(series.prototype):
            return series.family
        else:
            return series.prototype

    results['prototype'] = merged_df.apply(get_prototype, axis=1)

    # Extract lattice constants from ucell
    def get_a(series):
        return series.ucell.box.a

    def get_b(series):
        return series.ucell.box.b

    def get_c(series):
        return series.ucell.box.c

    def get_alpha(series):
        return series.ucell.box.alpha

    def get_beta(series):
        return series.ucell.box.beta

    def get_gamma(series):
        return series.ucell.box.gamma

    results['a'] = merged_df.apply(get_a, axis=1)
    results['b'] = merged_df.apply(get_b, axis=1)
    results['c'] = merged_df.apply(get_c, axis=1)
    results['alpha'] = merged_df.apply(get_alpha, axis=1)
    results['beta'] = merged_df.apply(get_beta, axis=1)
    results['gamma'] = merged_df.apply(get_gamma, axis=1)

    # Create results DataFrame and save to all_crystals_file
    results_keys = [
        'calc_key', 'potential_LAMMPS_key', 'potential_LAMMPS_id',
        'potential_key', 'potential_id', 'composition', 'prototype', 'family',
        'parent_key', 'method', 'transformed', 'E_coh', 'a', 'b', 'c', 'alpha',
        'beta', 'gamma', 'ucell', 'ucell_family'
    ]
    sort_keys = [
        'potential_LAMMPS_id', 'composition', 'prototype', 'family', 'E_coh'
    ]
    results = pd.DataFrame(results,
                           columns=results_keys).sort_values(sort_keys)
    results[results_keys[:-2]].to_csv(all_crystals_file, index=False)
    print(all_crystals_file, 'updated')

    # !!!!!!!!!!!!!!!! Add new records to relaxed_crystal !!!!!!!!!!!!!!! #

    results = results[~results.transformed]
    print(len(results), 'results remained untransformed')

    results['added'] = results.calc_key.isin(relaxed_records.parent_key)

    def set_parent_type(series):
        if series.family[0] == 'm' or series.family[0] == 'o':
            return 'reference'
        else:
            return 'prototype'

    results['parent_type'] = results.apply(set_parent_type, axis=1)

    def set_method_int(series):
        if series.method == 'dynamic':
            return 1
        elif series.method == 'static':
            return 2
        else:
            return 3

    results['method_int'] = results.apply(set_method_int, axis=1)

    newresults = results[~results['added']]
    print(f' - {len(newresults)} new results to add')

    # Loop over all new records
    for i, series in newresults.sort_values(['method_int',
                                             'parent_type']).iterrows():
        oldresults = results[results.added]

        # Create new record
        key = str(uuid.uuid4())
        record = load_record('relaxed_crystal', name=key)

        # Set simple properties
        input_dict = {}
        input_dict['key'] = key
        input_dict['method'] = series.method
        input_dict['family'] = series.family
        input_dict['parent_key'] = series.calc_key
        input_dict['length_unit'] = 'angstrom'

        # Set potential
        potential_record = database.get_record(style='potential_LAMMPS',
                                               key=series.potential_LAMMPS_key)
        input_dict['potential'] = lmp.Potential(potential_record.content)

        # Set ucell
        # Use spg crystals for ref and α-As
        if (series.prototype[:3] == 'mp-' or series.prototype[:4] == 'mvc-'
                or series.prototype[:5] == 'oqmd-'
                or series.prototype == 'A7--alpha-As'):
            ucell = series.ucell

        # Use scaled prototype crystals for the rest
        else:
            ucell = series.ucell_family
            ucell.symbols = series.ucell.symbols
            ucell.box_set(vects=series.ucell.box.vects, scale=True)
        input_dict['ucell'] = ucell

        # Check for existing duplicates
        matches = (
            (series.potential_LAMMPS_key == oldresults.potential_LAMMPS_key)
            & (series.composition == oldresults.composition)
            & np.isclose(series.E_coh, oldresults.E_coh)
            & np.isclose(series.a, oldresults.a)
            & np.isclose(series.b, oldresults.b)
            & np.isclose(series.c, oldresults.c)
            & np.isclose(series.alpha, oldresults.alpha)
            & np.isclose(series.beta, oldresults.beta)
            & np.isclose(series.gamma, oldresults.gamma))

        # Set standing
        if series.E_coh < -1e-5 and matches.sum() == 0:
            input_dict['standing'] = 'good'
        else:
            input_dict['standing'] = 'bad'

        # Build content and upload
        record.buildcontent('noscript', input_dict)
        database.add_record(record=record)

    relaxed_records = database.get_records_df(style='relaxed_crystal',
                                              full=True,
                                              flat=False)
    print(len(relaxed_records), 'relaxed records found')
    print(
        f' - {len(relaxed_records[relaxed_records.standing=="good"])} good and unique'
    )

    unique_results = pd.merge(results,
                              relaxed_records,
                              left_on='calc_key',
                              right_on='parent_key',
                              suffixes=('', '_dup'),
                              validate='one_to_one')
    unique_results = unique_results[unique_results.standing ==
                                    'good'].sort_values(sort_keys)

    unique_results[results_keys[:-2]].to_csv(unique_crystals_file, index=False)
    print(unique_crystals_file, 'updated')
Exemplo n.º 18
0
import pandas
import shutil
import atomman.lammps as lmp


config_lst, file_name_lst, name_lst, species_lst = [], [], [], []
potential_folder = 'NISTiprpy'
pyiron_pot_path = 'pyiron-resources/lammps/potentials/'
prev_data_frame = pandas.read_csv(os.path.join(pyiron_pot_path, 'potentials_lammps.csv'))
for f in os.listdir(potential_folder): 
    if '.json' in f: 
        with open(os.path.join(potential_folder, f), 'r') as potfile: 
            pot_json = potfile.readlines()
        try:
            pot_json_str = ''.join(pot_json)
            potential = lmp.Potential(pot_json_str)
            if potential.id not in prev_data_frame['Name']:
                potential.load(pot_json_str, pot_dir=potential_folder)
                config_lst.append([l + '\n' for l in potential.pair_info().replace('NISTiprpy/', '').split('\n') 
                                   if any([s in l for s in ['pair_style', 'pair_coeff']])])
                species_lst.append(potential.symbols)
                pot_spec_folder = os.path.join(potential_folder, os.path.splitext(f)[0])
                file_name_lst.append([os.path.join(pot_spec_folder, pot) 
                                      for pot in os.listdir(pot_spec_folder)])
                name_lst.append(potential.id)
                print(f, ' added')
        except json.decoder.JSONDecodeError:
            print(f, ' failed')

model_lst = ['NISTiprpy'] * len(name_lst)
new_data_frame = pandas.DataFrame({'Config': config_lst, 
Exemplo n.º 19
0
def create_relaxed_crystal_records(database_name,
                                   results=None,
                                   all_crystals_file=None):
    """
    Generates new relaxed_crystal records based on the untransformed listings
    from the compiled relaxation results.
    
    Parameters
    ----------
    database_name : str
        The name of the database to access.
    results : pandas.DataFrame, optional
        The compiled relaxation results.  Either but not both of results and
        all_crystals_file must be given.
    all_crystals_file : str, optional
        The file path to the csv file where the compiled relaxation results
        are saved.  Either but not both of results and all_crystals_file must
        be given.
    
    """
    # Access the database
    database = load_database(database_name)

    # Load results from all_crystals_file if needed
    if results is None:
        if all_crystals_file is not None:
            results = pd.read_csv(all_crystals_file)
        else:
            raise TypeError('results or all_crystals_file must be given')
    elif all_crystals_file is not None:
        raise TypeError('results and all_crystals_file cannot both be given')

    # Filter out the transformed results
    results = results[~results.transformed]
    print(len(results),
          'untransformed crystals found in the compiled relaxation results')

    # Load existing relaxed_crystal records from the database
    relaxed_records = database.get_records_df(style='relaxed_crystal',
                                              full=True,
                                              flat=False)
    print(len(relaxed_records),
          'relaxed_crystal records found in the database')

    # Identify new results using parent_key (i.e. one relaxed_crystal per parent)
    newresults = results[~results.calc_key.isin(relaxed_records.parent_key)]
    print(f' - {len(newresults)} new results to add')

    # Load potential_LAMMPS records
    potential_records, potential_records_df = database.get_records(
        style='potential_LAMMPS', return_df=True)

    # Loop over all new records
    for i in newresults.index:
        series = newresults.loc[i]

        # Create new record
        key = str(uuid.uuid4())
        record = load_record('relaxed_crystal', name=key)

        # Set simple properties
        input_dict = {}
        input_dict['key'] = key
        input_dict['method'] = series.method
        input_dict['family'] = series.family
        input_dict['parent_key'] = series.calc_key
        input_dict['length_unit'] = 'angstrom'
        input_dict['energy_unit'] = 'eV'
        input_dict['E_coh'] = series.E_coh

        # Set potential
        try:
            potential_record = potential_records[
                potential_records_df[potential_records_df.key ==
                                     series.potential_LAMMPS_key].index[0]]
        except:
            print(
                f'potential {series.potential_LAMMPS_id}({series.potential_LAMMPS_key}) not found for calculation {series.calc_key}'
            )
            continue
        input_dict['potential'] = lmp.Potential(potential_record.content)

        # Set ucell
        # Use spg crystals for ref and α-As
        if (series.prototype[:3] == 'mp-' or series.prototype[:4] == 'mvc-'
                or series.prototype[:5] == 'oqmd-'
                or series.prototype == 'A7--alpha-As'):
            ucell = series.ucell

        # Use scaled prototype crystals for the rest
        else:
            ucell = series.ucell_family
            ucell.symbols = series.ucell.symbols
            ucell.box_set(vects=series.ucell.box.vects, scale=True)
        input_dict['ucell'] = ucell

        # Set standing as bad for structures with positive or near-zero energies
        if series.E_coh < -1e-5:
            input_dict['standing'] = 'good'
        else:
            input_dict['standing'] = 'bad'

        # Build content and upload
        record.buildcontent(input_dict)
        database.add_record(record=record)