Commit Graph

263 Commits

Author SHA1 Message Date
1938aa23b7 Add first version of schemas describing I/O data models 2024-05-17 00:19:26 +02:00
Michele Guerini Rocco
60e30692cb
Makefile: stop at first syntax error
This flag prevents gcc from outputting a wall of text everytime you
forget a comma.
2024-04-29 10:08:16 +02:00
Michele Guerini Rocco
baf53b932b
simplify memory management
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.
2024-04-29 10:08:16 +02:00
Michele Guerini Rocco
3115e9e9f8
move vendored libraries to their own directory 2024-04-29 10:08:16 +02:00
Michele Guerini Rocco
27141d803c
move minpack license to minpack source 2024-04-22 19:09:30 +02:00
Michele Guerini Rocco
e4b9236dbe
depend: remove script
Using the libgray approach the script is not needed anymore.
Instead of collecting all indirect dependencies of an object
(essentially redoing the work of the linker), we just link libgray.

This causes slightly more recompilations, but it's a lot simpler.
2024-04-22 19:09:29 +02:00
Michele Guerini Rocco
be2cfe5ac9
doc: set default font, optionally 2024-04-22 19:09:29 +02:00
Michele Guerini Rocco
a596b0dff2
add gray-convert tool
This is a command line tool to convert between different GRAY
configuration file formats.
2024-04-22 19:09:29 +02:00
Michele Guerini Rocco
44e957f8d6
.gitignore: remove gray_cli_params.f90
The file is now generated into build/
2024-04-12 17:33:34 +02:00
Michele Guerini Rocco
dc3d719ace
.gitignore: ignore python bytecode cache 2024-04-12 17:32:56 +02:00
Michele Guerini Rocco
097fa42329
Makefile: run tests in parallel 2024-04-12 17:31:53 +02:00
Michele Guerini Rocco
babca8bdc4
tests: update references after f82f91bc
The following test cases:

  - 04-JT60SA
  - 05-JT60SA-startup
  - 06-ITER-startup.Mixed

were affected by the bug fixed in f82f91bc, so their reference outputs
had to be updated.
2024-04-11 22:16:45 +02:00
Michele Guerini Rocco
0a87a3ef76
src/polarization.f90: rewrite
- Remove the Stokes parameters as an intermediate step in the
  conversion between Jones vectors and polarisation ellipses.

- Document every single step performed when converting between
  different parametrisations and how the polarisation at the
  plasma boundary is computed. This includes how everything
  was derived from first principles.

- Mark the subroutines as pure.

- Remove `set_pol` entirely.
2024-04-11 21:49:52 +02:00
Michele Guerini Rocco
f82f91bc8d
fix coupling for subsequent beams
In situations when multiple beams are traced, either when allowing
multiple plasma crossings (raytracing.ipass > 0) or the initial polarisation
is mixed (raytracing.ipol == .true.), the couplings of all but the first
beam (with least index_rt) were invalid.

The bug is due to the re-use of the psipol,chipol variables as the beams
are traced sequentially over the beam_loop. For the first beam being
traced the psipol,chipol are correctly initialised to the user-defined
value and the resulting coupling is correct.
However, in each subsequent beam the values were not set to those of the
parent beam (or to the user-defined value in the case of the first X
mode beam), but to those of the previous beams (current index_rt - 1).

This change repurposes the psipv,chipv arrays to store the polarisation
of the parent beams, including the initial user-defined value and makes
plasma_in always use these to compute the coupling.

In addition, in the case the polarisation is not immediately known (i.e.
if raytracing.ipol == .false.), this change postpones the computation of
the Jones vector (ext, eyt) from the launch point, if the magnetic
equilibrium is available, to when the ray actually crosses the
plasma boundary.
The original code, besides being strictly incorrect, can lead to
non-negligible alterations to the coupling. This change also mean:

1. most of the functionality of `set_pol` has been merged with
   `plasma_in`
