• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gyrokinetics / gs2 / 1821477209

16 May 2025 02:50PM UTC coverage: 8.139% (+0.2%) from 7.92%
1821477209

push

gitlab-ci

David Dickinson
Merged in bugfix/use_uv_in_coverage_test_to_install_packages (pull request #1142)

3704 of 45511 relevant lines covered (8.14%)

122643.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/diagnostics/diagnostics_zonal_transfer.f90
1
!> FIXME : Add documentation
2
module diagnostics_zonal_transfer
3

4
!> calculate tau(kx,ky), the transfer of free energy by the non-linearity in fourier space
5
  implicit none
6

7
  private
8

9
!> allocate free energy transfer arrays
10
  public :: init_diagnostics_transfer
11
  public :: calculate_zonal_transfer, write_zonal_transfer
12

13
contains
14
  !> FIXME : Add documentation
15
  subroutine init_diagnostics_transfer(gnostics)
×
16
    use kt_grids, only: naky, ntheta0, nx, ny
17
    use theta_grid, only: ntgrid
18
    use species, only: nspec
19
    use le_grids, only: init_le_grids, nlambda, negrid
20
    use gs2_transforms, only: init_transforms
21
    use gs2_layouts, only: init_dist_fn_layouts
22
    use diagnostics_config, only: diagnostics_type
23
    use mp, only: nproc, iproc
24
    implicit none
25

26
    type(diagnostics_type), intent(inout) :: gnostics
27
    logical :: accel_x
28

29
    if(.not. gnostics%write_zonal_transfer) return
×
30

31
    !> initialize zonal_transfer to zero
32
    gnostics%current_results%zonal_transfer = 0.0
×
33
    
34
    ! call every initiation routine we need:
35
    ! le_grids for integration, init_gs2 transforms to initiate fourier transforms routines, etc.
36
    
37
    ! calls init_theta_grid, init_kt_grids, init_gs2_layouts, and init_species for later use
38
    call init_le_grids
×
39
    ! will need to use fft routines
40
    call init_transforms(ntgrid, naky, ntheta0, nlambda, negrid, nspec, nx, ny, accel_x)
×
41
    call init_dist_fn_layouts(ntgrid, naky, ntheta0, nlambda, negrid, nspec, nproc, iproc)
×
42

43
  end subroutine init_diagnostics_transfer
44
  
45
  !> calculate nonlinear term appearing in GKE
46
  !! for now assume electrostatic
47
  subroutine non_linear_term (g1)
×
48
    use theta_grid, only: ntgrid, kxfac
49
    use gs2_layouts, only: g_lo, ik_idx, it_idx, is_idx
50
    use gs2_layouts, only: yxf_lo
51
    use dist_fn_arrays, only: g, g_adjust, to_g_gs2, from_g_gs2
52
    use species, only: spec
53
    use gs2_transforms, only: transform2, inverse2
54
    use kt_grids, only: aky, akx
55
    use fields_arrays, only: phi, bpar
56
    use constants, only: zi
57

58
    implicit none
59

60
    complex, dimension (-ntgrid:,:,g_lo%llim_proc:), intent(out) :: g1
61
    integer :: i, j
62
    integer :: iglo, ik, it, ig, is
63

64
    real, dimension(:,:), allocatable :: banew, gbnew, bracketnew
×
65

66
    allocate (banew(yxf_lo%ny,yxf_lo%llim_proc:yxf_lo%ulim_alloc)) ; banew = 0.
×
67
    allocate (gbnew(yxf_lo%ny,yxf_lo%llim_proc:yxf_lo%ulim_alloc)) ; gbnew = 0.
×
68
    allocate (bracketnew(yxf_lo%ny,yxf_lo%llim_proc:yxf_lo%ulim_alloc)) ; bracketnew = 0.
×
69

70
    ! Form g1=i*kx*phi
71
    call load_kx_phi
×
72

73
    ! Transform to real space
74
    ! 2D fft of g1 is returned as banew
75
    call transform2 (g1, banew)
×
76

77
    ! Form g1=i*ky*g
78
    do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
79
       ik = ik_idx(g_lo,iglo)
×
80
       g1(:,:,iglo)=g(:,:,iglo)*zi*aky(ik)
×
81
    end do
82

83
    ! Transform to real space
84
    call transform2 (g1, gbnew)
×
85

86
    ! Calculate (d phi /dx).(dg/dy)
87
    do j = yxf_lo%llim_proc, yxf_lo%ulim_proc
×
88
       do i = 1, yxf_lo%ny
×
89
          bracketnew(i,j) = banew(i,j)*gbnew(i,j)*kxfac
×
90
       end do
91
    end do
92

93
    ! Form g1=i*ky*chi
94
    call load_ky_phi
×
95

96
    !Transform to real space
97
    call transform2 (g1, banew)
×
98

99
    do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
100
       it = it_idx(g_lo,iglo)
×
101
       g1(:,:,iglo)=g(:,:,iglo)*zi*akx(it)
×
102
    enddo
103

104
    ! Transform to real space
105
    call transform2 (g1, gbnew)
×
106

107
    ! Calculate (d phi /dy).(dg/dx) and subtract from (d phi /dx).(dg/dy)
108
    do j = yxf_lo%llim_proc, yxf_lo%ulim_proc
×
109
       do i = 1, yxf_lo%ny
×
110
          bracketnew(i,j) = bracketnew(i,j) - banew(i,j)*gbnew(i,j)*kxfac
×
111
       end do
112
    end do
113

114
    ! Transform nonlinearity back to spectral space
115
    ! g1 contains Fourier coefficients associated with nonlinearity
116
    call inverse2 (bracketnew, g1)
×
117

118
    call g_adjust(g,phi,bpar, direction = from_g_gs2)
×
119

120
    do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
121
       is = is_idx(g_lo,iglo)
×
122
       g1(:,:,iglo)=g1(:,:,iglo)*conjg(g(:,:,iglo))*spec(is)%temp
×
123
    end do
124

125
    call g_adjust(g,phi,bpar, direction = to_g_gs2)
×
126

127
    deallocate (banew, gbnew, bracketnew)
×
128

129
  contains
130

131
    !> FIXME : Add documentation
132
    subroutine load_kx_phi
×
133
      use dist_fn_arrays, only: aj0  !< bessel function from the fourier coeff of average
134
      implicit none
135
      complex :: fac
136

137
      do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
138
         it = it_idx(g_lo,iglo)
×
139
         ik = ik_idx(g_lo,iglo)
×
140
         do ig = -ntgrid, ntgrid
×
141
            fac = zi*akx(it)*aj0(ig,iglo)*phi(ig,it,ik)
×
142
            g1(ig,1,iglo) = fac
×
143
            g1(ig,2,iglo) = fac
×
144
         end do
145
      end do
146

147
    end subroutine load_kx_phi
×
148

149
    !> FIXME : Add documentation    
150
    subroutine load_ky_phi
×
151
      use dist_fn_arrays, only: aj0
152
      implicit none
153
      complex :: fac
154

155
      do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
156
         it = it_idx(g_lo,iglo)
×
157
         ik = ik_idx(g_lo,iglo)
×
158
         do ig = -ntgrid, ntgrid
×
159
            fac = zi*aky(ik)*aj0(ig,iglo)*phi(ig,it,ik)
×
160
            g1(ig,1,iglo) = fac
×
161
            g1(ig,2,iglo) = fac
×
162
         end do
163
      end do
164

165
    end subroutine load_ky_phi
×
166

167
  end subroutine non_linear_term
168

169
  !> Returns tau, the transfer of free energy as a function of (kx,ky)
170
  subroutine total_term(tau)
×
171
    use mp, only: proc0, broadcast
172
    use theta_grid, only: ntgrid, field_line_average
173
    use gs2_layouts, only: g_lo, ik_idx, it_idx
174
    use species, only: nspec
175
    use kt_grids, only: ntheta0, naky
176
    use le_grids, only: integrate_moment
177
    implicit none
178
    complex, dimension(:,:), intent(out) :: tau
179
    complex, dimension (:,:,:), allocatable :: g0
×
180
    complex, dimension (:,:,:), allocatable :: inter
×
181
    complex, dimension (:,:,:,:), allocatable :: inter_s
×
182
    integer :: is
183
    
184
    allocate (g0(-ntgrid:ntgrid,2,g_lo%llim_proc:g_lo%ulim_alloc))
×
185
    allocate (inter(-ntgrid:ntgrid,ntheta0,naky)) ; inter = 0.
×
186
    allocate (inter_s(-ntgrid:ntgrid,ntheta0,naky,nspec)) ; inter_s = 0.
×
187

188
    ! obtain the nonlinear term
189
    call non_linear_term(g0)
×
190

191
    ! integrate over velocities
192
    ! can only be called after w and wl are assigned in init_le_grids
193
    call integrate_moment(g0, inter_s)
×
194

195
    if (proc0) then
×
196
       ! sum over species
197
       do is=1,nspec
×
198
          inter = inter + inter_s(:,:,:,is)
×
199
       end do
200

201
       ! integrate over theta, must be done after velocity space integration
202
       tau = field_line_average(inter)
×
203
    end if
204
    
205
    call broadcast (tau)
×
206
    deallocate (g0, inter, inter_s)
×
207
  end subroutine total_term
×
208

209
  !> FIXME : Add documentation  
210
  subroutine write_zonal_transfer(gnostics)
×
211
    use gs2_io, only: starts, netcdf_write_complex
212
    use diagnostics_config, only: diagnostics_type
213
    use mp, only: proc0
214
    implicit none
215
    
216
    type(diagnostics_type), intent(in out) :: gnostics
217
    if (.not. proc0) return
×
218
    call netcdf_write_complex(gnostics%file_id, "zonal_transfer", gnostics%current_results%zonal_transfer, &
219
         dim_names=["ri" ,"kx", "ky", "t "], start=starts(4, gnostics%nout), &
220
         long_name="Time rate of change of free energy due to nonlinear transfer, as a function of kx, ky and time", &
221
         units="Tr2*rhor*c*ns*vth6 / Ba2*e*a3")
×
222
    
223
  end subroutine write_zonal_transfer
224

225
  !> FIXME : Add documentation  
226
  subroutine calculate_zonal_transfer(gnostics)
×
227
    use diagnostics_config, only: diagnostics_type
228
    use kt_grids, only: ntheta0, naky
229
    implicit none
230
    
231
    type(diagnostics_type), intent(inout) :: gnostics
232
    
233
    complex, dimension (:,:), allocatable ::  zonal_transfer
×
234

235
    allocate (zonal_transfer(ntheta0,naky)) ; zonal_transfer = 0.
×
236

237
    call total_term(zonal_transfer)
×
238
    gnostics%current_results%zonal_transfer = zonal_transfer
×
239

240
    deallocate (zonal_transfer)
×
241

242
  end subroutine calculate_zonal_transfer
×
243

244
end module diagnostics_zonal_transfer
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc