GCC Code Coverage Report


Directory: ./
File: src/orbit_fo_field.f90
Date: 2026-10-22 05:02:02
Coverage Exec Excl Total
Lines: 100.0% 26 0 26
Functions: 100.0% 3 0 3
Branches: 100.0% 8 0 8

Line Branch Exec Source
1 module orbit_fo_field
2 ! Field provider for the full-orbit (FO) Boris pusher on the production
3 ! Boozer/chartmap chart. The chartmap reference coordinate is rho = sqrt(s)
4 ! with the same angles as the production field_can_boozer chart, so the libneo
5 ! chartmap geometry (reference_coordinates%ref_coords) is native. The Boozer
6 ! flux potential A_theta(s), A_phi(s), |B| and the field |B|-derivatives come
7 ! from field_can, reparametrized from s = rho^2 by the radial chain rule
8 ! dF/drho = 2 rho dF/ds; the angular derivatives are unchanged.
9 use, intrinsic :: iso_fortran_env, only: dp => real64
10 implicit none
11 private
12
13 public :: fo_eval_field, fo_eval_reference_field, &
14 fo_reference_field_available
15
16 contains
17
18 1421438 logical function fo_reference_field_available()
19 use magfie_sub, only: has_magfie_refcoords_field
20
21 1 fo_reference_field_available = has_magfie_refcoords_field()
22 1 end function fo_reference_field_available
23
24 13 subroutine fo_eval_reference_field(u, hcov, Bmod, status)
25 1 use magfie_sub, only: evaluate_magfie_refcoords_field
26 real(dp), intent(in) :: u(3)
27 real(dp), intent(out) :: hcov(3), Bmod
28 integer, intent(out) :: status
29 real(dp) :: Acov(3)
30
31 13 call evaluate_magfie_refcoords_field(u, Acov, hcov, Bmod, status)
32 13 end subroutine fo_eval_reference_field
33
34 ! Production Boozer field at u=(rho,theta_B,phi_B), reparametrized from
35 ! field_can(s=rho^2). field_can returns covariant A_theta,A_phi (A_s=0),
36 ! covariant h_theta,h_phi (h_s=0), |B| and the s-derivatives. Only the radial
37 ! coordinate differs: F(rho)=F(s(rho)), dF/drho = 2 rho dF/ds; angular
38 ! derivatives are unchanged. dA(i,k)=dA_i/du_k carries the same chain rule on
39 ! its radial column.
40 1421437 subroutine fo_eval_field(u, Acov, dA, Bmod, dBmod, hcov)
41 13 use field_can_mod, only: eval_field => evaluate, field_can_t
42 real(dp), intent(in) :: u(3)
43 real(dp), intent(out) :: Acov(3), dA(3,3), Bmod, dBmod(3), hcov(3)
44 type(field_can_t) :: f
45 real(dp) :: rho, ds_drho
46
47 1421437 rho = u(1)
48 1421437 ds_drho = 2.0_dp*rho ! ds/drho = 2 rho (s = rho^2); dF/drho = ds/drho dF/ds
49
50 1421437 call eval_field(f, rho*rho, u(2), u(3), 0)
51
52
2/2
✓ Branch 0 taken 4264311 times.
✓ Branch 1 taken 1421437 times.
5685748 Acov = [0.0_dp, f%Ath, f%Aph]
53
2/2
✓ Branch 0 taken 4264311 times.
✓ Branch 1 taken 1421437 times.
5685748 hcov = [0.0_dp, f%hth, f%hph]
54 1421437 Bmod = f%Bmod
55
56 ! dA(i,k) = dA_i/du_k. A_s = 0 (row 1 all zero). Rows 2,3 (A_theta, A_phi):
57 ! radial column k=1 scales by ds/drho; angular columns unchanged.
58 1421437 dA = 0.0_dp
59 1421437 dA(2,1) = f%dAth(1)*ds_drho
60 1421437 dA(2,2) = f%dAth(2)
61 1421437 dA(2,3) = f%dAth(3)
62 1421437 dA(3,1) = f%dAph(1)*ds_drho
63 1421437 dA(3,2) = f%dAph(2)
64 1421437 dA(3,3) = f%dAph(3)
65
66 ! d|B|/du_k: radial column scales, angular columns unchanged.
67 1421437 dBmod(1) = f%dBmod(1)*ds_drho
68 1421437 dBmod(2) = f%dBmod(2)
69 1421437 dBmod(3) = f%dBmod(3)
70
4/4
✓ Branch 0 taken 1421437 times.
✓ Branch 1 taken 4264311 times.
✓ Branch 2 taken 8528622 times.
✓ Branch 3 taken 1421437 times.
17057244 end subroutine fo_eval_field
71
72 end module orbit_fo_field
73