Skip to content

New Grid API - #2053

Open
ddudt wants to merge 132 commits into
masterfrom
dd/grids
Open

New Grid API#2053
ddudt wants to merge 132 commits into
masterfrom
dd/grids

Conversation

@ddudt

@ddudt ddudt commented Jan 7, 2026

Copy link
Copy Markdown
Collaborator

Resolves #1840

Restructures and generalizes the Grid classes. The new ABC AbstractGrid that all other grids inherit from does not assume a particular coordinate system. The new ABC AbstractGridFlux is specific to ($\rho,\theta,\zeta$) coordinates and is the parent class of all existing grid classes in flux coordinates. Most of the changes involved moving existing code into one of these new ABCs.

The goal is to allow for new grid classes in the future that represent other coordinate systems, without changing the existing public API.

To-Do:

  • Ensure tests pass
  • Generalize Basis dimensions (no references to flux coords)
  • Include isinstance(grid, AbstractGridCurve) checks wherever appropriate
  • Add 1D grids for Curve objects
  • Add 2D grids for FourierRZToroidalSurface objects
  • Alias flux grid class names like Grid -> CustomGridFlux, etc. (do not deprecate)
  • Update docs/dev_guide/notebooks/grid.ipynb
  • Utility function for LinearGrid._create_nodes?

@ddudt ddudt self-assigned this Jan 7, 2026
@ddudt ddudt added interface New feature or request to make the code more usable or compatibility with another code functionality New feature or request to do things the code can't do now. enhancement General label for enhancement. Please also tag with "Speed", "Interface", "Functionality", etc labels Jan 7, 2026
Comment thread desc/transform.py Outdated
Comment thread tests/test_grid.py
Comment thread desc/grid/core.py
Comment thread desc/grid/core.py
Comment thread desc/grid/flux.py
@dpanici

dpanici commented Jan 7, 2026

Copy link
Copy Markdown
Collaborator

Add checks in objectives and inside geometric/magneticfield/coil compute methods to ensure grids passed in are correct (i.e. 1D for a filament coil, 3D for finite build coil, 1D or 2D rtz for surface)

@dpanici

dpanici commented Jan 7, 2026

Copy link
Copy Markdown
Collaborator

Rename AbstractRTZGrid to AbstractGridFlux instead of RTZ

@github-actions

github-actions Bot commented Jan 7, 2026

Copy link
Copy Markdown
Contributor

Memory benchmark result

|               Test Name                |      %Δ      |    Master (MB)     |      PR (MB)       |    Δ (MB)    |    Time PR (s)     |  Time Master (s)   |
| -------------------------------------- | ------------ | ------------------ | ------------------ | ------------ | ------------------ | ------------------ |
  test_objective_jac_w7x                 |   -0.79 %    |     4.044e+03      |     4.012e+03      |    -31.99    |       33.45        |       30.74        |
  test_proximal_jac_w7x_with_eq_update   |    1.61 %    |     6.522e+03      |     6.627e+03      |    105.12    |       153.69       |       155.95       |
  test_proximal_freeb_jac                |    0.32 %    |     1.333e+04      |     1.337e+04      |    42.28     |       80.03        |       79.93        |
  test_proximal_freeb_jac_blocked        |    0.06 %    |     7.665e+03      |     7.669e+03      |     4.38     |       72.61        |       71.60        |
  test_proximal_freeb_jac_batched        |   -0.06 %    |     7.638e+03      |     7.634e+03      |    -4.33     |       72.41        |       68.89        |
  test_proximal_jac_ripple               |   -2.01 %    |     3.582e+03      |     3.510e+03      |    -71.97    |       56.58        |       54.55        |
  test_proximal_jac_ripple_bounce1d      |    1.05 %    |     3.741e+03      |     3.781e+03      |    39.37     |       70.14        |       67.21        |
  test_eq_solve                          |    3.19 %    |     1.965e+03      |     2.028e+03      |    62.73     |       58.38        |       58.00        |

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

Comment thread desc/grid/core.py Outdated
@codecov

codecov Bot commented Jan 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.55224% with 175 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.09%. Comparing base (1f47d9c) to head (ea8b032).

Files with missing lines Patch % Lines
desc/grid/flux.py 86.94% 62 Missing ⚠️
desc/grid/surface.py 81.00% 34 Missing ⚠️
desc/grid/curve.py 79.71% 28 Missing ⚠️
desc/grid/core.py 94.47% 11 Missing ⚠️
desc/geometry/core.py 72.41% 8 Missing ⚠️
desc/objectives/_geometry.py 83.33% 7 Missing ⚠️
desc/external/terpsichore.py 0.00% 6 Missing ⚠️
desc/plotting.py 93.93% 6 Missing ⚠️
desc/coils.py 88.88% 2 Missing ⚠️
desc/grid/utils.py 98.92% 2 Missing ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2053      +/-   ##
==========================================
- Coverage   94.32%   94.09%   -0.24%     
==========================================
  Files         101      106       +5     
  Lines       28870    29403     +533     
==========================================
+ Hits        27231    27666     +435     
- Misses       1639     1737      +98     
Files with missing lines Coverage Δ
desc/basis.py 97.74% <100.00%> (ø)
desc/compat.py 88.61% <100.00%> (ø)
desc/compute/_geometry.py 97.70% <100.00%> (-0.01%) ⬇️
desc/compute/data_index.py 95.89% <ø> (ø)
desc/compute/utils.py 89.35% <100.00%> (+0.08%) ⬆️
desc/equilibrium/initial_guess.py 93.79% <100.00%> (ø)
desc/geometry/curve.py 96.44% <100.00%> (ø)
desc/geometry/surface.py 97.67% <100.00%> (ø)
desc/grid/__init__.py 100.00% <100.00%> (ø)
desc/input_reader.py 92.12% <100.00%> (ø)
... and 37 more

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

Comment thread desc/grid/flux.py Outdated
eq = self.things[0]
if self._grid is None:
grid = LinearGrid(
grid = LinearGridFlux(

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 don't totally understand why LinearGrid(M=M,N=N) and LinearGrid(N=N) have been separated into different classes, but LinearGrid(L=L) is a specific instance of LinearGridFlux and not a separate class.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

In this case we use a LinearGridFlux because the Pressure profile is evaluated in flux coordinates, even though it typically only cares about the $\rho$ coordinate and not the other two dimensions. Physically the pressure profile does not have to be a flux function and could vary in all three dimensions (e.g. if there are magnetic islands).

We might want to make a new 1D grid class for "profiles", similar to AbstractGridCurve but in the range $[0,1]$ instead of $[0,2\pi)$. But I think we can wait to do that in a future PR if it is needed.

@maya-avida maya-avida left a comment

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.

Looks great; I left a couple small comments but I have no real changes to recommend. The only major question (which doesn't need to be solved in this PR) I have is about FFT/DCT; we should generalize how grids that can FFT/DCT in a given coordinate/subset of coordinates are denoted, so that we can have more general transform methods.

maya-avida
maya-avida previously approved these changes Jul 20, 2026

@maya-avida maya-avida left a comment

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.

Looks great; I left a couple small comments but I have no real changes to recommend. The only major question (which doesn't need to be solved in this PR) I have is about FFT/DCT; we should generalize how grids that can FFT/DCT in a given coordinate/subset of coordinates are denoted, so that we can have more general transform methods.

YigitElma
YigitElma previously approved these changes Jul 22, 2026

@YigitElma YigitElma left a comment

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.

It looks good to me.

We are again about to hit 2 month mark since the last release. I was thinking of maybe having a quick release after merging PRs #2264, #2266, #2267, #2268 and maybe #2247 and #2262. I know this sounds a lot but all of them are easy and they improve the performance of a lot of things. I suggest this because we were planning to use this PR in master before making the release. Let me know what you think.

Alternatively, we can have a release couple weeks after merging this one.

@YigitElma
YigitElma requested a review from maya-avida July 23, 2026 03:39
Comment thread desc/grid/core.py
Comment thread desc/grid/flux.py
M, theta, theta_period, endpoint, sym=self.sym
)
# zeta
z, dz, self._fft_x2 = _create_linear_nodes(

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.

On master it throws an error if users create a LinearGrid with zeta values stretching beyond 2pi/NFP, whereas here it just mods those values. Should this be mentioned in the docstring?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Do we actually want this to be an error? phi=4pi is physically equivalent to phi=0 or 2pi. I need to check if this causes issues in the Transform class.

Comment thread desc/grid/curve.py Outdated
Comment thread desc/grid/utils.py Outdated
Comment thread desc/compute/utils.py Outdated
Comment thread desc/objectives/_geometry.py Outdated
Comment thread desc/objectives/_geometry.py Outdated
Comment thread desc/objectives/_coils.py Outdated
Comment thread desc/basis.py Outdated

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.

Is there a reason why bases are still hardcoded to be in flux coordinates?

Comment thread desc/basis.py
@property
def fft_toroidal(self):
"""bool: whether this basis is compatible with fft in the toroidal direction."""
if not hasattr(self, "_fft_toroidal"):

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.

See comment above; shouldn't fft_poloidal and fft_toroidal also be updated to be fft_x1 and fft_x2, or should that be a separate PR? If so, the generalization of bases and transforms should occur before #2253 since the cylindrical grid classes introduced there are mostly useful if they have corresponding bases and transforms.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I tried to not change much of the Basis classes in this PR to keep the scope limited (this is already a very large PR). But yes, we should generalize the bases to not assume flux coordinates and I don't think it is a difficult update. Not every basis class directly correspond to a single grid class, but the basis doesn't need much info about the grids. Can you make this change in #2253?

@YigitElma
YigitElma self-requested a review July 30, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement General label for enhancement. Please also tag with "Speed", "Interface", "Functionality", etc functionality New feature or request to do things the code can't do now. interface New feature or request to make the code more usable or compatibility with another code run_benchmarks Run timing benchmarks on this PR against current master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Grid API

8 participants