| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | module netcdf_orbit_output | ||
| 2 | use, intrinsic :: iso_fortran_env, only: dp => real64 | ||
| 3 | use finite_check, only: is_finite, quiet_nan | ||
| 4 | use netcdf | ||
| 5 | implicit none | ||
| 6 | |||
| 7 | private | ||
| 8 | public :: init_orbit_netcdf, close_orbit_netcdf | ||
| 9 | public :: write_orbit_to_netcdf | ||
| 10 | public :: netcdf_compression_level | ||
| 11 | |||
| 12 | ! Compression level: 0=none, 1-9=deflate (4 recommended) | ||
| 13 | integer :: netcdf_compression_level = 4 | ||
| 14 | |||
| 15 | ! NetCDF file handle and variable IDs | ||
| 16 | integer :: ncid | ||
| 17 | integer :: dimid_particle, dimid_timestep | ||
| 18 | integer :: varid_time, varid_s, varid_theta, varid_phi, varid_p_abs, varid_v_par | ||
| 19 | integer :: varid_r, varid_z | ||
| 20 | logical :: netcdf_initialized = .false. | ||
| 21 | logical :: cylindrical_output = .false. | ||
| 22 | real(dp) :: fill_value | ||
| 23 | |||
| 24 | contains | ||
| 25 | |||
| 26 | 869 | subroutine check_nc(status, location) | |
| 27 | integer, intent(in) :: status | ||
| 28 | character(len=*), intent(in) :: location | ||
| 29 | |||
| 30 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 869 times.
|
869 | if (status /= nf90_noerr) then |
| 31 | ✗ | print *, 'NetCDF error at ', trim(location), ': ', trim(nf90_strerror(status)) | |
| 32 | ✗ | error stop 'NetCDF operation failed' | |
| 33 | end if | ||
| 34 | 869 | end subroutine check_nc | |
| 35 | |||
| 36 | 7 | subroutine configure_cylindrical_output(cart_units, coordinate_type, & | |
| 37 | radial_coordinate) | ||
| 38 | use chartmap_metadata, only: read_chartmap_cart_units | ||
| 39 | use libneo_coordinates, only: chartmap_coordinate_system_t | ||
| 40 | use params, only: coord_input | ||
| 41 | use reference_coordinates, only: ref_coords | ||
| 42 | |||
| 43 | character(len=*), intent(out) :: cart_units, coordinate_type | ||
| 44 | character(len=*), intent(out) :: radial_coordinate | ||
| 45 | |||
| 46 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | cart_units = 'cm' |
| 47 |
2/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
7 | coordinate_type = 'unavailable' |
| 48 |
2/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
7 | radial_coordinate = 's' |
| 49 | 7 | cylindrical_output = allocated(ref_coords) | |
| 50 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
|
7 | if (.not. cylindrical_output) return |
| 51 | |||
| 52 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | coordinate_type = 'vmec' |
| 53 | select type (ref_coords) | ||
| 54 | class is (chartmap_coordinate_system_t) | ||
| 55 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | coordinate_type = 'chartmap' |
| 56 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | radial_coordinate = 'rho' |
| 57 | 3 | call read_chartmap_cart_units(coord_input, cart_units) | |
| 58 | class default | ||
| 59 | continue | ||
| 60 | end select | ||
| 61 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
14 | end subroutine configure_cylindrical_output |
| 62 | |||
| 63 | 8 | subroutine define_cylindrical_variable(name, description, cart_units, varid) | |
| 64 | character(len=*), intent(in) :: name, description, cart_units | ||
| 65 | integer, intent(out) :: varid | ||
| 66 | |||
| 67 | integer :: status | ||
| 68 | |||
| 69 | status = nf90_def_var(ncid, trim(name), nf90_double, & | ||
| 70 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
|
24 | [dimid_particle, dimid_timestep], varid) |
| 71 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | call check_nc(status, 'nf90_def_var '//trim(name)) |
| 72 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (netcdf_compression_level > 0) then |
| 73 | status = nf90_def_var_deflate(ncid, varid, 1, 1, & | ||
| 74 | 8 | netcdf_compression_level) | |
| 75 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | call check_nc(status, 'nf90_def_var_deflate '//trim(name)) |
| 76 | end if | ||
| 77 | 8 | status = nf90_put_att(ncid, varid, '_FillValue', fill_value) | |
| 78 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | call check_nc(status, 'nf90_put_att '//trim(name)//' _FillValue') |
| 79 | 8 | status = nf90_put_att(ncid, varid, 'units', trim(cart_units)) | |
| 80 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | call check_nc(status, 'nf90_put_att '//trim(name)//' units') |
| 81 | 8 | status = nf90_put_att(ncid, varid, 'description', trim(description)) | |
| 82 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | call check_nc(status, 'nf90_put_att '//trim(name)//' description') |
| 83 | 7 | end subroutine define_cylindrical_variable | |
| 84 | |||
| 85 | 4 | subroutine define_cylindrical_variables(cart_units) | |
| 86 | character(len=*), intent(in) :: cart_units | ||
| 87 | |||
| 88 | call define_cylindrical_variable('R', 'Cylindrical major radius', & | ||
| 89 | 4 | cart_units, varid_r) | |
| 90 | call define_cylindrical_variable('Z', & | ||
| 91 | 4 | 'Cylindrical vertical coordinate', cart_units, varid_z) | |
| 92 | 4 | end subroutine define_cylindrical_variables | |
| 93 | |||
| 94 | |||
| 95 | 7 | subroutine init_orbit_netcdf(n_particles, n_timesteps) | |
| 96 | use params, only: collision_model, particle_energy_eV_effective, & | ||
| 97 | nu_star_standard, lorentz_major_radius_cm, lorentz_iota, lorentz_nu, & | ||
| 98 | radial_electric_potential_slope | ||
| 99 | |||
| 100 | integer, intent(in) :: n_particles, n_timesteps | ||
| 101 | integer :: status, coord_varid_particle, coord_varid_timestep | ||
| 102 | character(len=16) :: cart_units, coordinate_type, radial_coordinate | ||
| 103 | |||
| 104 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (netcdf_initialized) then |
| 105 | ✗ | error stop 'init_orbit_netcdf: already initialized' | |
| 106 | end if | ||
| 107 | |||
| 108 | 7 | fill_value = quiet_nan() | |
| 109 | call configure_cylindrical_output(cart_units, coordinate_type, & | ||
| 110 | 7 | radial_coordinate) | |
| 111 | |||
| 112 | ! Create NetCDF file | ||
| 113 | 7 | status = nf90_create('orbits.nc', nf90_netcdf4, ncid) | |
| 114 | 7 | call check_nc(status, 'nf90_create') | |
| 115 | |||
| 116 | ! Define dimensions | ||
| 117 | 7 | status = nf90_def_dim(ncid, 'particle', n_particles, dimid_particle) | |
| 118 | 7 | call check_nc(status, 'nf90_def_dim particle') | |
| 119 | |||
| 120 | 7 | status = nf90_def_dim(ncid, 'timestep', n_timesteps, dimid_timestep) | |
| 121 | 7 | call check_nc(status, 'nf90_def_dim timestep') | |
| 122 | |||
| 123 | ! Define coordinate variables | ||
| 124 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | status = nf90_def_var(ncid, 'particle', nf90_int, [dimid_particle], coord_varid_particle) |
| 125 | 7 | call check_nc(status, 'nf90_def_var particle') | |
| 126 | |||
| 127 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | status = nf90_def_var(ncid, 'timestep', nf90_int, [dimid_timestep], coord_varid_timestep) |
| 128 | 7 | call check_nc(status, 'nf90_def_var timestep') | |
| 129 | |||
| 130 | ! Define data variables (all 2D: particle x timestep) | ||
| 131 | status = nf90_def_var(ncid, 'time', nf90_double, & | ||
| 132 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
|
21 | [dimid_particle, dimid_timestep], varid_time) |
| 133 | 7 | call check_nc(status, 'nf90_def_var time') | |
| 134 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (netcdf_compression_level > 0) then |
| 135 | 7 | status = nf90_def_var_deflate(ncid, varid_time, 1, 1, netcdf_compression_level) | |
| 136 | 7 | call check_nc(status, 'nf90_def_var_deflate time') | |
| 137 | end if | ||
| 138 | 7 | status = nf90_put_att(ncid, varid_time, '_FillValue', fill_value) | |
| 139 | 7 | call check_nc(status, 'nf90_put_att time _FillValue') | |
| 140 | |||
| 141 | status = nf90_def_var(ncid, 's', nf90_double, & | ||
| 142 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
|
21 | [dimid_particle, dimid_timestep], varid_s) |
| 143 | 7 | call check_nc(status, 'nf90_def_var s') | |
| 144 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (netcdf_compression_level > 0) then |
| 145 | 7 | status = nf90_def_var_deflate(ncid, varid_s, 1, 1, netcdf_compression_level) | |
| 146 | 7 | call check_nc(status, 'nf90_def_var_deflate s') | |
| 147 | end if | ||
| 148 | 7 | status = nf90_put_att(ncid, varid_s, '_FillValue', fill_value) | |
| 149 | 7 | call check_nc(status, 'nf90_put_att s _FillValue') | |
| 150 | status = nf90_put_att(ncid, varid_s, 'description', & | ||
| 151 | 7 | 'First reference coordinate; see radial_coordinate global attribute') | |
| 152 | 7 | call check_nc(status, 'nf90_put_att s description') | |
| 153 | |||
| 154 | status = nf90_def_var(ncid, 'theta', nf90_double, & | ||
| 155 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
|
21 | [dimid_particle, dimid_timestep], varid_theta) |
| 156 | 7 | call check_nc(status, 'nf90_def_var theta') | |
| 157 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (netcdf_compression_level > 0) then |
| 158 | 7 | status = nf90_def_var_deflate(ncid, varid_theta, 1, 1, netcdf_compression_level) | |
| 159 | 7 | call check_nc(status, 'nf90_def_var_deflate theta') | |
| 160 | end if | ||
| 161 | 7 | status = nf90_put_att(ncid, varid_theta, '_FillValue', fill_value) | |
| 162 | 7 | call check_nc(status, 'nf90_put_att theta _FillValue') | |
| 163 | |||
| 164 | status = nf90_def_var(ncid, 'phi', nf90_double, & | ||
| 165 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
|
21 | [dimid_particle, dimid_timestep], varid_phi) |
| 166 | 7 | call check_nc(status, 'nf90_def_var phi') | |
| 167 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (netcdf_compression_level > 0) then |
| 168 | 7 | status = nf90_def_var_deflate(ncid, varid_phi, 1, 1, netcdf_compression_level) | |
| 169 | 7 | call check_nc(status, 'nf90_def_var_deflate phi') | |
| 170 | end if | ||
| 171 | 7 | status = nf90_put_att(ncid, varid_phi, '_FillValue', fill_value) | |
| 172 | 7 | call check_nc(status, 'nf90_put_att phi _FillValue') | |
| 173 | |||
| 174 | status = nf90_def_var(ncid, 'p_abs', nf90_double, & | ||
| 175 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
|
21 | [dimid_particle, dimid_timestep], varid_p_abs) |
| 176 | 7 | call check_nc(status, 'nf90_def_var p_abs') | |
| 177 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (netcdf_compression_level > 0) then |
| 178 | 7 | status = nf90_def_var_deflate(ncid, varid_p_abs, 1, 1, netcdf_compression_level) | |
| 179 | 7 | call check_nc(status, 'nf90_def_var_deflate p_abs') | |
| 180 | end if | ||
| 181 | 7 | status = nf90_put_att(ncid, varid_p_abs, '_FillValue', fill_value) | |
| 182 | 7 | call check_nc(status, 'nf90_put_att p_abs _FillValue') | |
| 183 | |||
| 184 | status = nf90_def_var(ncid, 'v_par', nf90_double, & | ||
| 185 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
|
21 | [dimid_particle, dimid_timestep], varid_v_par) |
| 186 | 7 | call check_nc(status, 'nf90_def_var v_par') | |
| 187 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (netcdf_compression_level > 0) then |
| 188 | 7 | status = nf90_def_var_deflate(ncid, varid_v_par, 1, 1, netcdf_compression_level) | |
| 189 | 7 | call check_nc(status, 'nf90_def_var_deflate v_par') | |
| 190 | end if | ||
| 191 | 7 | status = nf90_put_att(ncid, varid_v_par, '_FillValue', fill_value) | |
| 192 | 7 | call check_nc(status, 'nf90_put_att v_par _FillValue') | |
| 193 | |||
| 194 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
|
7 | if (cylindrical_output) call define_cylindrical_variables(cart_units) |
| 195 | |||
| 196 | ! Add global attributes | ||
| 197 | status = nf90_put_att(ncid, nf90_global, 'description', & | ||
| 198 | 7 | 'SIMPLE orbit tracer output (macrostep mode)') | |
| 199 | 7 | call check_nc(status, 'nf90_put_att description') | |
| 200 | |||
| 201 | status = nf90_put_att(ncid, nf90_global, 'source', & | ||
| 202 | 7 | 'Direct Fortran NetCDF output') | |
| 203 | 7 | call check_nc(status, 'nf90_put_att source') | |
| 204 | |||
| 205 | 7 | status = nf90_put_att(ncid, nf90_global, 'n_particles', n_particles) | |
| 206 | 7 | call check_nc(status, 'nf90_put_att n_particles') | |
| 207 | |||
| 208 | 7 | status = nf90_put_att(ncid, nf90_global, 'n_timesteps', n_timesteps) | |
| 209 | 7 | call check_nc(status, 'nf90_put_att n_timesteps') | |
| 210 | |||
| 211 | status = nf90_put_att(ncid, nf90_global, 'coordinate_type', & | ||
| 212 | 7 | trim(coordinate_type)) | |
| 213 | 7 | call check_nc(status, 'nf90_put_att coordinate_type') | |
| 214 | |||
| 215 | status = nf90_put_att(ncid, nf90_global, 'radial_coordinate', & | ||
| 216 | 7 | trim(radial_coordinate)) | |
| 217 | 7 | call check_nc(status, 'nf90_put_att radial_coordinate') | |
| 218 | |||
| 219 | status = nf90_put_att(ncid, nf90_global, 'particle_energy_eV', & | ||
| 220 | 7 | particle_energy_eV_effective) | |
| 221 | 7 | call check_nc(status, 'nf90_put_att particle_energy_eV') | |
| 222 | status = nf90_put_att(ncid, nf90_global, 'collision_model', & | ||
| 223 | 7 | trim(collision_model)) | |
| 224 | 7 | call check_nc(status, 'nf90_put_att collision_model') | |
| 225 | status = nf90_put_att(ncid, nf90_global, 'nu_star_standard', & | ||
| 226 | 7 | nu_star_standard) | |
| 227 | 7 | call check_nc(status, 'nf90_put_att nu_star_standard') | |
| 228 | status = nf90_put_att(ncid, nf90_global, 'lorentz_major_radius_cm', & | ||
| 229 | 7 | lorentz_major_radius_cm) | |
| 230 | 7 | call check_nc(status, 'nf90_put_att lorentz_major_radius_cm') | |
| 231 | 7 | status = nf90_put_att(ncid, nf90_global, 'lorentz_iota', lorentz_iota) | |
| 232 | 7 | call check_nc(status, 'nf90_put_att lorentz_iota') | |
| 233 | 7 | status = nf90_put_att(ncid, nf90_global, 'lorentz_nu_s-1', lorentz_nu) | |
| 234 | 7 | call check_nc(status, 'nf90_put_att lorentz_nu_s-1') | |
| 235 | status = nf90_put_att(ncid, nf90_global, & | ||
| 236 | 7 | 'radial_electric_potential_slope', radial_electric_potential_slope) | |
| 237 | 7 | call check_nc(status, 'nf90_put_att radial_electric_potential_slope') | |
| 238 | |||
| 239 | ! End define mode | ||
| 240 | 7 | status = nf90_enddef(ncid) | |
| 241 | 7 | call check_nc(status, 'nf90_enddef') | |
| 242 | |||
| 243 | ! Write coordinate variables | ||
| 244 | 7 | call write_coordinates(n_particles, n_timesteps) | |
| 245 | |||
| 246 | 7 | netcdf_initialized = .true. | |
| 247 | 7 | end subroutine init_orbit_netcdf | |
| 248 | |||
| 249 | |||
| 250 | 7 | subroutine write_coordinates(n_particles, n_timesteps) | |
| 251 | integer, intent(in) :: n_particles, n_timesteps | ||
| 252 | integer :: status, i | ||
| 253 | integer :: coord_varid_particle, coord_varid_timestep | ||
| 254 | 7 | integer, allocatable :: particle_ids(:), timestep_ids(:) | |
| 255 | |||
| 256 |
6/12✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 7 times.
|
21 | allocate(particle_ids(n_particles)) |
| 257 |
6/12✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 7 times.
|
21 | allocate(timestep_ids(n_timesteps)) |
| 258 | |||
| 259 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 69 times.
|
76 | do i = 1, n_particles |
| 260 | 76 | particle_ids(i) = i | |
| 261 | end do | ||
| 262 | |||
| 263 |
2/2✓ Branch 0 taken 10613 times.
✓ Branch 1 taken 7 times.
|
10620 | do i = 1, n_timesteps |
| 264 | 10620 | timestep_ids(i) = i - 1 ! 0-based indexing for timesteps | |
| 265 | end do | ||
| 266 | |||
| 267 | 7 | status = nf90_inq_varid(ncid, 'particle', coord_varid_particle) | |
| 268 | 7 | call check_nc(status, 'nf90_inq_varid particle') | |
| 269 | 7 | status = nf90_put_var(ncid, coord_varid_particle, particle_ids) | |
| 270 | 7 | call check_nc(status, 'nf90_put_var particle') | |
| 271 | |||
| 272 | 7 | status = nf90_inq_varid(ncid, 'timestep', coord_varid_timestep) | |
| 273 | 7 | call check_nc(status, 'nf90_inq_varid timestep') | |
| 274 | 7 | status = nf90_put_var(ncid, coord_varid_timestep, timestep_ids) | |
| 275 | 7 | call check_nc(status, 'nf90_put_var timestep') | |
| 276 | |||
| 277 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
|
7 | deallocate(particle_ids, timestep_ids) |
| 278 | 7 | end subroutine write_coordinates | |
| 279 | |||
| 280 | |||
| 281 | |||
| 282 | |||
| 283 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 69 times.
|
69 | subroutine write_orbit_to_netcdf(ipart, orbit_traj, orbit_times) |
| 284 | use field_can_mod, only : integ_to_ref | ||
| 285 | use reference_coordinates, only: ref_coords | ||
| 286 | |||
| 287 | integer, intent(in) :: ipart | ||
| 288 | real(kind(1.0d0)), intent(in) :: orbit_traj(:,:) ! (5, ntimstep) | ||
| 289 | real(kind(1.0d0)), intent(in) :: orbit_times(:) ! (ntimstep) | ||
| 290 | |||
| 291 | integer :: it, status, n_times | ||
| 292 | real(dp) :: xcyl(3), xref(3) | ||
| 293 | 69 | real(dp), allocatable :: r_array(:), s_array(:), theta_array(:), phi_array(:) | |
| 294 | 69 | real(dp), allocatable :: z_array(:) | |
| 295 | |||
| 296 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
|
69 | if (.not. netcdf_initialized) then |
| 297 | ✗ | error stop 'write_orbit_to_netcdf: NetCDF not initialized' | |
| 298 | end if | ||
| 299 | |||
| 300 | 69 | n_times = size(orbit_times) | |
| 301 |
14/28✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 69 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 69 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 69 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 69 times.
✓ Branch 16 taken 69 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 69 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 69 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 69 times.
✓ Branch 26 taken 69 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 69 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 69 times.
|
345 | allocate(s_array(n_times), theta_array(n_times), phi_array(n_times)) |
| 302 |
2/2✓ Branch 0 taken 57 times.
✓ Branch 1 taken 12 times.
|
69 | if (cylindrical_output) then |
| 303 |
8/16✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 57 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 57 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 57 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 57 times.
✓ Branch 12 taken 57 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 57 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 57 times.
|
171 | allocate (r_array(n_times), z_array(n_times)) |
| 304 |
2/2✓ Branch 0 taken 320132 times.
✓ Branch 1 taken 57 times.
|
320189 | r_array = fill_value |
| 305 |
2/2✓ Branch 0 taken 57 times.
✓ Branch 1 taken 320132 times.
|
320189 | z_array = fill_value |
| 306 | end if | ||
| 307 | |||
| 308 | ! Convert integrator to reference coordinates | ||
| 309 |
2/2✓ Branch 0 taken 322532 times.
✓ Branch 1 taken 69 times.
|
322601 | do it = 1, n_times |
| 310 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 322532 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
322532 | call integ_to_ref(orbit_traj(1:3, it), xref) |
| 311 | 322532 | s_array(it) = xref(1) | |
| 312 | 322532 | theta_array(it) = xref(2) | |
| 313 | 322532 | phi_array(it) = xref(3) | |
| 314 |
2/2✓ Branch 0 taken 320132 times.
✓ Branch 1 taken 2400 times.
|
322601 | if (cylindrical_output) then |
| 315 |
6/6✓ Branch 0 taken 551046 times.
✓ Branch 1 taken 115457 times.
✓ Branch 2 taken 346371 times.
✓ Branch 3 taken 204675 times.
✓ Branch 4 taken 115457 times.
✓ Branch 5 taken 204675 times.
|
666503 | if (all(is_finite(xref))) then |
| 316 | 115457 | call ref_coords%evaluate_cyl(xref, xcyl) | |
| 317 | 115457 | r_array(it) = xcyl(1) | |
| 318 | 115457 | z_array(it) = xcyl(3) | |
| 319 | end if | ||
| 320 | end if | ||
| 321 | enddo | ||
| 322 | |||
| 323 | ! Write entire orbit to NetCDF in one shot | ||
| 324 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 69 times.
|
345 | status = nf90_put_var(ncid, varid_time, orbit_times, start=[ipart, 1], count=[1, n_times]) |
| 325 | 69 | call check_nc(status, 'nf90_put_var time') | |
| 326 | |||
| 327 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 69 times.
|
345 | status = nf90_put_var(ncid, varid_s, s_array, start=[ipart, 1], count=[1, n_times]) |
| 328 | 69 | call check_nc(status, 'nf90_put_var s') | |
| 329 | |||
| 330 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 69 times.
|
345 | status = nf90_put_var(ncid, varid_theta, theta_array, start=[ipart, 1], count=[1, n_times]) |
| 331 | 69 | call check_nc(status, 'nf90_put_var theta') | |
| 332 | |||
| 333 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 69 times.
|
345 | status = nf90_put_var(ncid, varid_phi, phi_array, start=[ipart, 1], count=[1, n_times]) |
| 334 | 69 | call check_nc(status, 'nf90_put_var phi') | |
| 335 | |||
| 336 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 69 times.
|
345 | status = nf90_put_var(ncid, varid_p_abs, orbit_traj(4, :), start=[ipart, 1], count=[1, n_times]) |
| 337 | 69 | call check_nc(status, 'nf90_put_var p_abs') | |
| 338 | |||
| 339 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 69 times.
|
345 | status = nf90_put_var(ncid, varid_v_par, orbit_traj(5, :), start=[ipart, 1], count=[1, n_times]) |
| 340 | 69 | call check_nc(status, 'nf90_put_var v_par') | |
| 341 | |||
| 342 |
2/2✓ Branch 0 taken 57 times.
✓ Branch 1 taken 12 times.
|
69 | if (cylindrical_output) then |
| 343 | status = nf90_put_var(ncid, varid_r, r_array, start=[ipart, 1], & | ||
| 344 |
4/4✓ Branch 0 taken 114 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 57 times.
|
285 | count=[1, n_times]) |
| 345 | 57 | call check_nc(status, 'nf90_put_var R') | |
| 346 | status = nf90_put_var(ncid, varid_z, z_array, start=[ipart, 1], & | ||
| 347 |
4/4✓ Branch 0 taken 114 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 57 times.
|
285 | count=[1, n_times]) |
| 348 | 57 | call check_nc(status, 'nf90_put_var Z') | |
| 349 | end if | ||
| 350 |
7/10✓ Branch 0 taken 57 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 57 times.
✓ Branch 7 taken 12 times.
✓ Branch 8 taken 69 times.
✗ Branch 9 not taken.
|
69 | end subroutine write_orbit_to_netcdf |
| 351 | |||
| 352 | |||
| 353 | 7 | subroutine close_orbit_netcdf() | |
| 354 | integer :: status | ||
| 355 | |||
| 356 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (.not. netcdf_initialized) then |
| 357 | ✗ | return ! Not an error, just nothing to close | |
| 358 | end if | ||
| 359 | |||
| 360 | ! Data already written incrementally, just close the file | ||
| 361 | 7 | status = nf90_close(ncid) | |
| 362 | 7 | call check_nc(status, 'nf90_close') | |
| 363 | |||
| 364 | 7 | netcdf_initialized = .false. | |
| 365 | 69 | end subroutine close_orbit_netcdf | |
| 366 | |||
| 367 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 time.
|
4 | end module netcdf_orbit_output |
| 368 |