5#include <PB3D_macros.h>
27 logical :: debug_setup_modes = .false.
41 module procedure calc_x_1
43 module procedure calc_x_2
53 module procedure redistribute_output_x_1
55 module procedure redistribute_output_x_2
87 module procedure print_output_x_1
89 module procedure print_output_x_2
94 integer function calc_x_1(mds,grid_eq,grid_X,eq_1,eq_2,X,lim_sec_X) &
97 character(*),
parameter :: rout_name =
'calc_X_1'
106 integer,
intent(in),
optional :: lim_sec_x(2)
112 call writo(
'Calculate vectorial perturbation variables')
116 call x%init(mds,grid_x,lim_sec_x)
119 call writo(
'Calculating U and DU...')
121 ierr = calc_u(grid_eq,grid_x,eq_1,eq_2,x)
127 end function calc_x_1
129 integer function calc_x_2(mds,grid_eq,grid_X,eq_1,eq_2,X_a,X_b,X,&
130 &lim_sec_X)
result(ierr)
132 character(*),
parameter :: rout_name =
'calc_X_2'
140 type(
x_1_type),
intent(inout) :: x_a
141 type(
x_1_type),
intent(inout) :: x_b
143 integer,
intent(in),
optional :: lim_sec_x(2,2)
149 call writo(
'Calculate tensorial perturbation variables')
153 call x%init(mds,grid_x,lim_sec_x)
157 call writo(
'Calculating PV...')
159 ierr = calc_pv(grid_eq,grid_x,eq_1,eq_2,x_a,x_b,x,lim_sec_x)
165 call writo(
'Calculating KV...')
167 ierr = calc_kv(grid_eq,grid_x,eq_1,eq_2,x_a,x_b,x,lim_sec_x)
173 end function calc_x_2
176 integer function redistribute_output_x_1(mds,grid,grid_out,X,X_out) &
180 character(*),
parameter :: rout_name =
'redistribute_output_X_1'
187 type(
x_1_type),
intent(inout) :: x_out
191 integer :: lims(2), lims_dis(2)
192 integer :: siz(3), siz_dis(3)
193 real(
dp),
allocatable :: temp_var(:)
199 call writo(
'Redistribute vectorial perturbation variables')
203 if (grid%n(1).ne.grid_out%n(1) .or. grid%n(2).ne.grid_out%n(2))
then
205 chckerr(
'grid and grid_out are not compatible')
209 call x_out%init(mds,grid_out,lim_sec_x=x%lim_sec_X)
212 lims(1) = product(grid%n(1:2))*(grid%i_min-1)+1
213 lims(2) = product(grid%n(1:2))*grid%i_max
214 lims_dis(1) = product(grid%n(1:2))*(grid_out%i_min-1)+1
215 lims_dis(2) = product(grid%n(1:2))*grid_out%i_max
216 siz = [grid%n(1:2),grid%loc_n_r]
217 siz_dis = [grid%n(1:2),grid_out%loc_n_r]
218 allocate(temp_var(product(siz_dis)))
221 do ld = 1,
size(x%U_0,4)
224 &[product(siz)]),temp_var,lims,lims_dis)
226 x_out%U_0(:,:,:,ld) = &
227 &reshape(temp_var(1:product(siz_dis)),siz_dis)
229 &[product(siz)]),temp_var,lims,lims_dis)
231 x_out%U_0(:,:,:,ld) = x_out%U_0(:,:,:,ld) +
iu*&
232 &reshape(temp_var(1:product(siz_dis)),siz_dis)
236 &[product(siz)]),temp_var,lims,lims_dis)
238 x_out%U_1(:,:,:,ld) = &
239 &reshape(temp_var(1:product(siz_dis)),siz_dis)
241 &[product(siz)]),temp_var,lims,lims_dis)
243 x_out%U_1(:,:,:,ld) = x_out%U_1(:,:,:,ld) +
iu*&
244 &reshape(temp_var(1:product(siz_dis)),siz_dis)
248 &[product(siz)]),temp_var,lims,lims_dis)
250 x_out%DU_0(:,:,:,ld) = &
251 &reshape(temp_var(1:product(siz_dis)),siz_dis)
253 &[product(siz)]),temp_var,lims,lims_dis)
255 x_out%DU_0(:,:,:,ld) = x_out%DU_0(:,:,:,ld) +
iu*&
256 &reshape(temp_var(1:product(siz_dis)),siz_dis)
260 &[product(siz)]),temp_var,lims,lims_dis)
262 x_out%DU_1(:,:,:,ld) = &
263 &reshape(temp_var(1:product(siz_dis)),siz_dis)
265 &[product(siz)]),temp_var,lims,lims_dis)
267 x_out%DU_1(:,:,:,ld) = x_out%DU_1(:,:,:,ld) +
iu*&
268 &reshape(temp_var(1:product(siz_dis)),siz_dis)
273 end function redistribute_output_x_1
275 integer function redistribute_output_x_2(mds,grid,grid_out,X,X_out) &
279 character(*),
parameter :: rout_name =
'redistribute_output_X_2'
286 type(
x_2_type),
intent(inout) :: x_out
291 integer :: lims(2), lims_dis(2)
292 integer :: siz(3), siz_dis(3)
293 logical :: is_field_averaged
294 real(
dp),
allocatable :: temp_var(:)
300 call writo(
'Redistribute tensorial perturbation variables')
304 is_field_averaged =
size(x%PV_0,1).eq.1
305 if ((grid%n(1).ne.grid_out%n(1) .or. grid%n(2).ne.grid_out%n(2)) .and. &
306 &.not.is_field_averaged)
then
308 chckerr(
'grid and grid_out are not compatible')
312 call x_out%init(mds,grid_out,lim_sec_x=x%lim_sec_X,&
313 &is_field_averaged=is_field_averaged)
317 if (is_field_averaged) n_loc(1) = 1
318 lims(1) = product(n_loc)*(grid%i_min-1)+1
319 lims(2) = product(n_loc)*grid%i_max
320 lims_dis(1) = product(n_loc)*(grid_out%i_min-1)+1
321 lims_dis(2) = product(n_loc)*grid_out%i_max
322 siz = [n_loc,grid%loc_n_r]
323 siz_dis = [n_loc,grid_out%loc_n_r]
324 allocate(temp_var(product(siz_dis)))
327 do ld = 1,
size(x%PV_0,4)
330 &[product(siz)]),temp_var,lims,lims_dis)
332 x_out%PV_0(1:n_loc(1),:,:,ld) = &
333 &reshape(temp_var(1:product(siz_dis)),siz_dis)
335 &[product(siz)]),temp_var,lims,lims_dis)
337 x_out%PV_0(1:n_loc(1),:,:,ld) = x_out%PV_0(1:n_loc(1),:,:,ld) +
iu*&
338 &reshape(temp_var(1:product(siz_dis)),siz_dis)
342 &[product(siz)]),temp_var,lims,lims_dis)
344 x_out%PV_2(1:n_loc(1),:,:,ld) = &
345 &reshape(temp_var(1:product(siz_dis)),siz_dis)
347 &[product(siz)]),temp_var,lims,lims_dis)
349 x_out%PV_2(1:n_loc(1),:,:,ld) = x_out%PV_2(1:n_loc(1),:,:,ld) +
iu*&
350 &reshape(temp_var(1:product(siz_dis)),siz_dis)
354 &[product(siz)]),temp_var,lims,lims_dis)
356 x_out%KV_0(1:n_loc(1),:,:,ld) = &
357 &reshape(temp_var(1:product(siz_dis)),siz_dis)
359 &[product(siz)]),temp_var,lims,lims_dis)
361 x_out%KV_0(1:n_loc(1),:,:,ld) = x_out%KV_0(1:n_loc(1),:,:,ld) +
iu*&
362 &reshape(temp_var(1:product(siz_dis)),siz_dis)
366 &[product(siz)]),temp_var,lims,lims_dis)
368 x_out%KV_2(1:n_loc(1),:,:,ld) = &
369 &reshape(temp_var(1:product(siz_dis)),siz_dis)
371 &[product(siz)]),temp_var,lims,lims_dis)
373 x_out%KV_2(1:n_loc(1),:,:,ld) = x_out%KV_2(1:n_loc(1),:,:,ld) +
iu*&
374 &reshape(temp_var(1:product(siz_dis)),siz_dis)
378 do ld = 1,
size(x%PV_1,4)
381 &[product(siz)]),temp_var,lims,lims_dis)
383 x_out%PV_1(1:n_loc(1),:,:,ld) = &
384 &reshape(temp_var(1:product(siz_dis)),siz_dis)
386 &[product(siz)]),temp_var,lims,lims_dis)
388 x_out%PV_1(1:n_loc(1),:,:,ld) = x_out%PV_1(1:n_loc(1),:,:,ld) +
iu*&
389 &reshape(temp_var(1:product(siz_dis)),siz_dis)
393 &[product(siz)]),temp_var,lims,lims_dis)
395 x_out%KV_1(1:n_loc(1),:,:,ld) = &
396 &reshape(temp_var(1:product(siz_dis)),siz_dis)
398 &[product(siz)]),temp_var,lims,lims_dis)
400 x_out%KV_1(1:n_loc(1),:,:,ld) = x_out%KV_1(1:n_loc(1),:,:,ld) +
iu*&
401 &reshape(temp_var(1:product(siz_dis)),siz_dis)
406 end function redistribute_output_x_2
409 integer function print_output_x_1(grid_X,X,data_name,rich_lvl,par_div,&
410 &lim_sec_X)
result(ierr)
419 character(*),
parameter :: rout_name =
'print_output_X_1'
424 character(len=*),
intent(in) :: data_name
425 integer,
intent(in),
optional :: rich_lvl
426 logical,
intent(in),
optional :: par_div
427 integer,
intent(in),
optional :: lim_sec_x(2)
433 integer :: norm_id(2)
437 logical :: par_div_loc
438 integer :: lim_sec_x_loc(2)
445 call writo(
'Write vectorial perturbation variables to output file')
449 ierr =
trim_grid(grid_x,grid_trim,norm_id)
453 par_div_loc = .false.
454 if (
present(par_div)) par_div_loc = par_div
458 par_id = [1,n_tot(1)]
459 if (grid_trim%n(1).gt.0 .and. par_div_loc)
then
465 loc_size =
size(x%U_0(:,:,norm_id(1):norm_id(2),:))
467 if (
present(lim_sec_x)) lim_sec_x_loc = lim_sec_x
476 x_1d_loc => x_1d(id); id = id+1
477 x_1d_loc%var_name =
'RE_U_0'
478 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
479 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
480 x_1d_loc%tot_i_min = [1,1,1,1]
481 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
482 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
483 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
485 allocate(x_1d_loc%p(loc_size))
486 x_1d_loc%p = reshape(rp(x%U_0(:,:,norm_id(1):norm_id(2),:)),&
490 x_1d_loc => x_1d(id); id = id+1
491 x_1d_loc%var_name =
'IM_U_0'
492 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
493 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
494 x_1d_loc%tot_i_min = [1,1,1,1]
495 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
496 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
497 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
499 allocate(x_1d_loc%p(loc_size))
500 x_1d_loc%p = reshape(ip(x%U_0(:,:,norm_id(1):norm_id(2),:)),&
504 x_1d_loc => x_1d(id); id = id+1
505 x_1d_loc%var_name =
'RE_U_1'
506 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
507 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
508 x_1d_loc%tot_i_min = [1,1,1,1]
509 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
510 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
511 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
513 allocate(x_1d_loc%p(loc_size))
514 x_1d_loc%p = reshape(rp(x%U_1(:,:,norm_id(1):norm_id(2),:)),&
518 x_1d_loc => x_1d(id); id = id+1
519 x_1d_loc%var_name =
'IM_U_1'
520 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
521 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
522 x_1d_loc%tot_i_min = [1,1,1,1]
523 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
524 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
525 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
527 allocate(x_1d_loc%p(loc_size))
528 x_1d_loc%p = reshape(ip(x%U_1(:,:,norm_id(1):norm_id(2),:)),&
532 x_1d_loc => x_1d(id); id = id+1
533 x_1d_loc%var_name =
'RE_DU_0'
534 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
535 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
536 x_1d_loc%tot_i_min = [1,1,1,1]
537 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
538 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
539 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
541 allocate(x_1d_loc%p(loc_size))
542 x_1d_loc%p = reshape(rp(x%DU_0(:,:,norm_id(1):norm_id(2),:)),&
546 x_1d_loc => x_1d(id); id = id+1
547 x_1d_loc%var_name =
'IM_DU_0'
548 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
549 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
550 x_1d_loc%tot_i_min = [1,1,1,1]
551 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
552 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
553 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
555 allocate(x_1d_loc%p(loc_size))
556 x_1d_loc%p = reshape(ip(x%DU_0(:,:,norm_id(1):norm_id(2),:)),&
560 x_1d_loc => x_1d(id); id = id+1
561 x_1d_loc%var_name =
'RE_DU_1'
562 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
563 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
564 x_1d_loc%tot_i_min = [1,1,1,1]
565 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
566 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
567 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
569 allocate(x_1d_loc%p(loc_size))
570 x_1d_loc%p = reshape(rp(x%DU_1(:,:,norm_id(1):norm_id(2),:)),&
574 x_1d_loc => x_1d(id); id = id+1
575 x_1d_loc%var_name =
'IM_DU_1'
576 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
577 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
578 x_1d_loc%tot_i_min = [1,1,1,1]
579 x_1d_loc%tot_i_max = [n_tot,
n_mod_x]
580 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,lim_sec_x_loc(1)]
581 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
583 allocate(x_1d_loc%p(loc_size))
584 x_1d_loc%p = reshape(ip(x%DU_1(:,:,norm_id(1):norm_id(2),:)),&
589 &rich_lvl=rich_lvl,ind_print=.not.grid_trim%divided)
593 call grid_trim%dealloc()
599 end function print_output_x_1
601 integer function print_output_x_2(grid_X,X,data_name,rich_lvl,par_div,&
602 &lim_sec_X,is_field_averaged)
result(ierr)
612 character(*),
parameter :: rout_name =
'print_output_X_2'
617 character(len=*),
intent(in) :: data_name
618 integer,
intent(in),
optional :: rich_lvl
619 logical,
intent(in),
optional :: par_div
620 integer,
intent(in),
optional :: lim_sec_x(2,2)
621 logical,
intent(in),
optional :: is_field_averaged
627 integer :: par_id_loc(2)
628 integer :: norm_id(2)
631 logical :: print_this(2)
632 integer :: nn_mod_tot(2)
633 integer :: nn_mod_loc(2)
635 logical :: par_div_loc
636 integer :: loc_size(2)
638 integer :: sxr_loc(2,2)
639 integer :: sxr_tot(2,2)
645 call writo(
'Write tensorial perturbation variables to output file')
649 ierr =
trim_grid(grid_x,grid_trim,norm_id)
653 par_div_loc = .false.
654 if (
present(par_div)) par_div_loc = par_div
658 par_id = [1,n_tot(1)]
659 par_id_loc = [1,n_tot(1)]
660 if (grid_trim%n(1).gt.0 .and. par_div_loc)
then
663 par_id_loc = par_id - par_id(1)+1
664 else if (
present(is_field_averaged))
then
665 if (is_field_averaged)
then
687 nn_mod_loc = sxr_loc(2,:)-sxr_loc(1,:)+1
690 if (sxr_loc(1,k).le.sxr_loc(2,k)) print_this(k) = .true.
694 loc_size(1) = (par_id(2)-par_id(1)+1)*n_tot(2)*&
695 &(norm_id(2)-norm_id(1)+1)*nn_mod_loc(1)
696 loc_size(2) = (par_id(2)-par_id(1)+1)*n_tot(2)*&
697 &(norm_id(2)-norm_id(1)+1)*nn_mod_loc(2)
699 if (print_this(1))
then
701 x_1d_loc => x_1d(id); id = id+1
702 x_1d_loc%var_name =
'RE_PV_0'
703 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
704 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
705 x_1d_loc%tot_i_min = [1,1,1,1]
706 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
707 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
708 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
710 allocate(x_1d_loc%p(loc_size(1)))
711 x_1d_loc%p = reshape(rp(x%PV_0(par_id_loc(1):par_id_loc(2),:,&
712 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
716 x_1d_loc => x_1d(id); id = id+1
717 x_1d_loc%var_name =
'IM_PV_0'
718 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
719 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
720 x_1d_loc%tot_i_min = [1,1,1,1]
721 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
722 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
723 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
725 allocate(x_1d_loc%p(loc_size(1)))
726 x_1d_loc%p = reshape(ip(x%PV_0(par_id_loc(1):par_id_loc(2),:,&
727 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
731 x_1d_loc => x_1d(id); id = id+1
732 x_1d_loc%var_name =
'RE_PV_2'
733 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
734 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
735 x_1d_loc%tot_i_min = [1,1,1,1]
736 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
737 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
738 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
740 allocate(x_1d_loc%p(loc_size(1)))
741 x_1d_loc%p = reshape(rp(x%PV_2(par_id_loc(1):par_id_loc(2),:,&
742 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
746 x_1d_loc => x_1d(id); id = id+1
747 x_1d_loc%var_name =
'IM_PV_2'
748 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
749 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
750 x_1d_loc%tot_i_min = [1,1,1,1]
751 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
752 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
753 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
755 allocate(x_1d_loc%p(loc_size(1)))
756 x_1d_loc%p = reshape(ip(x%PV_2(par_id_loc(1):par_id_loc(2),:,&
757 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
761 x_1d_loc => x_1d(id); id = id+1
762 x_1d_loc%var_name =
'RE_KV_0'
763 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
764 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
765 x_1d_loc%tot_i_min = [1,1,1,1]
766 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
767 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
768 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
770 allocate(x_1d_loc%p(loc_size(1)))
771 x_1d_loc%p = reshape(rp(x%KV_0(par_id_loc(1):par_id_loc(2),:,&
772 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
776 x_1d_loc => x_1d(id); id = id+1
777 x_1d_loc%var_name =
'IM_KV_0'
778 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
779 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
780 x_1d_loc%tot_i_min = [1,1,1,1]
781 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
782 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
783 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
785 allocate(x_1d_loc%p(loc_size(1)))
786 x_1d_loc%p = reshape(ip(x%KV_0(par_id_loc(1):par_id_loc(2),:,&
787 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
791 x_1d_loc => x_1d(id); id = id+1
792 x_1d_loc%var_name =
'RE_KV_2'
793 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
794 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
795 x_1d_loc%tot_i_min = [1,1,1,1]
796 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
797 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
798 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
800 allocate(x_1d_loc%p(loc_size(1)))
801 x_1d_loc%p = reshape(rp(x%KV_2(par_id_loc(1):par_id_loc(2),:,&
802 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
806 x_1d_loc => x_1d(id); id = id+1
807 x_1d_loc%var_name =
'IM_KV_2'
808 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
809 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
810 x_1d_loc%tot_i_min = [1,1,1,1]
811 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(1)]
812 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,1)]
813 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
815 allocate(x_1d_loc%p(loc_size(1)))
816 x_1d_loc%p = reshape(ip(x%KV_2(par_id_loc(1):par_id_loc(2),:,&
817 &norm_id(1):norm_id(2),sxr_loc(1,1):sxr_loc(2,1))),&
821 if (print_this(2))
then
823 x_1d_loc => x_1d(id); id = id+1
824 x_1d_loc%var_name =
'RE_PV_1'
825 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
826 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
827 x_1d_loc%tot_i_min = [1,1,1,1]
828 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(2)]
829 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,2)]
830 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
832 allocate(x_1d_loc%p(loc_size(2)))
833 x_1d_loc%p = reshape(rp(x%PV_1(par_id_loc(1):par_id_loc(2),:,&
834 &norm_id(1):norm_id(2),sxr_loc(1,2):sxr_loc(2,2))),&
838 x_1d_loc => x_1d(id); id = id+1
839 x_1d_loc%var_name =
'IM_PV_1'
840 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
841 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
842 x_1d_loc%tot_i_min = [1,1,1,1]
843 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(2)]
844 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,2)]
845 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
847 allocate(x_1d_loc%p(loc_size(2)))
848 x_1d_loc%p = reshape(ip(x%PV_1(par_id_loc(1):par_id_loc(2),:,&
849 &norm_id(1):norm_id(2),sxr_loc(1,2):sxr_loc(2,2))),&
853 x_1d_loc => x_1d(id); id = id+1
854 x_1d_loc%var_name =
'RE_KV_1'
855 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
856 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
857 x_1d_loc%tot_i_min = [1,1,1,1]
858 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(2)]
859 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,2)]
860 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
862 allocate(x_1d_loc%p(loc_size(2)))
863 x_1d_loc%p = reshape(rp(x%KV_1(par_id_loc(1):par_id_loc(2),:,&
864 &norm_id(1):norm_id(2),sxr_loc(1,2):sxr_loc(2,2))),&
868 x_1d_loc => x_1d(id); id = id+1
869 x_1d_loc%var_name =
'IM_KV_1'
870 allocate(x_1d_loc%tot_i_min(4),x_1d_loc%tot_i_max(4))
871 allocate(x_1d_loc%loc_i_min(4),x_1d_loc%loc_i_max(4))
872 x_1d_loc%tot_i_min = [1,1,1,1]
873 x_1d_loc%tot_i_max = [n_tot,nn_mod_tot(2)]
874 x_1d_loc%loc_i_min = [par_id(1),1,grid_trim%i_min,sxr_tot(1,2)]
875 x_1d_loc%loc_i_max = [par_id(2),n_tot(2),grid_trim%i_max,&
877 allocate(x_1d_loc%p(loc_size(2)))
878 x_1d_loc%p = reshape(ip(x%KV_1(par_id_loc(1):par_id_loc(2),:,&
879 &norm_id(1):norm_id(2),sxr_loc(1,2):sxr_loc(2,2))),&
886 &rich_lvl=rich_lvl,ind_print=.not.grid_trim%divided)
890 call grid_trim%dealloc()
896 end function print_output_x_2
925 character(*),
parameter :: rout_name =
'init_modes'
933 real(
dp),
allocatable :: jq_tot(:)
934 integer :: norm_eq_id(2)
940 call writo(
'Initializing perturbation modes variables')
944 ierr =
trim_grid(grid_eq,grid_eq_trim,norm_eq_id)
956 allocate(jq_tot(grid_eq_trim%n(3)))
958 if (grid_eq%divided)
then
959 ierr =
get_ser_var(eq%q_saf_FD(norm_eq_id(1):norm_eq_id(2),0),&
960 &jq_tot,scatter=.true.)
963 jq_tot = eq%q_saf_FD(:,0)
966 if (grid_eq%divided)
then
967 ierr =
get_ser_var(eq%rot_t_FD(norm_eq_id(1):norm_eq_id(2),0),&
968 &jq_tot,scatter=.true.)
971 jq_tot = eq%rot_t_FD(:,0)
993 if (
prim_x*jq_tot(1).gt.0)
then
1003 if (
prim_x*jq_tot(1).gt.0)
then
1018 call grid_eq_trim%dealloc()
1021 call writo(
'Perturbation modes variables initialized')
1066 character(*),
parameter :: rout_name =
'setup_modes'
1069 type(
modes_type),
intent(inout),
target :: mds
1072 character(len=*),
intent(in),
optional :: plot_name
1076 real(
dp),
allocatable :: x_plot(:,:)
1077 integer,
pointer :: nm_x(:,:)
1078 integer :: id, ld, kd
1080 integer :: n_mod_tot
1083 integer :: mod_x_range
1085 integer,
allocatable :: ind_cur(:)
1086 integer,
allocatable :: ind_tot(:,:)
1087 character(len=max_str_ln),
allocatable :: plot_titles(:)
1088 character(len=max_str_ln) :: plot_name_tot
1089 character(len=max_str_ln) :: err_msg
1091 real(
dp),
allocatable :: y_plot(:,:)
1098 call writo(
'Setting up general modes variables')
1106 allocate(mds%n(grid%n(3),
n_mod_x))
1107 allocate(mds%m(grid%n(3),
n_mod_x))
1140 ind_tot(ld,:) = [nm_x(1,ld),1,0,ld]
1143 if (debug_setup_modes)
write(*,*)
'starting with', ld,
':', &
1147 ind_cur = [(ld, ld=1,
n_mod_x)]
1153 ld_shift = ld_shift + delta_ld
1158 ld_loc = modulo(ld+ld_shift-1,
n_mod_x)+1
1159 nm_x(kd,ld_loc) = nint(
min_nm_x(kd)) + &
1160 &mod_x_range*(ld-1)/(
n_mod_x-1)
1164 if (abs(delta_ld).gt.0)
then
1166 if (debug_setup_modes)
write(*,*)
'kd', kd,
'delta', &
1169 do ld = 1,abs(delta_ld)
1170 if (delta_ld.gt.0)
then
1171 ind_tot(ind_cur(1),3) = kd - 1
1172 ind_tot(ind_id+ld,:) = [ &
1173 &ind_tot(ind_cur(
n_mod_x),1) + 1, &
1176 &modulo(ind_tot(ind_id,4)+ld-1,
n_mod_x) + 1]
1178 if (debug_setup_modes)
then
1179 write(*,*)
' FINISHES', ind_cur(1), &
1180 &
':', ind_tot(ind_cur(1),:)
1181 write(*,*)
' STARTS', ind_id+ld,
':', &
1182 &ind_tot(ind_id+ld,:)
1185 ind_cur = [ind_cur(2:
n_mod_x),ind_id+ld]
1187 ind_tot(ind_cur(
n_mod_x),3) = kd - 1
1188 ind_tot(ind_id+ld,:) = [ &
1189 &ind_tot(ind_cur(1),1) - 1, &
1192 &modulo(ind_tot(ind_id,4)-ld,
n_mod_x) + 1]
1194 if (debug_setup_modes)
then
1195 write(*,*)
' FINISHES', ind_cur(
n_mod_x), &
1196 &
':', ind_tot(ind_cur(
n_mod_x),:)
1197 write(*,*)
' STARTS', ind_id+ld,
':', &
1198 &ind_tot(ind_id+ld,:)
1201 ind_cur = [ind_id+ld,ind_cur(1:
n_mod_x-1)]
1204 ind_id = ind_id+abs(delta_ld)
1206 if (debug_setup_modes)
write(*,*)
' current indices:', &
1213 do ld = 1,
size(ind_cur)
1214 ind_tot(ind_cur(ld),3) = grid%n(3)
1220 allocate(mds%sec(ind_id,4))
1221 mds%sec = ind_tot(1:ind_id,:)
1226 if (
rank.eq.0 .and.
present(plot_name))
then
1227 call writo(
'Plotting mode numbers')
1231 n_mod_tot =
size(mds%sec,1)
1234 allocate(x_plot(grid%n(3),
n_mod_x))
1236 x_plot(:,ld) = grid%r_F
1239 allocate(plot_titles(1))
1242 plot_titles(1) =
'poloidal mode numbers'
1243 plot_name_tot =
'modes_m_'//trim(plot_name)
1244 call print_ex_2d(plot_titles(1:1),plot_name_tot,mds%m*1._dp,&
1245 &x=x_plot,draw=.false.)
1249 plot_titles(1) =
'toroidal mode numbers'
1250 plot_name_tot =
'modes_n_'//trim(plot_name)
1251 call print_ex_2d(plot_titles(1:1),plot_name_tot,mds%n*1._dp,&
1252 &x=x_plot,draw=.false.)
1257 deallocate(plot_titles)
1261 allocate(x_plot(n_mod_tot,n_mod_tot+2))
1262 allocate(y_plot(n_mod_tot,n_mod_tot+2))
1263 allocate(plot_titles(n_mod_tot+2))
1266 y_plot(:,ld) = mds%sec(ld,2)
1267 y_plot(n_mod_tot,ld) = mds%sec(ld,3)
1268 plot_titles(ld) =
'mode '//trim(
i2str(mds%sec(ld,1)))
1270 x_plot(:,n_mod_tot+1) = x_plot(1,1:n_mod_tot)
1271 y_plot(:,n_mod_tot+1) = mds%sec(:,1)
1272 plot_titles(n_mod_tot+1) =
'mode number'
1273 x_plot(:,n_mod_tot+2) = x_plot(1,1:n_mod_tot)
1274 y_plot(:,n_mod_tot+2) = mds%sec(:,4)
1275 plot_titles(n_mod_tot+2) =
'index'
1276 plot_name_tot =
'modes_sec_'//trim(plot_name)
1277 call print_ex_2d(plot_titles,plot_name_tot,y_plot,x=x_plot,&
1279 call draw_ex(plot_titles,plot_name_tot,n_mod_tot+2,1,.false.)
1280 plot_name_tot =
'modes_sec_flux_'//trim(plot_name)
1283 y_plot(n_mod_tot,ld) = grid%r_F(mds%sec(ld,3))*2*
pi/
max_flux_f
1285 call print_ex_2d(plot_titles(1:n_mod_tot),plot_name_tot,&
1286 &y_plot(:,1:n_mod_tot),x=x_plot(:,1:n_mod_tot),draw=.false.)
1287 call draw_ex(plot_titles(1:n_mod_tot),plot_name_tot,n_mod_tot,1,&
1291 deallocate(plot_titles)
1298 if (minval(mds%sec(:,3)-mds%sec(:,2)+1).lt.1)
then
1300 call writo(
'Mode '//&
1301 &trim(
i2str(minloc(mds%sec(:,3)-mds%sec(:,2),1)))//&
1302 &
' is not present in any flux surface')
1303 err_msg =
'Aument number of modes or choose finer equilibrium'
1311 call writo(
'General mode variables set up')
1353 character(*),
parameter :: rout_name =
'check_X_modes'
1357 type(eq_1_type),
intent(in) :: eq
1360 character(len=max_str_ln) :: err_msg
1365 call writo(
'Checking mode numbers')
1371 ierr = check_x_modes_1(eq)
1374 ierr = check_x_modes_2(grid_eq,eq)
1379 call writo(
'Mode numbers checked')
1384 integer function check_x_modes_1(eq)
result(ierr)
1388 character(*),
parameter :: rout_name =
'check_X_modes_1'
1391 type(eq_1_type),
intent(in) :: eq
1396 real(
dp) :: min_jq, max_jq
1397 real(
dp) :: lim_lo, lim_hi
1398 real(
dp),
allocatable :: temp_var(:)
1399 character(len=max_str_ln) :: jq_name
1400 character(len=1) :: mode_name
1401 logical :: all_modes_fine
1411 min_jq = minval(eq%q_saf_FD(:,0))
1412 max_jq = maxval(eq%q_saf_FD(:,0))
1414 min_jq = minval(eq%rot_t_FD(:,0))
1415 max_jq = maxval(eq%rot_t_FD(:,0))
1421 if (
rank.eq.0) min_jq = minval(temp_var)
1424 if (
rank.eq.0) max_jq = maxval(temp_var)
1430 jq_name =
'safety factor'
1433 jq_name =
'rotational transform'
1436 all_modes_fine = .true.
1439 if (min_jq.lt.0 .and. max_jq.lt.0)
then
1441 else if (min_jq.gt.0 .and. max_jq.gt.0)
then
1444 err_msg = trim(jq_name)//
' cannot change sign'
1462 &
'), there is no range in the plasma where the &
1463 &ratio |n q - m| << |n|,|m| is met',alert=.true.)
1464 all_modes_fine = .false.
1469 call writo(
'for (n,m) = ('//&
1472 &the plasma where the ratio |n - iota m| << &
1473 &|m|,|n| is met',alert=.true.)
1474 all_modes_fine = .false.
1480 if (all_modes_fine)
then
1481 call writo(
'The modes are all within the allowed range &
1482 &of '//trim(
i2str(ceiling(
prim_x*lim_lo)))//
' < '//&
1483 &mode_name//
' < '//trim(
i2str(floor(
prim_x*lim_hi)))//&
1486 call writo(
'Not all modes are within the allowed range &
1487 &of '//trim(
i2str(ceiling(
prim_x*lim_lo)))//
' < '//&
1488 &mode_name//
' < '//trim(
i2str(floor(
prim_x*lim_hi)))//&
1492 end function check_x_modes_1
1497 integer function check_x_modes_2(grid_eq,eq)
result(ierr)
1501 character(*),
parameter :: rout_name =
'check_X_modes_2'
1505 type(eq_1_type),
intent(in) :: eq
1509 integer :: norm_id(2)
1510 integer :: jd, kd, ld
1511 real(dp),
allocatable :: max_frac(:,:)
1512 real(dp),
allocatable :: max_frac_sum(:)
1513 real(dp),
allocatable :: max_frac_max(:)
1514 real(dp),
allocatable :: max_frac_temp(:)
1515 real(dp),
allocatable :: n(:,:), m(:,:)
1516 real(dp),
allocatable :: fac_n(:), fac_m(:)
1517 character(len=max_str_ln) :: frac_name
1519 real(dp),
allocatable :: x_plot(:,:)
1520 character(len=max_str_ln) :: plot_title
1521 character(len=max_str_ln) :: plot_name
1528 allocate(max_frac(grid_eq%loc_n_r,
n_mod_x))
1529 allocate(fac_n(grid_eq%loc_n_r))
1530 allocate(fac_m(grid_eq%loc_n_r))
1531 allocate(n(grid_eq%loc_n_r,
n_mod_x))
1532 allocate(m(grid_eq%loc_n_r,
n_mod_x))
1533 if (use_pol_flux_f)
then
1535 n(:,jd) =
min_n_x(grid_eq%i_min:grid_eq%i_max)
1536 m(:,jd) =
min_m_x(grid_eq%i_min:grid_eq%i_max)+jd-1
1538 fac_n = eq%q_saf_FD(:,0)
1542 n(:,jd) =
min_n_x(grid_eq%i_min:grid_eq%i_max)+jd-1
1543 m(:,jd) =
min_m_x(grid_eq%i_min:grid_eq%i_max)
1546 fac_m = eq%rot_t_FD(:,0)
1551 do kd = 1,grid_eq%loc_n_r
1553 &abs(n(kd,ld)*fac_n(kd)-m(kd,ld)*fac_m(kd))/&
1554 &min(abs(n(kd,ld)),abs(m(kd,ld)))
1559 ierr =
trim_grid(grid_eq,grid_eq_trim,norm_id=norm_id)
1563 if (rank.eq.0)
allocate(max_frac_temp(n_procs))
1564 if (rank.eq.0)
allocate(max_frac_sum(
n_mod_x))
1565 if (rank.eq.0)
allocate(max_frac_max(
n_mod_x))
1567 ierr =
get_ser_var([sum(max_frac(norm_id(1):norm_id(2),ld))],&
1570 if (rank.eq.0) max_frac_sum(ld) = sum(max_frac_temp)
1572 &[maxval(max_frac(norm_id(1):norm_id(2),ld))],max_frac_temp)
1574 if (rank.eq.0) max_frac_max(ld) = maxval(max_frac_temp)
1579 if (use_pol_flux_f)
then
1580 frac_name =
'|nq-m|/|n| or |nq-m|/|m|'
1582 frac_name =
'|n-iota m|/|n| or |n-iota m|/|m|'
1584 call writo(
'The fraction '//trim(frac_name)//
' is')
1587 call writo(
'for mode '//trim(
i2str(ld))//
' maximally '//&
1588 &trim(
r2strt(max_frac_max(ld)))//&
1590 &trim(
r2strt(max_frac_sum(ld)/grid_eq%n(3))))
1592 if (
n_mod_x.gt.1)
call writo(
'so for all modes maximally '//&
1593 &trim(
r2strt(maxval(max_frac_max)))//
', average '//&
1599 call writo(
'Plotting the fraction for all modes')
1600 allocate(x_plot(grid_eq%n(3),
n_mod_x))
1602 x_plot(:,ld) = grid_eq%r_F
1604 plot_name =
'TEST_max_frac'
1605 plot_title =
'maximum fraction'
1606 call print_ex_2d([plot_title],plot_name,max_frac,x=x_plot,&
1613 call grid_eq_trim%dealloc()
1614 end function check_x_modes_2
1645 character(*),
parameter :: rout_name =
'calc_res_surf'
1651 real(
dp),
intent(inout),
allocatable :: res_surf(:,:)
1652 logical,
intent(in),
optional :: info
1653 real(
dp),
intent(inout),
optional,
allocatable :: jq(:)
1656 real(
dp) :: nmfrac_fun
1659 integer :: norm_id(2)
1663 real(
dp),
allocatable :: res_surf_loc(:,:)
1664 real(
dp),
allocatable :: jq_tot(:)
1665 real(
dp),
allocatable :: jq_loc(:)
1666 real(
dp) :: norm_factor
1668 integer :: n_loc, m_loc
1669 character(len=max_str_ln) :: err_msg
1676 if (
present(info)) info_loc = info
1679 ierr =
trim_grid(grid_eq,grid_eq_trim,norm_id)
1683 allocate(jq_tot(grid_eq_trim%n(3)))
1685 if (grid_eq%divided)
then
1686 ierr =
get_ser_var(eq%q_saf_FD(norm_id(1):norm_id(2),0),&
1687 &jq_loc,scatter=.true.)
1691 jq_tot = eq%q_saf_FD(:,0)
1694 if (grid_eq%divided)
then
1695 ierr =
get_ser_var(eq%rot_t_FD(norm_id(1):norm_id(2),0),&
1696 &jq_loc,scatter=.true.)
1700 jq_tot = eq%rot_t_FD(:,0)
1703 if (
present(jq))
then
1704 allocate(jq(grid_eq_trim%n(3)))
1709 allocate(res_surf_loc(1:
size(mds%sec,1),3))
1716 do ld = 1,
size(mds%sec,1)
1723 m_loc = mds%sec(ld,1)
1724 nmfrac_fun = 1.0_dp*m_loc/n_loc
1726 n_loc = mds%sec(ld,1)
1728 nmfrac_fun = 1.0_dp*n_loc/m_loc
1733 res_surf_loc(ld_loc,1) = m_loc
1735 res_surf_loc(ld_loc,1) = n_loc
1737 res_surf_loc(ld_loc,3) = nmfrac_fun
1739 &[minval(grid_eq_trim%r_F),maxval(grid_eq_trim%r_F)])
1742 if (err_msg.ne.
'')
then
1744 call writo(
'Mode (n,m) = ('//trim(
i2str(n_loc))//
','//&
1745 &trim(
i2str(m_loc))//
') is not found')
1747 call writo(trim(err_msg))
1750 else if (res_surf_loc(ld_loc,2).lt.minval(grid_eq_trim%r_F) .or. &
1751 &res_surf_loc(ld_loc,2).gt.maxval(grid_eq_trim%r_F))
then
1752 if (info_loc)
call writo(
'Mode (n,m) = ('//&
1753 &trim(
i2str(n_loc))//
','//trim(
i2str(m_loc))//&
1754 &
') does not resonate in plasma')
1756 if (info_loc)
call writo(
'Mode (n,m) = ('//&
1757 &trim(
i2str(n_loc))//
','//trim(
i2str(m_loc))//&
1758 &
') resonates in plasma at normalized flux surface '//&
1759 &trim(
r2str(res_surf_loc(ld_loc,2)/norm_factor)))
1765 allocate(res_surf(ld_loc-1,3))
1766 res_surf = res_surf_loc(1:ld_loc-1,:)
1769 call grid_eq_trim%dealloc()
1774 real(
dp) function jq_fun(pt) result(res)
1778 real(
dp),
intent(in) :: pt
1781 integer :: i_min, i_max
1782 real(
dp) :: x_min, x_max
1783 real(
dp) :: res_loc(1)
1789 x_min = minval(grid_eq_trim%r_F)
1790 x_max = maxval(grid_eq_trim%r_F)
1791 i_min = minloc(grid_eq_trim%r_F,1)
1792 i_max = maxloc(grid_eq_trim%r_F,1)
1795 if (pt.ge.x_min .and. pt.le.x_max)
then
1797 ierr =
spline(grid_eq_trim%r_F,jq_tot-nmfrac_fun,[pt],res_loc,&
1823 character(*),
parameter :: rout_name =
'resonance_plot'
1827 type(grid_type),
intent(in) :: grid_eq
1832 integer :: n_mod_loc
1833 real(
dp),
allocatable :: res_surf(:,:)
1834 real(
dp),
allocatable :: x_plot_loc(:,:)
1835 real(
dp),
allocatable :: y_plot_loc(:,:)
1836 character(len=max_str_ln) :: plot_title, file_name
1837 real(
dp),
allocatable :: jq(:)
1839 integer :: plot_dim(4)
1840 type(grid_type) :: grid_trim
1841 type(grid_type) :: grid_plot
1842 real(
dp),
allocatable :: r_plot_e(:)
1843 real(
dp),
allocatable :: theta_plot(:,:,:), zeta_plot(:,:,:)
1844 real(
dp),
allocatable :: x_plot(:,:,:,:), y_plot(:,:,:,:), &
1846 real(dp),
allocatable :: vars(:,:,:,:)
1847 character(len=max_str_ln),
allocatable :: plot_titles(:)
1860 n_r = grid_trim%n(3)
1864 call writo(
'Plotting safety factor q and resonant surfaces &
1866 plot_title =
'safety factor q'
1869 call writo(
'Plotting rotational transform iota and resonant &
1870 &surfaces iota = n/m...')
1871 plot_title =
'rotational transform iota'
1877 call writo(
'Calculate resonant surfaces')
1881 ierr =
calc_res_surf(mds,grid_eq,eq,res_surf,info=.true.,jq=jq)
1889 n_mod_loc =
size(res_surf,1)
1892 allocate(plot_titles(n_mod_loc))
1895 plot_titles(ld) =
'resonance for m,n = '//&
1896 &trim(i2str(nint(res_surf(ld,3)*
prim_x)))//
','//&
1901 plot_titles(ld) =
'resonance for m,n = '//&
1902 &trim(i2str(
prim_x))//
','//&
1903 &trim(i2str(nint(res_surf(ld,3)*
prim_x)))
1908 allocate(x_plot_loc(n_r,n_mod_loc+1)); x_plot_loc = 0
1909 allocate(y_plot_loc(n_r,n_mod_loc+1)); y_plot_loc = 0
1912 x_plot_loc(:,1) = grid_trim%r_F
1913 y_plot_loc(:,1) = jq(:)
1917 x_plot_loc(:,ld+1) = res_surf(ld,2)
1918 y_plot_loc(n_r,ld+1) = res_surf(ld,3)
1922 if (
size(res_surf,1).gt.0)
then
1924 call writo(
'Plot resonant flux surfaces using HDF5')
1941 vars(:,:,:,ld) = y_plot_loc(n_r,ld+1)
1948 allocate(r_plot_e(n_mod_loc))
1949 ierr =
coord_f2e(grid_eq,x_plot_loc(n_r,2:n_mod_loc+1),&
1950 &r_plot_e,r_f_array=grid_eq%r_F,r_e_array=grid_eq%r_E)
1954 ierr = grid_plot%init(plot_dim(1:3))
1956 grid_plot%theta_E = theta_plot
1957 grid_plot%zeta_E = zeta_plot
1962 &grid_plot%zeta_E,grid_plot%trigon_factors)
1974 grid_plot%loc_r_E = r_plot_e(ld)
1978 &y_plot(:,:,:,ld),z_plot(:,:,:,ld))
1983 call plot_hdf5(plot_titles,file_name,vars,x=x_plot,y=y_plot,&
1984 &z=z_plot,col=1,descr=
'resonant surfaces')
1988 deallocate(theta_plot,zeta_plot,r_plot_e)
1989 deallocate(x_plot,y_plot,z_plot)
1990 call grid_plot%dealloc()
1995 call writo(
'Plot safety factor with resonant flux surfaces using &
2004 call print_ex_2d([plot_title,plot_titles],file_name,y_plot_loc,&
2005 &x=x_plot_loc,draw=.false.)
2006 call draw_ex([plot_title,plot_titles],file_name,n_mod_loc+1,1,&
2012 if (
size(res_surf,1).gt.0)
then
2013 call writo(
'Plot 2D map of resonances using HDF5')
2018 plot_dim = [1,n_mod_loc,1,0]
2021 allocate(x_plot(plot_dim(1),plot_dim(2),plot_dim(3),1))
2022 allocate(y_plot(plot_dim(1),plot_dim(2),plot_dim(3),1))
2023 allocate(z_plot(plot_dim(1),plot_dim(2),plot_dim(3),1))
2026 x_plot(1,ld,1,1) = x_plot_loc(1,ld+1)
2027 y_plot(1,ld,1,1) = res_surf(ld,1)
2028 z_plot(1,ld,1,1) = 1._dp
2032 call plot_hdf5(
'resonating surfaces',
'res_surf',&
2033 &z_plot(:,:,:,1),x=x_plot(:,:,:,1),y=y_plot(:,:,:,1))
2036 deallocate(x_plot,y_plot,z_plot)
2043 call grid_trim%dealloc()
2096 integer function calc_u(grid_eq,grid_X,eq_1,eq_2,X)
result(ierr)
2106 character(*),
parameter :: rout_name =
'calc_U'
2109 type(grid_type),
intent(in) :: grid_eq
2110 type(grid_type),
intent(in) :: grid_x
2111 type(
eq_1_type),
intent(in),
target :: eq_1
2112 type(
eq_2_type),
intent(in),
target :: eq_2
2113 type(x_1_type),
intent(inout) :: x
2116 integer :: id, jd, kd, ld
2120 real(
dp),
pointer :: j(:,:,:)
2121 real(
dp),
pointer :: d3j(:,:,:)
2123 real(
dp),
pointer :: g13(:,:,:)
2124 real(
dp),
pointer :: d3g13(:,:,:)
2125 real(
dp),
pointer :: g23(:,:,:)
2126 real(
dp),
pointer :: d3g23(:,:,:)
2127 real(
dp),
pointer :: g33(:,:,:)
2128 real(
dp),
pointer :: d3g33(:,:,:)
2130 real(
dp),
pointer :: h12(:,:,:)
2131 real(
dp),
pointer :: d3h12(:,:,:)
2132 real(
dp),
pointer :: h22(:,:,:)
2133 real(
dp),
pointer :: d1h22(:,:,:)
2134 real(
dp),
pointer :: d3h22(:,:,:)
2135 real(
dp),
pointer :: d13h22(:,:,:)
2136 real(
dp),
pointer :: d33h22(:,:,:)
2137 real(
dp),
pointer :: h23(:,:,:)
2138 real(
dp),
pointer :: d1h23(:,:,:)
2139 real(
dp),
pointer :: d3h23(:,:,:)
2140 real(
dp),
pointer :: d13h23(:,:,:)
2141 real(
dp),
pointer :: d33h23(:,:,:)
2143 real(
dp),
pointer :: ang_par_f(:,:,:)
2144 real(
dp),
pointer :: ang_geo_f(:,:,:)
2145 real(
dp),
pointer :: q_saf(:), rot_t(:)
2146 real(
dp),
allocatable :: djq(:)
2147 real(
dp),
allocatable :: theta_3(:,:,:), d1theta_3(:,:,:), &
2149 real(dp),
allocatable :: d13theta_3(:,:,:), d33theta_3(:,:,:)
2150 real(
dp),
allocatable :: n_frac(:,:)
2151 real(
dp),
allocatable :: nm(:,:)
2152 complex(dp),
allocatable :: u_corr(:,:,:,:)
2153 complex(dp),
allocatable :: d3u_corr(:,:,:,:)
2155 real(
dp),
allocatable,
target :: t1(:,:,:,:)
2156 real(
dp),
allocatable,
target :: t2(:,:,:,:)
2157 real(
dp),
allocatable,
target :: t3(:,:,:,:)
2158 real(
dp),
allocatable,
target :: t4(:,:,:,:)
2159 real(
dp),
allocatable,
target :: t5(:,:,:,:)
2160 real(
dp),
allocatable,
target :: t6(:,:,:,:)
2161 real(
dp),
pointer :: t1_x(:,:,:,:)
2162 real(
dp),
pointer :: t2_x(:,:,:,:)
2163 real(
dp),
pointer :: t3_x(:,:,:,:)
2164 real(
dp),
pointer :: t4_x(:,:,:,:)
2165 real(
dp),
pointer :: t5_x(:,:,:,:)
2166 real(
dp),
pointer :: t6_x(:,:,:,:)
2173 allocate(nm(grid_x%loc_n_r,x%n_mod))
2174 allocate(q_saf(grid_x%loc_n_r))
2175 allocate(rot_t(grid_x%loc_n_r))
2176 allocate(djq(grid_eq%loc_n_r))
2177 allocate(theta_3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2178 allocate(d1theta_3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2179 allocate(d3theta_3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2180 allocate(d13theta_3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2181 allocate(d33theta_3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2182 allocate(n_frac(grid_x%loc_n_r,x%n_mod))
2183 allocate(u_corr(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,2))
2184 allocate(d3u_corr(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,2))
2192 allocate(t1(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r,t_size))
2193 allocate(t2(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r,t_size))
2194 allocate(t3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r,t_size))
2195 allocate(t4(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r,t_size))
2196 allocate(t5(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r,t_size))
2197 allocate(t6(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r,t_size))
2202 allocate(q_saf(grid_x%loc_n_r))
2203 allocate(rot_t(grid_x%loc_n_r))
2204 allocate(t1_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,t_size))
2205 allocate(t2_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,t_size))
2206 allocate(t3_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,t_size))
2207 allocate(t4_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,t_size))
2208 allocate(t5_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,t_size))
2209 allocate(t6_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r,t_size))
2214 ang_par_f => grid_eq%theta_F
2215 ang_geo_f => grid_eq%zeta_F
2217 ang_par_f => grid_eq%zeta_F
2218 ang_geo_f => grid_eq%theta_F
2220 j => eq_2%jac_FD(:,:,:,0,0,0)
2221 d3j => eq_2%jac_FD(:,:,:,0,0,1)
2222 g13 => eq_2%g_FD(:,:,:,
c([1,3],.true.),0,0,0)
2223 d3g13 => eq_2%g_FD(:,:,:,
c([1,3],.true.),0,0,1)
2224 g23 => eq_2%g_FD(:,:,:,
c([2,3],.true.),0,0,0)
2225 d3g23 => eq_2%g_FD(:,:,:,
c([2,3],.true.),0,0,1)
2226 g33 => eq_2%g_FD(:,:,:,
c([3,3],.true.),0,0,0)
2227 d3g33 => eq_2%g_FD(:,:,:,
c([3,3],.true.),0,0,1)
2228 h12 => eq_2%h_FD(:,:,:,
c([1,2],.true.),0,0,0)
2229 d3h12 => eq_2%h_FD(:,:,:,
c([1,2],.true.),0,0,1)
2230 h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),0,0,0)
2231 d1h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),1,0,0)
2232 d3h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),0,0,1)
2233 d13h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),1,0,1)
2234 d33h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),0,0,2)
2235 h23 => eq_2%h_FD(:,:,:,
c([2,3],.true.),0,0,0)
2236 d1h23 => eq_2%h_FD(:,:,:,
c([2,3],.true.),1,0,0)
2237 d3h23 => eq_2%h_FD(:,:,:,
c([2,3],.true.),0,0,1)
2238 d13h23 => eq_2%h_FD(:,:,:,
c([2,3],.true.),1,0,1)
2239 d33h23 => eq_2%h_FD(:,:,:,
c([2,3],.true.),0,0,2)
2244 djq = eq_1%q_saf_FD(:,1)
2246 djq = -eq_1%rot_t_FD(:,1)
2252 d1theta_3 = d1h23/h22 - h23*d1h22/(h22**2)
2253 d3theta_3 = d3h23/h22 - h23*d3h22/(h22**2)
2254 d13theta_3 = d13h23/h22 - (d3h23*d1h22+d1h23*d3h22)/(h22**2) &
2255 &- h23*d13h22/(h22**2) + 2*h23*d3h22*d1h22/(h22**3)
2256 d33theta_3 = d33h23/h22 - 2*d3h23*d3h22/(h22**2) &
2257 &- h23*d33h22/(h22**2) + 2*h23*d3h22**2/(h22**3)
2261 do kd = 1,grid_eq%loc_n_r
2262 do id = 1,grid_eq%n(1)
2263 ierr =
spline(ang_geo_f(id,:,kd),theta_3(id,:,kd),&
2264 &ang_geo_f(id,:,kd),d1theta_3(id,:,kd),&
2274 do kd = 1,grid_eq%loc_n_r
2275 do jd = 1,grid_eq%n(2)
2276 ierr =
spline(ang_par_f(:,jd,kd),theta_3(:,jd,kd),&
2277 &ang_par_f(:,jd,kd),d3theta_3(:,jd,kd),&
2288 t1(:,:,:,1) = g13/g33
2289 do kd = 1,grid_eq%loc_n_r
2290 t2(:,:,kd,1) = h12(:,:,kd)/h22(:,:,kd) + djq(kd)*ang_par_f(:,:,kd)
2291 t3(:,:,kd,1) = t1(:,:,kd,1)*djq(kd) + &
2292 &j(:,:,kd)**2*
vac_perm*eq_1%pres_FD(kd,1)/g33(:,:,kd)
2293 t4(:,:,kd,1) = t1(:,:,kd,1)*djq(kd)*ang_par_f(:,:,kd) - &
2294 &g23(:,:,kd)/g33(:,:,kd)
2296 t5(:,:,:,1) = t1(:,:,:,1)*d3theta_3 - d1theta_3
2297 t6(:,:,:,1) = t1(:,:,:,1)*theta_3
2301 t1(:,:,:,2) = d3g13/g33 - g13*d3g33/g33**2
2302 do kd = 1,grid_eq%loc_n_r
2303 t2(:,:,kd,2) = d3h12(:,:,kd)/h22(:,:,kd) - &
2304 &h12(:,:,kd)*d3h22(:,:,kd)/h22(:,:,kd)**2 + djq(kd)
2305 t3(:,:,kd,2) = t1(:,:,kd,2)*djq(kd) + &
2306 &j(:,:,kd)*
vac_perm*eq_1%pres_FD(kd,1)/g33(:,:,kd) * &
2307 &(2*d3j(:,:,kd)-d3g33(:,:,kd)*j(:,:,kd)/g33(:,:,kd))
2308 t4(:,:,kd,2) = (t1(:,:,kd,2)*ang_par_f(:,:,kd)+t1(:,:,kd,1))*&
2309 &djq(kd) - d3g23(:,:,kd)/g33(:,:,kd) + &
2310 &g23(:,:,kd)*d3g33(:,:,kd)/g33(:,:,kd)**2
2312 t5(:,:,:,2) = t1(:,:,:,2)*d3theta_3 + t1(:,:,:,1)*d33theta_3 - &
2314 t6(:,:,:,2) = t1(:,:,:,2)*theta_3 + t1(:,:,:,1)*d3theta_3
2320 q_saf => eq_1%q_saf_FD(:,0)
2321 rot_t => eq_1%rot_t_FD(:,0)
2330 ierr =
spline(grid_eq%loc_r_F,eq_1%q_saf_FD(:,0),&
2333 ierr =
spline(grid_eq%loc_r_F,eq_1%rot_t_FD(:,0),&
2337 do jd = 1,grid_x%n(2)
2338 do id = 1,grid_x%n(1)
2339 ierr =
spline(grid_eq%loc_r_F,t1(id,jd,:,ld),&
2340 &grid_x%loc_r_F,t1_x(id,jd,:,ld),&
2343 ierr =
spline(grid_eq%loc_r_F,t2(id,jd,:,ld),&
2344 &grid_x%loc_r_F,t2_x(id,jd,:,ld),&
2347 ierr =
spline(grid_eq%loc_r_F,t3(id,jd,:,ld),&
2348 &grid_x%loc_r_F,t3_x(id,jd,:,ld),&
2351 ierr =
spline(grid_eq%loc_r_F,t4(id,jd,:,ld),&
2352 &grid_x%loc_r_F,t4_x(id,jd,:,ld),&
2355 ierr =
spline(grid_eq%loc_r_F,t5(id,jd,:,ld),&
2356 &grid_x%loc_r_F,t5_x(id,jd,:,ld),&
2359 ierr =
spline(grid_eq%loc_r_F,t6(id,jd,:,ld),&
2360 &grid_x%loc_r_F,t6_x(id,jd,:,ld),&
2369 do kd = 1,grid_x%loc_n_r
2371 n_frac(kd,:) = x%n(kd,:)*q_saf(kd) - x%m(kd,:)
2373 n_frac(kd,:) = -x%m(kd,:)*rot_t(kd) + x%n(kd,:)
2381 x%U_0(:,:,:,ld) = -t2_x(:,:,:,1)
2382 do kd = 1,grid_x%loc_n_r
2383 x%U_1(:,:,kd,ld) =
iu/nm(kd,ld)
2388 do kd = 1,grid_x%loc_n_r
2389 u_corr(:,:,kd,1) = t3_x(:,:,kd,1) + &
2390 &
iu*n_frac(kd,ld)*t4_x(:,:,kd,1)
2391 u_corr(:,:,kd,2) = n_frac(kd,ld)/nm(kd,ld)*t1_x(:,:,kd,1)
2392 x%U_0(:,:,kd,ld) = x%U_0(:,:,kd,ld) +
iu/nm(kd,ld)*&
2394 x%U_1(:,:,kd,ld) = x%U_1(:,:,kd,ld) +
iu/nm(kd,ld)*&
2400 do kd = 1,grid_x%loc_n_r
2401 u_corr(:,:,kd,1) =
iu*n_frac(kd,ld)*&
2402 &(-t5_x(:,:,kd,1)-
iu*n_frac(kd,ld)*t6_x(:,:,kd,1))
2403 x%U_0(:,:,kd,ld) = x%U_0(:,:,kd,ld) + (
iu/nm(kd,ld))**2*&
2408 call writo(
'The geodesic perturbation U is implemented up to &
2409 &order 3',warning=.true.)
2419 x%DU_0(:,:,:,ld) = -t2_x(:,:,:,2)
2420 x%DU_1(:,:,:,ld) = 0._dp
2424 do kd = 1,grid_x%loc_n_r
2425 u_corr(:,:,kd,1) = t3_x(:,:,kd,2) + &
2426 &
iu*n_frac(kd,ld)*t4_x(:,:,kd,2)
2427 u_corr(:,:,kd,2) = n_frac(kd,ld)/nm(kd,ld)*&
2429 x%DU_0(:,:,kd,ld) = x%DU_0(:,:,kd,ld) + &
2430 &
iu/nm(kd,ld)*u_corr(:,:,kd,1)
2431 x%DU_1(:,:,kd,ld) = x%DU_1(:,:,kd,ld) + &
2432 &
iu/nm(kd,ld)*u_corr(:,:,kd,2)
2437 do kd = 1,grid_x%loc_n_r
2438 u_corr(:,:,kd,1) =
iu*n_frac(kd,ld)*&
2439 &(-t5_x(:,:,kd,2)-
iu*n_frac(kd,ld)*&
2441 x%DU_0(:,:,kd,ld) = x%DU_0(:,:,kd,ld) + &
2442 &(
iu/nm(kd,ld))**2*u_corr(:,:,kd,1)
2446 call writo(
'The geodesic perturbation U is implemented &
2447 &only up to order 3',warning=.true.)
2452 call writo(
'Test calculation of DU')
2453 if(
get_log(.false.,ind=.true.))
then
2463 ang_par_f => grid_x%theta_F
2465 ang_par_f => grid_x%zeta_F
2470 do kd = 1,grid_x%loc_n_r
2471 do jd = 1,grid_x%n(2)
2472 ierr =
spline(ang_par_f(:,jd,kd),x%U_0(:,jd,kd,ld),&
2473 &ang_par_f(:,jd,kd),x%DU_0(:,jd,kd,ld),&
2476 ierr =
spline(ang_par_f(:,jd,kd),x%U_1(:,jd,kd,ld),&
2477 &ang_par_f(:,jd,kd),x%DU_1(:,jd,kd,ld),&
2486 do kd = 1,grid_x%loc_n_r
2488 x%DU_0(:,:,kd,ld) = x%DU_0(:,:,kd,ld) + &
2489 &
iu*n_frac(kd,ld)*x%U_0(:,:,kd,ld)
2490 x%DU_1(:,:,kd,ld) = x%DU_1(:,:,kd,ld) + &
2491 &
iu*n_frac(kd,ld)*x%U_1(:,:,kd,ld)
2496 nullify(ang_par_f,ang_geo_f)
2502 nullify(h22,d1h22,d3h22,d13h22,d33h22)
2503 nullify(h23,d1h23,d3h23,d13h23,d33h23)
2508 deallocate(q_saf,rot_t,t1_x,t2_x,t3_x,t4_x,t5_x,t6_x)
2510 nullify(q_saf,rot_t,t1_x,t2_x,t3_x,t4_x,t5_x,t6_x)
2517 character(*),
parameter :: rout_name =
'test_DU'
2520 integer :: jd, kd, ld
2521 complex(dp),
allocatable :: du_0(:,:,:)
2522 complex(dp),
allocatable :: du_1(:,:,:)
2523 character(len=max_str_ln) :: file_name
2524 character(len=max_str_ln) :: description
2530 call writo(
'This test is representable only if there are enough &
2531 ¶llel points in the grid!',warning=.true.)
2534 call writo(
'Going to test whether DU is consistent with U')
2538 allocate(du_0(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2539 allocate(du_1(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2543 ang_par_f => grid_x%theta_F
2545 ang_par_f => grid_x%zeta_F
2551 do kd = 1,grid_x%loc_n_r
2552 do jd = 1,grid_x%n(2)
2553 ierr =
spline(ang_par_f(:,jd,kd),x%U_0(:,jd,kd,ld),&
2554 &ang_par_f(:,jd,kd),du_0(:,jd,kd),&
2557 ierr =
spline(ang_par_f(:,jd,kd),x%U_1(:,jd,kd,ld),&
2558 &ang_par_f(:,jd,kd),du_1(:,jd,kd),&
2565 file_name =
'TEST_RE_DU_0_'//trim(i2str(ld))
2566 description =
'Verifying DU_0 by deriving U_0 numerically for &
2567 &mode '//trim(i2str(ld)//
', real part')
2570 call plot_diff_hdf5(rp(du_0),rp(x%DU_0(:,:,:,ld)),&
2571 &file_name,descr=description,output_message=.true.)
2574 file_name =
'TEST_IM_DU_0_'//trim(i2str(ld))
2575 description =
'Verifying DU_0 by deriving U_0 numerically for &
2576 &mode '//trim(i2str(ld)//
', imaginary part')
2579 call plot_diff_hdf5(ip(du_0),ip(x%DU_0(:,:,:,ld)),&
2580 &file_name,descr=description,output_message=.true.)
2583 file_name =
'TEST_RE_DU_1_'//trim(i2str(ld))
2584 description =
'Verifying DU_1 by deriving U_1 numerically for &
2585 &mode '//trim(i2str(ld)//
', real part')
2588 call plot_diff_hdf5(rp(du_1),rp(x%DU_1(:,:,:,ld)),&
2589 &file_name,descr=description,output_message=.true.)
2592 file_name =
'TEST_IM_DU_1_'//trim(i2str(ld))
2593 description =
'Verifying DU_1 by deriving U_1 numerically for &
2594 &mode '//trim(i2str(ld)//
', imaginary part')
2597 call plot_diff_hdf5(ip(du_1),ip(x%DU_1(:,:,:,ld)),&
2598 &file_name,descr=description,output_message=.true.)
2603 call writo(
'Test complete')
2644 integer function calc_pv(grid_eq,grid_X,eq_1,eq_2,X_a,X_b,X,lim_sec_X) &
2652 character(*),
parameter :: rout_name =
'calc_PV'
2655 type(grid_type),
intent(in) :: grid_eq
2656 type(grid_type),
intent(in) :: grid_x
2657 type(
eq_1_type),
intent(in),
target :: eq_1
2658 type(
eq_2_type),
intent(in),
target :: eq_2
2662 integer,
intent(in),
optional :: lim_sec_x(2,2)
2666 integer :: id, jd, kd
2668 logical :: calc_this(2)
2671 real(
dp),
pointer :: j(:,:,:)
2673 real(
dp),
pointer :: g33(:,:,:)
2675 real(
dp),
pointer :: h22(:,:,:)
2677 real(
dp),
pointer :: q_saf(:), rot_t(:)
2678 real(
dp),
allocatable :: fac_n(:), fac_m(:)
2680 real(
dp),
allocatable,
target :: t1(:,:,:)
2681 real(
dp),
allocatable,
target :: t2(:,:,:)
2682 real(
dp),
allocatable,
target :: t3(:,:,:)
2683 real(
dp),
allocatable,
target :: t4(:,:,:)
2684 real(
dp),
allocatable,
target :: t5(:,:,:)
2685 real(
dp),
pointer :: t1_x(:,:,:)
2686 real(
dp),
pointer :: t2_x(:,:,:)
2687 real(
dp),
pointer :: t3_x(:,:,:)
2688 real(
dp),
pointer :: t4_x(:,:,:)
2689 real(
dp),
pointer :: t5_x(:,:,:)
2696 allocate(q_saf(grid_x%loc_n_r))
2697 allocate(rot_t(grid_x%loc_n_r))
2698 allocate(fac_n(grid_x%loc_n_r),fac_m(grid_x%loc_n_r))
2700 allocate(t1(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2701 allocate(t2(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2702 allocate(t3(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2703 allocate(t4(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2704 allocate(t5(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2709 allocate(q_saf(grid_x%loc_n_r))
2710 allocate(rot_t(grid_x%loc_n_r))
2711 allocate(t1_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2712 allocate(t2_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2713 allocate(t3_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2714 allocate(t4_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2715 allocate(t5_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2719 j => eq_2%jac_FD(:,:,:,0,0,0)
2720 g33 => eq_2%g_FD(:,:,:,
c([3,3],.true.),0,0,0)
2721 h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),0,0,0)
2725 t2 = j*eq_2%S +
vac_perm*eq_2%sigma*g33/(j*h22)
2726 t3 = eq_2%sigma/j*t2
2728 do kd = 1,grid_eq%loc_n_r
2729 t5(:,:,kd) = 2*eq_1%pres_FD(kd,1)*eq_2%kappa_n(:,:,kd)
2735 q_saf => eq_1%q_saf_FD(:,0)
2736 rot_t => eq_1%rot_t_FD(:,0)
2744 ierr =
spline(grid_eq%loc_r_F,eq_1%q_saf_FD(:,0),&
2747 ierr =
spline(grid_eq%loc_r_F,eq_1%rot_t_FD(:,0),&
2750 do jd = 1,grid_x%n(2)
2751 do id = 1,grid_x%n(1)
2752 ierr =
spline(grid_eq%loc_r_F,t1(id,jd,:),&
2753 &grid_x%loc_r_F,t1_x(id,jd,:),&
2756 ierr =
spline(grid_eq%loc_r_F,t2(id,jd,:),&
2757 &grid_x%loc_r_F,t2_x(id,jd,:),&
2760 ierr =
spline(grid_eq%loc_r_F,t3(id,jd,:),&
2761 &grid_x%loc_r_F,t3_x(id,jd,:),&
2764 ierr =
spline(grid_eq%loc_r_F,t4(id,jd,:),&
2765 &grid_x%loc_r_F,t4_x(id,jd,:),&
2768 ierr =
spline(grid_eq%loc_r_F,t5(id,jd,:),&
2769 &grid_x%loc_r_F,t5_x(id,jd,:),&
2789 do kd = 1,grid_x%loc_n_r
2790 if (x%n_1(kd,k).ne.x_a%n(kd,k) .or. &
2791 &x%n_2(kd,
m).ne.x_b%n(kd,
m) .or. &
2792 &x%m_1(kd,k).ne.x_a%m(kd,k) .or. &
2793 &x%m_2(kd,
m).ne.x_b%m(kd,
m))
then
2795 chckerr(
'Modes do not match')
2804 c_loc(1) =
c([k,
m],.true.,
n_mod_x,lim_sec_x)
2805 c_loc(2) =
c([k,
m],.false.,
n_mod_x,lim_sec_x)
2808 if (calc_this(1))
then
2809 do kd = 1,grid_x%loc_n_r
2810 x%PV_0(:,:,kd,c_loc(1)) = t1_x(:,:,kd)*&
2811 &(x_b%DU_0(:,:,kd,
m) - t2_x(:,:,kd)) * &
2812 &(conjg(x_a%DU_0(:,:,kd,k)) - t2_x(:,:,kd)) - &
2813 &t3_x(:,:,kd) - t5_x(:,:,kd) + t4_x(:,:,kd)*&
2814 &(x_b%n(kd,
m)*fac_n(kd)-x_b%m(kd,
m)*fac_m(kd))*&
2815 &(x_a%n(kd,k)*fac_n(kd)-x_a%m(kd,k)*fac_m(kd))
2820 if (calc_this(2))
then
2821 x%PV_1(:,:,:,c_loc(2)) = t1_x * x_b%DU_1(:,:,:,
m) * &
2822 &(conjg(x_a%DU_0(:,:,:,k))-t2_x)
2826 if (calc_this(1))
then
2827 x%PV_2(:,:,:,c_loc(1)) = t1_x * x_b%DU_1(:,:,:,
m) * &
2828 &conjg(x_a%DU_1(:,:,:,k))
2841 deallocate(q_saf,rot_t,t1_x,t2_x,t3_x,t4_x,t5_x)
2843 nullify(q_saf,rot_t,t1_x,t2_x,t3_x,t4_x,t5_x)
2844 end function calc_pv
2877 integer function calc_kv(grid_eq,grid_X,eq_1,eq_2,X_a,X_b,X,lim_sec_X) &
2884 character(*),
parameter :: rout_name =
'calc_KV'
2887 type(grid_type),
intent(in) :: grid_eq
2888 type(grid_type),
intent(in) :: grid_x
2889 type(eq_1_type),
intent(in) :: eq_1
2890 type(eq_2_type),
intent(in),
target :: eq_2
2894 integer,
intent(in),
optional :: lim_sec_x(2,2)
2898 integer :: id, jd, kd
2900 logical :: calc_this(2)
2903 real(
dp),
pointer :: j(:,:,:)
2905 real(
dp),
pointer :: g33(:,:,:)
2907 real(
dp),
pointer :: h22(:,:,:)
2909 real(
dp),
allocatable,
target :: t1(:,:,:)
2910 real(
dp),
allocatable,
target :: t2(:,:,:)
2911 real(
dp),
pointer :: t1_x(:,:,:)
2912 real(
dp),
pointer :: t2_x(:,:,:)
2919 allocate(t1(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2920 allocate(t2(grid_eq%n(1),grid_eq%n(2),grid_eq%loc_n_r))
2925 allocate(t1_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2926 allocate(t2_x(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
2930 j => eq_2%jac_FD(:,:,:,0,0,0)
2931 g33 => eq_2%g_FD(:,:,:,
c([3,3],.true.),0,0,0)
2932 h22 => eq_2%h_FD(:,:,:,
c([2,2],.true.),0,0,0)
2935 do kd = 1,grid_eq%loc_n_r
2936 t1(:,:,kd) = eq_1%rho(kd)*j(:,:,kd)**2*h22(:,:,kd)/g33(:,:,kd)
2937 t2(:,:,kd) = eq_1%rho(kd)/h22(:,:,kd)
2947 do jd = 1,grid_x%n(2)
2948 do id = 1,grid_x%n(1)
2949 ierr =
spline(grid_eq%loc_r_F,t1(id,jd,:),&
2950 &grid_x%loc_r_F,t1_x(id,jd,:),&
2953 ierr =
spline(grid_eq%loc_r_F,t2(id,jd,:),&
2954 &grid_x%loc_r_F,t2_x(id,jd,:),&
2965 do kd = 1,grid_x%loc_n_r
2966 if (x%n_1(kd,k).ne.x_a%n(kd,k) .or. &
2967 &x%n_2(kd,
m).ne.x_b%n(kd,
m) .or. &
2968 &x%m_1(kd,k).ne.x_a%m(kd,k) .or. &
2969 &x%m_2(kd,
m).ne.x_b%m(kd,
m))
then
2971 chckerr(
'Modes do not match')
2980 c_loc(1) =
c([k,
m],.true.,
n_mod_x,lim_sec_x)
2981 c_loc(2) =
c([k,
m],.false.,
n_mod_x,lim_sec_x)
2986 if (calc_this(1))
then
2987 x%KV_0(:,:,:,c_loc(1)) = t2_x + t1_x * &
2988 &x_b%U_0(:,:,:,
m) * conjg(x_a%U_0(:,:,:,k))
2992 if (calc_this(2))
then
2993 x%KV_1(:,:,:,c_loc(2)) = t1_x * &
2994 &x_b%U_1(:,:,:,
m) * conjg(x_a%U_0(:,:,:,k))
2998 if (calc_this(1))
then
2999 x%KV_2(:,:,:,c_loc(1)) = t1_x * &
3000 &x_b%U_1(:,:,:,
m) * conjg(x_a%U_1(:,:,:,k))
3004 if (calc_this(1))
then
3005 x%KV_0(:,:,:,c_loc(1)) = t2_x
3009 if (calc_this(2))
then
3010 x%KV_1(:,:,:,c_loc(2)) = 0._dp
3014 if (calc_this(1))
then
3015 x%KV_2(:,:,:,c_loc(1)) = 0._dp
3029 deallocate(t1_x,t2_x)
3032 end function calc_kv
3080 &lim_sec_X)
result(ierr)
3089 character(*),
parameter :: rout_name =
'calc_magn_ints'
3094 type(eq_2_type),
intent(in),
target :: eq
3096 type(
x_2_type),
intent(inout) :: x_int
3097 integer,
intent(in),
optional :: prev_style
3098 integer,
intent(in),
optional :: lim_sec_x(2,2)
3101 logical :: calc_this(2)
3103 integer :: id, jd, kd
3106 integer :: prev_style_loc
3107 real(
dp) :: alpha_fac
3108 real(
dp) :: prev_mult_fac
3109 real(
dp),
allocatable :: step_size(:,:)
3110 real(
dp),
pointer :: ang_par_f(:,:,:) => null()
3111 complex(dp),
allocatable :: v_int_work(:,:)
3114 integer :: nr_int_regions
3115 integer,
allocatable :: int_dims(:,:)
3116 real(
dp),
allocatable :: int_facs(:)
3117 complex(dp),
allocatable :: j_exp_ang(:,:,:)
3122 real(
dp),
pointer :: j(:,:,:)
3128 call writo(
'Calculate field-line averages')
3133 if (
present(prev_style)) prev_style_loc = prev_style
3136 allocate(j_exp_ang(grid_x%n(1),grid_x%n(2),grid_x%loc_n_r))
3140 j => eq%jac_FD(:,:,:,0,0,0)
3143 allocate(j(grid_eq%n(1),grid_eq%n(2),grid_x%loc_n_r))
3146 do jd = 1,grid_x%n(2)
3147 do id = 1,grid_x%n(1)
3148 ierr =
spline(grid_eq%loc_r_F,eq%jac_FD(id,jd,:,0,0,0),&
3157 ang_par_f => grid_x%theta_F
3159 ang_par_f => grid_x%zeta_F
3175 select case (prev_style_loc)
3182 select case (prev_style_loc)
3191 allocate(int_facs(nr_int_regions))
3192 allocate(int_dims(nr_int_regions,3))
3195 select case (prev_style_loc)
3197 int_facs = 0.5_dp*[2]
3198 int_dims(1,:) = [1,grid_x%n(1),1]
3200 int_facs = 0.5_dp*[1,2]
3201 int_dims(1,:) = [1,grid_x%n(1),grid_x%n(1)-1]
3202 int_dims(2,:) = [2,grid_x%n(1)-1,1]
3205 select case (prev_style_loc)
3207 int_facs = 0.375_dp*[3,2,3]
3208 int_dims(1,:) = [1,grid_x%n(1)-2,3]
3209 int_dims(2,:) = [2,grid_x%n(1)-1,3]
3210 int_dims(3,:) = [3,grid_x%n(1),3]
3212 int_facs = 0.375_dp*[1,3,3,2]
3213 int_dims(1,:) = [1,grid_x%n(1),grid_x%n(1)-1]
3214 int_dims(2,:) = [2,grid_x%n(1)-2,3]
3215 int_dims(3,:) = [3,grid_x%n(1)-1,3]
3216 int_dims(4,:) = [4,grid_x%n(1)-3,3]
3221 select case (prev_style_loc)
3223 prev_mult_fac = 1.0_dp
3225 prev_mult_fac = 0.5_dp
3227 prev_mult_fac = 0.0_dp
3231 allocate(step_size(grid_x%n(2),grid_x%loc_n_r))
3232 step_size = ang_par_f(2,:,:)-ang_par_f(1,:,:)
3233 if (
rich_lvl.gt.1) step_size = step_size*0.5_dp
3236 allocate(v_int_work(grid_x%n(2),grid_x%loc_n_r))
3246 c_loc(1) =
c([k,
m],.true.,
n_mod_x,lim_sec_x)
3247 c_loc(2) =
c([k,
m],.false.,
n_mod_x,lim_sec_x)
3248 c_tot(1) =
c([lim_sec_x(1,1)-1+k,lim_sec_x(1,2)-1+
m],.true.,&
3250 c_tot(2) =
c([lim_sec_x(1,1)-1+k,lim_sec_x(1,2)-1+
m],.false.,&
3254 do kd = 1,grid_x%loc_n_r
3256 j_exp_ang(:,:,kd) = j(:,:,kd)*&
3257 &exp(
iu*(x%m_1(kd,k)-x%m_2(kd,
m))*&
3260 j_exp_ang(:,:,kd) = j(:,:,kd)*&
3261 &exp(-
iu*(x%n_1(kd,k)-x%n_2(kd,
m))*&
3267 if (calc_this(1))
then
3268 x_int%PV_0(1,:,:,c_tot(1)) = &
3269 &prev_mult_fac*x_int%PV_0(1,:,:,c_tot(1))
3270 x_int%KV_0(1,:,:,c_tot(1)) = &
3271 &prev_mult_fac*x_int%KV_0(1,:,:,c_tot(1))
3272 call calc_magn_int_loc(x%PV_0(:,:,:,c_loc(1))*alpha_fac,&
3273 &x_int%PV_0(1,:,:,c_tot(1)),v_int_work,step_size)
3274 call calc_magn_int_loc(x%KV_0(:,:,:,c_loc(1))*alpha_fac,&
3275 &x_int%KV_0(1,:,:,c_tot(1)),v_int_work,step_size)
3279 if (calc_this(2))
then
3280 x_int%PV_1(1,:,:,c_tot(2)) = &
3281 &prev_mult_fac*x_int%PV_1(1,:,:,c_tot(2))
3282 x_int%KV_1(1,:,:,c_tot(2)) = &
3283 &prev_mult_fac*x_int%KV_1(1,:,:,c_tot(2))
3284 call calc_magn_int_loc(x%PV_1(:,:,:,c_loc(2))*alpha_fac,&
3285 &x_int%PV_1(1,:,:,c_tot(2)),v_int_work,step_size)
3286 call calc_magn_int_loc(x%KV_1(:,:,:,c_loc(2))*alpha_fac,&
3287 &x_int%KV_1(1,:,:,c_tot(2)),v_int_work,step_size)
3291 if (calc_this(1))
then
3292 x_int%PV_2(1,:,:,c_tot(1)) = &
3293 &prev_mult_fac*x_int%PV_2(1,:,:,c_tot(1))
3294 x_int%KV_2(1,:,:,c_tot(1)) = &
3295 &prev_mult_fac*x_int%KV_2(1,:,:,c_tot(1))
3296 call calc_magn_int_loc(x%PV_2(:,:,:,c_loc(1))*alpha_fac,&
3297 &x_int%PV_2(1,:,:,c_tot(1)),v_int_work,step_size)
3298 call calc_magn_int_loc(x%KV_2(:,:,:,c_loc(1))*alpha_fac,&
3299 &x_int%KV_2(1,:,:,c_tot(1)),v_int_work,step_size)
3321 subroutine calc_magn_int_loc(V,V_int,V_int_work,step_size)
3323 complex(dp),
intent(in) :: v(:,:,:)
3324 complex(dp),
intent(inout) :: v_int(:,:)
3325 complex(dp),
intent(inout) :: v_int_work(:,:)
3326 real(
dp) :: step_size(:,:)
3329 integer :: id, kd, ld
3332 do ld = 1,nr_int_regions
3337 do kd = 1,
size(step_size,2)
3338 do id = int_dims(ld,1),int_dims(ld,2),int_dims(ld,3)
3339 v_int_work(:,kd) = v_int_work(:,kd) + &
3340 &j_exp_ang(id,:,kd)*v(id,:,kd)*step_size(:,kd)
3345 v_int = v_int + v_int_work*int_facs(ld)
3347 end subroutine calc_magn_int_loc
3368 character(*),
parameter :: rout_name =
'divide_X_jobs'
3371 integer,
intent(in) :: arr_size
3375 real(
dp) :: mem_size
3376 integer :: n_mod_block
3377 integer,
allocatable :: n_mod_loc(:)
3378 character(len=max_str_ln) :: block_message
3379 character(len=max_str_ln) :: err_msg
3385 call writo(
'Dividing the perturbation jobs')
3390 mem_size = huge(1._dp)
3393 n_mod_block = ceiling(
n_mod_x*1._dp/n_div)
3398 err_msg =
'The memory limit is too low'
3402 if (n_div.gt.1)
then
3403 block_message =
'The '//trim(i2str(
n_mod_x))//&
3404 &
' Fourier modes are split into '//trim(i2str(n_div))//&
3405 &
' and '//trim(i2str(n_div**2))//
' jobs are done separately'
3407 block_message = trim(block_message)//
', '//&
3408 &trim(i2str(
n_procs))//
' at a time'
3410 block_message = trim(block_message)//
', but simultaneously'
3413 block_message =
'The '//trim(i2str(
n_mod_x))//
' Fourier modes &
3414 &can be done without splitting them'
3416 call writo(block_message)
3417 call writo(
'The total memory for all processes together is estimated &
3418 &to be about '//trim(i2str(ceiling(mem_size)))//
'MB')
3420 call writo(
'(maximum: '//trim(i2str(ceiling(
max_x_mem)))//&
3421 &
'MB left over from equilibrium variables)')
3432 allocate(n_mod_loc(n_div))
3434 n_mod_loc(1:mod(
n_mod_x,n_div)) = n_mod_loc(1:mod(
n_mod_x,n_div)) + 1
3439 call writo(
'Perturbation jobs divided')
3454 recursive subroutine calc_x_jobs_lims(res,n_mod,ord)
3456 integer,
intent(inout),
allocatable :: res(:,:)
3457 integer,
intent(in) :: n_mod(:)
3458 integer,
intent(in) :: ord
3461 integer,
allocatable :: res_loc(:,:)
3469 if (
allocated(res))
deallocate(res)
3470 allocate(res(2*ord,n_div**ord))
3475 call calc_x_jobs_lims(res_loc,n_mod,ord-1)
3476 res(1:2*ord-2,(id-1)*n_div**(ord-1)+1:id*n_div**(ord-1)) = &
3479 res(2*ord-1,(id-1)*n_div**(ord-1)+1:id*n_div**(ord-1)) = &
3480 &sum(n_mod(1:id-1))+1
3481 res(2*ord,(id-1)*n_div**(ord-1)+1:id*n_div**(ord-1)) = &
3484 end subroutine calc_x_jobs_lims
3496 character(*),
parameter :: rout_name =
'print_debug_X_1'
3499 type(modes_type),
intent(in) :: mds
3501 type(x_1_type),
intent(in) :: x_1
3505 character(len=max_str_ln),
allocatable :: var_names(:)
3506 character(len=max_str_ln) :: file_name
3508 integer :: ld, kd, jd, rd, id
3510 integer :: n_mod_tot
3511 integer :: kdl_tot(2)
3514 integer :: kd_loc_trim
3515 integer :: plot_dim(4)
3516 integer :: plot_offset(4)
3517 complex(dp),
allocatable :: u(:,:,:,:,:)
3518 complex(dp),
allocatable :: du(:,:,:,:,:)
3519 real(
dp),
allocatable :: x_plot(:,:,:,:)
3520 real(
dp),
allocatable :: y_plot(:,:,:,:)
3521 real(
dp),
allocatable :: z_plot(:,:,:,:)
3531 min_nm_x = minval(mds%sec(:,1),1)
3532 n_mod_tot =
size(mds%sec,1)
3533 allocate(u(n_mod_tot,grid_trim%n(1),grid_trim%loc_n_r,grid_trim%n(2),&
3535 allocate(du(n_mod_tot,grid_trim%n(1),grid_trim%loc_n_r,grid_trim%n(2),&
3537 allocate(x_plot(n_mod_tot,grid_trim%n(1),grid_trim%loc_n_r,&
3539 allocate(y_plot(n_mod_tot,grid_trim%n(1),grid_trim%loc_n_r,&
3541 allocate(z_plot(n_mod_tot,grid_trim%n(1),grid_trim%loc_n_r,&
3547 do kd = 1,grid_trim%loc_n_r
3548 z_plot(:,:,kd,1) = 1000*grid_trim%loc_r_F(kd)/
max_flux_f*2*
pi
3550 do id = 1,grid_trim%n(1)
3551 x_plot(rd,id,kd,:) = min_nm_x+rd-1
3552 do jd = 1,grid_trim%n(2)
3554 y_plot(rd,id,kd,jd) = grid_trim%theta_F(id,jd,kd)*10
3556 y_plot(rd,id,kd,jd) = grid_trim%zeta_F(id,jd,kd)*10
3564 do k = 1,
size(mds%sec,1)
3566 kdl_tot(1) = mds%sec(k,2)
3567 kdl_tot(2) = mds%sec(k,3)
3570 kdl_tot(1) = max(kdl_tot(1),grid_trim%i_min)
3571 kdl_tot(2) = min(kdl_tot(2),grid_trim%i_max)
3574 if (kdl_tot(1).gt.kdl_tot(2)) cycle
3577 rd = mds%sec(k,1)-min_nm_x+1
3583 do kd = kdl_tot(1),kdl_tot(2)
3585 kd_loc = kd - grid_x%i_min + 1
3586 kd_loc_trim = kd - grid_trim%i_min + 1
3588 u(rd,:,kd_loc_trim,:,0) = x_1%U_0(:,:,kd_loc,rdl)
3589 u(rd,:,kd_loc_trim,:,1) = x_1%U_1(:,:,kd_loc,rdl)
3590 du(rd,:,kd_loc_trim,:,0) = x_1%DU_0(:,:,kd_loc,rdl)
3591 du(rd,:,kd_loc_trim,:,1) = x_1%DU_1(:,:,kd_loc,rdl)
3597 do ld = 1,
size(var_names)
3598 var_names(ld) =
'alpha = '//trim(r2strt(
alpha(ld)))
3600 plot_dim = [n_mod_tot,grid_trim%n(1),grid_trim%n(3),
n_alpha]
3601 plot_offset = [0,0,grid_trim%i_min-1,0]
3603 file_name =
'U_'//trim(i2str(id))//
'_R'//&
3605 call plot_hdf5(var_names,
'RE_'//trim(file_name),&
3606 &rp(u(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3607 &tot_dim=plot_dim, loc_offset=plot_offset,&
3609 call plot_hdf5(var_names,
'IM_'//trim(file_name),&
3610 &ip(u(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3611 &tot_dim=plot_dim, loc_offset=plot_offset,&
3614 file_name =
'DU_'//trim(i2str(id))//
'_R'//&
3616 call plot_hdf5(var_names,
'RE_'//trim(file_name),&
3617 &rp(du(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3618 &tot_dim=plot_dim, loc_offset=plot_offset,&
3620 call plot_hdf5(var_names,
'IM_'//trim(file_name),&
3621 &ip(du(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3622 &tot_dim=plot_dim, loc_offset=plot_offset,&
3625 deallocate(var_names)
3628 call grid_trim%dealloc()
3640 character(*),
parameter :: rout_name =
'print_debug_X_2'
3645 type(
x_2_type),
intent(in) :: x_2_int
3649 character(len=max_str_ln),
allocatable :: var_names(:)
3650 character(len=max_str_ln) :: file_name
3652 integer :: id, ld, kd, rd, cd
3654 integer :: n_mod_tot
3655 integer :: kdl_tot(2)
3657 integer :: kd_loc_trim
3658 integer :: plot_dim(4)
3659 integer :: plot_offset(4)
3662 complex(dp),
allocatable :: pv_int(:,:,:,:,:)
3663 complex(dp),
allocatable :: kv_int(:,:,:,:,:)
3664 real(dp),
allocatable :: x_plot(:,:,:,:)
3665 real(dp),
allocatable :: y_plot(:,:,:,:)
3666 real(dp),
allocatable :: z_plot(:,:,:,:)
3677 n_mod_tot =
size(mds%sec,1)
3678 allocate(pv_int(n_mod_tot,n_mod_tot,grid_trim%loc_n_r,&
3679 &grid_trim%n(2),0:2))
3680 allocate(kv_int(n_mod_tot,n_mod_tot,grid_trim%loc_n_r,&
3681 &grid_trim%n(2),0:2))
3682 allocate(x_plot(n_mod_tot,n_mod_tot,grid_trim%loc_n_r,1))
3683 allocate(y_plot(n_mod_tot,n_mod_tot,grid_trim%loc_n_r,1))
3684 allocate(z_plot(n_mod_tot,n_mod_tot,grid_trim%loc_n_r,1))
3689 do kd = 1,grid_trim%loc_n_r
3690 z_plot(:,:,kd,1) = 1000*grid_trim%loc_r_F(kd)/
max_flux_f*2*pi
3700 do m = 1,
size(mds%sec,1)
3701 do k = 1,
size(mds%sec,1)
3703 kdl_tot(1) = max(mds%sec(k,2),mds%sec(
m,2))
3704 kdl_tot(2) = min(mds%sec(k,3),mds%sec(
m,3))
3707 kdl_tot(1) = max(kdl_tot(1),grid_trim%i_min)
3708 kdl_tot(2) = min(kdl_tot(2),grid_trim%i_max)
3711 if (kdl_tot(1).gt.kdl_tot(2)) cycle
3722 c_loc(1) =
c([rdl,cdl],.true.,
n_mod_x)
3723 c_loc(2) =
c([rdl,cdl],.false.,
n_mod_x)
3726 do kd = kdl_tot(1),kdl_tot(2)
3728 kd_loc = kd - grid_x%i_min + 1
3729 kd_loc_trim = kd - grid_trim%i_min + 1
3732 pv_int(rd,cd,kd_loc_trim,:,0) = &
3733 &
con(x_2_int%PV_0(1,:,kd_loc,c_loc(1)),&
3735 pv_int(rd,cd,kd_loc_trim,:,2) = &
3736 &
con(x_2_int%PV_2(1,:,kd_loc,c_loc(1)),&
3738 kv_int(rd,cd,kd_loc_trim,:,0) = &
3739 &
con(x_2_int%KV_0(1,:,kd_loc,c_loc(1)),&
3741 kv_int(rd,cd,kd_loc_trim,:,2) = &
3742 &
con(x_2_int%KV_2(1,:,kd_loc,c_loc(1)),&
3746 pv_int(rd,cd,kd_loc_trim,:,1) = &
3747 &x_2_int%PV_1(1,:,kd_loc,c_loc(2))
3748 kv_int(rd,cd,kd_loc_trim,:,1) = &
3749 &x_2_int%KV_1(1,:,kd_loc,c_loc(2))
3756 do ld = 1,
size(var_names)
3757 var_names(ld) =
'alpha = '//trim(r2strt(
alpha(ld)))
3759 plot_dim = [n_mod_tot,n_mod_tot,grid_trim%n(3),
n_alpha]
3760 plot_offset = [0,0,grid_trim%i_min-1,0]
3762 file_name =
'PV_'//trim(i2str(id))//
'_int_R'//&
3764 call plot_hdf5(var_names,
'RE_'//trim(file_name),&
3765 &rp(pv_int(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3766 &tot_dim=plot_dim, loc_offset=plot_offset,&
3768 call plot_hdf5(var_names,
'IM_'//trim(file_name),&
3769 &ip(pv_int(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3770 &tot_dim=plot_dim, loc_offset=plot_offset,&
3773 file_name =
'KV_'//trim(i2str(id))//
'_int_R'//&
3775 call plot_hdf5(var_names,
'RE_'//trim(file_name),&
3776 &rp(kv_int(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3777 &tot_dim=plot_dim, loc_offset=plot_offset,&
3779 call plot_hdf5(var_names,
'IM_'//trim(file_name),&
3780 &ip(kv_int(:,:,:,:,id)),x=x_plot,y=y_plot,z=z_plot,&
3781 &tot_dim=plot_dim, loc_offset=plot_offset,&
3784 deallocate(var_names)
3787 call grid_trim%dealloc()
integer function test_du()
Calculate grid of equidistant points, where optionally the last point can be excluded.
Converts Flux coordinates to Equilibrium coordinates .
Gather parallel variable in serial version on group master.
Either takes the complex conjugate of a square matrix element A, defined on a 3-D grid,...
Wrapper to the pspline library, making it easier to use for 1-D applications where speed is not the m...
Print 2-D output on a file.
Calculates either vectorial or tensorial perturbation variables.
Print either vectorial or tensorial perturbation quantities of a certain order to an output file.
Redistribute the perturbation variables.
Variables that have to do with equilibrium quantities and the grid used in the calculations:
real(dp), public max_flux_f
max. flux in Flux coordinates, set in calc_norm_range_PB3D_in
real(dp), public vac_perm
either usual mu_0 (default) or normalized
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.
integer function, public calc_xyz_grid(grid_eq, grid_xyz, x, y, z, l, r)
Calculates , and on a grid grid_XYZ, determined through its E(quilibrium) coordinates.
Variables pertaining to the different grids used.
real(dp), dimension(:), allocatable, public alpha
field line label alpha
real(dp), public min_par_x
min. of parallel coordinate [ ] in field-aligned grid
integer, public n_alpha
nr. of field-lines
real(dp), public max_par_x
max. of parallel coordinate [ ] in field-aligned grid
Operations on HDF5 and XDMF variables.
integer function, public print_hdf5_arrs(vars, pb3d_name, head_name, rich_lvl, disp_info, ind_print, remove_previous_arrs)
Prints a series of arrays, in the form of an array of pointers, to an HDF5 file.
Variables pertaining to HDF5 and XDMF.
integer, parameter, public max_dim_var_1d
maximum dimension of var_1D
Numerical utilities related to giving output.
subroutine, public lvl_ud(inc)
Increases/decreases lvl of output.
subroutine, public writo(input_str, persistent, error, warning, alert)
Write output to file identified by output_i.
Numerical utilities related to MPI.
integer function, public redistribute_var(var, dis_var, lims, lims_dis)
Redistribute variables according to new limits.
character(len=max_str_ln) function, public calc_zero_zhang(zero, fun, x_int_in)
Finds the zero of a function using Zhang's method, which is simpler than Brent's method.
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.
integer, parameter, public dp
double precision
logical, public ltest
whether or not to call the testing routines
integer, public n_theta_plot
nr. of poloidal points in plot
integer, parameter, public max_name_ln
maximum length of filenames
real(dp), public min_theta_plot
min. of theta_plot
real(dp), parameter, public pi
real(dp), public max_zeta_plot
max. of zeta_plot
real(dp), public tol_norm
tolerance for normal range (normalized to 0..1)
integer, public n_procs
nr. of MPI processes
complex(dp), parameter, public iu
complex unit
integer, parameter, public max_str_ln
maximum length of strings
integer, dimension(:,:), allocatable, public x_jobs_lims
data about X jobs: [ , , , ] for all jobs
integer, public u_style
style for calculation of U (1: ord.2, 2: ord.1, 1: ord.0)
integer, public n_zeta_plot
nr. of toroidal points in plot
integer, dimension(:,:), allocatable, public eq_jobs_lims
data about eq jobs: [ , ] for all jobs
integer, public x_grid_style
style for normal component of X grid (1: eq, 2: sol, 3: enriched)
real(dp), public min_zeta_plot
min. of zeta_plot
integer, public eq_style
either 1 (VMEC) or 2 (HELENA)
character(len=max_str_ln), public pb3d_name
name of PB3D output file
integer, public norm_disc_prec_eq
precision for normal discretization for equilibrium
integer, public alpha_style
style for alpha (1: one field line, many turns, 2: many field lines, one turn)
integer, public rank
MPI rank.
integer, public k_style
style for kinetic energy
integer, public norm_disc_prec_x
precision for normal discretization for perturbation
integer, public x_style
style for secondary mode numbers (1: prescribed, 2: fast)
real(dp), public max_theta_plot
max. of theta_plot
integer, public eq_job_nr
nr. of eq job
logical, public use_pol_flux_f
whether poloidal flux is used in F coords.
integer, public magn_int_style
style for magnetic integrals (1: trapezoidal, 2: Simpson 3/8)
real(dp), public max_x_mem
maximum memory for perturbation calculations for all processes [MB]
logical, public no_plots
no plots made
Operations concerning giving output, on the screen as well as in output files.
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.
Variables concerning Richardson extrapolation.
integer, public rich_lvl
current level of Richardson extrapolation
elemental character(len=max_str_ln) function, public i2str(k)
Convert an integer to string.
elemental character(len=max_str_ln) function, public r2str(k)
Convert a real (double) to string.
elemental character(len=max_str_ln) function, public r2strt(k)
Convert a real (double) to string.
Numerical utilities related to the output of VMEC.
integer function, public calc_trigon_factors(theta, zeta, trigon_factors)
Calculate the trigonometric cosine and sine factors.
Operations considering perturbation quantities.
integer function, public calc_res_surf(mds, grid_eq, eq, res_surf, info, jq)
Calculates resonating flux surfaces for the perturbation modes.
logical, public debug_check_x_modes_2
plot debug information for check_x_modes_2()
integer function, public setup_modes(mds, grid_eq, grid, plot_name)
Sets up some variables concerning the mode numbers.
integer function, public divide_x_jobs(arr_size)
Divides the perturbation jobs.
integer function, public init_modes(grid_eq, eq)
Initializes some variables concerning the mode numbers.
integer function, public print_debug_x_1(mds, grid_x, x_1)
Prints debug information for X_1 driver.
integer function, public check_x_modes(grid_eq, eq)
Checks whether the high-n approximation is valid:
integer function, public resonance_plot(mds, grid_eq, eq)
plot -profile or -profile in flux coordinates with or indicated if requested.
integer function, public print_debug_x_2(mds, grid_x, x_2_int)
Prints debug information for X_2 driver.
integer function, public calc_magn_ints(grid_eq, grid_x, eq, x, x_int, prev_style, lim_sec_x)
Calculate the magnetic integrals from and in an equidistant grid where the step size can vary depen...
Numerical utilities related to perturbation operations.
integer function, public calc_memory_x(ord, arr_size, n_mod, mem_size)
Calculate memory in MB necessary for X variables.
subroutine, public get_sec_x_range(sec_x_range_loc, sec_x_range_tot, m, sym, lim_sec_x)
Gets one of the the local ranges of contiguous tensorial perturbation variables to be printed or read...
logical function, public is_necessary_x(sym, sec_x_id, lim_sec_x)
Determines whether a variable needs to be considered:
Variables pertaining to the perturbation quantities.
integer, dimension(:), allocatable, public min_n_x
lowest poloidal mode number m_X, in total eq grid
integer, public min_sec_x
m_X (pol. flux) or n_X (tor. flux) (only for X style 1)
integer, public n_mod_x
size of m_X (pol. flux) or n_X (tor. flux)
integer, dimension(:), allocatable, public max_n_x
highest poloidal mode number m_X, in total eq grid
integer function, public set_nn_mod(sym, lim_sec_x)
Sets number of entries for tensorial perturbation variables.
integer, dimension(:), allocatable, public max_m_x
highest poloidal mode number m_X, in total eq grid
integer, dimension(:), allocatable, public min_m_x
lowest poloidal mode number m_X, in total eq grid
integer, public min_nm_x
minimum for the high-n theory (debable)
integer, public max_sec_x
m_X (pol. flux) or n_X (tor. flux) (only for\ c X style 1)
integer, public prim_x
n_X (pol. flux) or m_X (tor. flux)
1D equivalent of multidimensional variables, used for internal HDF5 storage.
vectorial perturbation type
tensorial perturbation type