The file format parsed by read_beam2 also includes the polarisation,
unlike those of read_beam0 and read_beam1.
When running gray standalone, however, we expect the mode to be set by
`antenna.iox` in gray.ini, not by the beam file.
- Avoid logging the same error over and over
- Make all the gray_errors actually warnings
- Replace `large_npl` error with `unstable_beam`, which is actually
the root cause of the former
- Use the gray_main error as exit code
Similarly to eb648039 this change replaces the `equilibrium` module with
a new `gray_equil` module providing the same functionality without using
global variables.
- `read_eqdsk`, `read_equil_an` are replaced by a single `load_equil`
routine that handles all equilibrium kind (analytical, numerical,
and vacuum).
- `scale_equil` is merged into `load_equil`, which besides reading
the equilibrium from file peforms the rescaling and interpolation based
on the `gray_parameters` settings and the equilibrium kind.
To operate on G-EQDSK data specifically, the `change_cocors` and
`scale_eqdsk` are still available. The numeric equilibrium must then
be initialised manually by calling equil%init().
- `set_equil_spline`, `set_equil_an`, `unset_equil_spline`
are completely removed as the module no longer has any internal state.
- `fq` is replaced by `equil%safety`; `bfield` by `equil%b_field`;
`frhotor`, `frhopol` by `equil%pol2tor` and `equil%pol2tor`;
and the remaining subroutines by other methods of `abstract_equil`
retaining the old name.
- the `contours_psi` subroutine is replaced by `equil%flux_contour`,
with a slightly changed invocation but same functionality.
- the `gray_data` type is no longer required ans has been removed: all
the core subroutines now access the input data only though either
`abstract_equil`, `abstract_plasma` or the `limiter` contour.
This change replaces the `coreprofiles` module with a new `gray_plasma`
module providing the same functionality without using global variables.
- `read_profiles`, `read_profiles_an` are replaced by a single `load_plasma`
routines that handles both profiles kind (numerical, analytical).
- `scale_profiles` is merged into `load_plasma`, which besides reading
the profiles from file peforms the rescaling and interpolation based
on the `gray_parameters` settings.
- `set_profiles_spline`, `set_profiles_an`, `unset_profiles_spline`
are completely removed as the module no longer has any internal state.
- `density`, `ftemp`, `fzeff` are replaced by the `abstract_plasma`
type which provides the `dens`, `temp` and `zeff` methods for
either `numeric_plasma` or `analytic_plasma` subtypes.
1. Use the `contour` type for limiter and plasma boundary
(rlim, zlim, rbnd, zbnd)
2. Replace `inside` with `contour%contains`
3. Replace `range2rect` with a `contour` interface
4. Remove the limiter module which just re-exports the limiter
as a global; instead just pass the contour object around
This change replaces the output files (Fortran units) with a derived
type called table, that hold the data in memory until further
processing. The data stored in a table can be dumped to a file, as
before, or processed in other ways, for example converted to other
derived type.
This change replaces pointers with automatic arrays to greatly simplify
the memory management in the main subroutine:
- All arrays are defined in a single location and with their final
dimension explicitely shown.
- The allocation/deallocation is performed automatically when
entering/leaving the gray_main routine.
This change modifies the analytical equilibrium in order to simplify the
computation of the poloidal flux normalization and the derivatives.
In the power law parametrisation of the safety factor, ρ_t is replaced
with ρ_p and, similarly, the normalised poloidal radius is now
identified with ρ_p, instead of ρ_t.
With the same parameters (q₀,q₁,α...), this choice slightly changes the
plasma current distribution, but enables us to obtain a closed form for
ψ_a = ψ(r=a) and the relation ρ_t(ρ_p). In fact, both expressions are
now obtained by integrating the q(ρ_p), instead of 1/q(ρ_t), which has
no elementary antiderivative.
As the normalisation is now computed exactly, the values of the
normalised flux ψ_n = ψ/ψ_a and the gradient ∇ψ (entering the raytracing
equations in X and ∇X, respectively) are computed to the same precision.
Previously, ψ_n was computed to a lower precision due to the use of a
simple trapezoid integration of 1/q(ρ_p) for ψ_a, while ∇ψ was computed
up to machine precision using an exact formula.
This error effectively caused a very slight decoupling between X=ω_p²/ω²
and ∇X that introduced a systematic error in the numerical solution of
the raytracing equations.
The error manifests itself as a bias with a weak dependency on X in the
values taken by the dispersion function Λ(r̅, n̅) on the phase-space
points generated by the integrator. More specifically,
lim h→0 Λ(r̅_i, n̅_i) = -kX(r̅_i)
where h is the integrator step size;
r̅_i is the position at the i-th step;
k ≈ -3.258⋅10⁻⁵ and depends only on the number of points used to
perform the trapedoid integral for ψ_a (as ~ 1/n²).
After this change Λ behaves consistently with being a conserved quantity
(zero) up to the cumulative integration error of the 4° order
Runge-Kutta method. In fact we now have that:
Λ(r̅_i, n̅_i) ∝ - h⁴ ‖∂⁴X(r̅_i)/∂r̅⁴‖
It must be said that within this model the relation ρ_p(ρ_t) can't be
computed analytically (inverting ρ_t(ρ_p) produces a trascendental
equation of the form b = x + c x^α). However, this relation is not
necessary for raytracing and is easily solved, up to machine
precision, using minpack.
In addition, this change also makes the model consistetly use the
cocos=3 and fully implements the ability to force the signs of I_p, B_φ
(via equilibrium.sgni,sgnb) and rescaling the field (via
equilibrium.factb).
In the case of analytic equilibrium without a limiter contour, the
simple limiter was built incorrectly due to an unnecessary conversion
from cm (the equilibrium data are already in metre).
This adds a new `splines` module which implements a high-level interface
for creating and evaluating splines and rewrite almost all modules to
use it. Also, notably:
1. both `simplespline` and DIERCKX splines can now used with a uniform
interface
2. most complexity due to handling working space arrays is gone
3. memory management has been significantly simplified too
- Add missing array allocations
- Add parameter for varying number of columns in input files
- Change output unit numbers (dirty fix. Original units created an empty
named file, but wrote in default named fort.* files)
1. Fix the mismatch between the psnbnd in coreprofiles and gray_core.
This happens whenever gray overrides the externally provided one
(i.e. the density tail would become negative before psnbnd and is so
rescaled to end exactly on the zero).
2. Make psnbnd no longer required by always computing it as in 1.
It hasn't been removed, because gray_params.data is sacrosant,
but it no longer has any effect.
3. Cleanup: mark public functions, restructure the global variables into
three categories; add comments explaining the analytical profiles
format, formulae and how the polynomial tail is computed.
This adds a new configuration file based on the INI format.
The new format will allow adding GRAY parameters without breaking
compatibility with existing configurations, unlike as of the old
gray_params.data.
This change structures the arguments of most functions, in particular
gray_main, into well-defined categories using derived types.
All types are defined in the gray_params.f90 (location subject to
change) and are organised as follows:
gray_parameters (statically allocated data)
├── antenna_parameters
├── ecrh_cd_parameters
├── equilibrium_parameters
├── misc_parameters
├── output_parameters
├── profiles_parameters
└── raytracing_parameters
gray_data - inputs of gray_main (dynamically-allocated arrays)
├── equilibrium_data
└── profiles_data
gray_results - outputs of gray_main (dynamically-allocated arrays)