Skip to content

Add NetCDF results output with Cartesian positions for heat load analysis #295

@krystophny

Description

@krystophny

Summary

Add structured NetCDF output (results.nc) for particle tracing results, replacing/supplementing ASCII times_lost.dat. Key addition: Cartesian positions for wall heat load analysis.

Motivation

  • Efficiency: Binary NetCDF is 10-100x smaller than ASCII for large runs
  • Decoupling: Cartesian positions (xstart_cart, xend_cart) enable post-processing without coordinate transformation machinery
  • Self-describing: Config stored as attributes for reproducibility
  • Heat loads: Direct 3D wall positions for engineering optimization

Proposed Structure

results.nc

Dimensions:
  particle, xyz(3), phase(5), iclass_dim(3)

Variables:
  # Phase space (reference coordinates, 5D)
  zstart(phase, particle)     float64   # (rho, theta, zeta, p, v_par/v)
  zend(phase, particle)       float64
  
  # Cartesian position only (3D)
  xstart_cart(xyz, particle)  float64   # (x, y, z) in meters
  xend_cart(xyz, particle)    float64   # (x, y, z) at loss/end
  
  # Scalars
  times_lost(particle)        float64
  trap_par(particle)          float64
  perp_inv(particle)          float64
  iclass(iclass_dim, particle) int32
  class_lost(particle)        int8

Global Attributes:
  # All namelist config params
  ntestpart, trace_time, facE_al, v0, integmode, relerr, ...
  coord_input, field_input, netcdffile
  coordinate_type   ("vmec" | "chartmap")
  # etc.

Implementation

  1. New module netcdf_results_output.f90 (~150 lines)
  2. Add output_results_netcdf to namelist (default .false. initially)
  3. Compute xstart_cart, xend_cart via ref_coords%evaluate_cart()
  4. Write at end of simulation

Backwards Compatibility

  • times_lost.dat unchanged (ASCII legacy preserved)
  • New output is opt-in via namelist parameter

Use Case: Wall Heat Loads

import xarray as xr
ds = xr.open_dataset('results.nc')

# Wall hits (chartmap: rho >= 1)
lost = ds.where((ds.times_lost > 0) & (ds.zend[0] >= 0.99), drop=True)

# 3D positions and energy
x, y, z = lost.xend_cart[0], lost.xend_cart[1], lost.xend_cart[2]
energy_eV = lost.zend[3]**2 * ds.attrs['facE_al'] * 3.5e6

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions