Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
L_cs = prev_compsets # large region
S_cs = new_compsets # small region
L_phases = prev_phases
S_phases = new_phases
new_direction = direction
opp_reg_temperature = prev_temperature
else: # went from small to large region
L_cs = new_compsets # large region
S_cs = prev_compsets # small region
L_phases = new_phases
S_phases = prev_phases
new_direction = opposite_direction(direction)
opp_reg_temperature = new_temperature
opposing_small_region_cs = [c for c in S_cs if c.phase_name not in L_phases] + [c for c in L_cs if c.phase_name not in S_phases]
start_points.append(StartPoint(opp_reg_temperature, new_direction, opposing_small_region_cs))
return start_points
raise ValueError("Found more than 1 new phase")
elif len(new_phases) == 0: # TODO: this could get expensive, we hit it every time
# we have the same phases
# check that the composition of any two phases didn't change significantly
# if there is significant change, there may be a miscibility gap.
# add a start point at the current temperature in the opposite direction
for cs in prev_compsets:
matching_compsets = [c for c in compsets if c.phase_name == cs.phase_name]
if len(matching_compsets) == 1:
# we are not currently in a miscibility gap
matching_cs = matching_compsets[0]
same_phase_comp_diff = cs.xdiscrepancy(matching_cs)
if same_phase_comp_diff > tol_misc_gap:
if verbose:
print("Found potential miscibility gap compsets {} differ in composition by {}".format([cs, matching_cs], same_phase_comp_diff))
start_points.add_start_point(StartPoint(T_current, opposite_direction(curr_direction), [cs, matching_cs]))
# we need to start a new start point, otherwise there will be a boundary line that "jumps" the miscibility gap
# the tradeoff is that there is a break in the boundaries
start_points.add_start_point(StartPoint(T_current-delta, curr_direction, compsets))
converged = True
if converged:
continue
zpf_boundaries.add_compsets(compsets)
T_current += delta
x_current = BinaryCompSet.mean_composition(compsets)
prev_compsets = compsets
return zpf_boundaries
# We need to filter out regions where the phases aren't the same, those aren't true two phase regions.
# This might break in a miscibility gap.
# Condition 1: Number of phases must be 2
if len(trial_phases_set) != 2:
it.iternext()
continue
# Condition 2: Must share one unique phase
if len(current_phases_set.intersection(trial_phases_set)) < 1:
it.iternext()
continue
# Condition 3: Ordering of the set of phases must be different
if sorted_phases == sorted_trial_phases:
it.iternext()
continue
# If we made it here, we found a potential match!
sp = StartPoint(trial_T, trial_direction, trial_compsets)
if start_point_list.add_start_point(sp):
return sp # We found a valid start point
else:
it.iternext()
continue # We didn't find a valid start point, keep going.
# Don't add boundaries because this is an inaccurate set
if graceful:
return
else:
raise ValueError( "Could not find start point for neighbor to compsets: {}".format(compsets))
eq_kwargs['model'] = eq_kwargs['callables']['model']
# assumes only one composition
x_cond = [c for c in conds.keys() if isinstance(c, v.Composition)][0]
indep_comp = x_cond.species.name
comp_idx = sorted(set(comps) - {'VA'}).index(indep_comp)
# mapping conditions
x_min, x_max, dx = conds[x_cond]
T_min, T_max, dT = conds[v.T]
curr_conds = deepcopy(conds)
tol_zero_one = tol_zero_one if tol_zero_one is not None else dx # convergence tolerance
tol_same = tol_same if tol_same is not None else dx
zpf_boundaries = ZPFBoundarySets(comps, x_cond)
start_points = StartPointsList(eq_comp_tol=startpoint_comp_tol, eq_temp_tol=startpoint_temp_tol)
if initial_start_points is not None:
if isinstance(initial_start_points, StartPoint):
start_points.add_start_point(initial_start_points)
else:
# assume an iterable
for sp in initial_start_points:
start_points.add_start_point(sp)
# find a starting point
starting_T = 0.9*(T_max - T_min)+T_min
time_start = time.time()
max_startpoint_discrepancy = np.max([tol_zero_one, tol_same, dx])
while len(start_points.remaining_start_points) < 1:
curr_conds[v.T] = starting_T
hull = convex_hull(dbf, comps, phases, curr_conds, **eq_kwargs)
cs = find_two_phase_region_compsets(hull, starting_T, indep_comp, comp_idx, discrepancy_tol=max_startpoint_discrepancy)
if len(cs) == 2:
# verify that these show up in the equilibrium calculation
We also reassign the temperatures so that the next step (T+delta) will add
to the composition grid correctly.
"""
prev_phases = [c.phase_name for c in prev_compsets]
prev_comps = [c.composition for c in prev_compsets]
prev_comps_diff = np.abs(np.max(prev_comps) - np.min(prev_comps))
prev_temperature = prev_compsets[0].temperature
new_phases = [c.phase_name for c in new_compsets]
new_comps = [c.composition for c in new_compsets]
new_comps_diff = np.abs(np.max(new_comps) - np.min(new_comps))
new_temperature = new_compsets[0].temperature
# In all cases, we want a new StartPoint for the new compsets in the direction we were going
start_points = [StartPoint(prev_temperature, direction, new_compsets)]
# assign small and large regions
if (new_comps_diff < prev_comps_diff): # went from large to small region
L_cs = prev_compsets # large region
S_cs = new_compsets # small region
L_phases = prev_phases
S_phases = new_phases
new_direction = direction
opp_reg_temperature = prev_temperature
else: # went from small to large region
L_cs = new_compsets # large region
S_cs = prev_compsets # small region
L_phases = new_phases
S_phases = prev_phases
new_direction = opposite_direction(direction)
opp_reg_temperature = new_temperature
time_start = time.time()
max_startpoint_discrepancy = np.max([tol_zero_one, tol_same, dx])
while len(start_points.remaining_start_points) < 1:
curr_conds[v.T] = starting_T
hull = convex_hull(dbf, comps, phases, curr_conds, **eq_kwargs)
cs = find_two_phase_region_compsets(hull, starting_T, indep_comp, comp_idx, discrepancy_tol=max_startpoint_discrepancy)
if len(cs) == 2:
# verify that these show up in the equilibrium calculation
specific_conds = deepcopy(curr_conds)
specific_conds[x_cond] = BinaryCompSet.mean_composition(cs)
eq_cs = get_compsets(equilibrium(dbf, comps, phases, specific_conds, **eq_kwargs), indep_comp=indep_comp, indep_comp_index=comp_idx)
if len(eq_cs) == 2:
# add a direction of dT > 0 and dT < 0
zpf_boundaries.add_compsets(eq_cs)
# shift starting_T so they start at the same place.
start_points.add_start_point(StartPoint(starting_T - dT, pos, eq_cs))
start_points.add_start_point(StartPoint(starting_T + dT, neg, eq_cs))
if starting_T - dT > T_min:
starting_T -= dT
else:
raise StartingPointError("Unable to find an initial starting point.")
if verbose:
print("Found start points {} in {:0.2f}s".format(start_points, time.time()-time_start))
# Main loop
while len(start_points.remaining_start_points) > 0:
zpf_boundaries.add_boundary_set()
start_pt = start_points.get_next_start_point()
curr_direction = start_pt.direction
delta = curr_direction(dT)
max_startpoint_discrepancy = np.max([tol_zero_one, tol_same, dx])
while len(start_points.remaining_start_points) < 1:
curr_conds[v.T] = starting_T
hull = convex_hull(dbf, comps, phases, curr_conds, **eq_kwargs)
cs = find_two_phase_region_compsets(hull, starting_T, indep_comp, comp_idx, discrepancy_tol=max_startpoint_discrepancy)
if len(cs) == 2:
# verify that these show up in the equilibrium calculation
specific_conds = deepcopy(curr_conds)
specific_conds[x_cond] = BinaryCompSet.mean_composition(cs)
eq_cs = get_compsets(equilibrium(dbf, comps, phases, specific_conds, **eq_kwargs), indep_comp=indep_comp, indep_comp_index=comp_idx)
if len(eq_cs) == 2:
# add a direction of dT > 0 and dT < 0
zpf_boundaries.add_compsets(eq_cs)
# shift starting_T so they start at the same place.
start_points.add_start_point(StartPoint(starting_T - dT, pos, eq_cs))
start_points.add_start_point(StartPoint(starting_T + dT, neg, eq_cs))
if starting_T - dT > T_min:
starting_T -= dT
else:
raise StartingPointError("Unable to find an initial starting point.")
if verbose:
print("Found start points {} in {:0.2f}s".format(start_points, time.time()-time_start))
# Main loop
while len(start_points.remaining_start_points) > 0:
zpf_boundaries.add_boundary_set()
start_pt = start_points.get_next_start_point()
curr_direction = start_pt.direction
delta = curr_direction(dT)
prev_compsets = start_pt.compsets
# check that the composition of any two phases didn't change significantly
# if there is significant change, there may be a miscibility gap.
# add a start point at the current temperature in the opposite direction
for cs in prev_compsets:
matching_compsets = [c for c in compsets if c.phase_name == cs.phase_name]
if len(matching_compsets) == 1:
# we are not currently in a miscibility gap
matching_cs = matching_compsets[0]
same_phase_comp_diff = cs.xdiscrepancy(matching_cs)
if same_phase_comp_diff > tol_misc_gap:
if verbose:
print("Found potential miscibility gap compsets {} differ in composition by {}".format([cs, matching_cs], same_phase_comp_diff))
start_points.add_start_point(StartPoint(T_current, opposite_direction(curr_direction), [cs, matching_cs]))
# we need to start a new start point, otherwise there will be a boundary line that "jumps" the miscibility gap
# the tradeoff is that there is a break in the boundaries
start_points.add_start_point(StartPoint(T_current-delta, curr_direction, compsets))
converged = True
if converged:
continue
zpf_boundaries.add_compsets(compsets)
T_current += delta
x_current = BinaryCompSet.mean_composition(compsets)
prev_compsets = compsets
return zpf_boundaries
# find other two phase equilibrium
new_start_point = find_nearby_region_start_point(dbf, comps ,phases, compsets, comp_idx, T_current, dT, deepcopy(curr_conds), x_cond, start_points, verbose=verbose, hull_kwargs=eq_kwargs)
if new_start_point is not None:
if verbose:
print("New start point {} from convergence to same value at T={}K and X={}".format(new_start_point, T_current, x_current))
elif verbose:
print("Converged to same value at T={}K and X={}. No new start point found.".format(T_current, x_current))
continue
prev_phases = {c.phase_name for c in prev_compsets}
curr_phases = {c.phase_name for c in compsets}
common_phases = curr_phases.intersection(prev_phases)
new_phases = curr_phases - common_phases
if len(new_phases) == 1: # we found a new phase!
converged = True
end_point = StartPoint(T_current - delta, opposite_direction(curr_direction), prev_compsets)
start_points.add_end_point(end_point)
if veryverbose:
print("Adding end point {}".format(end_point))
new_start_points = find_three_phase_start_points(compsets, prev_compsets, curr_direction)
if verbose:
print("New start points {} from three phase equilibrium at T={}K and X={}".format(new_start_points, T_current, x_current))
for sp in new_start_points:
start_points.add_start_point(sp)
# don't need to add new compsets here because they will be picked up based on the new start points
continue
elif len(new_phases) > 1:
raise ValueError("Found more than 1 new phase")
elif len(new_phases) == 0: # TODO: this could get expensive, we hit it every time
# we have the same phases
# check that the composition of any two phases didn't change significantly
# if there is significant change, there may be a miscibility gap.
continue
else:
raise ValueError("Mapping error:" + found_str + " Last two phase region: {}".format(prev_compsets))
elif len(compsets) >= 3:
raise ValueError("Mapping error: found {} phases ({}) instead of 2".format(len(compsets), "/".join([c.phase_name for c in compsets])))
else:
T_backtracks = 0; total_T_backtrack_factor = 1
cs_0 = compsets[0].composition
cs_1 = compsets[1].composition
if close_zero_or_one(cs_0, tol_zero_one) and close_zero_or_one(cs_1, tol_zero_one):
converged = True
zpf_boundaries.add_compsets(compsets)
continue
if close_to_same(cs_0, cs_1, tol_same):
converged = True
end_point = StartPoint(T_current, opposite_direction(curr_direction), compsets)
start_points.add_end_point(end_point)
if veryverbose:
print("Adding end point {}".format(end_point))
zpf_boundaries.add_compsets(compsets)
# find other two phase equilibrium
new_start_point = find_nearby_region_start_point(dbf, comps ,phases, compsets, comp_idx, T_current, dT, deepcopy(curr_conds), x_cond, start_points, verbose=verbose, hull_kwargs=eq_kwargs)
if new_start_point is not None:
if verbose:
print("New start point {} from convergence to same value at T={}K and X={}".format(new_start_point, T_current, x_current))
elif verbose:
print("Converged to same value at T={}K and X={}. No new start point found.".format(T_current, x_current))
continue
prev_phases = {c.phase_name for c in prev_compsets}
curr_phases = {c.phase_name for c in compsets}
common_phases = curr_phases.intersection(prev_phases)