Skip to content

Commit

Permalink
additional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicholas Ury committed Dec 26, 2024
1 parent 6024c92 commit f66ec11
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 11 deletions.
7 changes: 4 additions & 3 deletions pycalphad/mapping/strategy/step_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,10 @@ def get_data(self, x: v.StateVariable, y: v.StateVariable, global_x = False, glo
The state variable to be used for the x-axis.
y : v.StateVariable
The state variable to be used for the y-axis.
x_is_global : bool, optional
Indicates whether `x` is a global or phase-local variable.
For example, if plotting global composition (`x`) vs. phase fraction (`y`), then `x` is global.
global_x : bool
Whether variable x applies to the global system
global_y : bool
Whether variable y applies to the global system
set_nan_to_zero : bool, optional
If True, NaN values will be set to zero in the data.
Expand Down
6 changes: 3 additions & 3 deletions pycalphad/mapping/strategy/strategy_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,16 @@ def add_nodes_from_conditions(self, conditions: dict[v.StateVariable, float], di
"""
point = point_from_equilibrium(self.dbf, self.components, self.phases, conditions, models=self.models, phase_record_factory=self.phase_records)
if point is None:
_log.warning(f"Point could not be found from {conditions}")
_log.info(f"Point could not be found from {conditions}")
return False

exit_hint, direction, err_reason = self._validate_custom_starting_point(point, direction)
if err_reason is not None:
_log.warning(f"Point could not be added at {conditions}. {err_reason}")
_log.info(f"Point could not be added at {conditions}. {err_reason}")
return False

if exit_hint == ExitHint.NORMAL:
self.node_queue.add_node(self._create_node_from_point(point, None, None, None, exit_hint))
self.node_queue.add_node(self._create_node_from_point(point, None, None, None, exit_hint), force_add)
else:
if direction is None:
_log.info(f"No direction is given, adding point from {conditions} with both directions")
Expand Down
68 changes: 64 additions & 4 deletions pycalphad/tests/test_mapping_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from pycalphad.mapping.starting_points import point_from_equilibrium
from pycalphad.mapping.zpf_equilibrium import find_global_min_point
from pycalphad.mapping.primitives import Point, Node, Direction, ZPFLine, ZPFState
from pycalphad.mapping.plotting import get_label

import pycalphad.tests.databases

Expand All @@ -33,7 +34,7 @@
def test_binary_strategy(load_database):
dbf = load_database()

ax, strategy = binplot(dbf, ["CR", "NI", "VA"], None, conditions={v.T: (1500, 2500, 40), v.X("CR"): (0, 1, 0.02), v.P: 101325}, return_strategy=True)
ax, strategy = binplot(dbf, ["CR", "NI", "VA"], None, conditions={v.T: (1500, 1800, 40), v.X("CR"): (0, 1, 0.02), v.P: 101325}, return_strategy=True)

# Two-phase regions intended to show up in the Cr-Ni system
desired_zpf_sets = [{"BCC_B2", "L12_FCC"}, {"BCC_B2", "LIQUID"}, {"L12_FCC", "LIQUID"}]
Expand All @@ -52,11 +53,20 @@ def test_binary_strategy(load_database):
for dnz in desired_node_sets:
assert dnz in node_sets

num_nodes = len(strategy.node_queue.nodes)
strategy.add_nodes_from_conditions({v.T: 1600, v.P: 101325, v.X('CR'): 0.3})
new_num_nodes = len(strategy.node_queue.nodes)
assert new_num_nodes == num_nodes

strategy.add_nodes_from_conditions({v.T: 1600, v.P: 101325, v.X('CR'): 0.6})
new_num_nodes = len(strategy.node_queue.nodes)
assert new_num_nodes == num_nodes + 2

@select_database("crtiv_ghosh.tdb")
def test_ternary_strategy(load_database):
dbf = load_database()

ax, strategy = ternplot(dbf, ["CR", "TI", "V", "VA"], None, conds={v.X("CR"): (0, 1, 0.02), v.X("TI"): (0, 1, 0.02), v.T: 923, v.P: 101325}, return_strategy=True)
ax, strategy = ternplot(dbf, ["CR", "TI", "V", "VA"], None, conds={v.X("CR"): (0, 1, 0.02), v.X("TI"): (0, 1, 0.02), v.T: 923, v.P: 101325}, return_strategy=True, label_nodes=True)

# Two-phase regions intended to show up in the Cr--Ti-V system
desired_zpf_sets = [{"BCC_A2", "LAVES_C15"}, {"BCC_A2", "HCP_A3"}, {"HCP_A3", "LAVES_C15"}]
Expand All @@ -75,12 +85,26 @@ def test_ternary_strategy(load_database):
for dnz in desired_node_sets:
assert dnz in node_sets

num_nodes = len(strategy.node_queue.nodes)
strategy.add_nodes_from_conditions({v.T: 923, v.P: 101325, v.X('CR'): 0.2, v.X('TI'): 0.2})
new_num_nodes = len(strategy.node_queue.nodes)
assert new_num_nodes == num_nodes

strategy.add_nodes_from_conditions({v.T: 923, v.P: 101325, v.X('CR'): 0.4, v.X('TI'): 0.4})
new_num_nodes = len(strategy.node_queue.nodes)
assert new_num_nodes == num_nodes + 2

num_nodes = len(strategy.node_queue.nodes)
strategy.add_nodes_from_conditions({v.T: 923, v.P: 101325, v.X('CR'): 0.129, v.X('TI'): 0.861}, force_add=True)
new_num_nodes = len(strategy.node_queue.nodes)
assert new_num_nodes == num_nodes + 1

@select_database("alcocrni.tdb")
def test_step_strategy_through_single_phase(load_database):
dbf = load_database()

# Step strategy through single phase regions
strategy = StepStrategy(dbf, ["CR", "NI", "VA"], None, conditions={v.T: (1200, 2200, 10), v.X("CR"): 0.8, v.P: 101325})
strategy = StepStrategy(dbf, ["CR", "NI", "VA"], None, conditions={v.T: (1300, 2000, 10), v.X("CR"): 0.8, v.P: 101325})
strategy.initialize()
strategy.do_map()

Expand All @@ -103,12 +127,34 @@ def test_step_strategy_through_single_phase(load_database):
for dnz in desired_node_sets:
assert dnz in node_sets

# Test behavior of data outputs

# For T vs. CPM, x and y refers to properties of the entire system -> phases = ['SYSTEM']
data = strategy.get_data(v.T, 'CPM')
assert len(data['data']) == 1 and 'SYSTEM' in data['data']

# v.X('CR') has phase wildcard '*' implicitly added, so phases = ['BCC_B2', 'L12_FCC', 'LIQUID']
data = strategy.get_data(v.T, v.X('CR'))
assert len(set(list(data['data'].keys())).symmetric_difference({'BCC_B2', 'L12_FCC', 'LIQUID'})) == 0

# We force y to be global and x is already global, so phases = ['SYSTEM']
data = strategy.get_data(v.T, v.X('CR'), global_y=True)
assert len(data['data']) == 1 and 'SYSTEM' in data['data']

# x is phase specific, so both x and y are global -> phases = ['SYSTEM']
data = strategy.get_data(v.X('BCC_B2', 'CR'), v.T)
assert len(data['data']) == 1 and 'SYSTEM' in data['data']

# We force x to be global -> phases = ['SYSTEM']
data = strategy.get_data(v.X('CR'), v.T, global_x=True)
assert len(data['data']) == 1 and 'SYSTEM' in data['data']

@select_database("pbsn.tdb")
def test_step_strategy_through_node(load_database):
dbf = load_database()

# Step strategy through single phase regions
strategy = StepStrategy(dbf, ["PB", "SN", "VA"], None, conditions={v.T: (373, 623, 5), v.X("SN"): 0.5, v.P: 101325})
strategy = StepStrategy(dbf, ["PB", "SN", "VA"], None, conditions={v.T: (425, 550, 5), v.X("SN"): 0.5, v.P: 101325})
strategy.initialize()
strategy.do_map()

Expand Down Expand Up @@ -391,3 +437,17 @@ def test_ternary_strategy_process_metastable_node(load_database):
assert len(strategy.node_queue.nodes) == 1+num_nodes
assert strategy.node_queue.nodes[-1] == stable_node

def test_plot_labels():
assert get_label(v.NP('*')) == 'Phase Fraction'
assert get_label(v.NP('BCC_A2')) == 'Phase Fraction (BCC_A2)'

assert get_label(v.X('CR')) == 'X(Cr)'
assert get_label(v.X('BCC_A2', 'CR')) == 'X(BCC_A2, Cr)'

assert get_label(v.W('CR')) == 'W(Cr)'
assert get_label(v.W('BCC_A2', 'CR')) == 'W(BCC_A2, Cr)'

assert get_label(v.MU('CR')) == 'MU(Cr)'
assert get_label('CPM') == 'CPM'
assert get_label(v.T) == 'Temperature'

22 changes: 21 additions & 1 deletion pycalphad/tests/test_variables.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Test variables module.
"""

import copy
import numpy as np
from pycalphad import variables as v
from pycalphad.tests.fixtures import select_database, load_database
Expand Down Expand Up @@ -61,3 +61,23 @@ def test_component_and_species_repr_str_methods():
sp = v.Species(None)
assert repr(sp) == "Species(None)"
assert str(sp) == ""

def test_deepcopy():
'''
Tests that deepcopy of variables produce the same variables
This addresses an unreported issue where copying the chemical potential
would use the name attribute rather than the species (this resulted in deepcopy(v.MU('A')) -> v.MU(v.MU('A')))
'''
assert copy.deepcopy(v.NP('*')) == v.NP('*')
assert copy.deepcopy(v.NP('A')) == v.NP('A')

assert copy.deepcopy(v.X('B')) == v.X('B')
assert copy.deepcopy(v.X('A','B')) == v.X('A','B')

assert copy.deepcopy(v.W('B')) == v.W('B')
assert copy.deepcopy(v.W('A','B')) == v.W('A','B')

assert copy.deepcopy(v.Y('A',0,'B')) == v.Y('A',0,'B')
assert copy.deepcopy(v.T) == v.T
assert copy.deepcopy(v.P) == v.P
assert copy.deepcopy(v.MU('A')) == v.MU('A')
3 changes: 3 additions & 0 deletions pycalphad/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ def jansson_derivative(self, compsets, cur_conds, chemical_potentials, deltas: J

def expand_wildcard(self, phase_names):
return [self.__class__(phase_name) for phase_name in phase_names]

def __reduce__(self):
return self.__class__, (self.phase_name,)

def _latex(self, printer=None):
"LaTeX representation."
Expand Down

0 comments on commit f66ec11

Please sign in to comment.