In [1]:
from pycalphad import equilibrium, Database, Model, variables as v
import sympy
import numpy as np
TDB = """
ELEMENT A GRAPHITE 12.011 1054.0 5.7423 !
ELEMENT B BCC_A2 55.847 4489.0 27.2797 !
ELEMENT C BCC_A2 55.847 4489.0 27.2797 !
TYPE_DEFINITION % SEQ * !
PHASE TEST % 1 1 !
CONSTITUENT TEST : A,B,C: !
"""
my_phases = ['TEST']
comps = ['A', 'B','C']
comps = sorted(comps)
conds = dict({v.T: 1000, v.P: 101325, v.N: 1})
dbf = Database(TDB)
mod = Model(dbf, ['A', 'B', 'C'], 'TEST')
NP = sympy.Symbol('NP', real=True)
total_moles = sum([NP*mod.moles(c) for c in comps])
total_moles = NP
variables = [v.N, v.P, v.T] + mod.site_fractions + [NP]
mass_cons = [v.N, v.P, v.T]
mass_cons.extend(mod.get_internal_constraints())
mass_cons.extend(NP*mod.moles(c) for c in comps)
mass_jac = []
for cons in mass_cons:
mass_jac.append([cons.diff(x) for x in variables])
energy_grad = [(total_moles*mod.GM).diff(x) for x in variables]
In [2]:
mass_cons
Out[2]:
In [3]:
mass_jac
Out[3]:
In [4]:
A = sympy.Matrix(mass_jac).T.pinv()
x = A * sympy.Matrix(energy_grad)
In [5]:
from pycalphad.codegen.sympydiff_utils import build_functions
mu_a = build_functions(x[4], variables, include_grad=True, include_hess=False)
mu_b = build_functions(x[5], variables, include_grad=True, include_hess=False)
mu_c = build_functions(x[6], variables, include_grad=True, include_hess=False)
energy = build_functions(mod.GM, variables, include_grad=True)
In [6]:
print(x[4].free_symbols)
In [7]:
mu_a.func([1, 1e5, 1000, 0.4, 0.6, 1e-12, 1e-6])
Out[7]:
In [8]:
np.array(mu_a.grad([1, 1e5, 1000, 0.4, 0.6, 1e-12, 1])) - np.array(mu_b.grad([1, 1e5, 1000, 0.4, 0.6, 1e-12, 1]))
Out[8]:
In [9]:
from pycalphad.core.solver import InteriorPointSolver
class ProblemSaver(InteriorPointSolver):
saved_problem = [None]
def solve(self, prob):
self.saved_problem[0] = prob
self.verbose = True
return super(ProblemSaver, self).solve(prob)
eq = equilibrium(dbf, ['A', 'B', 'C'], ['TEST'],
{v.MU('B'): -1000, v.X('A'): 0.1, v.T: 800, v.P: 101325}, solver=ProblemSaver())
In [10]:
ProblemSaver.saved_problem[0].jacobian([1, 1e5, 800, 0.1, 8.60415585e-01, 3.95844148e-2, 1.0])[-1]
Out[10]:
In [11]:
mu_b.grad([1, 1e5, 800, 0.1, 8.60415585e-01, 3.95844148e-2, 1.0])
Out[11]:
In [ ]: