Skip to content

Conversation

@dpanici
Copy link
Collaborator

@dpanici dpanici commented Jul 12, 2025

work towards #183

  • convert boundary part to use f90nml, right now I have not bc discerning the modenumbers from just the f90nml-read arrays of RBC and ZBS is not straightforward and I think has edge cases that could cause it to fail (i.e. if we always assume a [M, N] RBC array is such that the modenumbers are [-M//2, M//2] and [-N//2, N//2], this assumption fails if there are potentially ragged arrays or asymmetric arrays (like if one specifies only the m=1 n=0 m=1 n=1 m=1 n=2 modes, how do we discern this from something that has like m=1 n=-1 m=1 n=0 m=1 n=1? might not be an issue but I did not use much effort to figure it out)
  • resolves write_vmec_input will create a vmec input file that Equilibrium.from_input_file will not correctly handle #1902
  • potentially address Allow reading in of boundary from a SPEC file #224 (lower priority)
  • read in splines (also lower priority as there are many spline types in VMEC and other profile types, I'd prefer tokeep as just power series)

@github-actions
Copy link
Contributor

github-actions bot commented Jul 12, 2025

Memory benchmark result

|               Test Name                |      %Δ      |    Master (MB)     |      PR (MB)       |    Δ (MB)    |    Time PR (s)     |  Time Master (s)   |
| -------------------------------------- | ------------ | ------------------ | ------------------ | ------------ | ------------------ | ------------------ |
  test_objective_jac_w7x                 |    0.79 %    |     3.999e+03      |     4.030e+03      |    31.51     |       38.35        |       35.75        |
  test_proximal_jac_w7x_with_eq_update   |    3.63 %    |     6.449e+03      |     6.683e+03      |    234.21    |       160.35       |       160.25       |
  test_proximal_freeb_jac                |    0.03 %    |     1.320e+04      |     1.321e+04      |     4.22     |       82.22        |       81.90        |
  test_proximal_freeb_jac_blocked        |    0.11 %    |     7.477e+03      |     7.485e+03      |     8.35     |       71.48        |       72.09        |
  test_proximal_freeb_jac_batched        |   -0.74 %    |     7.545e+03      |     7.489e+03      |    -55.58    |       72.19        |       71.78        |
  test_proximal_jac_ripple               |    1.24 %    |     3.480e+03      |     3.523e+03      |    43.11     |       63.87        |       63.98        |
  test_proximal_jac_ripple_bounce1d      |    0.33 %    |     3.529e+03      |     3.541e+03      |    11.57     |       75.44        |       74.83        |
  test_eq_solve                          |    0.78 %    |     2.014e+03      |     2.030e+03      |    15.75     |       93.36        |       92.66        |

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

@codecov
Copy link

codecov bot commented Jul 12, 2025

Codecov Report

❌ Patch coverage is 89.69072% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.77%. Comparing base (087e2ab) to head (bdca2b9).

Files with missing lines Patch % Lines
desc/input_reader.py 89.69% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1816      +/-   ##
==========================================
+ Coverage   95.75%   95.77%   +0.01%     
==========================================
  Files         102      102              
  Lines       28344    28304      -40     
==========================================
- Hits        27142    27107      -35     
+ Misses       1202     1197       -5     
Files with missing lines Coverage Δ
desc/input_reader.py 92.23% <89.69%> (+0.10%) ⬆️

... and 1 file with indirect coverage changes

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

@dpanici
Copy link
Collaborator Author

dpanici commented Aug 20, 2025

Example of why idt we can safely use f90nml for reading in boundary coefficients
two simplified vmec inputs

&INDATA
  MPOL =    12
  NTOR =    0
  RBC( 0,0) =  3.510    ZBS( 0,0) =  0.000
  RBC( 0,1) =  1.000    ZBS( 0,1) =  1.470
  RBC( 0,2) =  0.106    ZBS( 0,2) = -0.160
import f90nml
nml = f90nml.read("input.VMEC1")
print(nml["indata"]["RBC"])

yields

[[3.51], [1.0], [0.106]]

ok this is fine, so it is a list of lists, the first index corresponds to the toroidal modes (hence why it is only length one, corresponds to the 0th index so we know it had only N=0 modes)

but if we add a single toroidal mode:

&INDATA
  MPOL =    12
  NTOR =    0
  RBC( 0,0) =  3.510    ZBS( 0,0) =  0.000
  RBC( 0,1) =  1.000    ZBS( 0,1) =  1.470
  RBC( 0,2) =  0.106    ZBS( 0,2) = -0.160
  RBC( -1,0) =  0.1

and run the same python script, we get

[[0.1, 3.51], [None, 1.0], [None, 0.106]]

if we add a toroidal mode with the opposite sign modenumber we get

&INDATA
  MPOL =    12
  NTOR =    0
  RBC( 0,0) =  3.510    ZBS( 0,0) =  0.000
  RBC( 0,1) =  1.000    ZBS( 0,1) =  1.470
  RBC( 0,2) =  0.106    ZBS( 0,2) = -0.160
  RBC( 1,0) =  0.1

and run the same python script, we get

[[3.51, 0.1], [1.0], [0.106]]

and the nail in the coffin for me is

&INDATA
  MPOL =    12
  NTOR =    0
  RBC( 0,0) =  3.510    ZBS( 0,0) =  0.000
  RBC( 0,1) =  1.000    ZBS( 0,1) =  1.470
  RBC( 0,2) =  0.106    ZBS( 0,2) = -0.160
  RBC( -2,4) =  0.1

yields

[[None, None, 3.51], [None, None, 1.0], [None, None, 0.106], [None], [0.1]]

I guess we could do something like checking for the longest array size among them and use that to then deduce what the n modes are, and then in the cases where the length is less than the longest we just automatically assign the largest number, but this is just not something I understand fully nor have I worked out all the edge cases, and so I would much prefer to keep our current method which feels less error prone.

@dpanici dpanici marked this pull request as ready for review August 20, 2025 18:47
@dpanici dpanici requested review from a team, YigitElma, ddudt, f0uriest, rahulgaur104 and unalmis and removed request for a team August 23, 2025 21:55
@f0uriest
Copy link
Member

it looks like it might store the start index as a separate variable?
https://f90nml.readthedocs.io/en/latest/usage.html#f90nml.namelist.Namelist.start_index

@dpanici
Copy link
Collaborator Author

dpanici commented Sep 3, 2025

it looks like it might store the start index as a separate variable? https://f90nml.readthedocs.io/en/latest/usage.html#f90nml.namelist.Namelist.start_index

Does not seem to be populate start_index correctly when I load in a vmec namelist for some reason

marshallward/f90nml#178

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.

write_vmec_input will create a vmec input file that Equilibrium.from_input_file will not correctly handle

3 participants