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

gyrokinetics / gs2 / 1640171109

24 Jan 2025 07:04PM UTC coverage: 7.915% (-0.03%) from 7.943%
1640171109

push

gitlab-ci

David Dickinson
Merged in experimental/generate_config_collection_module (pull request #1070)

3691 of 46631 relevant lines covered (7.92%)

99785.8 hits per line

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

0.0
/src/hyper.f90
1
!> FIXME : Add documentation
2
!!
3
!! @note nexp has been changed in a rush.  Only known to be correct for nexp=2
4
module hyper
5
  use abstract_config, only: abstract_config_type, CONFIG_MAX_NAME_LEN
6
  implicit none
7

8
  private
9

10
  public :: init_hyper, finish_hyper, hyper_diff, D_res
11
  public :: read_parameters, wnml_hyper, check_hyper
12
  public :: D_v, D_eta, nexp
13
  public :: hypervisc_filter
14

15
  public :: hyper_config_type
16
  public :: set_hyper_config
17
  public :: get_hyper_config
18
  
19
! D_v, D_eta are hyper coefficients, normalized correctly 
20
! i.e., either by unity or by 1/k_perp**2*nexp
21

22
  real :: D_v, D_eta
23
  real :: D_hypervisc, D_hyperres, omega_osc, D_hyper
24
  real :: akx4_max, aky4_max, aky_max, akperp4_max
25

26
  integer :: hyper_option_switch, nexp
27
  integer, parameter :: hyper_option_none = 1, &
28
       hyper_option_visc = 2, &
29
       hyper_option_res  = 3, &
30
       hyper_option_both = 4, &
31
       hyper_option_simple3D = 5 ! MRH
32
       
33
  character(9) :: hyper_option
34
  logical :: const_amp, include_kpar, isotropic_shear, damp_zonal_only
35
  logical :: hyper_on = .false.
36
  logical :: gridnorm
37

38
  real, dimension (:,:), allocatable :: D_res
39
  ! (it, ik)
40

41
  real, dimension (:,:,:), allocatable :: hypervisc_filter
42
  ! (-ntgrid:ntgrid, ntheta0, naky)
43

44
  ! ! MRH Coefficients for simple3D hyperviscous model
45
  real :: kperp2_max, kperp2_max_zonal
46
  ! the maximum k_perp ^ 2 including geometric coefficients for non-zonal and zonal modes
47
  real :: D_hyper3D, P_hyper3D, ky_cut, kx_cut
48
  ! Hyperviscous coefficient, hyperviscous power, ky cut-off, kx cut-off
49
  logical :: isotropic_model
50
  ! Controls if zonal modes are treated identically to non-zonal modes
51

52
  logical :: initialized = .false.
53

54

55
  !> Used to represent the input configuration of hyper
56
  type, extends(abstract_config_type) :: hyper_config_type
57
     ! namelist : hyper_knobs
58
     ! indexed : false
59
     !> Determines whether hyperviscosity includes time dependent amplitude
60
     !> factor when calculating damping rate. Recommend `true` for
61
     !> linear runs and `false` for nolinear runs, since amplutide of
62
     !> turbulence grows linearly with time in linear run.
63
     logical :: const_amp = .false.
64
     !> If `hyper_option = 'both'` is used then this sets both the
65
     !> hyperresistivity and hyperviscosity damping coefficients. Can
66
     !> override the individual coefficients with
67
     !> [[hyper_knobs:D_hyperres]] and [[hyper_knobs:D_hypervisc]].
68
     real :: d_hyper = -10.0
69
     !> Used with the simple3D hyperviscosity model of the form
70
     !> D_hyper3D * (|kperp|/ max |kperp|)^P_hyper3D 
71
     !> and ky_cut, kx_cut set max |kperp|
72
     real :: d_hyper3d = -10.
73
     !> Sets hyperresistivity parameter multiplying damping term.
74
     real :: d_hyperres = -10.0
75
     !> Sets hyperviscosity parameter multiplying damping term. See
76
     !> [E. Belli (2006)
77
     !> thesis](https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=50BFD54A8F8D72FC225D025FDEDFFFA5?doi=10.1.1.706.9568&rep=rep1&type=pdf)
78
     !> for more information.
79
     real :: d_hypervisc = -10.0
80
     !> If `true` then hyperdissipation only applied to the zonal
81
     !> mode.
82
     logical :: damp_zonal_only = .false.
83
     !> If `true` (default) then set wavenumber parameters entering
84
     !> the models based on the maximum `ky` and `kx` included in the
85
     !> current simulation. If `false` then these values are set to 1.
86
     logical :: gridnorm = .true.
87
     !> Selects the type of hyper terms included. Should be one of
88
     !>
89
     !> - 'default' -- no hyper terms included.
90
     !> - 'none' -- the same as default.
91
     !> - 'visc_only' -- only hyperviscosity included.
92
     !> - 'res_only' -- only hyperresistivity included.
93
     !> - 'both' -- both viscosity and resistivity included.
94
     !> - 'simple3D' -- simple hyperviscous dissipation rate of the
95
     !>    form D_hyper3D * (|kperp|/ max |kperp|)^P_hyper3D
96
     !>    described in [���Multiscale turbulence in magnetic
97
     !>    confinement fusion devices���, M. Hardman, DPhil Thesis,
98
     !>    appendix
99
     !>    B.4](https://ora.ox.ac.uk/objects/uuid:233a22cb-3c8b-4fe0-a689-4a37d8fe0314)
100
     !>    note that the dissipation in this version is applied to g, not h, as
101
     !>    in the reference. 
102
     character(len = 9) :: hyper_option = 'default'
103
     !> Not used.
104
     !>
105
     !> @todo Remove this variable.
106
     logical :: include_kpar = .false.
107
     !> if true damp zonal and drift waves with same dissipation formula
108
     logical :: isotropic_model = .true.
109
     !> If `true` then use isotropic shear model.
110
     logical :: isotropic_shear = .true.
111
     !> Used with the simple3D hyperviscosity model of the form
112
     !> D_hyper3D * (|kperp|/ max |kperp|)^P_hyper3D 
113
     !> and ky_cut, kx_cut set max |kperp|
114
     real :: kx_cut = -10.
115
     !> Used with the simple3D hyperviscosity model of the form
116
     !> D_hyper3D * (|kperp|/ max |kperp|)^P_hyper3D 
117
     !> and ky_cut, kx_cut set max |kperp|
118
     real :: ky_cut = -10.
119
     !> Sets the power to which \(k_\bot^2\) is raised in the dissipation filter.
120
     integer :: nexp = 2
121
     !> Sets a parameter in the anisotropic shearing rate calculation.
122
     real :: omega_osc = 0.4
123
     !> Used with the simple3D hyperviscosity model of the form
124
     !> D_hyper3D * (|kperp|/ max |kperp|)^P_hyper3D 
125
     !> and ky_cut, kx_cut set max |kperp|
126
     real :: p_hyper3d = 4.
127
   contains
128
     procedure, public :: read => read_hyper_config
129
     procedure, public :: write => write_hyper_config
130
     procedure, public :: reset => reset_hyper_config
131
     procedure, public :: broadcast => broadcast_hyper_config
132
     procedure, public, nopass :: get_default_name => get_default_name_hyper_config
133
     procedure, public, nopass :: get_default_requires_index => get_default_requires_index_hyper_config
134
  end type hyper_config_type
135

136
  type(hyper_config_type) :: hyper_config
137
  
138
contains
139

140
  !> FIXME : Add documentation
141
  subroutine check_hyper(report_unit)
×
142
    implicit none
143
    integer, intent(in) :: report_unit
144
    select case (hyper_option_switch)
×
145
    case (hyper_option_none)
146
       if (D_hyperres > 0.) then
×
147
          write (report_unit, *) 
×
148
          write (report_unit, fmt="('################# WARNING #######################')")
×
149
          write (report_unit, fmt="('hyper_option = ',a,' chooses no hyperresistivity.  &
150
               &D_hyperres ignored.')") trim(hyper_option)
×
151
          write (report_unit, fmt="('################# WARNING #######################')")
×
152
          write (report_unit, *) 
×
153
          D_hyperres = -10.
×
154
       end if
155
       if (D_hypervisc > 0.) then
×
156
          write (report_unit, *) 
×
157
          write (report_unit, fmt="('################# WARNING #######################')")
×
158
          write (report_unit, fmt="('hyper_option = ',a,' chooses no hyperviscosity.  &
159
               &D_hypervisc ignored.')") trim(hyper_option)
×
160
          write (report_unit, fmt="('################# WARNING #######################')")
×
161
          write (report_unit, *) 
×
162
          D_hypervisc = -10.
×
163
       endif
164

165
    case (hyper_option_visc)
166
       hyper_on = .true.
×
167
       if (D_hyperres > 0.) then
×
168
          write (report_unit, *) 
×
169
          write (report_unit, fmt="('################# WARNING #######################')")
×
170
          write (report_unit, fmt="('hyper_option = ',a,' chooses no hyperresistivity.  &
171
               &D_hyperres ignored.')") trim(hyper_option)
×
172
          write (report_unit, fmt="('################# WARNING #######################')")
×
173
          write (report_unit, *) 
×
174
          D_hyperres = -10.
×
175
       end if
176
       if (D_hypervisc < 0.) then
×
177
          write (report_unit, *) 
×
178
          write (report_unit, fmt="('################# WARNING #######################')")
×
179
          write (report_unit, fmt="('hyper_option = ',a,' chooses hyperviscosity but &
180
               &D_hypervisc < 0.')") trim(hyper_option)
×
181
          write (report_unit, fmt="('No hyperviscosity used.')")
×
182
          write (report_unit, fmt="('################# WARNING #######################')")
×
183
          write (report_unit, *) 
×
184
          hyper_on = .false.
×
185
       endif
186

187
    case (hyper_option_res)
188
       hyper_on = .true.
×
189
       if (D_hyperres < 0.) then
×
190
          write (report_unit, *) 
×
191
          write (report_unit, fmt="('################# WARNING #######################')")
×
192
          write (report_unit, fmt="('hyper_option = ',a,' chooses hyperresistivity but D_hyperres < 0.')") trim(hyper_option)
×
193
          write(report_unit, fmt="('No hyperresistivity used.')")
×
194
          write (report_unit, fmt="('################# WARNING #######################')")
×
195
          write (report_unit, *) 
×
196
          hyper_on = .false.
×
197
       end if
198
       if (D_hypervisc > 0.) then
×
199
          write (report_unit, *) 
×
200
          write (report_unit, fmt="('################# WARNING #######################')")
×
201
          write (report_unit, fmt="('hyper_option = ',a,' chooses no hyperviscosity.  D_hypervisc ignored.')") trim(hyper_option)
×
202
          write (report_unit, fmt="('################# WARNING #######################')")
×
203
          write (report_unit, *) 
×
204
          D_hypervisc = -10.
×
205
       endif
206

207
    case (hyper_option_both)
208
       hyper_on = .true.
×
209
       if (D_hyperres < 0.) then
×
210
          write (report_unit, *) 
×
211
          write (report_unit, fmt="('################# WARNING #######################')")
×
212
          write (report_unit, fmt="('hyper_option = ',a,' chooses hyperresistivity but D_hyperres < 0.')") trim(hyper_option)
×
213
          write (report_unit, fmt="('No hyperresistivity used.')")
×
214
          write (report_unit, fmt="('################# WARNING #######################')")
×
215
          write (report_unit, *) 
×
216
       end if
217
       if (D_hypervisc < 0.) then
×
218
          write (report_unit, *) 
×
219
          write (report_unit, fmt="('################# WARNING #######################')")
×
220
          write (report_unit, fmt="('hyper_option = ',a,' chooses hyperviscosity but D_hypervisc < 0.')") trim(hyper_option)
×
221
          write (report_unit, fmt="('No hyperviscosity used.')")
×
222
          write (report_unit, fmt="('################# WARNING #######################')")
×
223
          write (report_unit, *) 
×
224
       endif
225
       if (D_hypervisc < 0. .and. D_hyperres < 0.) hyper_on = .false.
×
226

227
    end select
228

229
    if (hyper_on) then
×
230
       write (report_unit, *) 
×
231
       write (report_unit, fmt="('------------------------------------------------------------')")
×
232
       write (report_unit, *) 
×
233

234
       select case (hyper_option_switch)
×
235

236
       case (hyper_option_visc)
237

238
          write (report_unit, *) 
×
239
          write (report_unit, fmt="('Hyperviscosity included without hyperresistivity.')")
×
240
          if (const_amp) then
×
241
             write (report_unit, fmt="('Damping rate is ',e11.4,' at highest k_perp.')") D_hypervisc
×
242
          else
243
             write (report_unit, fmt="('The damping coefficent is ',e11.4)") D_hypervisc
×
244
             write (report_unit, fmt="('The damping rate is proportional to the RMS amplitude of the turbulence.')")
×
245
          end if
246
          if (isotropic_shear) then
×
247
             write (report_unit, fmt="('The hyperviscosity is isotropic in the perpendicular plane.')")
×
248
             write (report_unit, fmt="('This is appropriate for MHD-like calculations.')")
×
249
          else
250
             write (report_unit, fmt="('The hyperviscosity is anisotropic in the perpendicular plane.')")
×
251
             write (report_unit, fmt="('This is appropriate for drift-type calculations.')")
×
252
             write (report_unit, fmt="('omega_osc = ',e11.4)") omega_osc
×
253
          end if
254

255
       case (hyper_option_res)
256

257
          write (report_unit, *) 
×
258
          write (report_unit, fmt="('Hyperresistivity included without hyperviscosity.')")
×
259
          if (const_amp) then
×
260
             write (report_unit, fmt="('Damping rate is ',e11.4,' at highest k_perp.')") D_hyperres
×
261
          else
262
             write (report_unit, fmt="('################# WARNING #######################')")
×
263
             write (report_unit, fmt="('const_amp = .false. is not implemented for hyperresistivity.')")
×
264
             write (report_unit, fmt="('################# WARNING #######################')")
×
265
             write (report_unit, *) 
×
266
          end if
267
          if (isotropic_shear) then
×
268
             write (report_unit, fmt="('The hyperresistivity is isotropic in the perpendicular plane.')")
×
269
             write (report_unit, fmt="('This is appropriate for MHD-like calculations.')")
×
270
          else
271
             write (report_unit, fmt="('################# WARNING #######################')")
×
272
             write (report_unit, fmt="('isotropic_shear = .false. is not implemented for hyperresistivity.')")
×
273
             write (report_unit, fmt="('################# WARNING #######################')")
×
274
             write (report_unit, *) 
×
275
          end if
276

277
       case (hyper_option_both)
278

279
          write (report_unit, *) 
×
280
          write (report_unit, fmt="('Hyperresistivity and hyperviscosity included.')")
×
281
          if (const_amp) then
×
282
             write (report_unit, fmt="('Damping rate is ',e11.4,' at highest k_perp.')") D_hyperres
×
283
          else
284
             write (report_unit, fmt="('################# WARNING #######################')")
×
285
             write (report_unit, fmt="('const_amp = .false. is not implemented for hyperresistivity.')")
×
286
             write (report_unit, fmt="('THIS IS AN ERROR.')")
×
287
             write (report_unit, fmt="('################# WARNING #######################')")
×
288
             write (report_unit, *) 
×
289
          end if
290
          if (isotropic_shear) then
×
291
             write (report_unit, fmt="('The damping is isotropic in the perpendicular plane.')")
×
292
             write (report_unit, fmt="('This is appropriate for MHD-like calculations.')")
×
293
          else
294
             write (report_unit, fmt="('################# WARNING #######################')")
×
295
             write (report_unit, fmt="('isotropic_shear = .false. is not implemented for hyperresistivity.')")
×
296
             write (report_unit, fmt="('THIS IS AN ERROR.')")
×
297
             write (report_unit, fmt="('################# WARNING #######################')")
×
298
             write (report_unit, *) 
×
299
          end if
300
       end select
301
    end if
302
  end subroutine check_hyper
×
303

304
  !> FIXME : Add documentation
305
  subroutine wnml_hyper(unit)
×
306
    implicit none
307
    integer, intent(in) :: unit          
308
    if (.not. hyper_on) return
×
309
    write (unit, *)
×
310
    write (unit, fmt="(' &',a)") "hyper_knobs"
×
311

312
    select case (hyper_option_switch)
×
313

314
    case (hyper_option_visc) 
315
       write (unit, fmt="(' hyper_option = ',a)") '"visc_only"'
×
316
       write (unit, fmt="(' D_hypervisc = ',e17.10)") D_hypervisc
×
317

318
    case (hyper_option_res) 
319
       write (unit, fmt="(' hyper_option = ',a)") '"res_only"'
×
320
       write (unit, fmt="(' D_hyperres = ',e17.10)") D_hyperres
×
321

322
    case (hyper_option_both) 
323
       write (unit, fmt="(' hyper_option = ',a)") '"both"'
×
324
       if (D_hyperres == D_hypervisc) then
×
325
          write (unit, fmt="(' D_hyper = ',e17.10)") D_hyper
×
326
       else
327
          write (unit, fmt="(' D_hypervisc = ',e17.10)") D_hypervisc
×
328
          write (unit, fmt="(' D_hyperres = ',e17.10)") D_hyperres
×
329
       end if
330
    end select
331

332
    select case (hyper_option_switch)
×
333
    
334
    case (hyper_option_visc, hyper_option_res, hyper_option_both)
335
!    write (unit, fmt="(' include_kpar = ',L1)") include_kpar
336
    
337
    write (unit, fmt="(' const_amp = ',L1)") const_amp
×
338
    write (unit, fmt="(' isotropic_shear = ',L1)") isotropic_shear
×
339
    if (.not. isotropic_shear) &
×
340
         write (unit, fmt="(' omega_osc = ',e17.10)") omega_osc
×
341

342
    write (unit, fmt="(' gridnorm = ',L1)") gridnorm
×
343
    write (unit, fmt="(' /')")
×
344
    
345
    case (hyper_option_simple3D)
346
    write (unit, fmt="(' hyper_option = ',a)") '"simple3D"'
×
347
    write (unit, fmt="(' D_hyper3D = ',e17.10)") D_hyper3D
×
348
    write (unit, fmt="(' P_hyper3D = ',e17.10)") P_hyper3D
×
349
    if (ky_cut > 0.) &
×
350
         write (unit, fmt="(' ky_cut = ',e17.10)") ky_cut
×
351
    if (kx_cut > 0.) &
×
352
         write (unit, fmt="(' kx_cut = ',e17.10)") kx_cut
×
353
    write (unit, fmt="(' isotropic_model = ',L1)") isotropic_model
×
354
    write (unit, fmt="(' /')")
×
355
        
356
    end select
357
  end subroutine wnml_hyper
358

359
  !> FIXME : Add documentation
360
  subroutine init_hyper(hyper_config_in)
×
361
    use kt_grids, only: ntheta0, naky, akx, aky
362
    use kt_grids, only: kperp2 ! MRH
363
    use theta_grid, only: gds2, gds21, gds22, shat ! MRH
364
    use gs2_time, only: code_dt
365
    use gs2_layouts, only: init_gs2_layouts
366
    implicit none
367
    type(hyper_config_type), intent(in), optional :: hyper_config_in        
368
    integer :: ik, it
369

370
    if (initialized) return
×
371
    initialized = .true.
×
372
    
373
    call init_gs2_layouts
×
374
    call read_parameters(hyper_config_in)
×
375
    call allocate_arrays
×
376

377
    ! Initialise module level variables
378
    D_v = 0
×
379
    D_eta = 0
×
380

381
    select case (hyper_option_switch)
×
382
        case(hyper_option_both, hyper_option_res, hyper_option_visc)
383
    
384
        ! Define variables used in hyperviscosity and hyperresistivity models
385

386
            if (gridnorm) then
×
387
               akx4_max    = akx(ntheta0/2 + 1) ** (2*nexp)
×
388
               aky_max     = aky(naky)
×
389
               aky4_max     = aky(naky) ** (2*nexp)
×
390
               akperp4_max = ( akx(ntheta0/2 + 1) ** 2  +  aky(naky) ** 2) ** (nexp)
×
391
            else
392
               akx4_max = 1.
×
393
               aky_max = 1.
×
394
               aky4_max = 1.
×
395
               akperp4_max = 1.
×
396
            end if
397

398
        ! Get D_res set up if needed
399

400
            if (D_hyperres > 0.) then
×
401
               do ik = 1, naky
×
402
                  do it = 1, ntheta0
×
403
                     D_res(it, ik) = D_hyperres*code_dt &
×
404
                          * (aky(ik)**2 + akx(it)**2)**nexp/akperp4_max
×
405
                  end do
406
               end do
407
               D_eta = D_hyperres/akperp4_max
×
408
            else
409
               D_res = 0.
×
410
               D_eta = 0.
×
411
            end if
412

413
            if (D_hypervisc > 0.) then
×
414
               D_v = D_hypervisc/akperp4_max
×
415
            else
416
               D_v = 0.
×
417
            end if
418
            
419
        case(hyper_option_simple3D)  ! MRH
420
            ! Make the default cut-offs the grid scale
421
            if(.not. ky_cut > 0.) ky_cut = aky(naky)
×
422
            if(.not. kx_cut > 0.) kx_cut = akx((ntheta0+1)/2)
×
423
            
424
            kperp2_max = maxval(ky_cut*ky_cut*gds2(:) + &
×
425
                              2.0*ky_cut*kx_cut*gds21(:)/shat + &
×
426
                              kx_cut*kx_cut*gds22/(shat*shat))
×
427
            if (isotropic_model) then 
×
428
                kperp2_max_zonal = kperp2_max
×
429
            else 
430
                kperp2_max_zonal = maxval(kx_cut*kx_cut*gds22/(shat*shat))
×
431
            endif
432
            ! Calculate the filter
433
            ik =1  ! Zonal modes
×
434
            do it = 1, ntheta0
×
435
                 hypervisc_filter(:,it,ik) = exp(- ( D_hyper3D * code_dt * &
×
436
               ( kperp2(:,it,ik)/kperp2_max_zonal )**(P_hyper3D/2.0)) ) 
×
437
            end do
438
              
439
            do ik = 2, naky ! Non-zonal modes
×
440
              do it = 1, ntheta0
×
441
                 hypervisc_filter(:,it,ik) = exp(- ( D_hyper3D * code_dt * &
×
442
               ( kperp2(:,it,ik)/kperp2_max )**(P_hyper3D/2.0)) ) 
×
443
              end do
444
            end do
445

446
                    
447
    end select
448

449
  end subroutine init_hyper
450

451
  !> FIXME : Add documentation
452
  subroutine read_parameters(hyper_config_in)
×
453
    use file_utils, only: error_unit
454
    use text_options, only: text_option, get_option_value
455
    use mp, only: proc0
456
    implicit none
457
    type(hyper_config_type), intent(in), optional :: hyper_config_in    
458
    type (text_option), dimension(6), parameter :: hyperopts = &
459
         (/ text_option('default', hyper_option_none), &
460
            text_option('none', hyper_option_none), &
461
            text_option('visc_only', hyper_option_visc), &
462
            text_option('res_only', hyper_option_res), &
463
            text_option('both', hyper_option_both), &            
464
            text_option('simple3D', hyper_option_simple3D) /)
465
    integer :: ierr
466

467
    if (present(hyper_config_in)) hyper_config = hyper_config_in
×
468

469
    call hyper_config%init(name = 'hyper_knobs', requires_index = .false.)
×
470

471
    ! Copy out internal values into module level parameters
472
    associate(self => hyper_config)
473
#include "hyper_copy_out_auto_gen.inc"
474
    end associate
475
    
476
    ierr = error_unit()
×
477
    
478
    call get_option_value &
479
         (hyper_option, hyperopts, hyper_option_switch, &
480
         ierr, "hyper_option in hyper_knobs",.true.)
×
481
    
482
    if (.not. isotropic_shear .and. nexp /=2) then
×
483
       if (proc0) write (ierr, *) 'Forcing nexp = 2.  Higher values not implemented for anisotropic shear model.'
×
484
       nexp = 2
×
485
    end if
486

487
    
488
    select case (hyper_option_switch)
×
489

490
    case (hyper_option_none)
491
       if (D_hyperres > 0.) then
×
492
          if (proc0) write(ierr, *) 'hyper_option = ',hyper_option, &
×
493
               ' chooses no hyperresistivity.  D_hyperres ignored.'
×
494
          D_hyperres = -10.
×
495
       end if
496
       if (D_hypervisc > 0.) then
×
497
          if (proc0) write(ierr, *) 'hyper_option = ',hyper_option, &
×
498
               ' chooses no hyperviscosity.  D_hypervisc ignored.'
×
499
          D_hypervisc = -10.
×
500
       endif
501

502
    case (hyper_option_visc)
503
       hyper_on = .true.
×
504
       if (proc0) write (ierr, *) 'WARNING: It is inconsistent to set D_hypervisc different from ', &
×
505
            'D_hyperres.  Recommend: Set them equal.'
×
506
       if (D_hyperres > 0.) then
×
507
          if (proc0) write(ierr, *) 'hyper_option = ',hyper_option, &
×
508
               ' chooses no hyperresistivity.  D_hyperres ignored.'
×
509
          D_hyperres = -10.
×
510
       end if
511
       if (D_hypervisc < 0.) then
×
512
          if (proc0) then
×
513
             write(ierr, *) 'hyper_option = ',hyper_option, &
×
514
                  ' chooses hyperviscosity but D_hypervisc < 0 is illegal.'
×
515
             write(ierr, *) 'No hyperviscosity used.'
×
516
          end if
517
          hyper_on = .false.
×
518
       endif
519

520
    case (hyper_option_res)
521
       hyper_on = .true.
×
522
       if (proc0) write (ierr, *) 'WARNING: It is inconsistent to set D_hypervisc different from ', &
×
523
            'D_hyperres.  Recommend: Set them equal.'
×
524
       if (D_hyperres < 0.) then
×
525
          if (proc0) then
×
526
             write(ierr, *) 'hyper_option = ',hyper_option, &
×
527
                  ' chooses hyperresistivity but  D_hyperres < 0 is illegal.'
×
528
             write(ierr, *) 'No hyperresistivity used.'
×
529
          end if
530
          hyper_on = .false.
×
531
       end if
532
       if (D_hypervisc > 0.) then
×
533
          if (proc0) write(ierr, *) 'hyper_option = ',hyper_option, &
×
534
               ' chooses no hyperviscosity.  D_hypervisc ignored.'
×
535
          D_hypervisc = -10.
×
536
       endif
537

538
    case (hyper_option_both)
539
       hyper_on = .true.
×
540

541
       if (D_hyper < 0.) then
×
542
          if (D_hyperres /= D_hyperres) then
×
543
             if (proc0) write (ierr, *) 'WARNING: It is inconsistent to set D_hypervisc different from ', &
×
544
                  'D_hyperres.  Recommend: Set them equal.'
×
545
          end if
546
       else
547
          if (proc0) write (ierr, *) 'WARNING: Setting D_hypervisc = D_hyperres, each to value of D_hyper'
×
548
          D_hyperres  = D_hyper
×
549
          D_hypervisc = D_hyper
×
550
       end if
551

552
       if (D_hyperres < 0.) then
×
553
          if (proc0) then
×
554
             write(ierr, *) 'hyper_option = ',hyper_option, &
×
555
                  ' chooses hyperresistivity but  D_hyperres < 0 is illegal.'
×
556
             write(ierr, *) 'No hyperresistivity used.'
×
557
          end if
558
       end if
559
       if (D_hypervisc < 0.) then
×
560
          if (proc0) then
×
561
             write(ierr, *) 'hyper_option = ',hyper_option, &
×
562
                  ' chooses hyperviscosity but D_hypervisc < 0 is illegal.'
×
563
             write(ierr, *) 'No hyperviscosity used.'
×
564
          end if
565
       endif
566
       if (D_hypervisc < 0. .and. D_hyperres < 0.) hyper_on = .false.
×
567

568
    case (hyper_option_simple3D) ! MRH
569
       hyper_on = .true.
×
570

571
       if (P_hyper3D < 4.) then
×
572
          hyper_on = .false.
×
573
          if(proc0) write(ierr, *) 'hyper_option = ',hyper_option, &
×
574
               ' chooses a simple hyperviscous filter but  P_hyper3D < 4. is illegal.'
×
575
          if(proc0) write(ierr, *) 'No hyperviscosity used.'
×
576
       endif
577

578
       if (D_hyper3D < 0.) then
×
579
          hyper_on = .false.
×
580
          if(proc0) write(ierr, *) 'hyper_option = ',hyper_option, &
×
581
               ' chooses a simple hyperviscous filter but  D_hyper3D < 0 is illegal.'
×
582
          if(proc0) write(ierr, *) 'No hyperviscosity used.'
×
583
       endif
584
    end select
585
  end subroutine read_parameters
×
586

587
  !> FIXME : Add documentation
588
  subroutine allocate_arrays
×
589
    use theta_grid, only: ntgrid
590
    use kt_grids, only: ntheta0, naky
591
    implicit none
592

593
    if (.not. allocated(D_res)) then
×
594
       allocate (D_res(ntheta0, naky)) 
×
595
    endif
596
    if (.not. allocated(hypervisc_filter)) then
×
597
       allocate (hypervisc_filter(-ntgrid:ntgrid,ntheta0,naky)) ; hypervisc_filter = 1.0
×
598
    end if
599
    D_res = 0.
×
600
    
601
  end subroutine allocate_arrays
×
602

603
  !> FIXME : Add documentation
604
  subroutine hyper_diff (g0, phi)
×
605

606
    use gs2_layouts, only: ik_idx, it_idx, is_idx
607
    use theta_grid, only: ntgrid
608
    use gs2_time, only: code_dt
609
    use gs2_layouts, only: g_lo
610
    use kt_grids, only: aky, akx, naky, ntheta0
611

612
    implicit none
613
    complex, dimension (-ntgrid:,:,g_lo%llim_proc:), intent (in out) :: g0
614
    complex, dimension (-ntgrid:,:,:), intent (in) :: phi
615

616
    real, dimension (-ntgrid:ntgrid) :: shear_rate_nz, shear_rate_z, shear_rate_z_nz
×
617

618
    integer :: iglo, ik, it
619
 
620
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
621
!
622
! Includes models by Belli and Hammett
623
! to calculate the x-y avged shearing rate
624
! S(theta)^2 = <|grad_perp|^4 |phi|^2> 
625
!            =  sum_over_k(kperp^4 * |phi|^2)
626
!               (times crazy fac factor due to FFT conventions.)
627
!
628
! and to implement this anisotropically in k_perp, taking into 
629
! account properties of zonal flows.
630
!
631
! Begun December 2001
632
!
633
! Number conservation added April 2006
634
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
635

636
    if (.not. hyper_on) return
×
637
    
638
    select case (hyper_option_switch)
×
639
        case(hyper_option_both, hyper_option_res, hyper_option_visc)
640
            
641
            if (D_hypervisc < 0.) return
×
642

643
            if(isotropic_shear) then
×
644
               call iso_shear
×
645
            else
646
               call aniso_shear
×
647
            end if
648
            
649
        case(hyper_option_simple3D) ! MRH
650
            
651
            call simple3Dfilter
×
652
            
653
    end select    
654

655
  contains
656
    !> FIXME : Add documentation
657
    subroutine simple3Dfilter
×
658
    
659
        implicit none
660
        
661
        do iglo = g_lo%llim_proc, g_lo%ulim_alloc
×
662
         ik = ik_idx(g_lo, iglo)
×
663
         it = it_idx(g_lo, iglo)
×
664
                  
665
         g0(:,1,iglo) = g0(:,1,iglo) * hypervisc_filter(:,it,ik)
×
666
         g0(:,2,iglo) = g0(:,2,iglo) * hypervisc_filter(:,it,ik)
×
667
        end do
668
      
669
    end subroutine simple3Dfilter
×
670

671
    !> FIXME : Add documentation
672
    subroutine aniso_shear
×
673

674
      real, dimension(naky) :: fac
×
675
      
676
! Do the Belli-Hammett anisotropic calculation 
677
! which accounts for some zonal/non-zonal differences
678
       
679
      fac = 0.5
×
680
      fac(1) = 1.0
×
681
         
682
! shearing rate due to non-zonal modes (on nonzonal modes)
683
      shear_rate_nz = 0.
×
684
      do ik = 2, naky
×
685
         do it = 1, ntheta0
×
686
            shear_rate_nz(:) = shear_rate_nz(:) + real(conjg(phi(:,it,ik)) * &
×
687
                 phi(:,it,ik)) * (akx(it)**2 + aky(ik)**2)**2 * fac(ik)
×
688
         end do
689
      end do
690
      shear_rate_nz = 0.5 * ( -omega_osc + (omega_osc ** 2 + 2 * shear_rate_nz) ** 0.5 )
×
691
       
692
! shearing rate due to zonal modes (on nonzonal modes)
693
      shear_rate_z = 0.
×
694
      do ik = 1, 1
×
695
         do it = 1, ntheta0
×
696
            shear_rate_z(:) = shear_rate_z(:) + real(conjg(phi(:,it,ik)) * &
×
697
                 phi(:,it,ik)) * (akx(it)**2 + aky(ik)**2)**2 * fac(ik)
×
698
         end do
699
      end do
700
! shear_rate_z = shear_rate_z ** 0.5
701
      shear_rate_z = 0.5 * ( -omega_osc + (omega_osc ** 2 + 2 * shear_rate_z) ** 0.5 )
×
702
      
703
! shearing rate due to nonzonal modes (on zonal modes)
704
      shear_rate_z_nz = 0.
×
705
      do ik = 2, naky
×
706
         do it = 1, ntheta0
×
707
            shear_rate_z_nz(:) = shear_rate_z_nz(:) + real(conjg(phi(:,it,ik)) * &
×
708
                 phi(:,it,ik)) *  aky(ik)**4 * fac(ik)
×
709
         end do
710
      end do
711
! shear_rate_z_nz = shear_rate_z_nz ** 0.5
712
      shear_rate_z_nz = 0.5 * ( -omega_osc + (omega_osc ** 2 + 2 * shear_rate_z_nz) ** 0.5 )
×
713
       
714
! end of anisotropic shearing rate calculations
715
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
716

717
      do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
718
         ik = ik_idx(g_lo, iglo)
×
719
         it = it_idx(g_lo, iglo)
×
720
         
721
         if(aky(ik) == 0.) then
×
722
            hypervisc_filter(:,it,ik) = exp(- (D_hypervisc * code_dt &
×
723
                 * ( shear_rate_z_nz(:) * akx(it) ** 4 / akx4_max )))
×
724
         else
725
            hypervisc_filter(:,it,ik) = exp(- ( D_hypervisc * code_dt & 
×
726
                 * ( shear_rate_nz(:) *  (aky(ik) ** 2 + akx(it) ** 2 )**nexp / akperp4_max & 
×
727
                 + shear_rate_z(:) * akx(it) ** 4/ akx4_max * aky(ik) / aky_max )))
×
728
         endif
729
         
730
         g0(:,1,iglo) = g0(:,1,iglo) * hypervisc_filter(:,it,ik)
×
731
         g0(:,2,iglo) = g0(:,2,iglo) * hypervisc_filter(:,it,ik)
×
732
      end do
733
    
734
    end subroutine aniso_shear
×
735

736
    !> FIXME : Add documentation
737
    subroutine iso_shear
×
738

739
      real, dimension(naky) :: fac
×
740
      
741
      if (const_amp) then
×
742
         shear_rate_nz = 1.
×
743
      else
744
         fac = 0.5
×
745
         fac(1) = 1.0
×
746
         shear_rate_nz = 0.
×
747
         do ik = 1, naky
×
748
            do it = 1, ntheta0
×
749
               shear_rate_nz(:) = shear_rate_nz(:) &
×
750
                    + real(conjg(phi(:,it,ik))*phi(:,it,ik)) &
×
751
                    * (akx(it)**2 + aky(ik)**2)**2 * fac(ik)
×
752
            end do
753
         end do
754
         shear_rate_nz = shear_rate_nz**0.5
×
755
      end if
756

757
      do iglo = g_lo%llim_proc, g_lo%ulim_proc
×
758
         ik = ik_idx(g_lo, iglo)
×
759
         it = it_idx(g_lo, iglo)
×
760
         if (damp_zonal_only .and. .not. aky(ik)==epsilon(0.0)) cycle
×
761
         hypervisc_filter(:,it,ik) = exp(- ( D_hypervisc * code_dt &
×
762
              * ( shear_rate_nz(:) *  (aky(ik) ** 2 + akx(it) ** 2 )**nexp / akperp4_max)))
×
763
         
764
         g0(:,1,iglo) = g0(:,1,iglo) * hypervisc_filter(:,it,ik)
×
765
         g0(:,2,iglo) = g0(:,2,iglo) * hypervisc_filter(:,it,ik)
×
766
      end do
767
      
768
    end subroutine iso_shear
×
769

770
  end subroutine hyper_diff
771

772
  !> FIXME : Add documentation
773
  subroutine finish_hyper
×
774

775
    implicit none
776

777
    hyper_on = .false.
×
778
    initialized = .false.
×
779
    if (allocated(D_res)) deallocate (D_res)
×
780
    if (allocated(hypervisc_filter)) deallocate (hypervisc_filter)
×
781

782
    call hyper_config%reset()
×
783
  end subroutine finish_hyper
×
784

785
#include "hyper_auto_gen.inc"
786
end module hyper
×
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