2. the polarisation is undefined and the Jones vector is set to the
   placeholder value [1, 0] till `plasma_im` is called

Finally, `polarcold` is removed because it's unused.
2024-04-11 18:06:46 +02:00
Michele Guerini Rocco
38a8edd439
doc: reorganize example input files 2024-02-16 00:38:43 +01:00
Michele Guerini Rocco
6a91eaa3a8
src/gray_params.f90: handle missing mandatory parameters 2024-02-09 11:16:21 +01:00
Michele Guerini Rocco
b582eb19b8
Makefile: fix for multiple #include directives
Forgot to add a \ separator
2024-02-09 11:16:21 +01:00
Michele Guerini Rocco
79d67c8128
tests: replace all gray_params.data with gray.ini 2024-02-09 11:16:21 +01:00
Michele Guerini Rocco
23a8caff37
remove references to COCOS 0,10
While technically accepted by GRAY, these indices do not carry a special
meaning, as wrongly implied by the documentation: they are equivalent
to 8, 18 and specifically don't change the meaning of sgnbi,sgni.
2024-02-09 11:16:20 +01:00
Michele Guerini Rocco
c99fc0b343
src/equilibrium.f90: set q=0 for ψ>1 in numeric case 2024-02-09 11:16:20 +01:00
Michele Guerini Rocco
85c84c9a48
src/equilibrium.f90: fix J_phi at ψ>1 in print_prof
Since 24edfdc4 print_prof tabulates the input profiles up to ψ_bnd,
however the torr_curr_psi may fail (producing FPEs) outside ψ=1.
Moreover, torr_curr_psi gives the current on the LFS on the specific
line z=z_maxis, while the flux surface average is usually more
interesting, say when comparing J_φ with Jcd.

This change fixes both issues.
2024-02-09 11:16:20 +01:00
Michele Guerini Rocco
7ed2f9a394
src/equilibrium.f90: fix floating point exception
If frhopol is called with a very small ρ_p, less than then step size of
ε_machine^⅓, the two sided finite step differentiation evaluates frhotor
at ρ_p < 0, producing a floating point exception.
In this case we use the single- sided definition.
2024-02-09 11:16:20 +01:00
Michele Guerini Rocco
32f44c5cba
src/splines.f90: add procedure to transform spline_2d
This adds a proper procedure to rescale and shift a 2D B-spline by
manipulating the coefficients.

Note: the previous code in set_equil_spline did work, but by
transforming the whole partial(i,j) triggered warnings about operations
on uninitialised memory.
2024-02-09 11:16:20 +01:00
Michele Guerini Rocco
19f6d7f2f0
src/dierckx.f90: detect overflow in fpgrre
When a call to regrid results in ier=-1 (data needs to be refitted with
interpolating spline) the computation of the sum of the residuals can
overflow. In this case we can exit immediately (avoiding raising a FPE)
ignoring the results. The latter need to be recomputed anyway.
2024-02-09 11:16:19 +01:00
Michele Guerini Rocco
b0674c2d9b
tests: handle missing ECCD results 2024-02-09 11:16:19 +01:00
Michele Guerini Rocco
2d16617db8
src/gray_core.f90: fix possible division by zero
If the EQDSK grid extends all the way to R=0, evaluating B ~ 1/R on a
regular grid from rmnm to rmxm results in a division by zero.
2024-02-09 11:16:19 +01:00
Michele Guerini Rocco
3bc1efc2a6
src/minpack.f90: ignore FPE in user-supplied subs
The minimisation algorithm may try to evaluate a function outside of its
domain triggering a floating point exception. However, this is not a
concern because it won't affect the final result, so they can be ignored
2024-02-09 11:16:19 +01:00
Michele Guerini Rocco
3dcacf685c
src/dierckx.f90: fix use of uninitialised var 2024-02-09 11:16:19 +01:00
Michele Guerini Rocco
7c5b443847
src/equilibrium.f90: use enums 2024-02-09 11:16:19 +01:00
Michele Guerini Rocco
fac0c6ded8
src/main.f90: use enums 2024-02-09 11:16:18 +01:00
Michele Guerini Rocco
c5a4b180bc
src/gray_params.f90: replace magic numbers with enums
1. Introduces enumerations (and some booleans) intended to replace all
   the magic numbers used throughout the code to represent multiple
   choices.

