PB3D [2.47]
Ideal linear high-n MHD stability in 3-D
Loading...
Searching...
No Matches
driver_sol.f90
Go to the documentation of this file.
1!------------------------------------------------------------------------------!
2!> Driver of the solution part of PB3D.
3!------------------------------------------------------------------------------!
5#include <PB3D_macros.h>
6#include <wrappers.h>
8 use output_ops
9 use messages
10 use num_vars, only: dp, pi, max_str_ln, iu
11 use grid_vars, only: grid_type
12 use x_vars, only: x_2_type, modes_type, &
14 use vac_vars, only: vac_type
15 use sol_vars, only: sol_type
16
17 implicit none
18 private
19 public run_driver_sol
20
21 ! global variables
22#if ldebug
23 logical :: debug_run_driver_sol = .false. !< debug information for run_driver_sol \ldebug
24 logical :: debug_interp_V = .false. !< debug information for interp_v \ldebug
25 integer :: ivs_stats(3) !< statistics of interp_v_spline (copy, linear, spline)
26#endif
27
28contains
29 !> Main driver of PB3D solution part.
30 !!
31 !! - sets up:
32 !! * \c grid_sol (only first Richardson level)
33 !! * \c sol
34 !! - writes to HDF5:
35 !! * \c grid_sol (only first Richardson level)
36 !! * \c sol
37 !! - deallocates:
38 !! * sol before setting up (but after guess)
39 !!
40 !! \return ierr
41 integer function run_driver_sol(grid_eq,grid_X,grid_sol,X,vac,sol) &
42 &result(ierr)
43
46 use grid_vars, only: n_r_sol, n_alpha
51 use sol_ops, only: print_output_sol
52 use rich_vars, only: rich_lvl
53 use rich_ops, only: calc_rich_ex
55 use grid_utilities, only: trim_grid
57#if ldebug
58 use x_ops, only: print_debug_x_2
59#endif
60
61 character(*), parameter :: rout_name = 'run_driver_sol'
62
63 ! input / output
64 type(grid_type), intent(in) :: grid_eq !< equilibrium grid
65 type(grid_type), intent(in), target :: grid_x !< perturbation grid
66 type(grid_type), intent(inout) :: grid_sol !< solution grid
67 type(x_2_type), intent(in) :: x !< integrated tensorial perturbation variables
68 type(vac_type), intent(inout) :: vac !< vacuum variables
69 type(sol_type), intent(inout) :: sol !< solution variables
70
71 ! local variables
72 type(grid_type) :: grid_sol_trim ! trimmed solution grid
73 type(grid_type) :: grid_x_rdst ! redistributed perturbation grid
74 type(grid_type) :: grid_x_sol ! perturbation grid with solution normal part
75 type(x_2_type) :: x_rdst ! redistributed X
76 type(x_2_type) :: x_sol ! interpolated X
77 integer :: sol_limits(2) ! min. and max. index of sol grid for this process
78 integer :: rich_lvl_name ! either the Richardson level or zero, to append to names
79 real(dp), allocatable :: r_f_sol(:) ! normal points in solution grid
80 logical :: do_vac_ops ! whether specific calculations for vacuum are necessary
81 character(len=max_str_ln) :: err_msg ! error message
82
83 ! initialize ierr
84 ierr = 0
85
86 ! set up solution grid if first level
87 if (rich_lvl.eq.rich_restart_lvl) then
88 ! Divide solution grid under group processes, calculating the limits
89 ! and the normal coordinate.
90 allocate(r_f_sol(n_r_sol))
91 ierr = calc_norm_range('PB3D_sol',sol_limits=sol_limits,&
92 &r_f_sol=r_f_sol)
93 chckerr('')
94
95 if (rich_lvl.eq.1) then
96 call writo('Set up solution grid')
97 call lvl_ud(1)
98
99 call writo('Calculate the grid')
100 call lvl_ud(1)
101 ierr = setup_grid_sol(grid_eq,grid_x,grid_sol,r_f_sol,&
102 &sol_limits)
103 chckerr('')
104 call lvl_ud(-1)
105
106 call writo('Write to output file')
107 call lvl_ud(1)
108 ierr = print_output_grid(grid_sol,'solution','sol',&
109 &remove_previous_arrs=(jump_to_sol.and.&
110 &(x_grid_style.eq.1 .or. x_grid_style.eq.3)))
111 chckerr('')
112 call lvl_ud(-1)
113
114 ! set up modes
115 ierr = setup_modes(mds_sol,grid_eq,grid_sol,plot_name='sol')
116 chckerr('')
117
118 call lvl_ud(-1)
119 else
120 ! restore solution grid and trim it
121 ierr = reconstruct_pb3d_grid(grid_sol,'sol',&
122 &grid_limits=sol_limits)
123 chckerr('')
124 ierr = trim_grid(grid_sol,grid_sol_trim)
125 chckerr('')
126
127 ! set up modes
128 ierr = setup_modes(mds_sol,grid_eq,grid_sol,plot_name='sol')
129 chckerr('')
130
131 ! reconstruct solution on trimmed grid
132 ierr = reconstruct_pb3d_sol(mds_sol,grid_sol_trim,sol,'sol',&
134 chckerr('')
135
136 ! clean up
137 call grid_sol_trim%dealloc()
138 end if
139
140 deallocate(r_f_sol)
141 end if
142
143 ! set up whether Richardson level has to be appended to the name and
144 ! whether to do vacuum operations
145 select case (eq_style)
146 case (1) ! VMEC
147 rich_lvl_name = rich_lvl ! append richardson level
148 do_vac_ops = .true.
149 case (2) ! HELENA
150 rich_lvl_name = 0 ! do not append name
151 if (rich_lvl.eq.rich_restart_lvl) then
152 do_vac_ops = .true.
153 else
154 do_vac_ops = .false.
155 end if
156 end select
157
158 if (do_vac_ops) then
159 ! calculate vacuum
160 ierr = calc_vac_res(mds_sol,vac)
161 chckerr('')
162
163 call writo('Write to output file')
164 call lvl_ud(1)
165 chckerr('')
166 if (rank.eq.n_procs-1) then
167 ierr = print_output_vac(vac,'vac',rich_lvl=rich_lvl_name)
168 chckerr('')
169 end if
170 call lvl_ud(-1)
171 end if
172
173 ! initialize interpolated X
174 ierr = grid_x_sol%init([1,n_alpha,grid_sol%n(3)],&
175 &[grid_sol%i_min,grid_sol%i_max],grid_sol%divided)
176 chckerr('')
177 grid_x_sol%r_F = grid_sol%r_F
178 grid_x_sol%r_E = grid_sol%r_E
179 grid_x_sol%loc_r_F = grid_sol%loc_r_F
180 grid_x_sol%loc_r_E = grid_sol%loc_r_E
181
182
183 select case (x_grid_style)
184 case (1,3) ! equilibrium or enriched
185 ! user output
186 call writo('Redistribute and interpolate the perturbation &
187 &variables to solution grid')
188 call lvl_ud(1)
189
190 ! redistribute grid and X variables
191 ierr = redistribute_output_grid(grid_x,grid_x_rdst)
192 chckerr('')
193 ierr = redistribute_output_x(mds_x,grid_x,grid_x_rdst,x,x_rdst)
194 chckerr('')
195
196 ! initialize
197 call x_sol%init(mds_sol,grid_x_sol,is_field_averaged=.true.)
198
199 ! interpolate
200 ierr = interp_v(mds_x,grid_x_rdst,x_rdst,mds_sol,grid_x_sol,&
201 &x_sol)
202 chckerr('')
203
204 ! clean up
205 call x_rdst%dealloc()
206 call grid_x_rdst%dealloc()
207
208 call lvl_ud(-1)
209 case (2) ! solution
210 ! user output
211 call writo('Copy the perturbation variables to solution grid')
212 call lvl_ud(1)
213
214 ! copy
215 call x%copy(mds_sol,grid_x,x_sol)
216
217 call lvl_ud(-1)
218 end select
219
220#if ldebug
221 ! write integrated field-aligned tensorial perturbation quantities
222 ! to output and plot
223 if (debug_run_driver_sol) then
224 ierr = print_debug_x_2(mds_sol,grid_x_sol,x_sol)
225 chckerr('')
226 end if
227#endif
228
229 ! clean up
230 call grid_x_sol%dealloc()
231
232 ! solve the system
233 call writo('Solving the system')
234 call lvl_ud(1)
235 select case (ev_style)
236 case(1) ! SLEPC solver for EV problem
237 ! solve the system
238 ierr = solve_ev_system_slepc(mds_sol,grid_sol,x_sol,vac,sol)
239 chckerr('')
240 case default
241 err_msg = 'No EV solver style associated with '//&
242 &trim(i2str(ev_style))
243 ierr = 1
244 chckerr(err_msg)
245 end select
246 call lvl_ud(-1)
247 call writo('System solved')
248
249 ! write solution variables to output
250 ierr = print_output_sol(grid_sol,sol,'sol',rich_lvl=rich_lvl,&
251 &remove_previous_arrs=&
252 &(jump_to_sol.and.(x_grid_style.eq.1 .or. x_grid_style.eq.3)))
253 chckerr('')
254
255 ! calculate Richardson extrapolation factors if necessary
256 call calc_rich_ex(sol%val)
257
258 ! clean up
259 call x_sol%dealloc()
260 end function run_driver_sol
261
262 !> \public Interpolate tensorial perturbation quantities in the third
263 !! dimension.
264 !!
265 !! The input grid should not be divided, though the output grid can be.
266 !!
267 !! The procedure considers all possible mode number combinations. For \c
268 !! X_style 2 (fast), each secondary mode only lives in a certain normal
269 !! range of the plasma. Therefore, each secondary mode pair also has a
270 !! limited normal range, given by the overlap of the ranges of the members.
271 !!
272 !! The interpolated mode number combinations have a normal range that might
273 !! slightly differ from the input ranges, in which case extrapolation can be
274 !! done if the method allows for it.
275 !!
276 !! \note If the input grid is too coarse, but the interpolated grid is not,
277 !! it is in theory possible that there are mode numbers and therefore mode
278 !! number pairs that exist in the input grid, though they do so in the
279 !! interpolated grid. In this case, they can not be calculated and
280 !! are currently set to zero. However, the current implementation of
281 !! setup_modes() produces an error if less than the full range of mode
282 !! numbers is accurately present.
283 integer function interp_v(mds_i,grid_i,X_i,mds_o,grid_o,X_o) result(ierr)
285 use x_vars, only: n_mod_x
286 use num_vars, only: rank
287 use eq_vars, only: max_flux_f
288 use num_utilities, only: c
290!#if ldebug
291 !use num_vars, only: ex_plot_style
292!#endif
293
294 character(*), parameter :: rout_name = 'interp_V'
295
296 ! input / output
297 type(modes_type), intent(in), target :: mds_i !< general modes variables for input
298 type(grid_type), intent(in) :: grid_i !< grid at which \c X_i is tabulated
299 type(x_2_type), intent(in), target :: x_i !< tensorial perturbation variable on input grid
300 type(modes_type), intent(in), target :: mds_o !< general modes variables for output
301 type(grid_type), intent(in) :: grid_o !< grid at which \c X_o is interpolated
302 type(x_2_type), intent(inout), target :: x_o !< interpolated tensorial perturbation variable
303
304 ! local variables
305 integer :: kd ! counter
306 integer :: k, m ! counters for mode numbers
307 integer :: c_loc_i(2) ! local input c for symmetric and asymmetric variables
308 integer :: c_loc_o(2) ! local output c for symmetric and asymmetric variables
309 integer :: n_mod_tot ! total amount of modes
310 integer :: kdl_i(2), kdl_o(2) ! limits on normal index for a mode combination
311 integer :: id_lim_i(2), id_lim_o(2) ! limits on total modes
312 integer :: ivs_stat(6) ! local stats for interp_V_spline
313 integer, pointer :: sec_i_loc(:,:), sec_o_loc(:,:) ! pointers to secondary mode variables
314 real(dp), pointer :: r_i_loc(:), r_o_loc(:) ! local r_i and r_o for a mode combination
315 complex(dp), pointer :: v_i(:,:,:), v_o(:,:,:) ! pointers to input and output PV_i and KV_i
316 logical :: calc_this(2) ! whether this combination needs to be calculated
317 logical :: extrap = .true. ! whether extrapolation is used
318 character(len=max_str_ln) :: err_msg ! error message
319#if ldebug
320 integer :: km_id
321 integer, allocatable :: norm_ext_i(:,:) ! normal extent for input quantity mode combinations
322 real(dp), allocatable :: r_loc_tot(:,:,:) ! r_i_loc and r_o_loc for all combinations
323 character(len=max_str_ln) :: ivs_stats_names(3) ! names used in interp_V_spline statistics
324 !complex(dp), allocatable :: V_plot(:,:) ! for debug plotting of interpolated V
325#endif
326
327 ! initialize ierr
328 ierr = 0
329
330 ! test
331 if (grid_i%n(2).ne.grid_o%n(2)) then
332 ierr = 1
333 err_msg = 'input and output grid are not compatible in the &
334 &geodesic coordinate: '//trim(i2str(grid_i%n(2)))//' vs. '//&
335 &trim(i2str(grid_o%n(2)))
336 chckerr(err_msg)
337 end if
338
339 ! initialize to zero
340 x_o%PV_0 = 0._dp
341 x_o%PV_1 = 0._dp
342 x_o%PV_2 = 0._dp
343 x_o%KV_0 = 0._dp
344 x_o%KV_1 = 0._dp
345 x_o%KV_2 = 0._dp
346
347 ! limit input modes to output modes
348 ! (X grid should comprise sol grid)
349 ierr = trim_modes(mds_i,mds_o,id_lim_i,id_lim_o)
350 chckerr('')
351 sec_i_loc => mds_i%sec(id_lim_i(1):id_lim_i(2),:)
352 sec_o_loc => mds_o%sec(id_lim_o(1):id_lim_o(2),:)
353
354 ! select all mode number combinations of interpolated grid
355 n_mod_tot = size(sec_o_loc,1)
356#if ldebug
357 allocate(r_loc_tot(2,n_mod_tot**2,3))
358 allocate(norm_ext_i(n_mod_tot,n_mod_tot))
359 km_id = 0
360 norm_ext_i = 0
361#endif
362 do m = 1,n_mod_tot
363 do k = 1,n_mod_tot
364#if ldebug
365 ! test whether input and output mode numbers are consistent
366 if (sec_i_loc(k,1).ne.sec_o_loc(k,1) .or. &
367 &sec_i_loc(m,1).ne.sec_o_loc(m,1)) then
368 ierr = 1
369 err_msg = 'For ('//trim(i2str(k))//','//trim(i2str(m))//&
370 &'), no consistency for modes in grid_i and grid_o'
371 chckerr(err_msg)
372 end if
373#endif
374
375 ! set input and output grid normal limits for mode pair (k,m)
376 kdl_i(1) = max(sec_i_loc(k,2),sec_i_loc(m,2))
377 kdl_i(2) = min(sec_i_loc(k,3),sec_i_loc(m,3))
378 kdl_o(1) = max(sec_o_loc(k,2),sec_o_loc(m,2))
379 kdl_o(2) = min(sec_o_loc(k,3),sec_o_loc(m,3))
380
381 ! limit to grid ranges
382 kdl_i(1) = max(kdl_i(1),grid_i%i_min)
383 kdl_i(2) = min(kdl_i(2),grid_i%i_max)
384 kdl_o(1) = max(kdl_o(1),grid_o%i_min)
385 kdl_o(2) = min(kdl_o(2),grid_o%i_max)
386
387 ! limit output range to input range if not extrapolating
388 if (.not.extrap) then
389 do kd = kdl_o(1),kdl_o(2)
390 if (grid_o%r_F(kd).ge.grid_i%r_F(kdl_i(1))) exit
391 end do
392 kdl_o(1) = kd
393
394 do kd = kdl_o(2),kdl_o(1),-1
395 if (grid_o%r_F(kd).le.grid_i%r_F(kdl_i(2))) exit
396 end do
397 kdl_o(2) = kd
398 end if
399
400 ! cycle if mode combination does not exist anywhere
401 if (kdl_i(1).gt.kdl_i(2) .or. kdl_o(1).gt.kdl_o(2)) cycle
402
403 ! convert limits to local
404 kdl_i = kdl_i - grid_i%i_min + 1
405 kdl_o = kdl_o - grid_o%i_min + 1
406
407 ! get input ranges for this mode number
408 r_i_loc => grid_i%loc_r_F(kdl_i(1):kdl_i(2))
409 r_o_loc => grid_o%loc_r_F(kdl_o(1):kdl_o(2))
410
411 ! check whether mode combination needs to be calculated
412 calc_this(1) = is_necessary_x(.true.,&
413 &[sec_o_loc(k,1),sec_o_loc(m,1)])
414 calc_this(2) = is_necessary_x(.false.,&
415 &[sec_o_loc(k,1),sec_o_loc(m,1)])
416
417#if ldebug
418 km_id = km_id + 1
419 r_loc_tot(:,km_id,1) = [r_i_loc(1),r_i_loc(size(r_i_loc))]
420 r_loc_tot(:,km_id,2) = [r_o_loc(1),r_o_loc(size(r_o_loc))]
421 r_loc_tot(:,km_id,3) = km_id
422 norm_ext_i(k,m) = size(r_i_loc)
423 if (debug_interp_v) write(*,*) 'k, m', k, m, 'of', n_mod_tot, &
424 &'with calc_this = ', calc_this
425#endif
426
427 ! set up c_loc for input and output
428 c_loc_i(1) = c([sec_i_loc(k,4),sec_i_loc(m,4)],.true.,n_mod_x)
429 c_loc_i(2) = c([sec_i_loc(k,4),sec_i_loc(m,4)],.false.,n_mod_x)
430 c_loc_o(1) = c([sec_o_loc(k,4),sec_o_loc(m,4)],.true.,n_mod_x)
431 c_loc_o(2) = c([sec_o_loc(k,4),sec_o_loc(m,4)],.false.,n_mod_x)
432
433 if (calc_this(1)) then
434 v_i => x_i%PV_0(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
435 v_o => x_o%PV_0(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
436 ierr = interp_v_spline(v_i,v_o,r_i_loc,r_o_loc,extrap,&
437 &ivs_stat(1))
438 chckerr('')
439
440 v_i => x_i%PV_2(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
441 v_o => x_o%PV_2(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
442 ierr = interp_v_spline(v_i,v_o,r_i_loc,r_o_loc,extrap,&
443 &ivs_stat(2))
444 chckerr('')
445
446 v_i => x_i%KV_0(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
447 v_o => x_o%KV_0(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
448 ierr = interp_v_spline(v_i,v_o,r_i_loc,r_o_loc,extrap,&
449 &ivs_stat(3))
450 chckerr('')
451
452 v_i => x_i%KV_2(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
453 v_o => x_o%KV_2(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
454 ierr = interp_v_spline(v_i,v_o,r_i_loc,r_o_loc,extrap,&
455 &ivs_stat(4))
456 chckerr('')
457
458#if ldebug
459 if (debug_interp_v) then
460 !call writo('For [k,m] = ['//&
461 !&trim(i2str(sec_o_loc(k,1)))//','//&
462 !&trim(i2str(sec_o_loc(m,1)))//']:')
463 !call lvl_ud(1)
464 !call writo('input normal range: '//&
465 !&trim(i2str(kdl_i(1)))//'..'//trim(i2str(kdl_i(2))))
466 !call writo('output normal range: '//&
467 !&trim(i2str(kdl_o(1)))//'..'//trim(i2str(kdl_o(2))))
468 !allocate(V_plot(max(size(V_i,3),size(V_o,3)),4))
469 !V_plot(1:size(V_i,3),1) = V_i(1,1,:)
470 !V_plot(1:size(V_o,3),2) = V_o(1,1,:)
471 !V_plot(1:size(V_i,3),3) = r_i_loc/max_flux_F*2*pi
472 !V_plot(1:size(V_o,3),4) = r_o_loc/max_flux_F*2*pi
473 !V_plot(size(V_i,3)+1:size(V_plot,1),1) = &
474 !&V_plot(size(V_i,3),1)
475 !V_plot(size(V_o,3)+1:size(V_plot,1),2) = &
476 !&V_plot(size(V_o,3),2)
477 !V_plot(size(V_i,3)+1:size(V_plot,1),3) = &
478 !&V_plot(size(V_i,3),3)
479 !V_plot(size(V_o,3)+1:size(V_plot,1),4) = &
480 !&V_plot(size(V_o,3),4)
481 !call print_ex_2D(['V_i','V_o'],'RE_V',&
482 !&rp(V_plot(:,1:2)),x=rp(V_plot(:,3:4)))
483 !!call print_ex_2D(['V_i','V_o'],'IM_V',&
484 !!&ip(V_plot(:,1:2)),x=rp(V_plot(:,3:4)))
485 !deallocate(V_plot)
486 !if (ex_plot_style.eq.2) read(*,*)
487 !call lvl_ud(-1)
488 end if
489#endif
490 end if
491
492 if (calc_this(2)) then
493 v_i => x_i%PV_1(:,:,kdl_i(1):kdl_i(2),c_loc_i(2))
494 v_o => x_o%PV_1(:,:,kdl_o(1):kdl_o(2),c_loc_o(2))
495 ierr = interp_v_spline(v_i,v_o,r_i_loc,r_o_loc,extrap,&
496 &ivs_stat(5))
497 chckerr('')
498
499 v_i => x_i%KV_1(:,:,kdl_i(1):kdl_i(2),c_loc_i(2))
500 v_o => x_o%KV_1(:,:,kdl_o(1):kdl_o(2),c_loc_o(2))
501 ierr = interp_v_spline(v_i,v_o,r_i_loc,r_o_loc,extrap,&
502 &ivs_stat(6))
503 chckerr('')
504 end if
505#if ldebug
506 do kd = 1,size(ivs_stat)
507 !if (ivs_stat(kd).eq.1) call writo('Used direct copy for '//&
508 !&trim(i2str(kd))//' of mode combination ('//&
509 !&trim(i2str(k))//', '//trim(i2str(m))//') at ψ = '//&
510 !&trim(r2strt(r_loc_tot(1,km_id,1)/max_flux_F*2*pi)))
511 ivs_stats(ivs_stat(kd)) = ivs_stats(ivs_stat(kd)) + 1
512 end do
513#endif
514 end do
515 end do
516
517#if ldebug
518 call writo('interp_V_spline statistics:')
519 call lvl_ud(1)
520 ivs_stats_names(1) = 'direct copy'
521 ivs_stats_names(2) = 'linear interpolation'
522 ivs_stats_names(3) = 'spline interpolation'
523 do kd = 1,3
524 call writo(trim(ivs_stats_names(kd))//' was performed '//&
525 &trim(i2str(ivs_stats(kd)))//' times: '//&
526 &trim(r2strt(100._dp*ivs_stats(kd)/sum(ivs_stats)))//'%')
527 end do
528 if (ivs_stats(1).gt.0) then
529 call writo('It is possible that more secondary modes and/or a &
530 &lower max_njq_change are needed.',warning=.true.)
531 call writo('If unphysical modes appear, consider changing these &
532 &variables.',warning=.true.)
533 end if
534 call lvl_ud(-1)
535 call print_ex_2d([''],'r_i_loc_'//trim(i2str(rank)),&
536 &r_loc_tot(:,1:km_id,1)/max_flux_f*2*pi,x=r_loc_tot(:,1:km_id,3),&
537 &draw=.false.)
538 call draw_ex([''],'r_i_loc_'//trim(i2str(rank)),km_id,1,.false.,&
539 &ex_plot_style=1)
540 call print_ex_2d([''],'r_o_loc_'//trim(i2str(rank)),&
541 &r_loc_tot(:,1:km_id,2)/max_flux_f*2*pi,x=r_loc_tot(:,1:km_id,3),&
542 &draw=.false.)
543 call draw_ex([''],'r_o_loc_'//trim(i2str(rank)),km_id,1,.false.,&
544 &ex_plot_style=1)
545 call plot_hdf5('normal extent','norm_ext_i_'//trim(i2str(rank)),1._dp*&
546 &reshape(norm_ext_i*1._dp,[n_mod_tot,n_mod_tot,1]))
547#endif
548
549 ! clean up
550 nullify(r_i_loc,r_o_loc)
551 nullify(sec_i_loc,sec_o_loc)
552 nullify(v_i,v_o)
553 end function interp_v
554end module driver_sol
Prints variables vars with names var_names in an HDF5 file with name c file_name and accompanying XDM...
Print 2-D output on a file.
Redistribute the perturbation variables.
Definition X_ops.f90:51
Driver of the solution part of PB3D.
Definition driver_sol.f90:4
integer function interp_v(mds_i, grid_i, x_i, mds_o, grid_o, x_o)
Interpolate tensorial perturbation quantities in the third dimension.
integer function, public run_driver_sol(grid_eq, grid_x, grid_sol, x, vac, sol)
Main driver of PB3D solution part.
Variables that have to do with equilibrium quantities and the grid used in the calculations:
Definition eq_vars.f90:27
real(dp), public max_flux_f
max. flux in Flux coordinates, set in calc_norm_range_PB3D_in
Definition eq_vars.f90:50
Operations that have to do with the grids and different coordinate systems.
Definition grid_ops.f90:4
integer function, public print_output_grid(grid, grid_name, data_name, rich_lvl, par_div, remove_previous_arrs)
Print grid variables to an output file.
integer function, public calc_norm_range(style, in_limits, eq_limits, x_limits, sol_limits, r_f_eq, r_f_x, r_f_sol, jq)
Calculates normal range for the input grid, the equilibrium grid and/or the solution grid.
Definition grid_ops.f90:46
integer function, public redistribute_output_grid(grid, grid_out, no_outer_trim)
Redistribute a grid to match the normal distribution of solution grid.
Definition grid_ops.f90:995
integer function, public setup_grid_sol(grid_eq, grid_x, grid_sol, r_f_sol, sol_limits)
Sets up the general solution grid, in which the solution variables are calculated.
Definition grid_ops.f90:728
Numerical utilities related to the grids and different coordinate systems.
integer function, public trim_grid(grid_in, grid_out, norm_id)
Trim a grid, removing any overlap between the different regions.
Variables pertaining to the different grids used.
Definition grid_vars.f90:4
integer, public n_alpha
nr. of field-lines
Definition grid_vars.f90:23
integer, public n_r_sol
nr. of normal points in solution grid
Definition grid_vars.f90:22
Numerical utilities related to giving output.
Definition messages.f90:4
subroutine, public lvl_ud(inc)
Increases/decreases lvl of output.
Definition messages.f90:254
subroutine, public writo(input_str, persistent, error, warning, alert)
Write output to file identified by output_i.
Definition messages.f90:275
Numerical utilities.
integer function, public c(ij, sym, n, lim_n)
Convert 2-D coordinates (i,j) to the storage convention used in matrices.
integer, dimension(:,:), allocatable, public m
1-D array indices of metric indices
Numerical variables used by most other modules.
Definition num_vars.f90:4
integer, parameter, public dp
double precision
Definition num_vars.f90:46
real(dp), parameter, public pi
Definition num_vars.f90:83
integer, public n_procs
nr. of MPI processes
Definition num_vars.f90:69
complex(dp), parameter, public iu
complex unit
Definition num_vars.f90:85
integer, parameter, public max_str_ln
maximum length of strings
Definition num_vars.f90:50
integer, public x_grid_style
style for normal component of X grid (1: eq, 2: sol, 3: enriched)
Definition num_vars.f90:99
integer, public eq_style
either 1 (VMEC) or 2 (HELENA)
Definition num_vars.f90:89
integer, public ex_plot_style
external plot style (1: GNUPlot, 2: Bokeh for 2D, Mayavi for 3D)
Definition num_vars.f90:175
integer, public ev_style
determines the method used for solving an EV problem
Definition num_vars.f90:88
integer, public rank
MPI rank.
Definition num_vars.f90:68
integer, public rich_restart_lvl
starting Richardson level (0: none [default])
Definition num_vars.f90:173
logical, public jump_to_sol
jump to solution
Definition num_vars.f90:141
Operations concerning giving output, on the screen as well as in output files.
Definition output_ops.f90:5
subroutine, public draw_ex(var_names, draw_name, nplt, draw_dim, plot_on_screen, ex_plot_style, data_name, draw_ops, extra_ops, is_animated, ranges, delay, persistent)
Use external program to draw a plot.
Operations on PB3D output.
Definition PB3D_ops.f90:8
integer function, public reconstruct_pb3d_grid(grid, data_name, rich_lvl, tot_rich, lim_pos, grid_limits)
Reconstructs grid variables from PB3D HDF5 output.
Definition PB3D_ops.f90:442
integer function, public reconstruct_pb3d_sol(mds, grid_sol, sol, data_name, rich_lvl, lim_sec_sol, lim_pos)
Reconstructs the solution variables from PB3D HDF5 output.
Operations concerning Richardson extrapolation.
Definition rich_ops.f90:4
subroutine, public calc_rich_ex(sol_val)
Calculates the coefficients of the Eigenvalues in the Richardson extrapolation.
Definition rich_ops.f90:459
Variables concerning Richardson extrapolation.
Definition rich_vars.f90:4
integer, public rich_lvl
current level of Richardson extrapolation
Definition rich_vars.f90:19
Operations that use SLEPC (and PETSC) routines.
Definition SLEPC_ops.f90:10
integer function, public solve_ev_system_slepc(mds, grid_sol, x, vac, sol)
Solve the eigenvalue system using SLEPC.
Definition SLEPC_ops.f90:62
Operations on the solution vectors such as decompososing the energy, etc...
Definition sol_ops.f90:4
integer function, public print_output_sol(grid, sol, data_name, rich_lvl, remove_previous_arrs)
Print solution quantities to an output file:
Definition sol_ops.f90:1566
Numerical utilities related to the solution vectors.
integer function, public interp_v_spline(v_i, v_o, r_i, r_o, extrap, ivs_stat)
Interpolation for a quantity V using splines.
Variables pertaining to the solution quantities.
Definition sol_vars.f90:4
Operations on strings.
elemental character(len=max_str_ln) function, public i2str(k)
Convert an integer to string.
elemental character(len=max_str_ln) function, public r2strt(k)
Convert a real (double) to string.
Operations and variables pertaining to the vacuum response.
Definition vac_ops.f90:23
integer function, public calc_vac_res(mds, vac)
Calculates the vacuum response.
Definition vac_ops.f90:1417
integer function, public print_output_vac(vac, data_name, rich_lvl)
Print vacuum quantities of a certain order to an output file.
Definition vac_ops.f90:2347
Variables pertaining to the vacuum quantities.
Definition vac_vars.f90:4
Operations considering perturbation quantities.
Definition X_ops.f90:4
integer function, public setup_modes(mds, grid_eq, grid, plot_name)
Sets up some variables concerning the mode numbers.
Definition X_ops.f90:1060
integer function, public print_debug_x_2(mds, grid_x, x_2_int)
Prints debug information for X_2 driver.
Definition X_ops.f90:3633
Numerical utilities related to perturbation operations.
logical function, public is_necessary_x(sym, sec_x_id, lim_sec_x)
Determines whether a variable needs to be considered:
integer function, public trim_modes(mds_i, mds_o, id_lim_i, id_lim_o)
Limit input mode range to output mode range.
Variables pertaining to the perturbation quantities.
Definition X_vars.f90:4
integer, public n_mod_x
size of m_X (pol. flux) or n_X (tor. flux)
Definition X_vars.f90:129
type(modes_type), public mds_x
modes variables for perturbation grid
Definition X_vars.f90:124
type(modes_type), public mds_sol
modes variables for solution grid
Definition X_vars.f90:125
Type for grids.
Definition grid_vars.f90:59
solution type
Definition sol_vars.f90:30
vacuum type
Definition vac_vars.f90:46
mode number type
Definition X_vars.f90:36
tensorial perturbation type
Definition X_vars.f90:81