5 #include <PB3D_macros.h>
41 character(*),
parameter :: rout_name =
'generic_tests'
46 call writo(
'Test smoothed second derivative?')
53 call writo(
'Test splines?')
60 call writo(
'Test lock system?')
67 call writo(
'Test calculation of RZL?')
69 ierr = test_calc_rzl()
74 call writo(
'Test calculation of toroidal functions?')
86 call writo(
'Test reading of subsets?')
93 call writo(
'Test calculation of volume integral?')
108 character(*),
parameter :: rout_name =
'test_calc_D2_smooth'
116 real(
dp),
allocatable :: x(:)
117 real(
dp),
allocatable :: y(:,:)
118 real(
dp),
allocatable :: d2y(:)
125 call writo(
'testing Holoborodko''s smoothed second derivatives')
129 call writo(
'how many points?')
135 x(kd) = (kd-1._dp)/(nx-1._dp)
136 y(kd,0) = sin(2*
pi*x(kd))
137 y(kd,1) = 2*
pi*cos(2*
pi*x(kd))
138 y(kd,2) = -(2*
pi)**2*sin(2*
pi*x(kd))
145 do while (.not.ready)
147 call writo(
'filter length?')
148 fil_n =
get_int(lim_lo=5,lim_hi=nx)
154 call writo(
'1: central')
155 call writo(
'2: left')
157 style =
get_int(lim_lo=1,lim_hi=2)
164 call print_ex_2d([
'y ',
'D2y'],
'',reshape([y(:,2),d2y],[nx,2]),&
165 &x=reshape(x,[nx,1]))
169 &y(sym_m+1:nx-sym_m,2)-d2y(sym_m+1:nx-sym_m),&
170 &x=x(sym_m+1:nx-sym_m))
173 &y(2*sym_m+1:nx,2)-d2y(2*sym_m+1:nx),&
177 call writo(
'repeat?')
191 character(*),
parameter :: rout_name =
'test_splines'
200 real(dp) :: bcs_val(2)
201 real(dp) :: extrap_fraction
202 real(dp),
allocatable :: x(:)
203 real(dp),
allocatable :: x_int(:)
204 real(dp),
allocatable :: y(:,:)
205 real(dp),
allocatable :: y_int(:)
208 character(len=5) :: side_str(2)
214 call writo(
'testing splines')
222 x(kd) = (kd-1._dp)/(nx-1._dp)
223 y(kd,0) = sin(2*pi*x(kd))
224 y(kd,1) = 2*pi*cos(2*pi*x(kd))
225 y(kd,2) = -(2*pi)**2*sin(2*pi*x(kd))
226 y(kd,3) = -(2*pi)**3*cos(2*pi*x(kd))
231 allocate(x_int(nx_int))
232 allocate(y_int(nx_int))
235 do while (.not.ready)
239 call writo(
'1: linear')
240 call writo(
'2: akima hermite')
241 call writo(
'3: cubic')
243 ord =
get_int(lim_lo=1,lim_hi=3)
246 call writo(
'test extrapolation?')
249 call writo(
'Extrapolation fraction?')
250 extrap_fraction =
get_real(lim_lo=0._dp,lim_hi=10._dp)
256 side_str(2) =
'right'
259 call writo(
'boundary condition '//trim(side_str(kd))//&
262 call writo(
'-1: periodic')
263 call writo(
' 0: not-a-knot')
264 call writo(
' 1: first derivative prescribed')
265 call writo(
' 2: second derivative prescribed')
267 bcs(kd) =
get_int(lim_lo=-1,lim_hi=2)
268 if (bcs(kd).eq.1 .or. bcs(kd).eq.2)
then
269 call writo(
'value of derivative of order '//&
270 &trim(
i2str(bcs(kd))))
290 x_int(kd) = -extrap_fraction + &
291 &(1+2*extrap_fraction)*(kd-1._dp)/(nx_int-1._dp)
296 ierr =
spline(x,y(:,0),x_int,y_int,ord=ord,deriv=id,bcs=bcs,&
297 &bcs_val=bcs_val,extrap=extrap)
299 call plot_y(x,x_int,y(:,id),y_int,id)
302 call writo(
'repeat?')
308 subroutine plot_y(x,x_int,y,y_int,deriv)
310 real(dp),
intent(in) :: x(:)
311 real(dp),
intent(in) :: x_int(:)
312 real(dp),
intent(in) :: y(:)
313 real(dp),
intent(in) :: y_int(:)
314 integer,
intent(in) :: deriv
317 integer :: nx, nx_int
318 real(dp) :: minmax_y(2)
319 real(dp),
allocatable :: x_plot(:,:)
320 real(dp),
allocatable :: y_plot(:,:)
321 character(len=max_str_ln),
allocatable :: plot_names(:)
326 allocate(x_plot(max(nx,nx_int),2))
327 allocate(y_plot(max(nx,nx_int),2))
330 x_plot(1:nx_int,1) = x_int
331 x_plot(nx_int+1:max(nx,nx_int),1) = x_int(nx_int)
332 y_plot(1:nx_int,1) = y_int
333 y_plot(nx_int+1:max(nx,nx_int),1) = y_int(nx_int)
337 x_plot(nx+1:max(nx,nx_int),2) = x(nx)
339 y_plot(nx+1:max(nx,nx_int),2) = y(nx)
342 minmax_y(1) = minval(y_plot(:,1:2))
343 minmax_y(2) = maxval(y_plot(:,1:2))
346 allocate(plot_names(2))
347 plot_names(1) =
'D'//trim(
i2str(deriv))//
'y_int'
348 plot_names(2) =
'D'//trim(
i2str(deriv))//
'y'
349 call print_ex_2d(plot_names,plot_names(1),y_plot,x=x_plot)
356 integer function test_lock()
result(ierr)
363 character(*),
parameter :: rout_name =
'test_lock'
368 integer(kind=8) :: sleep_time(2)
374 integer,
allocatable :: wl(:)
375 character(len=max_str_ln) :: title
383 call writo(
'which test?')
385 call writo(
'1. blocking')
386 call writo(
'2. non-blocking')
387 call writo(
'3. blocking and non-blocking')
388 testcase =
get_int(lim_lo=1,lim_hi=3)
391 call writo(
'How many cycles?')
394 if (testcase.eq.2 .or. testcase.eq.3)
then
395 call writo(
'Do you want to check whether locking and unlocking the &
396 &window multiple times by the master helps reduce latency?')
401 select case (testcase)
405 title =
'non-blocking'
407 title =
'blocking and non-blocking'
411 ierr = lock%init(100)
415 call writo(
'Testing '//trim(title)//
' access')
417 call writo(
'Every process immediately requests access and then &
418 &waits some seconds between 0 and 3')
421 select case (testcase)
423 call writo(
'Every process is blocking')
425 call writo(
'Every process is non-blocking')
427 call writo(
'In the first cycle, every process is non-blocking')
428 call writo(
'Afterwards, each process becomes blocking &
437 select case (testcase)
443 if (id.eq.
rank+2)
then
452 wait_time = random_int([0,3])
454 &wait_time,
' seconds'
455 if (red_lat .and.
rank.eq.0 .and. wait_time.gt.0)
then
456 call system_clock(sleep_time(1))
457 call system_clock(sleep_time(2))
458 do while (1.e-9_dp*(sleep_time(2)-sleep_time(1)).lt.wait_time)
462 call system_clock(sleep_time(2))
466 call sleep(wait_time)
469 &wait_time,
' seconds, returning lock'
476 ierr = lock%dealloc()
487 integer function random_int(lim)
result(res)
489 integer,
intent(in) :: lim(2)
494 integer :: n_steps = 5
499 call random_number(r_nr)
502 seed = int(1000_dp*r_nr*(
rank+1))
503 call random_seed(put=seed)
507 call random_number(r_nr)
508 res = lim(1) + floor((lim(2)-lim(1)+1)*r_nr)
509 end function random_int
510 end function test_lock
515 integer function test_calc_rzl()
result(ierr)
519 character(*),
parameter :: rout_name =
'test_calc_RZL'
531 ierr = test_calc_rzl_vmec()
541 integer function test_calc_rzl_vmec()
result(ierr)
549 character(*),
parameter :: rout_name =
'test_calc_RZL_VMEC'
555 real(dp) :: grid_lims(2,2)
556 real(dp),
allocatable :: norm(:,:,:)
557 real(dp),
allocatable :: R(:,:,:), Z(:,:,:), L(:,:,:)
560 integer :: max_deriv(3)
563 call writo(
'Going to test the calculation of R, Z and L')
571 call writo(
'For which normal point do you want the analysis?')
577 call writo(
'grid size in dimension '//trim(
i2str(id))//
'?')
580 call writo(
'limits for angle '//trim(
i2str(id))//
' [pi]?')
582 grid_lims(2,id-1) =
get_real(lim_lo=grid_lims(1,id-1)/pi)*pi
585 ierr = grid%init(dims)
589 allocate(norm(dims(1),dims(2),dims(3)))
596 norm = (norm_id-1._dp)/(
n_r_eq-1)
597 grid%r_E = norm(1,1,:)
602 call writo(
'maximum derivative in dimension '//&
603 &trim(
i2str(id))//
'?')
604 max_deriv(id) =
get_int(lim_lo=0,lim_hi=3)
608 allocate(r(dims(1),dims(2),dims(3)))
609 allocate(z(dims(1),dims(2),dims(3)))
610 allocate(l(dims(1),dims(2),dims(3)))
612 &grid%trigon_factors)
614 do jd = 0,max_deriv(3)
615 do id = 0,max_deriv(2)
617 call writo(
'Calculating for deriv = ['//&
618 &trim(
i2str(deriv(1)))//
','//&
619 &trim(
i2str(deriv(2)))//
','//&
620 &trim(
i2str(deriv(3)))//
']')
623 &
r_v_s(:,norm_id:norm_id,deriv(1)),&
625 &grid%trigon_factors,&
626 &r,sym=[.true.,is_asym_v],&
627 &deriv=[deriv(2),deriv(3)])
630 &
z_v_s(:,norm_id:norm_id,deriv(1)),&
632 &grid%trigon_factors,&
633 &z,sym=[is_asym_v,.true.],&
634 &deriv=[deriv(2),deriv(3)])
637 &
l_v_s(:,norm_id:norm_id,deriv(1)),&
639 &grid%trigon_factors,&
640 &l,sym=[is_asym_v,.true.],&
641 &deriv=[deriv(2),deriv(3)])
643 call plot_hdf5([
'R',
'Z',
'L'],
'TEST_RZL_0_'//&
645 &reshape([r,z,l],[dims,3]),&
646 &x=reshape([grid%theta_E],[dims,1]),&
647 &y=reshape([grid%zeta_E],[dims,1]),&
648 &z=reshape([norm],[dims,1]))
656 call writo(
'Test complete')
657 end function test_calc_rzl_vmec
658 end function test_calc_rzl
668 character(*),
parameter :: rout_name =
'test_tor_fun'
674 real(dp),
allocatable :: x(:)
675 real(dp),
allocatable :: f(:,:,:)
681 logical :: test_approx
682 logical :: test_rel_diff
683 character(len=max_str_ln),
allocatable :: plot_name(:)
684 character(len=max_str_ln),
allocatable :: fun_names(:,:)
690 test_approx = .false.
692 do while (.not.done .and.
rank.eq.0)
696 call writo(
'Test approximation at singular point?')
698 test_rel_diff = .false.
699 if (test_approx)
then
700 call writo(
'Relative difference in stead of absolute?')
701 test_rel_diff =
get_log(.false.)
705 call writo(
'Lower bound to plot?')
707 call writo(
'Upper bound to plot?')
709 call writo(
'How many points?')
711 call writo(
'Max. degree? (subscript n in P_(n-0.5)^m)')
713 call writo(
'Min. degree? (subscript n in P_(n-0.5)^m)')
714 min_n =
get_int(lim_lo=0,lim_hi=n)
715 if (.not.test_approx)
then
716 call writo(
'Order? (superscript m in P_(n-0.5)^m)')
719 call writo(
'Order is 0 when testing approximation')
725 allocate(f(npt,0:n,2))
728 if (test_approx)
then
729 allocate(plot_name(min_n:n))
730 allocate(fun_names(min_n:n,2))
731 if (test_rel_diff)
then
733 plot_name(kd) =
'tor_Q_rel_diff_'//trim(
i2str(kd))
734 fun_names(kd,1) =
'ReldiffQ_{'//trim(
i2str(kd))//&
735 &
'-0.5}^'//trim(
i2str(m))
736 fun_names(kd,2) =
'Q_{'//trim(
i2str(kd))//&
737 &
'-0.5}^'//trim(
i2str(m))
741 plot_name(kd) =
'tor_Q_comp_'//trim(
i2str(kd))
742 fun_names(kd,1) =
'ApproxQ_{'//trim(
i2str(kd))//&
743 &
'-0.5}^'//trim(
i2str(m))
744 fun_names(kd,2) =
'Q_{'//trim(
i2str(kd))//&
745 &
'-0.5}^'//trim(
i2str(m))
749 allocate(plot_name(2))
750 allocate(fun_names(2,min_n:n))
751 plot_name(1) =
'tor_P'
752 plot_name(2) =
'tor_Q'
754 fun_names(1,kd) =
'P_{'//trim(
i2str(kd))//
'-0.5}^'//&
756 fun_names(2,kd) =
'Q_{'//trim(
i2str(kd))//
'-0.5}^'//&
763 ierr =
dtorh1(x(kd),m,n,f(kd,:,1),f(kd,:,2),max_n)
765 if (max_n.lt.n)
call writo(
'For point x = '//&
766 &trim(
r2str(x(kd)))//
', the solution did not converge for &
767 °ree > '//trim(
i2str(max_n)),warning=.true.)
768 if (test_approx)
then
769 f(kd,:,1) = -0.5*log((x(kd)-1._dp)/32)
771 f(kd,jd:n,1) = f(kd,jd:n,1) - 2_dp/(2._dp*jd-1._dp)
773 if (test_rel_diff) f(kd,:,1) = &
774 &2._dp*(f(kd,:,1)-f(kd,:,2))/(f(kd,:,1)+f(kd,:,2))
779 do kd = lbound(plot_name,1),ubound(plot_name,1)
780 if (test_approx)
then
781 call print_ex_2d(fun_names(kd,:),trim(plot_name(kd)),&
782 &f(:,kd,:),x=reshape(x,[npt,1]))
784 call print_ex_2d(fun_names(kd,:),trim(plot_name(kd)),&
785 &f(:,min_n:n,kd),x=reshape(x,[npt,1]))
787 call draw_ex(fun_names(kd,:),trim(plot_name(kd)),&
788 &
size(fun_names,2),1,.false.)
792 deallocate(x,f,fun_names,plot_name)
795 call writo(
'Test again?')
821 character(*),
parameter :: rout_name =
'test_read_HDF5_subset'
833 integer :: rich_lvl_name
834 integer :: rich_lvl_name_eq
835 integer :: id, jd, kd
839 integer :: n_sub_norm
840 integer :: norm_ol = 4
841 integer :: norm_id(2)
843 integer :: plot_dim(3)
844 integer :: plot_offset(3)
847 integer,
allocatable :: n_sub_loc(:)
848 integer,
allocatable :: n_sub_norm_loc(:)
849 integer,
allocatable :: lims(:,:,:)
850 integer,
allocatable :: lims_loc(:,:,:)
851 real(dp),
allocatable :: xyz(:,:,:,:)
852 real(dp),
allocatable :: xyz_i(:,:,:,:)
853 character(len=max_str_ln) :: description
854 character(len=8) :: name_suff(2)
855 character(len=3) :: grid_name
856 character :: xyz_name(3)
857 logical :: direct_grid_read
858 logical :: divide_over_procs
866 call writo(
'Checking reading of HDF5 subsets')
877 call writo(
'Which variable do you want to test?')
879 call writo(
'1. eq_2: Jac_FD and kappa_n')
880 call writo(
'2. X_1: IM(U_0), RE(DU_1)')
881 call writo(
'3. sol: RE(sol_vec)')
883 test_case = get_int(lim_lo=1,lim_hi=3)
889 select case (test_case)
906 select case (test_case)
917 &
rich_lvl=rich_lvl_name,tot_rich=.true.)
922 call writo(
'Read the grids directly using subsets?')
923 direct_grid_read = get_log(.true.)
927 call writo(
'Divide over MPI processes?')
928 divide_over_procs = get_log(.true.)
930 divide_over_procs = .false.
934 call writo(
'Total '//trim(grid_name)//
' grid size: ['//&
935 &trim(
i2str(n_tot(1)))//
','//trim(
i2str(n_tot(2)))//
','//&
936 &trim(
i2str(n_tot(3)))//
']')
938 if (n_tot(id).gt.0)
then
939 call writo(
'how many divisions in dimension '//trim(
i2str(id)))
940 n_sub(id) = get_int(lim_lo=0,lim_hi=n_tot(id)-1) + 1
945 allocate(lims(3,2,product(n_sub)))
950 lims(3,:,1) = [-1,-1]
952 &tot_rich=.true.,lim_pos=lims(:,:,1))
963 lims(1,1,i_sub) = (id-1)*(n_tot(1)/n_sub(1)) + &
964 &min(mod(n_tot(1),n_sub(1)),id-1) + 1
965 lims(1,2,i_sub) = id*(n_tot(1)/n_sub(1)) + &
966 &min(mod(n_tot(1),n_sub(1)),id)
967 lims(2,1,i_sub) = (jd-1)*(n_tot(2)/n_sub(2)) + &
968 &min(mod(n_tot(2),n_sub(2)),jd-1) + 1
969 lims(2,2,i_sub) = jd*(n_tot(2)/n_sub(2)) + &
970 &min(mod(n_tot(2),n_sub(2)),jd)
971 lims(3,1,i_sub) = (kd-1)*(n_tot(3)/n_sub(3)) + &
972 &min(mod(n_tot(3),n_sub(3)),kd-1) + 1
973 lims(3,2,i_sub) = kd*(n_tot(3)/n_sub(3)) + &
974 &min(mod(n_tot(3),n_sub(3)),kd)
984 allocate(n_sub_norm_loc(
n_procs))
985 if (divide_over_procs)
then
987 n_sub_loc = product(n_sub)
988 allocate(lims_loc(3,2,product(n_sub)))
990 call writo(
'All process perform every job together, dividing each &
991 &one normally with overlap '//trim(
i2str(norm_ol)))
994 n_sub_loc = product(n_sub)/
n_procs
995 n_sub_loc(1:mod(product(n_sub),
n_procs)) = &
996 &n_sub_loc(1:mod(product(n_sub),
n_procs)) + 1
997 allocate(lims_loc(3,2,n_sub_loc(
rank+1)))
999 &lims(:,:,sum(n_sub_loc(1:
rank))+1:sum(n_sub_loc(1:
rank+1)))
1004 do i_sub = 1,
size(lims_loc,3)
1005 call writo(
'subset '//trim(
i2str(i_sub)),persistent=pers_out)
1009 &) = ['//trim(
i2str(lims_loc(id,1,i_sub)))//
'..'//&
1010 &trim(
i2str(lims_loc(id,2,i_sub)))//
']',&
1011 &persistent=pers_out)
1023 if (test_case.eq.2 .or. test_case.eq.3)
then
1033 call writo(
'Which perturbation mode do you want to plot?')
1034 i_sec = get_int(lim_lo=1,lim_hi=
size(mds%m,2))
1042 do i_sub = 1,
size(lims_loc,3)
1045 &trim(
i2str(i_sub))//
':',persistent=.true.)
1051 description = trim(description)//
' lim('//trim(
i2str(id))//&
1052 &
') = ['//trim(
i2str(lims_loc(id,1,i_sub)))//
'..'//&
1053 &trim(
i2str(lims_loc(id,2,i_sub)))//
']'
1054 if (id.lt.3) description = trim(description)//
','
1058 n_sub_norm = lims_loc(3,2,i_sub)-lims_loc(3,1,i_sub)+1
1059 if (divide_over_procs)
then
1060 n_sub_norm_loc = n_sub_norm/
n_procs
1061 n_sub_norm_loc(1:mod(n_sub_norm,
n_procs)) = &
1062 &n_sub_norm_loc(1:mod(n_sub_norm,
n_procs)) + 1
1063 i_lim = [sum(n_sub_norm_loc(1:
rank))+1,&
1064 &sum(n_sub_norm_loc(1:
rank+1))]
1065 if (
rank+1.lt.
n_procs) i_lim(2) = i_lim(2)+norm_ol
1066 description = trim(description)//
', normal range = '//&
1067 &trim(
i2str(i_lim(1)))//
'..'//trim(
i2str(i_lim(2)))
1069 n_sub_norm_loc = n_sub_norm
1070 i_lim = lims_loc(3,:,i_sub) - lims_loc(3,1,i_sub) + 1
1074 description = adjustl(description)
1075 call writo(trim(description),persistent=.true.)
1078 if (direct_grid_read)
then
1081 &
rich_lvl=rich_lvl_name,tot_rich=.true.,&
1082 &lim_pos=lims_loc(:,:,i_sub),grid_limits=i_lim)
1086 &lims_b=lims_loc(:,:,i_sub),i_lim=i_lim)
1091 ierr =
trim_grid(grid_sub,grid_trim,norm_id)
1095 plot_dim = grid_trim%n
1096 plot_offset = [0,0,grid_trim%i_min-1]
1100 select case (test_case)
1103 &
rich_lvl=rich_lvl_name,tot_rich=.true.,&
1104 &lim_pos=lims_loc(:,:,i_sub))
1108 &
rich_lvl=rich_lvl_name,tot_rich=.true.,&
1109 &lim_pos=lims_loc(:,:,i_sub),&
1110 &lim_sec_x=[i_sec,i_sec])
1115 &lim_pos=lims_loc(3:3,:,i_sub),&
1116 &lim_sec_sol=[i_sec,i_sec])
1121 if (divide_over_procs)
then
1122 name_suff(1) =
'_'//trim(
i2str(i_sub))
1124 name_suff(1) =
'_'//trim(
i2str(sum(n_sub_loc(1:
rank))+i_sub))
1126 if (divide_over_procs)
then
1127 name_suff(2) = trim(name_suff(1))//
'_'//trim(
i2str(
rank))
1129 name_suff(2) = trim(name_suff(1))
1133 if (test_case.eq.1 .or. test_case.eq.2)
then
1136 &grid_trim%zeta_E,grid_trim%trigon_factors)
1139 allocate(xyz(grid_trim%n(1),grid_trim%n(2),&
1140 &grid_trim%loc_n_r,3))
1142 &xyz(:,:,:,2),xyz(:,:,:,3))
1145 &xyz_i(grid_trim%n(1),grid_trim%n(2),grid_trim%loc_n_r,3))
1146 do id = 1,grid_trim%n(1)
1147 xyz_i(id,:,:,1) = lims_loc(1,1,i_sub) + id - 2
1149 do jd = 1,grid_trim%n(2)
1150 xyz_i(:,jd,:,2) = lims_loc(2,1,i_sub) + jd - 2
1152 do kd = 1,grid_trim%loc_n_r
1153 xyz_i(:,:,kd,3) = lims_loc(3,1,i_sub) + kd - 2 + &
1154 &grid_trim%i_min - 1
1157 allocate(xyz_i(1,grid_trim%loc_n_r,1,1))
1158 do kd = 1,grid_trim%loc_n_r
1159 xyz_i(1,kd,1,1) = lims_loc(3,1,i_sub) + kd - 2 + &
1160 &grid_trim%i_min - 1
1165 select case (test_case)
1168 &
'jac_FD'//trim(name_suff(1)),&
1169 &eq_2%jac_FD(:,:,norm_id(1):norm_id(2),0,0,0),&
1170 &tot_dim=plot_dim,loc_offset=plot_offset,&
1171 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3),&
1174 &
'kappa_n'//trim(name_suff(1)),&
1175 &eq_2%kappa_n(:,:,norm_id(1):norm_id(2)),&
1176 &tot_dim=plot_dim,loc_offset=plot_offset,&
1177 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3),&
1181 &
'U_0_IM'//trim(name_suff(1)),&
1182 &ip(x_1%U_0(:,:,norm_id(1):norm_id(2),1)),&
1183 &tot_dim=plot_dim,loc_offset=plot_offset,&
1184 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3),&
1187 &
'DU_1_RE'//trim(name_suff(1)),&
1188 &rp(x_1%DU_1(:,:,norm_id(1):norm_id(2),1)),&
1189 &tot_dim=plot_dim,loc_offset=plot_offset,&
1190 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3),&
1193 call print_ex_2d([
'sol_RE'],
'sol_RE'//trim(name_suff(2)),&
1194 &rp(sol%vec(1,norm_id(1):norm_id(2),:)),&
1195 &x=xyz_i(1,:,:,1),draw=.false.)
1196 call draw_ex([
'sol_RE'],
'sol_RE'//trim(name_suff(2)),&
1197 &
size(sol%vec,3),1,.false.)
1199 if (test_case.eq.1 .or. test_case.eq.2)
then
1201 call plot_hdf5(xyz_name(id),xyz_name(id)//&
1202 &trim(name_suff(2)),xyz(:,:,:,id),&
1203 &x=xyz_i(:,:,:,1),y=xyz_i(:,:,:,2),z=xyz_i(:,:,:,3))
1208 call grid_sub%dealloc()
1209 call grid_trim%dealloc()
1210 select case (test_case)
1218 if (test_case.eq.1 .or. test_case.eq.2)
deallocate(xyz)
1228 call writo(
'Do you want to plot the entire region at once?')
1229 if (get_log(.false.) .and.
rank.eq.0)
then
1231 select case (test_case)
1234 &
rich_lvl=rich_lvl_name,tot_rich=.true.)
1238 &
rich_lvl=rich_lvl_name,tot_rich=.true.,&
1239 &lim_sec_x=[i_sec,i_sec])
1244 &lim_sec_sol=[i_sec,i_sec])
1249 if (test_case.eq.1 .or. test_case.eq.2)
then
1252 &grid%zeta_E,grid%trigon_factors)
1255 allocate(xyz(grid%n(1),grid%n(2),grid%loc_n_r,3))
1257 &xyz(:,:,:,2),xyz(:,:,:,3))
1259 allocate(xyz_i(grid%n(1),grid%n(2),grid%loc_n_r,3))
1261 xyz_i(id,:,:,1) = id - 1
1264 xyz_i(:,jd,:,2) = jd - 1
1266 do kd = 1,grid%loc_n_r
1267 xyz_i(:,:,kd,3) = kd - 1
1270 allocate(xyz_i(1,grid%loc_n_r,1,1))
1271 do kd = 1,grid%loc_n_r
1272 xyz_i(1,kd,1,1) = kd - 1
1277 description =
'total range'
1278 select case (test_case)
1281 &eq_2%jac_FD(:,:,:,0,0,0),&
1282 &descr=description,&
1283 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3))
1284 call plot_hdf5(
'kappa_n',
'kappa_n_tot',eq_2%kappa_n,&
1285 &descr=description,&
1286 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3))
1289 &ip(x_1%U_0(:,:,:,1)),&
1290 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3),&
1292 call plot_hdf5(
'DU_1_RE',
'DU_1_RE_tot',&
1293 &rp(x_1%DU_1(:,:,:,1)),&
1294 &x=xyz(:,:,:,1),y=xyz(:,:,:,2),z=xyz(:,:,:,3),&
1298 &rp(sol%vec(1,:,:)),x=xyz_i(1,:,:,1),draw=.false.)
1299 call draw_ex([
'sol_RE'],
'sol_RE_tot',&
1300 &
size(sol%vec,3),1,.false.)
1302 if (test_case.eq.1 .or. test_case.eq.2)
then
1304 call plot_hdf5(xyz_name(id),xyz_name(id)//
'_tot',&
1306 &x=xyz_i(:,:,:,1),y=xyz_i(:,:,:,2),z=xyz_i(:,:,:,3))
1312 if (test_case.eq.1 .or. test_case.eq.2)
deallocate(xyz)
1319 if (test_case.eq.2 .or. test_case.eq.3)
call grid_eq%dealloc()
1328 call writo(
'Test complete')
1339 character(*),
parameter :: rout_name =
'test_calc_int_vol'
1342 real(dp),
allocatable :: theta(:,:,:), zeta(:,:,:)
1343 complex(dp),
allocatable :: fun(:,:,:,:)
1344 real(dp),
allocatable :: j(:,:,:)
1345 real(dp),
allocatable :: x(:,:,:), y(:,:,:), z(:,:,:)
1346 real(dp),
allocatable :: norm(:)
1347 real(dp),
allocatable :: r(:)
1349 complex(dp),
allocatable :: fun_int(:,:,:)
1350 integer,
allocatable :: dims(:,:)
1352 integer :: id, jd, kd
1353 real(dp),
allocatable :: eqd_grid_dum(:)
1354 character(len=max_str_ln) :: var_name(3), file_name(3)
1355 complex(dp),
allocatable :: fun_int_plot(:,:)
1361 call writo(
'Checking integral of')
1363 call writo(
'f = 1 - r^2 + i cos(theta)')
1365 call writo(
'on a torus')
1367 call writo(
'Debug mode?')
1374 call writo(
'How many different grid sizes?')
1377 allocate(dims(3,n_steps))
1378 allocate(eqd_grid_dum(n_steps))
1381 if (n_steps.gt.1)
then
1382 do kd = 1,
size(dims,1)
1383 call writo(
'Starting dimension '//trim(
i2str(kd)))
1384 dims(kd,1) =
get_int(lim_lo=4)
1385 call writo(
'Final dimension '//trim(
i2str(kd)))
1386 dims(kd,n_steps) =
get_int(lim_lo=dims(kd,1)+n_steps)
1388 &1._dp*dims(kd,n_steps))
1390 dims(kd,:) = nint(eqd_grid_dum)
1392 call writo(
'Performing calculations for '//&
1393 &trim(
i2str(n_steps))//
' grid sizes')
1395 do kd = 1,
size(dims)
1397 dims(kd,1) =
get_int(lim_lo=1)
1398 if (dims(kd,1).eq.1)
then
1400 call writo(
'Make sure the integrand does not depend on &
1401 &dimension '//trim(
i2str(kd)))
1402 call writo(
'A factor such as 2pi can be missing from &
1403 &resulting integral')
1409 allocate(fun_int(2,1,n_steps))
1413 call writo(
'grid size = ['//trim(
i2str(dims(1,jd)))//
' ,'//&
1414 &trim(
i2str(dims(2,jd)))//
', '//trim(
i2str(dims(3,jd)))//&
1419 allocate(theta(dims(1,jd),dims(2,jd),dims(3,jd)))
1420 allocate(zeta(dims(1,jd),dims(2,jd),dims(3,jd)))
1421 allocate(j(dims(1,jd),dims(2,jd),dims(3,jd)))
1422 allocate(fun(dims(1,jd),dims(2,jd),dims(3,jd),1))
1423 allocate(x(dims(1,jd),dims(2,jd),dims(3,jd)))
1424 allocate(y(dims(1,jd),dims(2,jd),dims(3,jd)))
1425 allocate(z(dims(1,jd),dims(2,jd),dims(3,jd)))
1426 allocate(norm(dims(3,jd)))
1427 allocate(r(dims(3,jd)))
1436 do kd = 1,dims(3,jd)
1437 r(kd) = (kd-1._dp)/(dims(3,jd)-1)
1438 fun(:,:,kd,1) = 1._dp - r(kd)**2 + iu*cos(theta(:,:,kd))
1439 do id = 1,dims(1,jd)
1440 j(id,:,kd) = r(kd)*(r_0+r(kd)*cos(theta(id,:,kd)))
1442 x(:,:,kd) = cos(zeta(:,:,kd))*(r_0+r(kd)*cos(theta(:,:,kd)))
1443 y(:,:,kd) = sin(zeta(:,:,kd))*(r_0+r(kd)*cos(theta(:,:,kd)))
1444 z(:,:,kd) = r(kd)*sin(theta(:,:,kd))
1447 var_name(1) =
'TEST_J_torus'
1448 var_name(2) =
'TEST_RE_fun_torus'
1449 var_name(3) =
'TEST_IM_fun_torus'
1450 file_name(1) =
'TEST_J_torus'
1451 file_name(2) =
'TEST_RE_fun_torus'
1452 file_name(3) =
'TEST_IM_fun_torus'
1453 if (n_steps.gt.1)
then
1455 file_name(kd) = trim(file_name(kd))//
'_'//trim(
i2str(jd))
1458 call plot_hdf5(var_name(1),file_name(1),j,x=x,y=y,z=z)
1459 call plot_hdf5(var_name(2),file_name(2),rp(fun(:,:,:,1)),&
1461 call plot_hdf5(var_name(3),file_name(3),ip(fun(:,:,:,1)),&
1465 call writo(
'Analytically calculating integral')
1468 fun_int(1,1,jd) = r_0*pi**2 + iu*2*pi**2/3
1471 call writo(
'Numerically calculating integral')
1474 ierr =
calc_int_vol(theta,zeta,norm,j,fun,fun_int(2,:,jd))
1478 call writo(
'Analytical value: '//&
1479 &trim(
c2str(fun_int(1,1,jd))))
1480 call writo(
'Numerical value: '//&
1481 &trim(
c2str(fun_int(2,1,jd))))
1484 deallocate(theta,zeta,j,fun)
1491 if (n_steps.gt.1)
then
1492 allocate(fun_int_plot(n_steps,2))
1494 fun_int_plot(jd,:) = fun_int(:,1,jd)/fun_int(1,1,jd)
1497 &
'numerical integral, RE '],
'',rp(fun_int_plot))
1499 &
'numerical integral, IM '],
'',ip(fun_int_plot))