Skip to content

Add shared family coil parameters objective#2133

Draft
lkadz wants to merge 6 commits intomasterfrom
feature/share-family-coil-params
Draft

Add shared family coil parameters objective#2133
lkadz wants to merge 6 commits intomasterfrom
feature/share-family-coil-params

Conversation

@lkadz
Copy link
Copy Markdown
Collaborator

@lkadz lkadz commented Mar 18, 2026

This PR introduces a new objective ShareFamilyCoilParameters that enforces equality constraints between selected parameters across groups of coils. The objective allows users to tie parameters (e.g. currents) between coils belonging to the same family or across multiple families, optionally restricted to specific indices.

Motivation

In coil optimization problems, it is desirable to:

  • enforce symmetry between coils (e.g. TF, PF, CS families)
  • reduce the number of independent design variables
  • impose engineering constraints linking coil parameters

Description of the approach

The objective:

  • groups coils using:
    • "family" (single family)
    • "families" (multiple families)
    • "coils" (explicit indices)
  • selects parameters via "param"
  • optionally restricts to subsets via "indices"
  • constructs linear residuals of the form: first_coil_param − other_coil_param = 0

Example usage

A usage example is provided in stage_two_ShareFamilyCoilParameters.ipynb demonstrating sharing currents between coils.

@lkadz lkadz requested a review from YigitElma March 18, 2026 21:12
@YigitElma YigitElma marked this pull request as draft March 19, 2026 15:58
@YigitElma YigitElma marked this pull request as draft March 19, 2026 15:58
Comment thread desc/objectives/linear_objectives.py Outdated

class ShareFamilyCoilParameters(_Objective):
"""
Objective enforcing shared parameter values across groups of coils.
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.

Suggested change
Objective enforcing shared parameter values across groups of coils.
Fix specific degrees of freedom to be the same between coils.

Comment thread desc/objectives/linear_objectives.py Outdated

Parameters
----------
thing : CoilSet or Coil
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.

Suggested change
thing : CoilSet or Coil
thing : CoilSet or MixedCoilSet

Comment thread desc/objectives/linear_objectives.py Outdated
return f


class ShareFamilyCoilParameters(_Objective):
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.

I think ShareCoilParameters is a better name for this. We use family only for EquilibriaFamily, not coilsets.

Comment thread desc/objectives/linear_objectives.py Outdated
----------
thing : CoilSet or Coil
Coil container object.
groups : list of dict
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.

I think if we use the same API as ShareParameters, it would be easier for users. Because I think people don't give names to their coils in general. I was thinking something like,

"""
params : dict
    Dict keys are the names of parameters to fix (str), and dict values are the
    indices to fix for each corresponding parameter (int array).
    Use True (False) instead of an int array to fix all (none) of the indices
    for that parameter.

Example
-------
"""
# Let's say we have a MixedCoilSet with
# CoilSet with 3 unique coils and 2 extra single coils
# Something like this will fix the currents of the 
# first 2 coils of the coilset as well as second single coil
params = {
   "current": {{True, True, False}, False, True},
}

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.

If the parameter that will be shared is an array, the example usage can be

# For above MixedCoilSet, this will make sure that index 0 of the 3
# coils of the coilset are the same (also index 1, but it can be different than 
# index 0)
params = {
   "R_n": {{[0, 1], [0, 1], [0, 1]}, False, False},
}

Comment thread desc/objectives/linear_objectives.py Outdated
n = len(leaves)
name = getattr(child, "name", "") or f"family_{i}"

errorif(
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.

I think instead of using the name, we can use the pytree structure to map indices.

@YigitElma
Copy link
Copy Markdown
Collaborator

Try to extend ShareParameters. Make it work with OptimizableCollection

@lkadz
Copy link
Copy Markdown
Collaborator Author

lkadz commented Mar 19, 2026

I have extended ShareParameters to call a single OptimizableCollection. Here is the updated notebook:
stage_two_ShareCoilParameters.ipynb
@YigitElma tell me what you think of it

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 19, 2026

Memory benchmark result

|               Test Name                |      %Δ      |    Master (MB)     |      PR (MB)       |    Δ (MB)    |    Time PR (s)     |  Time Master (s)   |
| -------------------------------------- | ------------ | ------------------ | ------------------ | ------------ | ------------------ | ------------------ |
  test_objective_jac_w7x                 |   -3.78 %    |     4.086e+03      |     3.932e+03      |   -154.51    |       41.36        |       39.16        |
  test_proximal_jac_w7x_with_eq_update   |   -0.08 %    |     6.560e+03      |     6.555e+03      |    -5.57     |       157.79       |       163.89       |
  test_proximal_freeb_jac                |    0.11 %    |     1.339e+04      |     1.340e+04      |    14.25     |       87.72        |       87.92        |
  test_proximal_freeb_jac_blocked        |   -0.42 %    |     7.747e+03      |     7.715e+03      |    -32.80    |       79.92        |       78.19        |
  test_proximal_freeb_jac_batched        |    0.55 %    |     7.659e+03      |     7.702e+03      |    42.49     |       78.60        |       78.70        |
  test_proximal_jac_ripple               |    2.65 %    |     3.675e+03      |     3.772e+03      |    97.32     |       65.57        |       68.40        |
  test_proximal_jac_ripple_bounce1d      |    0.09 %    |     3.916e+03      |     3.919e+03      |     3.34     |       79.35        |       79.17        |
  test_eq_solve                          |    1.39 %    |     2.214e+03      |     2.245e+03      |    30.74     |       98.33        |       97.94        |

For the memory plots, go to the summary of Memory Benchmarks workflow and download the artifact.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 65.51724% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.42%. Comparing base (f8c0ec0) to head (af81b60).
⚠️ Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
desc/objectives/linear_objectives.py 65.51% 20 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2133      +/-   ##
==========================================
- Coverage   94.48%   94.42%   -0.06%     
==========================================
  Files         102      102              
  Lines       28721    28777      +56     
==========================================
+ Hits        27137    27173      +36     
- Misses       1584     1604      +20     
Files with missing lines Coverage Δ
desc/objectives/linear_objectives.py 94.93% <65.51%> (-2.35%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lkadz lkadz force-pushed the feature/share-family-coil-params branch from 2530536 to af81b60 Compare April 7, 2026 16:52
@lkadz
Copy link
Copy Markdown
Collaborator Author

lkadz commented Apr 9, 2026

Here is a notebook, with an example of a single MixedCoilSet, that go through the updated ShareParameters class:
ShareParameters.ipynb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants