Skip to content

Add coil limits to the inverse solver#54

Merged
kpentland merged 7 commits into
FusionComputingLab:mainfrom
timothy-nunn:inverse_solver_coil_limits_cvxpy
Feb 12, 2026
Merged

Add coil limits to the inverse solver#54
kpentland merged 7 commits into
FusionComputingLab:mainfrom
timothy-nunn:inverse_solver_coil_limits_cvxpy

Conversation

@timothy-nunn
Copy link
Copy Markdown
Contributor

@timothy-nunn timothy-nunn commented Feb 6, 2026

Adds coil limits to the inverse solver and cleans up some of the delta_current calculations.

Both of these changes have been tested on a MAST-U example.

Change delta_current calculation

Changed the calculation of delta_current from

mat = np.linalg.inv(np.matmul(self.A.T, self.A) + reg_matrix)
delta_current = np.dot(mat, np.dot(self.A.T, self.b))
to use np.linalg.solve. This ensures we get the most accurate solution and is possibly more numerically stable.

There is negligible difference caused by this change for the MAST-U example.
image
image

Coil limits

Adds support for specifying coil limits. When limits are specified, a convex solver is used to solve the least-squares problem; this is because you can specify additional constraints on the convex solver, such as box constraints for the coil limits. These additional constraints have an added slack to their bound which allows the coil limits to be violated for a penalty.

The problem that is being solved is slightly different due to the coil limits and slack.

$$ \min_{x} | A\vec{x} - \vec{b}|^2 + | \gamma \vec{x} |^2 + \mu| \vec{S}_{\text{upper}} |^2 + \mu| \vec{S}_{\text{lower}} |^2 $$

subject to

$$ \vec{x} + \vec{I}^c \leq \vec{I}^c_{\text{max}} + \vec{S}_{\text{upper}} $$

$$ \vec{x} + \vec{I}^c \geq\vec{I}^c_{\text{min}} - \vec{S}_{\text{lower}} $$

where

  • $\vec{S}$ is the slack for the upper/lower limit. A slack of $0$ implies that the limit is satisfied. Slack must be positive.
  • $\vec{I}^c$ is the current coil currents
  • $\vec{x}$ is the step to be taken in the coil currents
  • $\vec{I}^c_{\text{max}}$ and $\vec{I}^c_{\text{min}}$ are the maximum and minimum coil currents, respectively.
  • $\mu$ scales the penalty in the objective function from a non-zero slack (coil limit violation).

As can be seen, using the convex solver with no coil limits yields near-identical results to above:
image

When we add limits, the solution changes because the inverse solver attempts to ensure the coil currents are always within limits:
image
image

@timothy-nunn timothy-nunn marked this pull request as ready for review February 6, 2026 15:17
@kpentland kpentland self-assigned this Feb 11, 2026
@kpentland kpentland added the enhancement New feature or request label Feb 11, 2026
@kpentland
Copy link
Copy Markdown
Collaborator

kpentland commented Feb 11, 2026

Hi Tim,

This looks awesome at first glance! I'm just going to stress test it a bit on some real equilibria then will add some more comments.

I've updated some of the text in the Example01 notebook and have added a plot that shows the coil currents within their limits.

Screenshot 2026-02-11 at 13 58 01

Comment thread freegsnke/GSstaticsolver.py Outdated
self.rhs_before_jtor = -freegs4e.gradshafranov.mu0 * eq.R

# random seed for reproducibility
self.rng = np.random.default_rng(seed=42)
Copy link
Copy Markdown
Contributor

@theo-brown theo-brown Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please can the seed be exposed to the user as an optional input?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks guys!

@kpentland kpentland added the ready-for-final-tests Pull request is ready to run final pre-merge tests label Feb 12, 2026
@kpentland kpentland merged commit 562b955 into FusionComputingLab:main Feb 12, 2026
2 checks passed
@timothy-nunn timothy-nunn deleted the inverse_solver_coil_limits_cvxpy branch February 12, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ready-for-final-tests Pull request is ready to run final pre-merge tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants