Skip to content

Commit b637e83

Browse files
authored
Fix bug when calling find_fluxoid_solution multiple times with the same model (#117)
1 parent 4bee8b5 commit b637e83

File tree

3 files changed

+47
-44
lines changed

3 files changed

+47
-44
lines changed

superscreen/device/device.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ def mutual_inductance_matrix(
574574
from ..solver import factorize_model, solve
575575

576576
holes = self.holes
577+
hole_names = list(self.holes)
577578
if hole_polygon_mapping is None:
578579
from ..fluxoid import make_fluxoid_polygons
579580

@@ -607,11 +608,11 @@ def mutual_inductance_matrix(
607608
films_by_hole[hole.name] = film
608609
model = None
609610
for j, hole_name in enumerate(
610-
tqdm(hole_polygon_mapping, desc="Holes", disable=(not progress_bar))
611+
tqdm(hole_names, desc="Holes", disable=(not progress_bar))
611612
):
612613
logger.info(
613614
f"Evaluating {self.name!r} mutual inductance matrix "
614-
f"column ({j+1}/{len(hole_polygon_mapping)}), "
615+
f"column ({j+1}/{len(hole_names)}), "
615616
f"source = {hole_name!r}."
616617
)
617618
if model is None:
@@ -623,15 +624,15 @@ def mutual_inductance_matrix(
623624
I_circ_val = model.circulating_currents[hole_name]
624625
else:
625626
model.set_circulating_currents({hole_name: I_circ_val})
626-
solutions = solve(device=None, model=model, **solve_kwargs)[solution_slice]
627+
solutions = solve(model=model, **solve_kwargs)[solution_slice]
627628

628629
for n, solution in enumerate(solutions):
629630
logger.info(
630631
f"Evaluating fluxoids for solution {n + 1}/{len(solutions)}."
631632
)
632-
for i, (name, polygon) in enumerate(hole_polygon_mapping.items()):
633+
for i, name in enumerate(hole_names):
633634
fluxoid = solution.polygon_fluxoid(
634-
polygon, film=films_by_hole[name]
635+
hole_polygon_mapping[name], film=films_by_hole[name]
635636
)
636637
mutual_inductance[n, i, j] = (
637638
(sum(fluxoid) / I_circ).to(units).magnitude

superscreen/fluxoid.py

+40-38
Original file line numberDiff line numberDiff line change
@@ -73,45 +73,47 @@ def find_fluxoid_solution(
7373
"""
7474
device = model.device
7575
fluxoids = fluxoids or {}
76-
holes = list(device.holes)
76+
hole_names = list(device.holes)
7777
current_units = model.current_units
78+
inductance_units = f"Phi_0 / {current_units}"
7879
solve_kwargs = solve_kwargs.copy()
7980
applied_field = solve_kwargs.pop("applied_field", None)
80-
target_fluxoids = np.array([fluxoids.get(name, 0) for name in holes])
81-
82-
model = model.copy()
83-
model.circulating_currents = {}
84-
85-
# Find the hole fluxoids assuming no circulating currents.
86-
solution_no_circ = solve(
87-
model=model,
88-
applied_field=applied_field,
89-
**solve_kwargs,
90-
)[-1]
91-
92-
if not holes:
93-
if np.any(target_fluxoids):
94-
raise ValueError(
95-
"Cannot calculate nonzero fluxoid solution for a device with no holes."
96-
)
97-
return solution_no_circ
98-
99-
fluxoids = [
100-
sum(solution_no_circ.hole_fluxoid(name)).to("Phi_0").magnitude for name in holes
101-
]
102-
fluxoids = np.array(fluxoids)
103-
104-
M = device.mutual_inductance_matrix(
105-
units=f"Phi_0 / {current_units}", **solve_kwargs
106-
)
107-
# Solve for the circulating currents needed to realize the target_fluxoids.
108-
I_circ = np.linalg.solve(M.magnitude, target_fluxoids - fluxoids)
109-
circulating_currents = dict(zip(holes, I_circ))
110-
# Solve the model with the optimized circulating currents.
111-
model.set_circulating_currents(circulating_currents)
112-
solution = solve(
113-
model=model,
114-
applied_field=applied_field,
115-
**solve_kwargs,
116-
)[-1]
81+
target_fluxoids = np.array([fluxoids.get(name, 0) for name in hole_names])
82+
83+
orig_circulating_currents = model.circulating_currents
84+
try:
85+
# Find the hole fluxoids assuming no circulating currents.
86+
model.set_circulating_currents({name: 0 for name in hole_names})
87+
solution_no_circ = solve(
88+
model=model,
89+
applied_field=applied_field,
90+
**solve_kwargs,
91+
)[-1]
92+
93+
if not hole_names:
94+
if np.any(target_fluxoids):
95+
raise ValueError(
96+
"Cannot calculate nonzero fluxoid solution for a device with no holes."
97+
)
98+
return solution_no_circ
99+
100+
fluxoids = [
101+
sum(solution_no_circ.hole_fluxoid(name)).to("Phi_0").magnitude
102+
for name in hole_names
103+
]
104+
fluxoids = np.array(fluxoids)
105+
M = device.mutual_inductance_matrix(units=inductance_units, **solve_kwargs)
106+
107+
# Solve for the circulating currents needed to realize the target_fluxoids.
108+
I_circ = np.linalg.solve(M.magnitude, target_fluxoids - fluxoids)
109+
circulating_currents = dict(zip(hole_names, I_circ))
110+
# Solve the model with the optimized circulating currents.
111+
model.set_circulating_currents(circulating_currents)
112+
solution = solve(
113+
model=model,
114+
applied_field=applied_field,
115+
**solve_kwargs,
116+
)[-1]
117+
finally:
118+
model.set_circulating_currents(orig_circulating_currents)
117119
return solution

superscreen/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version_info__ = (0, 12, 0)
1+
__version_info__ = (0, 12, 1)
22
__version__ = ".".join(map(str, __version_info__))

0 commit comments

Comments
 (0)