In [1]:
from pycalphad import Database
dbf = Database('Mg-piecewise-example.tdb')
In [2]:
from sympy import Symbol
from sympy.utilities import topological_sort
from pycalphad import variables as v
def extract_symbol_value(symbol):
"""Return the value of a Piecewise if it only has one expression
"""
# A Piecewise with a length of 2 has the expression over the range and then 0 otherwise.
# We want to return the expression in this case, otherwise the expression is a "real" Piecewise.
if len(symbol.args) == 2:
return symbol.args[0].expr
return symbol
def sorted_symbols(symbols):
"""Takes a dictionary of {Symbol: Piecewise} and returns the topological sort replacement
"""
# Topological sorting requires the verticies and edges of the a graph of symbol dependencies.
verticies = list(symbols.keys())
edges = []
for vertex in verticies:
free_symbols = symbols[vertex].free_symbols
# Filter out the StateVariables.
# This will ensure P, T variables are not included in the graph because they can be variables in TDBs.
free_symbols = [symbol for symbol in free_symbols if not isinstance(symbol, v.StateVariable)]
# construct the edges (dependencies) of the symbols if there are any
if len(free_symbols):
edges.extend([(str(vertex), str(symbol)) for symbol in free_symbols])
return topological_sort((verticies, edges))
def get_reduced_expression(dbf, symbol):
"""Return an expression for the passed symbol (as a string) reduced to only a function of state variables
"""
# To reduce an expression, we have to pass a list of substitions to the expression in the order
# we want to substitute them to get to having only StateVaribles as degrees of freedom.
# Topological sorting orders the replacements in the correct order.
topologically_sorted_symbols = sorted_symbols(dbf.symbols)
# Then we construct the values that we will replace each symbol with, deconstructing the
# symbols that are Piecewise, if necessary.
replacements = [(sym, extract_symbol_value(dbf.symbols[sym])) for sym in topologically_sorted_symbols]
return dbf.symbols[symbol].subs(replacements)
In [3]:
print(sorted_symbols(dbf.symbols))
In [4]:
print(get_reduced_expression(dbf, 'GHSERMg'))
In [5]:
print(get_reduced_expression(dbf, 'GLIQMg'))
In [6]:
print(get_reduced_expression(dbf, 'GFCCMg'))
In [ ]: