Recipes
Construct a series of Debye workflows by substituting into a template structure
DRY_RUN = True # Don't submit the workflows VERBOSE = True # Turn on printing of substitutions # Filename of the template structure to use, usually a dilute or SQS structure TEMPLATE_STRUCTURE_FILENAME = 'structures/FCC_A1.sqs.12Ni-4Fe.POSCAR' # sublattice configuration of the template structure. # This will be substitued exactly, this does not need to be sorted, # however the individual configurations to build should be sorted. TEMPLATE_SUBLATTICE_CONFIGURATION = [['Fe', 'Ni']] TEMPLATE_SUBLATTICE_OCCUPANCIES = [[0.25, 0.75]] SUBLATTICE_SITE_RATIOS = [1.0] PHASE_NAME = 'FCC_A1' configurations_to_build = [ # list of sublattice configurations in DFTTK format [['Cr', 'Ni']], [['Fe', 'Ni']], # [['V', 'Ni']], # should not use this because it's out of order, make a second script with the templates flipped ] # Dictionary of densities for each pure element. # Not necessary, using the peridic_table in pymatgen instead #DENSITY_DICT = { # 'V': 6.313, # bcc # 'Cr': 7.463, # bcc # 'Ni': 9.03, # fcc # 'Ti': 4.58, # hcp # 'Fe': 8.028 # bcc #}
# SCRIPT #
# Should not need to edit below this line.
from pymatgen import Structure
from fireworks import LaunchPad
from dfttk import get_wf_gibbs
from dfttk.structure_builders.substitutions import substitute_configuration_with_metadata
workflows = []
temp_struct = Structure.from_file(TEMPLATE_STRUCTURE_FILENAME)
for config in configurations_to_build:
struct, meta = substitute_configuration_with_metadata(temp_struct, TEMPLATE_SUBLATTICE_CONFIGURATION, config, TEMPLATE_SUBLATTICE_OCCUPANCIES, PHASE_NAME, SUBLATTICE_SITE_RATIOS)
if VERBOSE:
print("PHASE: {} CONFIGURATION: {} OCCUPANCIES: {} STRUCTURE: {}".format(PHASE_NAME, config, TEMPLATE_SUBLATTICE_OCCUPANCIES, struct.composition.hill_formula))
workflows.append(get_wf_gibbs(struct, deformation_fraction=(-0.05,0.10), phonon=False, num_deformations=11, t_max=2000, metadata=meta))
################################################################################
# Load everything in the LaunchPad
################################################################################
if VERBOSE:
print("{} workflows.".format(len(workflows)))
if DRY_RUN:
exit()
if VERBOSE:
print('Adding workflows to LaunchPad')
lpad = LaunchPad.auto_load()
for workflow in workflows:
lpad.add_wf(workflow)
ESPEI datasets from a QHA database
The following code snippet will take ESPEI datasets from a QHA database, optionally writing the (nicely named) files to dict. The QHA database requires the following metadata schema:
{
'metadata': {
'phase_name': 'FCC_A1',
'tag': 'ed447049-ad67-4090-ba99-378188d3416b',
'sublattice': {
'configuration': [['Cr', 'Ni']],
'occupancies': [[0.03125, 0.96875]]
},
}
}
########
# EDIT #
########
phase_name = 'BCC_A2'
configuration_to_find = [['Ni', 'V']]
sublattice_site_ratios = [1.0]
db_username = 'BrandonResultsRO'
db_password = 'piqhg38hap3'
db_uri = 'mongodb://206.189.190.225:27018'
WRITE_FILES = True
temperature_index = 59 # index of 300 K temperature (close to 298 K), found by hand
refstate_tags = {
'Fe': '4ac77fce-0e43-4c07-8418-4843a2cd5723',
'Ni': '0059ee69-4a8f-4e86-9895-9b40cf67dd96',
'Cr': '8cceb186-2796-4488-ba8c-2380c5278f62',
'V': 'fba46b6b-1699-419f-b5e1-da9533530701',
}
########################
### SCRIPT
########################
from dfttk.analysis.formation_energies import get_formation_energy, get_thermal_props
from dfttk.espei_compat import make_dataset, dfttk_config_to_espei, dfttk_occupancies_to_espei
from pymatgen import Structure
import numpy as np
from dfttk.utils import recursive_flatten
import json
from pymongo import MongoClient
# create the MongoClient
cli = MongoClient(db_uri)
db = cli.results
db.authenticate(name=db_username, password=db_password)
coll = db.qha
# construct the energies, assupmtion of same temperature grid
# energies are J/mol-atom
refstate_energies = {}
for el, tag in refstate_tags.items():
qha_result = coll.find_one({'metadata.tag': tag})
refstate_energies[el] = get_thermal_props(qha_result)
# calculate all the dataset values
configs = []
occupancies = []
hm_values = []
sm_values = []
cpm_values = []
# we'll change the T to the right temperatures later
fixed_conds = {'P': 101325, 'T': 0}
temp_conds = {'P': 101325, 'T': 0}
for qha_res in coll.find({'metadata.sublattice.configuration': configuration_to_find, 'metadata.phase_name': phase_name}):
configs.append(qha_res['metadata']['sublattice']['configuration'])
occupancies.append(qha_res['metadata']['sublattice']['occupancies'])
tprops = get_thermal_props(qha_res)
struct = Structure.from_dict(qha_res['structure'])
hm_form = get_formation_energy(tprops, struct, refstate_energies, 'HM', idx=temperature_index)
sm_form = get_formation_energy(tprops, struct, refstate_energies, 'SM', idx=temperature_index)
cpm_form = get_formation_energy(tprops, struct, refstate_energies, 'CPM', thin=10)[:-2]
fixed_temp = tprops['T'][temperature_index]
cpm_temps = tprops['T'][::10][:-2]
hm_values.append(hm_form)
sm_values.append(sm_form)
cpm_values.append(cpm_form)
fixed_conds['T'] = fixed_temp.tolist()
temp_conds['T'] = cpm_temps.tolist()
# make the HM, SM, CPM values arrays of the proper shape
hm_values = np.array([[hm_values]])
sm_values = np.array([[sm_values]])
cpm_values = np.array(cpm_values).T[np.newaxis, ...]
if WRITE_FILES:
# write JSON files
comps = [c.upper() for c in sorted(recursive_flatten(configuration_to_find))]
for prop, vals, conds in [('HM_FORM', hm_values, fixed_conds), ('SM_FORM', sm_values, fixed_conds), ('CPM_FORM', cpm_values, temp_conds)]:
ds = make_dataset(phase_name, prop, sublattice_site_ratios, configs, conds, vals, occupancies=occupancies, tag=tag)
with open('{}-{}-{}-DFTTK.json'.format('-'.join(comps), phase_name, prop), 'w') as fp:
json.dump(ds, fp)