Skip to content

Commit 8263951

Browse files
authored
Take the collision profile radius from a tabulated label at the physical position (#613)
Collisional runs on geometric REFCOORDS chartmaps (`rho_convention = unknown`, for example map2disc charts that reach the wall) cannot use radially varying `&profiles` today, because the chart radius carries no flux meaning and `init_profile_radius` stops (src/profile_radius.f90:114). The profiles are, however, often known as a function of a flux label from a separate equilibrium or field-line model. This adds the `&config` key `profile_label_file`. It names a netCDF table `label(phi, Z, R)` over one field period (uniform `R`, `Z` in m or cm, `phi` at `(i-1)*2*pi/(nfp*nphi)`, global attribute `nfp`). With `integ_coords = 5`, `profile_s` evaluates the reference coordinates at the marker state to obtain `(R, phi, Z)` and interpolates the label trilinearly, periodic in phi. A position outside the table stops the run instead of extrapolating. Without the file, the existing error and all other radius mappings are unchanged. The format is documented in `src/profile_label.f90` and `docs/model/collisions.rst`, and the input reference is regenerated. Tests (synthetic data only): - `test_profile_radius_label` builds an analytic label (bilinear in R, Z plus a periodic triangle wave in phi with kinks on grid nodes, which trilinear interpolation reproduces exactly) on the existing test chartmap. It compares `profile_s` and the collision coefficients with the closed form at the independently computed physical position to 1e-12, and it also checks the metre-to-cm conversion and phi periodicity. - `test_profile_radius_label_outside` checks that a table which does not cover the marker stops the run. Native verification (sCluster, Release, libneo 924ba77, CMake/CTest), head bcfec2c: - job 3356096 (node20): `ctest -R 'profile_radius|profiles|input_reference|input_validation|config_reference|collision'` 21/21 pass. `ctest -L unit` 76/77, where the only failure was a 120 s timeout of `test_splined_kernel_bench` on a loaded node. Rerun alone in job 3356160, it passes in 42 s, and this PR does not touch that code. - The same commit on top of #608-#611 (job 3356095, node10): `golden_record_collision` passes and 37/37 focused native tests pass. Chris&AI
1 parent 3f2a72b commit 8263951

10 files changed

Lines changed: 426 additions & 28 deletions

File tree

‎docs/input-reference.json‎

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"namelists": {
55
"config": {
66
"source": "src/params.f90",
7-
"source_line": 240,
7+
"source_line": 243,
88
"variables": [
99
{
1010
"name": "notrace_passing",
@@ -1312,6 +1312,19 @@
13121312
"source": "src/params.f90",
13131313
"source_line": 198
13141314
},
1315+
{
1316+
"name": "profile_label_file",
1317+
"type": "character",
1318+
"kind": "",
1319+
"length": "1000",
1320+
"shape": [],
1321+
"extent": [],
1322+
"default": "''",
1323+
"default_value": "''",
1324+
"documentation": "Optional netCDF profile label s(R, phi, Z) for the collision profiles with integ_coords = REFCOORDS (format: src/profile_label.f90).",
1325+
"source": "src/params.f90",
1326+
"source_line": 201
1327+
},
13151328
{
13161329
"name": "wall_input",
13171330
"type": "character",
@@ -1323,7 +1336,7 @@
13231336
"default_value": "''",
13241337
"documentation": "",
13251338
"source": "src/params.f90",
1326-
"source_line": 199
1339+
"source_line": 202
13271340
},
13281341
{
13291342
"name": "wall_units",
@@ -1336,7 +1349,7 @@
13361349
"default_value": "'m'",
13371350
"documentation": "",
13381351
"source": "src/params.f90",
1339-
"source_line": 200,
1352+
"source_line": 203,
13401353
"validation": {
13411354
"choices": [
13421355
"m",
@@ -1355,7 +1368,7 @@
13551368
"default_value": "'auto'",
13561369
"documentation": "",
13571370
"source": "src/params.f90",
1358-
"source_line": 204,
1371+
"source_line": 207,
13591372
"validation": {
13601373
"choices": [
13611374
"auto",
@@ -1376,7 +1389,7 @@
13761389
"default_value": "-1000",
13771390
"documentation": "Sentinel: -1000 means user did not set it",
13781391
"source": "src/params.f90",
1379-
"source_line": 206
1392+
"source_line": 209
13801393
},
13811394
{
13821395
"name": "crossing_level",
@@ -1389,7 +1402,7 @@
13891402
"default_value": "3",
13901403
"documentation": "SPECTRE interface treatment: only full orbit (3) is supported.",
13911404
"source": "src/params.f90",
1392-
"source_line": 208,
1405+
"source_line": 211,
13931406
"validation": {
13941407
"choices": [
13951408
3
@@ -1407,7 +1420,7 @@
14071420
"default_value": "1.5_dp",
14081421
"documentation": "Full orbit near SPECTRE interfaces: entry distance in radial gyroradii and the relative tolerance of RK45 on the sharp per-volume field. 1.5 keeps the switch's p_zeta invariant as at 3 (entry 1 breaks it) at about half the FO time (concept/spectre_loss_study/results/fo-residence).",
14091422
"source": "src/params.f90",
1410-
"source_line": 213,
1423+
"source_line": 216,
14111424
"validation": {
14121425
"positive": true
14131426
}
@@ -1423,7 +1436,7 @@
14231436
"default_value": "1.0e-9_dp",
14241437
"documentation": "",
14251438
"source": "src/params.f90",
1426-
"source_line": 214,
1439+
"source_line": 217,
14271440
"validation": {
14281441
"positive": true
14291442
}
@@ -1443,7 +1456,7 @@
14431456
"default_value": "(/32, 64, 32/)",
14441457
"documentation": "Per-volume FO spline points: rho, theta, zeta per field period.",
14451458
"source": "src/params.f90",
1446-
"source_line": 216
1459+
"source_line": 219
14471460
},
14481461
{
14491462
"name": "spectre_sbeg_is_toroidal_flux",
@@ -1456,7 +1469,7 @@
14561469
"default_value": ".false.",
14571470
"documentation": "",
14581471
"source": "src/params.f90",
1459-
"source_line": 217
1472+
"source_line": 220
14601473
},
14611474
{
14621475
"name": "spectre_ncon_r",
@@ -1469,7 +1482,7 @@
14691482
"default_value": "48",
14701483
"documentation": "SPECTRE per-volume Meiss construction grid (n_r, n_th, n_phi). Each volume allocates rank-3 arrays plus batch splines of this size, so the total peak memory scales as Mvol*n_r*n_th*n_phi. spectre_ncon_phi = -1 means automatic: 32 for fields with toroidal harmonics and a minimal phi grid for axisymmetric fields (all n = 0), the dominant memory saver for tokamak cases. A positive value forces that phi count verbatim, bypassing the axisymmetric clamp.",
14711484
"source": "src/params.f90",
1472-
"source_line": 226,
1485+
"source_line": 229,
14731486
"validation": {
14741487
"min": 1
14751488
}
@@ -1485,7 +1498,7 @@
14851498
"default_value": "48",
14861499
"documentation": "",
14871500
"source": "src/params.f90",
1488-
"source_line": 227,
1501+
"source_line": 230,
14891502
"validation": {
14901503
"min": 1
14911504
}
@@ -1501,7 +1514,7 @@
15011514
"default_value": "-1",
15021515
"documentation": "",
15031516
"source": "src/params.f90",
1504-
"source_line": 228
1517+
"source_line": 231
15051518
},
15061519
{
15071520
"name": "spectre_ncon_order",
@@ -1514,7 +1527,7 @@
15141527
"default_value": "5",
15151528
"documentation": "",
15161529
"source": "src/params.f90",
1517-
"source_line": 229,
1530+
"source_line": 232,
15181531
"validation": {
15191532
"min": 1
15201533
}
@@ -1530,7 +1543,7 @@
15301543
"default_value": "1000000",
15311544
"documentation": "",
15321545
"source": "src/params.f90",
1533-
"source_line": 230,
1546+
"source_line": 233,
15341547
"validation": {
15351548
"min": 1
15361549
}
@@ -1546,7 +1559,7 @@
15461559
"default_value": "1.0e-2_dp",
15471560
"documentation": "",
15481561
"source": "src/params.f90",
1549-
"source_line": 231,
1562+
"source_line": 234,
15501563
"validation": {
15511564
"positive": true
15521565
}
@@ -1646,7 +1659,7 @@
16461659
"default_value": ".true.",
16471660
"documentation": "Removed &config keys. They are still read so that old input files run; a value other than the historical default prints a warning.",
16481661
"source": "src/params.f90",
1649-
"source_line": 235
1662+
"source_line": 238
16501663
},
16511664
{
16521665
"name": "loopskip",
@@ -1659,7 +1672,7 @@
16591672
"default_value": "0",
16601673
"documentation": "",
16611674
"source": "src/params.f90",
1662-
"source_line": 236
1675+
"source_line": 239
16631676
},
16641677
{
16651678
"name": "bmod_ref",
@@ -1672,7 +1685,7 @@
16721685
"default_value": "5.0d4",
16731686
"documentation": "",
16741687
"source": "src/params.f90",
1675-
"source_line": 237
1688+
"source_line": 240
16761689
},
16771690
{
16781691
"name": "macrostep_log_ratio",
@@ -1685,7 +1698,7 @@
16851698
"default_value": "1.0d3",
16861699
"documentation": "",
16871700
"source": "src/params.f90",
1688-
"source_line": 238
1701+
"source_line": 241
16891702
}
16901703
]
16911704
},

‎docs/input-reference.rst‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ and ``DOC/config.md`` for additional usage, units and option interactions.
2525
&config
2626
-------
2727

28-
Source: ``src/params.f90:240``.
28+
Source: ``src/params.f90:243``.
2929

3030
.. list-table::
3131
:header-rows: 1
@@ -565,6 +565,12 @@ Source: ``src/params.f90:240``.
565565
- ``scalar``
566566
- ``''``
567567
-
568+
* - ``profile_label_file``
569+
- ``character(len=1000)``
570+
- ``default``
571+
- ``scalar``
572+
- ``''``
573+
- Optional netCDF profile label s(R, phi, Z) for the collision profiles with integ_coords = REFCOORDS (format: src/profile_label.f90).
568574
* - ``wall_input``
569575
- ``character(len=1000)``
570576
- ``default``

‎docs/model/collisions.rst‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,18 @@ radius; for 6 the enclosed toroidal flux of the SPECTRE chart
9898
radius gives :math:`s = \rho^2`, and ``vmec_extended``/``vmec_to_wall``
9999
charts give :math:`s = (\rho/\rho_\mathrm{lcfs})^2`. Radii without
100100
toroidal-flux meaning (geometric or poloidal chartmaps) are accepted only
101-
for radially uniform ``&profiles``.
101+
for radially uniform ``&profiles``, unless ``&config profile_label_file``
102+
supplies the profile radius as a table :math:`s(R,\varphi,Z)`. With
103+
``integ_coords = 5`` the label is then interpolated trilinearly at the
104+
marker's physical position, which the reference coordinates give, and
105+
periodically in :math:`\varphi` modulo :math:`2\pi/N_\mathrm{fp}`. The
106+
netCDF file has dimensions ``R``, ``Z`` and ``phi``, uniform coordinate
107+
variables ``R(R)`` and ``Z(Z)`` with ``units`` ``"m"`` or ``"cm"``,
108+
``phi(phi)`` at :math:`(i-1)\,2\pi/(N_\mathrm{fp} n_\varphi)`, the
109+
variable ``label(phi, Z, R)`` and the integer global attribute ``nfp``.
110+
The table has to cover the whole tracing domain, and a position outside
111+
it stops the run. How the label is constructed, for example a flux label
112+
of a separate equilibrium, is the user's model choice.
102113

103114
Discrete step
104115
-------------

‎examples/simple_full.in‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ field_input = '' ! field file: VMEC wout (.nc), Boozer chartmap
6666
! SPECTRE (.h5) or coils file; '' = use netcdffile
6767
coord_input = '' ! reference coordinate file: VMEC wout or chartmap (.nc);
6868
! '' = netcdffile, then field_input
69+
profile_label_file = '' ! netCDF label s(R,phi,Z) as &profiles radius for
70+
! integ_coords = 5 (src/profile_label.f90); '' = chart radius
6971
netcdffile = '' ! VMEC wout file; deprecated fallback for field_input and
7072
! coord_input; '' = 'wout.nc' where a VMEC file is required
7173
radial_electric_potential_slope = 0d0 ! Boozer integration: Phi(s) = slope*s added to H; 0 = off

‎src/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
parse_ants.f90
5656
profiles.f90
5757
collis_alphas.f90
58+
profile_label.f90
5859
profile_radius.f90
5960
netcdf_orbit_output.f90
6061
netcdf_results_output.f90

‎src/params.f90‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ module params
196196

197197
character(1000) :: field_input = ''
198198
character(1000) :: coord_input = ''
199+
!> Optional netCDF profile label s(R, phi, Z) for the collision profiles
200+
!> with integ_coords = REFCOORDS (format: src/profile_label.f90).
201+
character(1000) :: profile_label_file = ''
199202
character(1000) :: wall_input = ''
200203
character(16) :: wall_units = 'm'
201204
!> Radial threshold for querying an external STL wall. A negative value
@@ -261,7 +264,7 @@ module params
261264
am1, am2, Z1, Z2, &
262265
densi1, densi2, tempi1, tempi2, tempe, &
263266
batch_size, ran_seed, particle_index_offset, reuse_batch, &
264-
field_input, coord_input, &
267+
field_input, coord_input, profile_label_file, &
265268
wall_input, wall_units, chart_boundary_kind, integ_coords, crossing_level, &
266269
spectre_fo_entry_larmor, spectre_fo_tolerance, spectre_fo_grid, &
267270
spectre_sbeg_is_toroidal_flux, spectre_ncon_r, spectre_ncon_th, &

0 commit comments

Comments
 (0)