forge.utils
Collection of various utilities that do not nicely sit elsewhere.
Copyright 2025-2026 Chris Marsden
This file is part of FORGE.
FORGE is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
FORGE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with FORGE. If not, see <http://www.gnu.org/licenses/>.
- forge.utils.filter_distant_points(x_coords, y_coords, reference_point, critical_distance)[source]
Filters points that are farther than a given critical distance from a reference point.
- Parameters:
- Returns:
filtered_x (np.ndarray) – x coordinates of filtered points.
filtered_y (np.ndarray) – y coordinates of filtered points.
- forge.utils.magnitude_scale_factors(x)[source]
Returns the order of mangitude scale factor for a list of numbers.
- Parameters:
x (list) – List of numbers.
- Returns:
List of magnitude scale factors (list)
Examples
print(magnitude_floor(5374)) # Output: 1000 print(magnitude_floor([5374, 0.0056])) # Output: [1000, 0.001]
- forge.utils.reflect_and_join_shape(points)[source]
Reflects a shape about y=0 and creates a newly joined up shape.
Constructs a new shape by: - Keeping only the points below y = 0 - Reflecting those points across y = 0 - Joining the original and reflected points in a continuous loop
- Parameters:
points (list) – List of (x,y) points defining the shape [(x1,y1),….].
- Returns:
Reflected joined up shape – List of (x,y) points defining the new shape.
- forge.utils.interactive_shape_editor(x_coords, y_coords, x_min=None, x_max=None, y_min=None, y_max=None, ax=None)[source]
Interactively edit a shape.
- Parameters:
x_coords (list) – List of the x coordinates of the shape.
y_coords (list) – List of the y coordinates of the shape.
x_min (float) – Minimum x coordinate for plotting the shape.
x_max (float) – Maximum x coordinate for plotting the shape.
y_min (float) – Minimum y coordinate for plotting the shape.
y_max (float) – Maximum y coordinate for plotting the shape.
ax (matplotlib axes) – Axes to plot onto. If None, these will be created.
- Returns:
x_list (list) – List of the x coordinate of the new shape.
y_list (list) – List of the y coordinate of the new shape.
- forge.utils.plot_currents_comparison_bar_chart(x_labels, initial_data, optimised_data, scale_kA=True)[source]
Bar chart comparing coil current.
Plots a bar chart with absolute values of initial and optimised per-turn coil currents, and includes a title showing the sum of squares of each dataset.
- forge.utils.interactive_buffered_polygon(x_points, y_points, ax=None)[source]
Interactively create buffers around parts of a shape.
Allows the user to interactively select edges constituting a shape, around which a buffer of a user-specifid thickness is created. Multiple edges can, in turn, have buffers created around them. The buffer thickness is entered by the user in the terminal each time an edge is selected.
- Parameters:
- Returns:
buffers (list) – List of shapely.geometry.LineString objects representing the buffers.
buffer_data (list) – List of dictionaries recording each buffer definition. Each dictionary contains the keys
"R"and"Z"(the two endpoints of the wall segment) and"distance"(the buffer distance). This data can be saved to a JSON file and later passed to theOptimiserto reproduce the same buffers non-interactively.
- forge.utils.draw_shape(ax=None, remove_pixel_radius=10, return_closed=True)[source]
Interactive creation of a closed polygon with Add, Remove, Move, and Finish buttons.
- Modes:
Add (default): click in the axes to add points (blue markers, black edges).
Remove : click near a point (within remove_pixel_radius pixels) to delete it.
Move : click near a point to grab it, drag to reposition, release to drop.
Finish : close the window and return the points (closed lists if return_closed=True).
If return_closed=True, the first point is repeated at the end (with sensible handling for 0/1/2 points).
- Display:
Solid black line connects points, always drawn closed if ≥2 points.
Filled gray polygon shown if ≥3 points.
Zoom/Pan toolbar interactions are ignored (do not add/remove/move points).
- Parameters:
- Returns:
xs (list) – List of the x coordinates of the new shape.
ys (list) – List of the y coordinates of the new shape.
- forge.utils.densify_closed_shape(x, y, max_dist, return_closed=True, rtol=1e-12, atol=1e-12)[source]
Adds points along the boundary of a shape.
Densify a closed polygon by inserting points along each edge so that the spacing between consecutive boundary points is <= max_dist.
- Parameters:
x (sequence of floats) – Coordinates of the polygon vertices, ordered along the boundary. The input may be explicitly closed (last point equals first) or open; the function treats it as a closed shape in either case.
y (sequence of floats) – Coordinates of the polygon vertices, ordered along the boundary. The input may be explicitly closed (last point equals first) or open; the function treats it as a closed shape in either case.
max_dist (float) – Maximum allowed distance between consecutive points along each edge. Must be > 0.
return_closed (bool, default True) – If True, the output is explicitly closed (last point equals first). If False, the output is open (no duplicate endpoint); wrapping is implied.
rtol (float) – Tolerances to detect a duplicate last point equal to the first.
atol (float) – Tolerances to detect a duplicate last point equal to the first.
- Returns:
Xd, Yd (np.ndarray) – Densified boundary coordinates.
Notes
Original vertices are preserved.
For an edge of length L, we split it into N = ceil(L / max_dist) segments with equal spacing L/N <= max_dist.
Complexity: O(N_edges + N_output_points).
- forge.utils.calc_winding_number(Br, Bz)[source]
Calclates the winding number of the poloidal magnetic flux around a closed boundary.
Takes the radial (Br) and vertical (Bz) components of the poloidal magnetic field at points along an arbitary closed boundary and calculates the resultant winding number (Poincare index). The data provided is assumed to correspond to points on a closed boundary that are packed sufficiently dense such that the maximum change in poloidal angle between points does not exceed pi.
- forge.utils.estimate_xpoint_location(R, Z, Br, Bz, jacobians, delta_R, delta_Z)[source]
Estimates the (R,Z) location of an X-point using the derivatives of the poloidal magnetic field at nearby points.
Takes the R,Z location of points to search for nearby X-points, along with the poloidal field components Br, Bz and the 2x2 matrices for the poloidal field Jacobians. The grid point spacings in (R,Z) are also given.
- Rlist
List of the R coordinates of points to search for nearby X-points.
- Zlist
List of the Z coordinates of points to search for nearby X-points.
- Brlist
List of the values of the radial magnetic field at the (R,Z) points.
- Bzlist
List of the values of the vertical magnetic field at the (R,Z) points.
- jacobianslist
List of the 2x2 poloidal magnetic field Jacobian matrices at the (R,Z) points.
- delta_Rfloat
Spacing of grid points in R of the grid on which the equilibrium is defined.
- delta_Zfloat
Spacing of grid points in Z of the grid on which the equilibrium is defined.
- Returns:
Rx (float) – R coordinate of the located X-point. If no X-point is present, this will be NaN.
Zx (float) – Z coordinate of the located X-point. If no X-point is present, this will be NaN.
xpoint_present (bool) – Flag for whether or not an X-point was present.
- forge.utils.grid_points_inside_linestring(X, Y, ls: shapely.geometry.LineString, include_boundary=True)[source]
Return lists of x and y coordinates for grid points inside/on a closed Shapely LineString.
- Parameters:
X (2D numpy arrays) – Meshgrid arrays of the grid coordinates. Must have the same shape.
Y (2D numpy arrays) – Meshgrid arrays of the grid coordinates. Must have the same shape.
ls (shapely.geometry.LineString) – Boundary curve of the region. If not closed, it will be closed automatically.
include_boundary (bool) – If True, points on the boundary are counted as inside.
- Returns:
xs_in, ys_in (list of floats) – 1D lists containing the x and y coordinates of the grid points that lie inside (and optionally on) the shape.
- forge.utils.closest_point_along_shape(x_coords, y_coords, px, py)[source]
Finds the closest point along a shape to a point.
Finds the closest point along the boundary of the supplied shape to a single (x,y) point provided by the user.
- forge.utils.update_figure(fig, pause=0.001)[source]
Updates a matplotlib figure in such a way that visualisation in both scripts and notebooks works.
- forge.utils.force_opaque_figure(fig, facecolour='white', text_colour='black')[source]
Forces a matplotlib figure to have an opaque background.
This is important when updating a figure in a notebook that is in dark mode.
- forge.utils.orthogonalised_convex_hull_from_rects(xc: List[float], yc: List[float], dx: List[float], dy: List[float], *, closed: bool = True, elbow_rule: str = 'left') Tuple[List[float], List[float]][source]
Draws a polygon around a set of filaments of finite width.
Filaments are given by a set of axes-aligned rectangles with widths/heights provided.
Single-function version:
Build convex hull of all rectangle corners (may include diagonals).
Replace each diagonal hull edge with a vertical-horizontal or horizontal-vertical pair. The left elbow rule selects the elbow that lies to the left of the hull edge (for CCW orientation), bulging outward and avoiding self-intersections.
'vh'forces the elbow at(x0, y1);'hv'forces it at(x1, y0).Close the polygon and remove redundant collinear points.
- Parameters:
xc (lists of float) – Centers and sizes of axis-aligned rectangles (no rotation).
yc (lists of float) – Centers and sizes of axis-aligned rectangles (no rotation).
dx (lists of float) – Centers and sizes of axis-aligned rectangles (no rotation).
dy (lists of float) – Centers and sizes of axis-aligned rectangles (no rotation).
closed (bool) – If True (default), repeat the first point at the end.
elbow_rule ({'left', 'vh', 'hv'}) – Strategy to choose the elbow for diagonal hull edges. ‘left’ is recommended.
- Returns:
xs, ys (lists of float) – Coordinates of the resulting orthogonal polygon. If closed=True, the first point is repeated at the end.