def run_test(): dbf = Database() dbf.elements = frozenset(["A"]) dbf.add_phase("TEST", {}, [1]) dbf.add_phase_constituents("TEST", [["A"]]) # add THETA parameters here dbf.add_parameter("THETA", "TEST", [["A"]], 0, 334.0) conds = {v.T: np.arange(1.0, 800.0, 1), v.P: 101325} res = calculate(dbf, ["A"], "TEST", T=conds[v.T], P=conds[v.P], model=EinsteinModel, output="testprop") # res_TE = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], # model=EinsteinModel, output='einstein_temperature') import matplotlib.pyplot as plt plt.scatter(res["T"], res["testprop"]) plt.xlabel("Temperature (K)") plt.ylabel("Molar Heat Capacity (J/mol-K)") plt.savefig("einstein.png")
def run_test(): dbf = Database() dbf.elements = frozenset(['A']) dbf.add_phase('TEST', {}, [1]) dbf.add_phase_constituents('TEST', [['A']]) # add THETA parameters here dbf.add_parameter('THETA', 'TEST', [['A']], 0, 334.) conds = {v.T: np.arange(1.,800.,1), v.P: 101325} res = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], model=EinsteinModel, output='testprop') #res_TE = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], # model=EinsteinModel, output='einstein_temperature') import matplotlib.pyplot as plt plt.scatter(res['T'], res['testprop']) plt.xlabel('Temperature (K)') plt.ylabel('Molar Heat Capacity (J/mol-K)') plt.savefig('einstein.png') print(dbf.to_string(fmt='tdb'))
def run_test(): dbf = Database() dbf.elements = frozenset(['A']) dbf.add_phase('TEST', {}, [1]) dbf.add_phase_constituents('TEST', [['A']]) # add THETA parameters here dbf.add_parameter('THETA', 'TEST', [['A']], 0, 334.) conds = {v.T: np.arange(1., 800., 1), v.P: 101325} res = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], model=EinsteinModel, output='testprop') #res_TE = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], # model=EinsteinModel, output='einstein_temperature') import matplotlib.pyplot as plt plt.scatter(res['T'], res['testprop']) plt.xlabel('Temperature (K)') plt.ylabel('Molar Heat Capacity (J/mol-K)') plt.savefig('einstein.png') print(dbf.to_string(fmt='tdb'))
def initialize_database(phase_models, ref_state, dbf=None, fallback_ref_state="SGTE91"): """Return a Database boostraped with elements, species, phases and unary lattice stabilities. Parameters ---------- phase_models : Dict[str, Any] Dictionary of components and phases to fit. ref_state : str String of the reference data to use, e.g. 'SGTE91' or 'SR2016' dbf : Optional[Database] Initial pycalphad Database that can have parameters that would not be fit by ESPEI fallback_ref_state : str String of the reference data to use for SER data, defaults to 'SGTE91' Returns ------- Database A new pycalphad Database object, or a modified one if it was given. """ if dbf is None: dbf = Database() lattice_stabilities = getattr(espei.refdata, ref_state) ser_stability = getattr(espei.refdata, ref_state + "Stable") aliases = extract_aliases(phase_models) phases = sorted({ph.upper() for ph in phase_models["phases"].keys()}) elements = {el.upper() for el in phase_models["components"]} dbf.elements.update(elements) dbf.species.update({v.Species(el, {el: 1}, 0) for el in elements}) # Add SER reference data for this element for element in dbf.elements: if element in dbf.refstates: continue # Do not clobber user reference states el_ser_data = _get_ser_data(element, ref_state, fallback_ref_state=fallback_ref_state) # Try to look up the alias that we are using in this fitting el_ser_data["phase"] = aliases.get(el_ser_data["phase"], el_ser_data["phase"]) # Don't warn if the element is a species with no atoms because per-atom # formation energies are not possible (e.g. VA (VACUUM) or /- (ELECTRON_GAS)) if el_ser_data["phase"] not in phases and v.Species( element).number_of_atoms != 0: # We have the Gibbs energy expression that we need in the reference # data, but this phase is not a candidate in the phase models. The # phase won't be added to the database, so looking up the phases's # energy won't work. _log.warning( "The reference phase for %s, %s, is not in the supplied phase models " "and won't be added to the Database phases. Fitting formation " "energies will not be possible.", element, el_ser_data["phase"]) dbf.refstates[element] = el_ser_data # Add the phases for phase_name, phase_data in phase_models['phases'].items(): if phase_name not in dbf.phases.keys(): # Do not clobber user phases # TODO: Need to support model hints for: magnetic, order-disorder, etc. site_ratios = phase_data['sublattice_site_ratios'] subl_model = phase_data['sublattice_model'] # Only generate the sublattice model for active components subl_model = [ sorted(set(subl).intersection(dbf.elements)) for subl in subl_model ] if all(len(subl) > 0 for subl in subl_model): dbf.add_phase(phase_name, dict(), site_ratios) dbf.add_phase_constituents(phase_name, subl_model) # Add the GHSER functions to the Database for element in dbf.elements: # Use setdefault here to not clobber user-provided functions if element == "VA": dbf.symbols.setdefault("GHSERVA", 0) else: # note that `c.upper()*2)[:2]` returns "AL" for "Al" and "BB" for "B" # Using this ensures that GHSER functions will be unique, e.g. # GHSERC would be an abbreviation for GHSERCA. sym_name = "GHSER" + (element.upper() * 2)[:2] dbf.symbols.setdefault(sym_name, ser_stability[element]) return dbf
def generate_parameters(phase_models, datasets, ref_state, excess_model): """Generate parameters from given phase models and datasets Parameters ---------- phase_models : dict Dictionary of components and phases to fit. datasets : PickleableTinyDB database of single- and multi-phase to fit. ref_state : str String of the reference data to use, e.g. 'SGTE91' or 'SR2016' excess_model : str String of the type of excess model to fit to, e.g. 'linear' Returns ------- pycalphad.Database """ logging.info('Generating parameters.') dbf = Database() dbf.elements = set(phase_models['components']) for el in dbf.elements: if Species is not None: # TODO: drop this on release of pycalphad 0.7 dbf.species.add(Species(el, {el: 1}, 0)) # Write reference state to Database refdata = getattr(espei.refdata, ref_state) stabledata = getattr(espei.refdata, ref_state + 'Stable') for key, element in refdata.items(): if isinstance(element, sympy.Piecewise): newargs = element.args + ((0, True), ) refdata[key] = sympy.Piecewise(*newargs) for key, element in stabledata.items(): if isinstance(element, sympy.Piecewise): newargs = element.args + ((0, True), ) stabledata[key] = sympy.Piecewise(*newargs) comp_refs = { c.upper(): stabledata[c.upper()] for c in dbf.elements if c.upper() != 'VA' } comp_refs['VA'] = 0 # note that the `c.upper()*2)[:2]` returns 'AL' for c.upper()=='AL' and 'VV' for c.upper()=='V' dbf.symbols.update( {'GHSER' + (c.upper() * 2)[:2]: data for c, data in comp_refs.items()}) for phase_name, phase_obj in sorted(phase_models['phases'].items(), key=operator.itemgetter(0)): # Perform parameter selection and single-phase fitting based on input # TODO: Need to pass particular models to include: magnetic, order-disorder, etc. symmetry = phase_obj.get('equivalent_sublattices', None) aliases = phase_obj.get('aliases', None) # TODO: More advanced phase data searching site_ratios = phase_obj['sublattice_site_ratios'] subl_model = phase_obj['sublattice_model'] dbf.add_phase(phase_name, dict(), site_ratios) dbf.add_phase_constituents(phase_name, subl_model) dbf.add_structure_entry(phase_name, phase_name) phase_fit(dbf, phase_name, symmetry, subl_model, site_ratios, datasets, refdata, aliases=aliases) logging.info('Finished generating parameters.') return dbf