Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
exc_search = (where('excluded_model_contributions').test(lambda x: tuple(sorted(x)) == exclusion)) & (where('solver').exists())
curr_data = get_prop_data(comps, phase_name, prop, datasets, additional_query=exc_search)
calculate_dict = get_prop_samples(dbf, comps, phase_name, curr_data)
mod = Model(dbf, comps, phase_name, parameters=symbols_to_fit)
if prop.endswith('_FORM'):
output = ''.join(prop.split('_')[:-1])+'R'
mod.shift_reference_state(ref_states, dbf, contrib_mods={e: sympy.S.Zero for e in exclusion})
else:
output = prop
for contrib in exclusion:
mod.models[contrib] = sympy.S.Zero
mod.reference_model.models[contrib] = sympy.S.Zero
species = sorted(unpack_components(dbf, comps), key=str)
data_dict['species'] = species
model = {phase_name: mod}
statevar_dict = {getattr(v, c, None): vals for c, vals in calculate_dict.items() if isinstance(getattr(v, c, None), v.StateVariable)}
statevar_dict = OrderedDict(sorted(statevar_dict.items(), key=lambda x: str(x[0])))
str_statevar_dict = OrderedDict((str(k), vals) for k, vals in statevar_dict.items())
phase_records = build_phase_records(dbf, species, [phase_name], statevar_dict, model,
output=output, parameters={s: 0 for s in symbols_to_fit},
build_gradients=False, build_hessians=False)
data_dict['str_statevar_dict'] = str_statevar_dict
data_dict['phase_records'] = phase_records
data_dict['calculate_dict'] = calculate_dict
data_dict['model'] = model
data_dict['output'] = output
data_dict['weights'] = np.array(property_std_deviation[prop.split('_')[0]])/np.array(calculate_dict.pop('weights'))
all_data_dicts.append(data_dict)
return all_data_dicts
try:
out = getattr(mod, output)
except AttributeError:
raise AttributeError('Missing Model attribute {0} specified for {1}'
.format(output, mod.__class__))
# Construct an ordered list of the variables
variables, sublattice_dof = generate_dof(phase_obj, mod.components)
site_ratios = list(phase_obj.sublattices)
# Build the "fast" representation of that model
if callable_dict[phase_name] is None:
# As a last resort, treat undefined symbols as zero
# But warn the user when we do this
# This is consistent with TC's behavior
undefs = list(out.atoms(Symbol) - out.atoms(v.StateVariable))
for undef in undefs:
out = out.xreplace({undef: float(0)})
logger.warning('Setting undefined symbol %s for phase %s to zero',
undef, phase_name)
comp_sets[phase_name] = make_callable(out, \
list(statevar_dict.keys()) + variables, mode=mode)
else:
comp_sets[phase_name] = callable_dict[phase_name]
# Eliminate pure vacancy endmembers from the calculation
vacancy_indices = list()
for idx, sublattice in enumerate(phase_obj.constituents):
if 'VA' in sorted(sublattice) and 'VA' in sorted(comps):
vacancy_indices.append(sorted(sublattice).index('VA'))
if len(vacancy_indices) != len(phase_obj.constituents):
vacancy_indices = None
def __init__(self, equation):
"""
Construct a generic equilibrium condition.
Parameters
----------
equation : SymPy object
Independent condition in the form: `equation` = 0
"""
self.equation = equation
self.variables = equation.atoms(v.StateVariable)
def __repr__(self):
# Construct models for each phase; prioritize user models
models = unpack_kwarg(model, default_arg=Model)
if verbose:
print('Components:', ' '.join(comps))
print('Phases:', end=' ')
for name in progressbar(active_phases, desc='Initialize (1/3)', unit='phase', disable=not pbar):
mod = models[name]
if isinstance(mod, type):
models[name] = mod = mod(dbf, comps, name)
variables = sorted(mod.energy.atoms(v.StateVariable).union({key for key in conditions.keys() if key in [v.T, v.P]}), key=str)
site_fracs = sorted(mod.energy.atoms(v.SiteFraction), key=str)
maximum_internal_dof = max(maximum_internal_dof, len(site_fracs))
# Extra factor '1e-100...' is to work around an annoying broadcasting bug for zero gradient entries
#models[name].models['_broadcaster'] = 1e-100 * Mul(*variables) ** 3
out = models[name].energy
undefs = list(out.atoms(Symbol) - out.atoms(v.StateVariable))
for undef in undefs:
out = out.xreplace({undef: float(0)})
callable_dict[name], grad_callable_dict[name], hess_callable_dict[name] = \
build_functions(out, [v.P, v.T] + site_fracs)
# Adjust gradient by the approximate chemical potentials
hyperplane = Add(*[v.MU(i)*mole_fraction(dbf.phases[name], comps, i)
for i in comps if i != 'VA'])
plane_obj, plane_grad, plane_hess = build_functions(hyperplane, [v.MU(i) for i in comps if i != 'VA']+site_fracs)
mass_obj, mass_grad, mass_hess = build_functions(Add(*[mole_fraction(dbf.phases[name], comps, i)
for i in comps if i != 'VA']), site_fracs)
phase_records[name.upper()] = PhaseRecord(variables=variables,
grad=grad_callable_dict[name],
hess=hess_callable_dict[name],
plane_grad=plane_grad,
plane_hess=plane_hess,
from scipy.stats import norm
from pycalphad.plot.eqplot import _map_coord_to_variable
from pycalphad import Database, Model, ReferenceState, variables as v
from pycalphad.core.equilibrium import _eqcalculate
from pycalphad.codegen.callables import build_phase_records
from pycalphad.core.utils import instantiate_models, filter_phases, extract_parameters, unpack_components, unpack_condition
from pycalphad.core.phase_rec import PhaseRecord
from espei.utils import PickleableTinyDB
from espei.shadow_functions import equilibrium_, calculate_, no_op_equilibrium_, update_phase_record_parameters
EqPropData = NamedTuple('EqPropData', (('dbf', Database),
('species', Sequence[v.Species]),
('phases', Sequence[str]),
('potential_conds', Dict[v.StateVariable, float]),
('composition_conds', Sequence[Dict[v.X, float]]),
('models', Dict[str, Model]),
('params_keys', Dict[str, float]),
('phase_records', Sequence[Dict[str, PhaseRecord]]),
('output', str),
('samples', np.ndarray),
('weight', np.ndarray),
('reference', str),
))
def build_eqpropdata(data: tinydb.database.Document,
dbf: Database,
parameters: Optional[Dict[str, float]] = None,
data_weight_dict: Optional[Dict[str, float]] = None
) -> EqPropData:
def _print_Symbol(self, expr):
if isinstance(expr, v.StateVariable):
return expr.name
else:
# Thermo-Calc likes symbol references to be marked with a '#' at the end
return expr.name + "#"
#pylint: disable=E1121
new_self = StateVariable.__new__(cls, varname, nonnegative=True)
new_self.phase_name = phase_name.upper()
new_self.multiplicity = multiplicity
return new_self
def __getnewargs__(self):
return self.phase_name, self.multiplicity
def _latex(self, printer=None):
"LaTeX representation."
#pylint: disable=E1101
return 'f^{'+self.phase_name.replace('_', '-') + \
'}_{'+str(self.multiplicity)+'}'
class Composition(StateVariable):
"""
Compositions are symbols with built-in assumptions of being real
and nonnegative.
"""
def __new__(cls, *args): #pylint: disable=W0221
new_self = None
varname = None
phase_name = None
species = None
if len(args) == 1:
# this is an overall composition variable
species = Species(args[0])
varname = 'X_' + species.escaped_name.upper()
elif len(args) == 2:
# this is a phase-specific composition variable
phase_name = args[0].upper()
species = None
if len(args) == 1:
# this is an overall composition variable
species = Species(args[0])
varname = 'X_' + species.escaped_name.upper()
elif len(args) == 2:
# this is a phase-specific composition variable
phase_name = args[0].upper()
species = Species(args[1])
varname = 'X_' + phase_name + '_' + species.escaped_name.upper()
else:
# not defined
raise ValueError('Composition not defined for args: '+args)
#pylint: disable=E1121
new_self = StateVariable.__new__(cls, varname, nonnegative=True)
new_self.phase_name = phase_name
new_self.species = species
return new_self
conds[v.N] = [1.0]
if 'pdens' not in calc_kwargs:
calc_kwargs['pdens'] = 2000
species = unpack_components(dbf, comps)
parameters = eq_kwargs.get('parameters', {})
models = eq_kwargs.get('model')
statevars = get_state_variables(models=models, conds=conds)
if models is None:
models = instantiate_models(dbf, comps, phases, model=eq_kwargs.get('model'),
parameters=parameters, symbols_only=True)
prxs = build_phase_records(dbf, species, phases, conds, models, output='GM',
parameters=parameters, build_gradients=True, build_hessians=True)
indep_comp = [key for key, value in conds.items() if isinstance(key, v.Composition) and len(np.atleast_1d(value)) > 1]
indep_pot = [key for key, value in conds.items() if (type(key) is v.StateVariable) and len(np.atleast_1d(value)) > 1]
if (len(indep_comp) != 1) or (len(indep_pot) != 1):
raise ValueError('Binary map requires exactly one composition and one potential coordinate')
if indep_pot[0] != v.T:
raise ValueError('Binary map requires that a temperature grid must be defined')
# binary assumption, only one composition specified.
comp_cond = [k for k in conds.keys() if isinstance(k, v.X)][0]
indep_comp = comp_cond.name[2:]
indep_comp_idx = sorted(get_pure_elements(dbf, comps)).index(indep_comp)
composition_grid = unpack_condition(conds[comp_cond])
dX = composition_grid[1] - composition_grid[0]
Xmax = composition_grid.max()
temperature_grid = unpack_condition(conds[v.T])
dT = temperature_grid[1] - temperature_grid[0]
boundary_sets = boundary_sets or ZPFBoundarySets(comps, comp_cond)
"State variables can be added with the `additional_statevars` "
"argument.".format(state_variables))
state_variables = sorted(state_variables, key=str)
for name in phases:
mod = models[name]
site_fracs = mod.site_fractions
try:
out = getattr(mod, output)
except AttributeError:
raise AttributeError('Missing Model attribute {0} specified for {1}'
.format(output, mod.__class__))
# Build the callables of the output
# Only force undefineds to zero if we're not overriding them
undefs = {x for x in out.free_symbols if not isinstance(x, v.StateVariable)} - set(parameter_symbols)
undef_vals = repeat(0., len(undefs))
out = out.xreplace(dict(zip(undefs, undef_vals)))
build_output = build_functions(out, tuple(state_variables + site_fracs), parameters=parameter_symbols,
include_grad=build_gradients, include_hess=build_hessians)
cf, gf, hf = build_output.func, build_output.grad, build_output.hess
# trigger the JIT
cf.kernel
if gf is not None:
gf.kernel
if hf is not None:
hf.kernel
_callables['callables'][name] = cf
_callables['grad_callables'][name] = gf
_callables['hess_callables'][name] = hf
# Build the callables for mass