2. Replace the gray_params.sh script a new one that automatically
   generates code for all the GRAY parameters by parsing
   gray_params.f90.

3. Also generate extra code to accept the enum identifiers as valid
   values in the configuration files and command line arguments.

4. Set sensible default values for parameters that are rarely changes.
2024-02-09 11:16:18 +01:00
Michele Guerini Rocco
fa89439994
src/ini_parser.f90: handle inline comments and whitespace
While the Fortran read statement will ignore whitespace
and ignored remaining tokens, these are problematic when
manually parsing the INI values.
2024-02-09 11:16:18 +01:00
Michele Guerini Rocco
73bd010458
remove unnecessary implicit statements
Only a single `implicit none` at the start of each module is required.
2024-02-09 11:16:18 +01:00
86ff5ecb06
improve inside and move it to utils.f90
This slightly improves the performance of inside.
For a ~100 points contour the instructions cost is reduced by ~5%.
2024-02-09 11:16:18 +01:00
Michele Guerini Rocco
686f63b01a
fix some gfortran warnings 2024-02-09 11:16:17 +01:00
Michele Guerini Rocco
26976a31dd
src/equilibrium.f90: give the poloidal flux a definition domain
This change limits the evaluation of the poloidal flux spline ψ(R,z) to
a particular domain where ψ(R,z) is strictly monotonic. This choice
ensures that ψ_n < 1 only inside the plasma boundary; so plasma
parameters like q(ψ), Te(ψ), etc. can be mapped to the physical space
without ambiguities.

Before this change, anywhere ψ_n happened to decrease below 1 (either as
a result of a physical current or simply from the spline extrapolation),
Gray would effectively create a spurious plasma region.
This behavior is seriously problematic because it completely invalidates
the simulation: it can alter the ray directions, the power disribution
and total power if the beam enters one such region.

The domain is computed by applying a transformation to the contour of
the plasma boundary: for each contour point we cast a ray from the
magnetic axis to that point and extend the ray until the restriction of
ψ(R,z) on the ray starts decreasing or reach a maximum scaling factor.
The endpoint of the ray is then taken as the new point.
If ψ(R,z) is globally monotonic, the transformation is a homotety wrt
the magnetic axis, so the domain will be an enlarged boundary; otherwise
the shape will be more irregular (an intersection of the enlarged
boundary and several level curves of ψ).

Finally, each `pol_flux(r, z)` call is now guarded behind a check
`inside(psi_domain, r, z)`. For points outside the domain the subroutine
returns, as usual, -1 for ψ and 0 for derivatives.
2024-02-09 11:16:17 +01:00
Michele Guerini Rocco
6fad08ed7c
add tests 2024-02-09 11:16:17 +01:00
Michele Guerini Rocco
ae9f605111
src/gray_core.f90: set initial ray position to z=0
Previously the ray initial positions were set to the wavefront
S_R(x,y,z) = 0, with (x,y) chosen such that S_I(x,y,0) = const.
The wavefront itself, however, was determined using the value of the
beam parameters (k_ξ, k_η, w_ξ, w_η, etc.) fixed at z=0, which is valid
only when the initial wavefront is approximately flat.
Moreover, since the ray are distributed according to S_I(z=0), this
choice creates an inconsistency between the phase (from S_R at z≠0) and
the power (from S_I at z=0) assigned to the rays.

Satisfying both conditions on S_R and S_I exactly is really hard;
however, given we do not really care about the phase and we want to
precisely track the power, so it's more sensible to simply set z=0.

