Source code for pycalphad.core.equilibrium

"""
The equilibrium module defines routines for interacting with
calculated phase equilibria.
"""
import warnings
from collections import OrderedDict
from collections.abc import Iterable
from datetime import datetime
from pycalphad.core.workspace import Workspace
from pycalphad.core.light_dataset import LightDataset
import numpy as np
from pycalphad.property_framework import as_property


[docs] def equilibrium(dbf, comps, phases, conditions, output=None, model=None, verbose=False, calc_opts=None, to_xarray=True, parameters=None, solver=None, phase_records=None, **kwargs): """ Calculate the equilibrium state of a system containing the specified components and phases, under the specified conditions. Parameters ---------- dbf : Database Thermodynamic database containing the relevant parameters. comps : list Names of components to consider in the calculation. phases : list or dict Names of phases to consider in the calculation. conditions : dict or (list of dict) StateVariables and their corresponding value. output : str or list of str, optional Additional equilibrium model properties (e.g., CPM, HM, etc.) to compute. These must be defined as attributes in the Model class of each phase. model : Model, a dict of phase names to Model, or a seq of both, optional Model class to use for each phase. verbose : bool, optional Print details of calculations. Useful for debugging. calc_opts : dict, optional Keyword arguments to pass to `calculate`, the energy/property calculation routine. to_xarray : bool Whether to return an xarray Dataset (True, default) or an EquilibriumResult. parameters : dict, optional Maps SymEngine Symbol to numbers, for overriding the values of parameters in the Database. solver : pycalphad.core.solver.SolverBase Instance of a solver that is used to calculate local equilibria. Defaults to a pycalphad.core.solver.Solver. phase_records : Optional[Mapping[str, PhaseRecord]] Mapping of phase names to PhaseRecord objects with `'GM'` output. Must include all active phases. The `model` argument must be a mapping of phase names to instances of Model objects. Returns ------- Structured equilibrium calculation Examples -------- None yet. """ if output is None: output = set() elif (not isinstance(output, Iterable)) or isinstance(output, str): output = [output] wks = Workspace(database=dbf, components=comps, phases=phases, conditions=conditions, models=model, parameters=parameters, verbose=verbose, calc_opts=calc_opts, solver=solver, phase_record_factory=phase_records) # Compute equilibrium values of any additional user-specified properties # We already computed these properties so don't recompute them properties = wks.eq conds_keys = [str(k) for k in properties.coords.keys() if k not in ('vertex', 'component', 'internal_dof')] output = sorted(set(output) - {'GM', 'MU'}) for out in output: cprop = as_property(out) out = str(cprop) result_array = np.zeros(properties.GM.shape) # Will not work for non-scalar properties for index, composition_sets in wks.enumerate_composition_sets(): cur_conds = OrderedDict(zip(conds_keys, [np.asarray(properties.coords[b][a], dtype=np.float64) for a, b in zip(index, conds_keys)])) chemical_potentials = properties.MU[index] result_array[index] = cprop.compute_property(composition_sets, cur_conds, chemical_potentials) result = LightDataset({out: (conds_keys, result_array)}, coords=properties.coords) properties.merge(result, inplace=True, compat='equals') if to_xarray: properties = wks.eq.get_dataset() properties.attrs['created'] = datetime.now().isoformat() if len(kwargs) > 0: warnings.warn('The following equilibrium keyword arguments were passed, but unused:\n{}'.format(kwargs)) return properties