This means that when integrating in the phase (idst=2), gray will no
longer construct wavefronts, but merely transport the initial phase
on the z=0 plane.
Note that k₀⋅s will still give the correct phase. so if necessary, a
wavefront could be reconstructed by interpolating the (s, x̅, y̅, z̅)
points.
2024-01-24 14:37:21 +01:00
Michele Guerini Rocco
9a0f19e9e1
default.nix: update to Nixpkgs 23.05 2024-01-24 14:37:21 +01:00
Michele Guerini Rocco
7417d88d73
Makefile: make use of install portable
install -D on GNU is actually install -d on BSD.
2024-01-24 14:37:21 +01:00
Michele Guerini Rocco
02ade0e2d0
fix static compilation on macOS 2024-01-24 14:37:21 +01:00
Michele Guerini Rocco
d8ffd97739
Makefile: hide warnings when .d missing 2024-01-24 14:37:21 +01:00
Michele Guerini Rocco
b25cdf5f35
Makefile: link gray to libgray
This changes gray to always link to libgray, either statically or dynamically.
2024-01-24 14:37:21 +01:00
Michele Guerini Rocco
af1ed7d1b6
Makefile: fix libgray.a with parallel building
ar does not support multiple builder writing to the same file.
This disable parallel building for .a targets.
See also "Archive Pitfalls" in the GNU Make manual.
2024-01-24 14:37:20 +01:00
Michele Guerini Rocco
c889c754f7
fix partial updates to libgray.a when using Nix
When building the static library the Nixpkgs stdenv `ar` defaults to not
writing timestamps for the members file. This imply make will always try
to add all members to the archive, which defeats the purpose of the
file-level granularity.
2024-01-24 14:37:20 +01:00
Michele Guerini Rocco
95d398d503
src/equilibrium.f90: use the exact toroidal flux
To improve the analytical model correctness this changes the formula
of the toroidal flux to lift the large aspect ratio approximation (a << R₀).
In fact, Φ(r) = B₀πr² is technically inconsistent with the field varying
as B₀R₀/R. The exact expression is:

  Φ(r) = B₀πr² 2/[1 + √(1 - r²/R₀²)],

which is approximately equal to the former for r << R₀.

Note that this change introduces a divergence in the poloidal field at
r=R₀ (since ∂Φ/∂r → +∞), so the domain of the equilibrium has been
restricted to r<R₀, as expected.
This should not be a concern because the field outside the plasma
boundary is never directly, particularly not by the integrator.
2024-01-24 14:37:20 +01:00
Michele Guerini Rocco
9a301f5799
src/equilibrium.f90: re-introduce ρ_t(R,z) mapping
Directly mapping r(R,z) to ρ_p greatly simplifies the implementation of
pol_flux, but also produces a weird current profile and resonance curve.

This keeps the previous changes to the model but reverts the mapping to
the previous one: r → ρ_t.
2024-01-24 14:37:20 +01:00
Michele Guerini Rocco
24edfdc43a
src/gray_core.f90: print_* do not depend on q_spline
This changes all the print_* subroutines to not depend on q_spline,
either for the ψ data points or just their number.
In fact, in the new analytical model q_spline doesn't exist anymore.

Pro: This allows to mark q_spline as private.
2024-01-24 14:37:20 +01:00
Michele Guerini Rocco
8d86d70e91
src/equilibrium.f90: pol_curr return derivative wrt ψ_n 2023-12-12 23:37:56 +01:00
Michele Guerini Rocco
31a7b95fe1
combine equian and equinum_* subroutines
This change combines `equian` and `equinum_psi` into a new `pol_flux`
subroutine that computes ψ(R,z) and derivatives for either numerical or
analytical equilibria.
Similarly, `equian` (the fpol and dfpol outputs) and `equinum_fpol` are
combined intro `pol_curr` that computes F(ψ) and its derivative.

Callers of these subroutines do not select a specific version based on
the value of `iequil` anymore.
2023-12-12 23:37:56 +01:00