5 #include <PB3D_macros.h>
83 integer function read_hel(n_r_in,use_pol_flux_H)
result(ierr)
90 character(*),
parameter :: rout_name =
'read_HEL'
93 integer,
intent(inout) :: n_r_in
94 logical,
intent(inout) :: use_pol_flux_h
97 character(len=max_str_ln) :: err_msg
100 integer :: max_loc_z(2)
101 real(dp),
allocatable :: s_h(:)
102 real(dp),
allocatable :: curj(:)
103 real(dp),
allocatable :: vx(:), vy(:)
105 real(dp) :: tol_diff_dp
110 real(dp) :: radius, raxis
116 real(dp) :: delta_rz(2)
118 real(dp),
allocatable :: inv_loc(:)
125 call writo(
'Reading data from HELENA output "' &
130 err_msg =
'Failed to read HELENA output file. &
131 &Does it output IAS and B0? See tutorial!'
137 read(
eq_i,*,iostat=ierr) n_r_in,
ias
141 allocate(s_h(n_r_in))
142 read(
eq_i,*,iostat=ierr) (s_h(kd),kd=1,n_r_in)
146 read(
eq_i,*,iostat=ierr) (
q_saf_h(kd,0),kd=1,n_r_in)
148 read(
eq_i,*,iostat=ierr) dq0, dqe
153 read(
eq_i,*,iostat=ierr) (
q_saf_h(kd,1),kd=2,n_r_in)
156 allocate(curj(n_r_in))
157 read(
eq_i,*,iostat=ierr) (curj(kd),kd=1,n_r_in)
160 read(
eq_i,*,iostat=ierr) dj0,dje
169 read(
eq_i,*,iostat=ierr) (
chi_h(id),id=1,nchi_loc)
173 allocate(h_h_11(
nchi,n_r_in))
174 read(
eq_i,*,iostat=ierr) &
175 &(h_h_11(mod(id-1,nchi_loc)+1,(id-1)/nchi_loc+1),&
176 &id=nchi_loc+1,n_r_in*nchi_loc)
179 if (
ias.ne.0) h_h_11(
nchi,:) = h_h_11(1,:)
181 allocate(h_h_12(
nchi,n_r_in))
182 read(
eq_i,*,iostat=ierr) &
183 &(h_h_12(mod(id-1,nchi_loc)+1,(id-1)/nchi_loc+1),&
184 &id=nchi_loc+1,n_r_in*nchi_loc)
187 ierr =
spline(s_h(2:n_r_in),h_h_12(id,2:n_r_in),s_h(1:1),&
188 &h_h_12(id,1:1),deriv=0,extrap=.true.)
191 if (
ias.ne.0) h_h_12(
nchi,:) = h_h_12(1,:)
193 read(
eq_i,*,iostat=ierr) cpsurf, radius
196 allocate(h_h_33(
nchi,n_r_in))
197 read(
eq_i,*,iostat=ierr) &
198 &(h_h_33(mod(id-1,nchi_loc)+1,(id-1)/nchi_loc+1),id=&
199 &nchi_loc+1,n_r_in*nchi_loc)
201 read(
eq_i,*,iostat=ierr) raxis, b0
203 h_h_33(:,1) = raxis**2
204 if (
ias.ne.0) h_h_33(
nchi,:) = h_h_33(1,:)
205 h_h_33 = 1._dp/h_h_33
208 read(
eq_i,*,iostat=ierr) (
pres_h(kd,0),kd=1,n_r_in)
210 read(
eq_i,*,iostat=ierr) dp0, dpe
214 read(
eq_i,*,iostat=ierr) (
rbphi_h(kd,0),kd=1,n_r_in)
217 read(
eq_i,*,iostat=ierr) df0, dfe
221 read(
eq_i,*,iostat=ierr) (vx(id),id=1,nchi_loc)
226 read(
eq_i,*,iostat=ierr) (vy(id),id=1,nchi_loc)
230 read(
eq_i,*,iostat=ierr) eps
234 read(
eq_i,*,iostat=ierr) (
r_h(mod(id-1,nchi_loc)+1,(id-1)/nchi_loc+1),&
235 &id=nchi_loc+1,n_r_in*nchi_loc)
239 read(
eq_i,*,iostat=ierr) (
z_h(mod(id-1,nchi_loc)+1,(id-1)/nchi_loc+1),&
240 &id=nchi_loc+1,n_r_in*nchi_loc)
245 flux_p_h(:,0) = 2*pi*s_h**2 * cpsurf
246 radius = radius * raxis
247 r_h = radius*(1._dp/eps +
r_h)
256 &x=
r_h(:,n_r_in),draw=.false.)
257 call draw_ex([
'boundary'],
'RZ',1,1,.false.)
258 call writo(
'Inverting top and bottom to debug HELENA',&
260 allocate(inv_loc(
nchi))
267 z_h(:,kd) = -inv_loc(
nchi:1:-1)
270 inv_loc = h_h_11(:,kd)
271 h_h_11(:,kd) = inv_loc(
nchi:1:-1)
272 inv_loc = h_h_12(:,kd)
273 h_h_12(:,kd) = -inv_loc(
nchi:1:-1)
274 inv_loc = h_h_33(:,kd)
275 h_h_33(:,kd) = inv_loc(
nchi:1:-1)
279 &x=
r_h(:,n_r_in),draw=.false.)
280 call draw_ex([
'boundary'],
'RZ_inv_TB',1,1,.false.)
289 max_loc_z = maxloc(
z_h)
290 delta_rz(1) = maxval(
r_h)-minval(
r_h)
292 delta_rz(2) = 2*maxval(
z_h)
294 delta_rz(2) = maxval(
z_h)-minval(
z_h)
296 ellip = delta_rz(2)/delta_rz(1)
297 tria = ((maxval(
r_h)+minval(
r_h))*0.5_dp-&
298 &
r_h(max_loc_z(1),max_loc_z(2)))/&
299 &(delta_rz(2)*0.5_dp)
300 call writo(
'Calculated ellipticity: '//trim(
r2str(ellip)))
301 call writo(
'Calculated triangularity: '//trim(
r2str(tria)))
322 &bcs_val=[0._dp,dpe*pi/(
flux_p_h(n_r_in,0)*s_h(n_r_in))])
338 if (abs(diff_dp).gt.tol_diff_dp)
then
339 call writo(
'Difference between pressure derivative on axis is &
340 &large ('//trim(
r2str(diff_dp))//
')')
341 call writo(
'Maybe increase precision or number of normal points',&
345 if (abs(diff_dp).gt.tol_diff_dp)
then
346 call writo(
'Difference between pressure derivative at edge is &
347 &large ('//trim(
r2str(diff_dp))//
')')
348 call writo(
'Maybe increase precision or number of normal points',&
361 use_pol_flux_h = .true.
365 &
' poloidal and '//trim(
i2str(n_r_in))//
' normal points')
366 if (
ias.eq.0)
call writo(
'The equilibrium is top-bottom symmetric')
368 call writo(
'Data from HELENA output succesfully read')
412 &fund_theta_int_displ,tb_sym,use_E)
result(ierr)
415 character(*),
parameter :: rout_name =
'get_ang_interp_data_HEL'
420 real(
dp),
allocatable,
intent(inout) :: theta_i(:,:,:)
421 integer,
allocatable,
intent(inout) :: fund_theta_int_displ(:,:,:)
422 logical,
intent(in),
optional :: tb_sym
423 logical,
intent(in),
optional :: use_e
426 integer :: id, jd, kd
427 logical :: tb_sym_loc
429 real(
dp) :: theta_loc
430 real(
dp),
pointer :: theta_in(:) => null()
431 character(len=max_str_ln) :: err_msg
432 integer :: fund_theta_int_lo, fund_theta_int_hi
438 if (grid_in%n(2).ne.1)
then
440 err_msg =
'Not an axisymmetric grid'
444 if (grid_in%loc_n_r.ne.grid_out%loc_n_r)
then
446 write(*,*) grid_in%loc_n_r, grid_out%loc_n_r
447 err_msg =
'Grids are not compatible in normal direction'
453 if (
present(use_e)) use_e_loc = use_e
455 if (
present(tb_sym)) tb_sym_loc = tb_sym
458 allocate(theta_i(grid_out%n(1),grid_out%n(2),grid_out%loc_n_r))
459 allocate(fund_theta_int_displ(grid_out%n(1),grid_out%n(2),&
463 fund_theta_int_displ = 0
470 do kd = 1,grid_out%loc_n_r
473 theta_in => grid_in%theta_E(:,1,kd)
475 theta_in => grid_in%theta_F(:,1,kd)
479 do jd = 1,grid_out%n(2)
481 do id = 1,grid_out%n(1)
484 theta_loc = grid_out%theta_E(id,jd,kd)
486 theta_loc = grid_out%theta_F(id,jd,kd)
491 fund_theta_int_lo = -1
492 fund_theta_int_hi = 1
494 fund_theta_int_lo = 0
495 fund_theta_int_hi = 2
501 if (theta_loc.lt.fund_theta_int_lo*pi)
then
502 do while (theta_loc.lt.fund_theta_int_lo*pi)
503 theta_loc = theta_loc + 2*pi
504 fund_theta_int_displ(id,jd,kd) = &
505 &fund_theta_int_displ(id,jd,kd) - 1
507 else if (theta_loc.gt.fund_theta_int_hi*pi)
then
508 do while (theta_loc.gt.fund_theta_int_hi*pi)
509 theta_loc = theta_loc - 2*pi
510 fund_theta_int_displ(id,jd,kd) = &
511 &fund_theta_int_displ(id,jd,kd) + 1
514 ierr =
con2dis(abs(theta_loc),theta_i(id,jd,kd),theta_in)
516 if (theta_loc.lt.0) theta_i(id,jd,kd) = - theta_i(id,jd,kd)
549 &eq_2_out,X_1_out,X_2_out,eq_1,grid_name)
result(ierr)
553 character(*),
parameter :: rout_name =
'interp_HEL_on_grid'
558 type(
eq_2_type),
intent(inout),
optional :: eq_2
559 type(
x_1_type),
intent(inout),
optional :: x_1
560 type(
x_2_type),
intent(inout),
optional :: x_2
561 type(
eq_2_type),
intent(inout),
optional :: eq_2_out
562 type(
x_1_type),
intent(inout),
optional :: x_1_out
563 type(
x_2_type),
intent(inout),
optional :: x_2_out
564 type(
eq_1_type),
intent(in),
optional :: eq_1
565 character(len=*),
intent(in),
optional :: grid_name
568 real(dp),
allocatable :: theta_i(:,:,:)
569 integer,
allocatable :: fund_theta_int_displ(:,:,:)
571 character(len=max_str_ln) :: err_msg
577 if (
present(grid_name))
then
578 call writo(
'Adapt quantities to '//trim(grid_name))
583 if (
present(eq_2).and..not.
present(eq_1))
then
585 err_msg =
'To interpolate metric equilibrium variables, flux &
586 &equilibrium has to be provided as well through eq_1'
589 if (
present(eq_2) .and. (
present(x_1).or.
present(x_2)))
then
591 err_msg =
'Only the quantities on one type of grid can be &
592 &interpolated in a single call'
605 &fund_theta_int_displ,tb_sym=tb_sym,use_e=.false.)
609 if (
present(eq_2))
then
610 if (
present(eq_2_out))
then
611 ierr = interp_var_6d_real(eq_2%jac_FD,eq_2_out%jac_FD)
613 ierr = interp_var_7d_real(eq_2%g_FD,eq_2_out%g_FD,sym_type=3)
615 ierr = interp_var_7d_real(eq_2%h_FD,eq_2_out%h_FD,sym_type=4)
617 ierr = interp_var_3d_real(eq_2%S,eq_2_out%S)
619 ierr = interp_var_3d_real(eq_2%sigma,eq_2_out%sigma)
621 ierr = interp_var_3d_real(eq_2%kappa_n,eq_2_out%kappa_n)
623 ierr = interp_var_3d_real(eq_2%kappa_g,eq_2_out%kappa_g,&
627 ierr = interp_var_6d_real_ow(eq_2%jac_FD)
629 ierr = interp_var_7d_real_ow(eq_2%g_FD,sym_type=3)
631 ierr = interp_var_7d_real_ow(eq_2%h_FD,sym_type=4)
633 ierr = interp_var_3d_real_ow(eq_2%S)
635 ierr = interp_var_3d_real_ow(eq_2%sigma)
637 ierr = interp_var_3d_real_ow(eq_2%kappa_n)
639 ierr = interp_var_3d_real_ow(eq_2%kappa_g,sym_type=2)
645 if (
present(x_1))
then
646 if (
present(x_1_out))
then
647 ierr = interp_var_4d_complex(x_1%U_0,x_1_out%U_0,sym_type=2)
649 ierr = interp_var_4d_complex(x_1%U_1,x_1_out%U_1,sym_type=2)
651 ierr = interp_var_4d_complex(x_1%DU_0,x_1_out%DU_0,sym_type=1)
653 ierr = interp_var_4d_complex(x_1%DU_1,x_1_out%DU_1,sym_type=1)
656 ierr = interp_var_4d_complex_ow(x_1%U_0,sym_type=2)
658 ierr = interp_var_4d_complex_ow(x_1%U_1,sym_type=2)
660 ierr = interp_var_4d_complex_ow(x_1%DU_0,sym_type=1)
662 ierr = interp_var_4d_complex_ow(x_1%DU_1,sym_type=1)
668 if (
present(x_2))
then
669 if (
present(x_2_out))
then
670 ierr = interp_var_4d_complex(x_2%PV_0,x_2_out%PV_0,sym_type=1)
672 ierr = interp_var_4d_complex(x_2%PV_1,x_2_out%PV_1,sym_type=1)
674 ierr = interp_var_4d_complex(x_2%PV_2,x_2_out%PV_2,sym_type=1)
676 ierr = interp_var_4d_complex(x_2%KV_0,x_2_out%KV_0,sym_type=1)
678 ierr = interp_var_4d_complex(x_2%KV_1,x_2_out%KV_1,sym_type=1)
680 ierr = interp_var_4d_complex(x_2%KV_2,x_2_out%KV_2,sym_type=1)
683 ierr = interp_var_4d_complex_ow(x_2%PV_0,sym_type=1)
685 ierr = interp_var_4d_complex_ow(x_2%PV_1,sym_type=1)
687 ierr = interp_var_4d_complex_ow(x_2%PV_2,sym_type=1)
689 ierr = interp_var_4d_complex_ow(x_2%KV_0,sym_type=1)
691 ierr = interp_var_4d_complex_ow(x_2%KV_1,sym_type=1)
693 ierr = interp_var_4d_complex_ow(x_2%KV_2,sym_type=1)
699 if (
present(grid_name))
then
732 integer function interp_var_3d_real(var,var_int,sym_type)
result(ierr)
734 real(dp),
intent(in) :: var(1:,1:,1:)
735 real(dp),
intent(inout) :: var_int(1:,1:,1:)
736 integer,
intent(in),
optional :: sym_type
739 integer :: i_lo, i_hi
740 integer :: id, jd, kd
741 integer :: sym_type_loc
748 if (
present(sym_type)) sym_type_loc = sym_type
751 if (sym_type_loc.lt.0 .or. sym_type_loc.gt.2)
then
753 err_msg =
'Nonsensible symmetry type '//&
754 &trim(
i2str(sym_type_loc))
759 do kd = 1,
size(var_int,3)
761 do jd = 1,
size(var_int,2)
763 do id = 1,
size(var_int,1)
765 i_lo = floor(abs(theta_i(id,jd,kd)))
766 i_hi = ceiling(abs(theta_i(id,jd,kd)))
768 var_int(id,jd,kd) = var(i_lo,1,kd) + &
769 &(var(i_hi,1,kd)-var(i_lo,1,kd))*&
770 &(abs(theta_i(id,jd,kd))-i_lo)
771 if (theta_i(id,jd,kd).lt.0)
then
772 if (sym_type_loc.eq.2) var_int(id,jd,kd) = &
778 end function interp_var_3d_real
780 integer function interp_var_3d_real_ow(var,sym_type)
result(ierr)
782 real(dp),
intent(inout),
allocatable :: var(:,:,:)
783 integer,
intent(in),
optional :: sym_type
786 real(dp),
allocatable :: var_3d_loc(:,:,:)
787 integer :: var_dim(3,2)
793 var_dim(:,1) = [1,1,1]
794 var_dim(:,2) = [shape(theta_i)]
797 allocate(var_3d_loc(var_dim(1,1):var_dim(1,2),&
798 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2)))
801 ierr = interp_var_3d_real(var,var_3d_loc,sym_type)
806 allocate(var(var_dim(1,1):var_dim(1,2),&
807 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2)))
811 end function interp_var_3d_real_ow
813 integer function interp_var_4d_complex(var,var_int,sym_type) &
817 complex(dp),
intent(in) :: var(1:,1:,1:,1:)
818 complex(dp),
intent(inout) :: var_int(1:,1:,1:,1:)
819 integer,
intent(in),
optional :: sym_type
822 integer :: i_lo, i_hi
823 integer :: id, jd, kd
824 integer :: sym_type_loc
831 if (
present(sym_type)) sym_type_loc = sym_type
834 if (sym_type_loc.lt.0 .or. sym_type_loc.gt.2)
then
836 err_msg =
'Nonsensible symmetry type '//&
837 &trim(
i2str(sym_type_loc))
842 do kd = 1,
size(var_int,3)
844 do jd = 1,
size(var_int,2)
846 do id = 1,
size(var_int,1)
848 i_lo = floor(abs(theta_i(id,jd,kd)))
849 i_hi = ceiling(abs(theta_i(id,jd,kd)))
851 var_int(id,jd,kd,:) = var(i_lo,1,kd,:) + &
852 &(var(i_hi,1,kd,:)-var(i_lo,1,kd,:))*&
853 &(abs(theta_i(id,jd,kd))-i_lo)
854 if (theta_i(id,jd,kd).lt.0)
then
855 if (sym_type_loc.eq.1) var_int(id,jd,kd,:) = &
856 &conjg(var_int(id,jd,kd,:))
857 if (sym_type_loc.eq.2) var_int(id,jd,kd,:) = &
858 &- conjg(var_int(id,jd,kd,:))
863 end function interp_var_4d_complex
865 integer function interp_var_4d_complex_ow(var,sym_type)
result(ierr)
867 complex(dp),
intent(inout),
allocatable :: var(:,:,:,:)
868 integer,
intent(in),
optional :: sym_type
871 complex(dp),
allocatable :: var_4d_loc(:,:,:,:)
872 integer :: var_dim(4,2)
878 var_dim(:,1) = [1,1,1,1]
879 var_dim(:,2) = [shape(theta_i),
size(var,4)]
882 allocate(var_4d_loc(var_dim(1,1):var_dim(1,2),&
883 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2),&
884 &var_dim(4,1):var_dim(4,2)))
887 ierr = interp_var_4d_complex(var,var_4d_loc,sym_type)
892 allocate(var(var_dim(1,1):var_dim(1,2),&
893 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2),&
894 &var_dim(4,1):var_dim(4,2)))
898 end function interp_var_4d_complex_ow
900 integer function interp_var_6d_real(var,var_int,sym_type)
result(ierr)
902 real(dp),
intent(in) :: var(1:,1:,1:,0:,0:,0:)
903 real(dp),
intent(inout) :: var_int(1:,1:,1:,0:,0:,0:)
904 integer,
intent(in),
optional :: sym_type
907 integer :: i_lo, i_hi
908 integer :: id, jd, kd, ld
909 integer :: sym_type_loc
916 if (
present(sym_type)) sym_type_loc = sym_type
919 if (sym_type_loc.lt.0 .or. sym_type_loc.gt.2)
then
921 err_msg =
'Nonsensible symmetry type '//&
922 &trim(
i2str(sym_type_loc))
927 do kd = 1,
size(var_int,3)
929 do jd = 1,
size(var_int,2)
931 do id = 1,
size(var_int,1)
933 i_lo = floor(abs(theta_i(id,jd,kd)))
934 i_hi = ceiling(abs(theta_i(id,jd,kd)))
936 var_int(id,jd,kd,:,:,:) = var(i_lo,1,kd,:,:,:) + &
937 &(var(i_hi,1,kd,:,:,:)-var(i_lo,1,kd,:,:,:))*&
938 &(abs(theta_i(id,jd,kd))-i_lo)
939 if (theta_i(id,jd,kd).lt.0)
then
940 if (sym_type_loc.eq.2) var_int(id,jd,kd,:,:,:) = &
941 &- var_int(id,jd,kd,:,:,:)
944 do ld = 0,
size(var_int,6)-1
945 var_int(id,jd,kd,:,:,ld) = &
946 &(-1)**ld*var_int(id,jd,kd,:,:,ld)
950 err_msg =
'!!! INTERP_VAR_6D_REAL NOT YET &
951 &IMPLEMENTED FOR TOROIDAL FLUX !!!'
958 end function interp_var_6d_real
960 integer function interp_var_6d_real_ow(var,sym_type)
result(ierr)
962 real(dp),
intent(inout),
allocatable :: var(:,:,:,:,:,:)
963 integer,
intent(in),
optional :: sym_type
966 real(dp),
allocatable :: var_6d_loc(:,:,:,:,:,:)
967 integer :: var_dim(6,2)
973 var_dim(:,1) = [1,1,1,0,0,0]
974 var_dim(:,2) = [shape(theta_i),
size(var,4)-1,
size(var,5)-1,&
978 allocate(var_6d_loc(var_dim(1,1):var_dim(1,2),&
979 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2),&
980 &var_dim(4,1):var_dim(4,2),var_dim(5,1):var_dim(5,2),&
981 &var_dim(6,1):var_dim(6,2)))
984 ierr = interp_var_6d_real(var,var_6d_loc,sym_type)
989 allocate(var(var_dim(1,1):var_dim(1,2),&
990 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2),&
991 &var_dim(4,1):var_dim(4,2),var_dim(5,1):var_dim(5,2),&
992 &var_dim(6,1):var_dim(6,2)))
996 end function interp_var_6d_real_ow
998 integer function interp_var_7d_real(var,var_int,sym_type)
result(ierr)
1003 real(dp),
intent(in) :: var(1:,1:,1:,1:,0:,0:,0:)
1004 real(dp),
intent(inout) :: var_int(1:,1:,1:,1:,0:,0:,0:)
1005 integer,
intent(in),
optional :: sym_type
1008 integer :: i_lo, i_hi
1009 integer :: id, jd, kd, ld
1010 integer :: sym_type_loc
1011 real(dp),
allocatable :: t_met(:,:,:,:,:,:)
1012 integer,
allocatable :: derivs_loc(:,:)
1020 if (
present(sym_type)) sym_type_loc = sym_type
1023 if (sym_type_loc.lt.0 .or. sym_type_loc.gt.4)
then
1025 err_msg =
'Nonsensible symmetry type '//&
1026 &trim(
i2str(sym_type_loc))
1031 do kd = 1,
size(var_int,3)
1032 do jd = 1,
size(var_int,2)
1033 do id = 1,
size(var_int,1)
1034 i_lo = floor(abs(theta_i(id,jd,kd)))
1035 i_hi = ceiling(abs(theta_i(id,jd,kd)))
1037 var_int(id,jd,kd,:,:,:,:) = var(i_lo,1,kd,:,:,:,:) + &
1038 &(var(i_hi,1,kd,:,:,:,:)-var(i_lo,1,kd,:,:,:,:))*&
1039 &(abs(theta_i(id,jd,kd))-i_lo)
1045 if (sym_type_loc.eq.2 .or. sym_type_loc.eq.3 .or. &
1046 &sym_type_loc.eq.4)
then
1047 do kd = 1,
size(var_int,3)
1048 do jd = 1,
size(var_int,2)
1049 do id = 1,
size(var_int,1)
1050 if (theta_i(id,jd,kd).lt.0)
then
1052 if (sym_type_loc.eq.2)
then
1053 var_int(id,jd,kd,:,:,:,:) = &
1054 &- var_int(id,jd,kd,:,:,:,:)
1055 else if (sym_type_loc.eq.3 .or. &
1056 &sym_type_loc.eq.4)
then
1057 c_loc(1) =
c([2,1],.true.)
1058 c_loc(2) =
c([3,2],.true.)
1059 var_int(id,jd,kd,c_loc(1),:,:,:) = &
1060 &- var_int(id,jd,kd,c_loc(1),:,:,:)
1061 var_int(id,jd,kd,c_loc(2),:,:,:) = &
1062 &- var_int(id,jd,kd,c_loc(2),:,:,:)
1065 if (use_pol_flux_f)
then
1066 do ld = 0,
size(var_int,7)-1
1067 var_int(id,jd,kd,:,:,:,ld) = (-1)**ld*&
1068 &var_int(id,jd,kd,:,:,:,ld)
1072 err_msg =
'!!! INTERP_VAR_7D_REAL NOT YET &
1073 &IMPLEMENTED FOR TOROIDAL FLUX !!!'
1083 if (sym_type_loc.eq.3 .or. sym_type_loc.eq.4)
then
1084 allocate(t_met(
size(var_int,1),
size(var_int,2),&
1085 &
size(var_int,3),0:
size(var_int,5)-1,&
1086 &0:
size(var_int,6)-1,0:
size(var_int,7)-1))
1088 if (use_pol_flux_f)
then
1090 do kd = 1,
size(theta_i,3)
1091 t_met(:,:,kd,0,ld,0) = &
1092 &2*pi*eq_1%q_saf_FD(kd,ld+1)
1097 do kd = 1,
size(theta_i,3)
1098 t_met(:,:,kd,0,ld,0) = &
1099 &-2*pi*eq_1%rot_t_FD(kd,ld+1)
1103 do kd = 1,
size(theta_i,3)
1104 do jd = 1,
size(theta_i,2)
1105 do id = 1,
size(theta_i,1)
1106 t_met(id,jd,kd,:,:,:) = t_met(id,jd,kd,:,:,:)*&
1107 &fund_theta_int_displ(id,jd,kd)
1114 if (sym_type_loc.eq.3)
then
1115 if (use_pol_flux_f)
then
1118 do jd = 1,
size(derivs_loc,2)
1120 c_loc(1) =
c([3,2],.true.)
1121 c_loc(2) =
c([2,2],.true.)
1123 &var_int(:,:,:,c_loc(1),:,:,:),t_met,&
1124 &var_int(:,:,:,c_loc(2),&
1125 &derivs_loc(1,jd),derivs_loc(2,jd),&
1126 &derivs_loc(3,jd)),derivs_loc(:,jd))
1129 c_loc(1) =
c([3,1],.true.)
1130 c_loc(2) =
c([3,2],.true.)
1132 &var_int(:,:,:,c_loc(1),:,:,:),t_met,&
1133 &var_int(:,:,:,c_loc(2),&
1134 &derivs_loc(1,jd),derivs_loc(2,jd),&
1135 &derivs_loc(3,jd)),derivs_loc(:,jd))
1138 c_loc(1) =
c([3,2],.true.)
1139 c_loc(2) =
c([2,2],.true.)
1141 &var_int(:,:,:,c_loc(1),:,:,:),t_met,&
1142 &var_int(:,:,:,c_loc(2),&
1143 &derivs_loc(1,jd),derivs_loc(2,jd),&
1144 &derivs_loc(3,jd)),derivs_loc(:,jd))
1147 c_loc(1) =
c([1,1],.true.)
1148 c_loc(2) =
c([1,2],.true.)
1150 &var_int(:,:,:,c_loc(1),:,:,:),t_met,&
1151 &var_int(:,:,:,c_loc(2),&
1152 &derivs_loc(1,jd),derivs_loc(2,jd),&
1153 &derivs_loc(3,jd)),derivs_loc(:,jd))
1159 err_msg =
'!!! INTERP_VAR_7D_REAL NOT YET &
1160 &IMPLEMENTED FOR TOROIDAL FLUX !!!'
1166 if (sym_type_loc.eq.4)
then
1167 if (use_pol_flux_f)
then
1170 do jd = 1,
size(derivs_loc,2)
1172 c_loc(1) =
c([1,2],.true.)
1173 c_loc(2) =
c([1,1],.true.)
1175 &var_int(:,:,:,c_loc(1),:,:,:),-t_met,&
1176 &var_int(:,:,:,c_loc(2),&
1177 &derivs_loc(1,jd),derivs_loc(2,jd),&
1178 &derivs_loc(3,jd)),derivs_loc(:,jd))
1181 c_loc(1) =
c([2,2],.true.)
1182 c_loc(2) =
c([1,2],.true.)
1184 &var_int(:,:,:,c_loc(1),:,:,:),-t_met,&
1185 &var_int(:,:,:,c_loc(2),&
1186 &derivs_loc(1,jd),derivs_loc(2,jd),&
1187 &derivs_loc(3,jd)),derivs_loc(:,jd))
1190 c_loc(1) =
c([1,2],.true.)
1191 c_loc(2) =
c([1,1],.true.)
1193 &var_int(:,:,:,c_loc(1),:,:,:),-t_met,&
1194 &var_int(:,:,:,c_loc(2),&
1195 &derivs_loc(1,jd),derivs_loc(2,jd),&
1196 &derivs_loc(3,jd)),derivs_loc(:,jd))
1199 c_loc(1) =
c([2,3],.true.)
1200 c_loc(2) =
c([1,3],.true.)
1202 &var_int(:,:,:,c_loc(1),:,:,:),-t_met,&
1203 &var_int(:,:,:,c_loc(2),&
1204 &derivs_loc(1,jd),derivs_loc(2,jd),&
1205 &derivs_loc(3,jd)),derivs_loc(:,jd))
1211 err_msg =
'!!! INTERP_VAR_7D_REAL NOT YET &
1212 &IMPLEMENTED FOR TOROIDAL FLUX !!!'
1216 end function interp_var_7d_real
1218 integer function interp_var_7d_real_ow(var,sym_type)
result(ierr)
1221 real(dp),
intent(inout),
allocatable :: var(:,:,:,:,:,:,:)
1222 integer,
intent(in),
optional :: sym_type
1225 real(dp),
allocatable :: var_7d_loc(:,:,:,:,:,:,:)
1226 integer :: var_dim(7,2)
1232 var_dim(:,1) = [1,1,1,1,0,0,0]
1233 var_dim(:,2) = [shape(theta_i),
size(var,4),
size(var,5)-1,&
1234 &
size(var,6)-1,
size(var,7)-1]
1237 allocate(var_7d_loc(var_dim(1,1):var_dim(1,2),&
1238 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2),&
1239 &var_dim(4,1):var_dim(4,2),var_dim(5,1):var_dim(5,2),&
1240 &var_dim(6,1):var_dim(6,2),var_dim(7,1):var_dim(7,2)))
1243 ierr = interp_var_7d_real(var,var_7d_loc,sym_type)
1248 allocate(var(var_dim(1,1):var_dim(1,2),&
1249 &var_dim(2,1):var_dim(2,2),var_dim(3,1):var_dim(3,2),&
1250 &var_dim(4,1):var_dim(4,2),var_dim(5,1):var_dim(5,2),&
1251 &var_dim(6,1):var_dim(6,2),var_dim(7,1):var_dim(7,2)))
1255 end function interp_var_7d_real_ow
1295 character(*),
parameter :: rout_name =
'test_metrics_H'
1300 real(dp) :: bcs_val(2,3)
1301 real(dp),
allocatable :: rchi(:,:), rpsi(:,:)
1302 real(dp),
allocatable :: zchi(:,:), zpsi(:,:)
1303 real(dp),
allocatable :: jac(:,:)
1304 real(dp),
allocatable :: jac_alt(:,:)
1305 real(dp),
allocatable :: h_h_11_alt(:,:,:)
1306 real(dp),
allocatable :: h_h_12_alt(:,:,:)
1307 real(dp),
allocatable :: h_h_33_alt(:,:,:)
1308 character(len=max_str_ln) :: file_name
1309 character(len=max_str_ln) :: description
1310 integer :: r_min = 4
1311 real(dp),
allocatable :: tempvar(:,:,:,:)
1318 call writo(
'Checking consistency of metric factors')
1342 &deriv=1,bcs=bcs(:,3),bcs_val=bcs_val(:,3))
1346 &deriv=1,bcs=bcs(:,3),bcs_val=bcs_val(:,3))
1352 &bcs_val=bcs_val(:,1))
1356 &bcs_val=bcs_val(:,2))
1367 jac_alt =
r_h*(zchi*rpsi - zpsi*rchi)
1371 file_name =
'TEST_jac_H'
1372 description =
'Testing whether the HELENA Jacobian is consistent.'
1376 &reshape(jac(:,r_min:
n_r_eq),&
1378 &[
nchi,1,
n_r_eq-r_min+1]),file_name,descr=description,&
1379 &output_message=.true.)
1386 h_h_11_alt(:,1,:) = (
r_h/jac)**2 * (zchi**2 + rchi**2)
1387 h_h_12_alt(:,1,:) = -(
r_h/jac)**2 * (zchi*zpsi + rchi*rpsi)
1388 h_h_33_alt(:,1,:) = 1._dp/(
r_h**2)
1392 file_name =
'TEST_h_H_1_1'
1393 description =
'Testing whether the HELENA metric factor h_1_1 is &
1399 &file_name,descr=description,output_message=.true.)
1403 file_name =
'TEST_h_H_1_2'
1404 description =
'Testing whether the HELENA metric factor h_1_2 is &
1410 &file_name,descr=description,output_message=.true.)
1414 file_name =
'TEST_h_H_3_3'
1415 description =
'Testing whether the HELENA metric factor h_3_3 is &
1421 &file_name,descr=description,output_message=.true.)
1425 call writo(
'Test complete')
1428 call writo(
'Checking pressure balance')
1438 tempvar(:,1,kd,1) =
rbphi_h(kd,1)
1439 tempvar(:,1,kd,2) =
pres_h(kd,1)
1444 &
flux_p_h(:,0)/(2*pi),tempvar(id,1,:,3),&
1446 &bcs_val=bcs_val(:,3))
1452 &bcs=bcs(:,2),bcs_val=bcs_val(:,2))
1459 tempvar(:,1,kd,1) = &
1461 &(tempvar(:,1,kd,1)*
q_saf_h(kd,0) + tempvar(:,1,kd,3) + &
1467 file_name =
'TEST_p_H'
1468 description =
'Testing whether the HELENA pressure balance is &
1473 &file_name,descr=description,output_message=.true.)
1477 call writo(
'Test complete')
1489 character(*),
parameter :: rout_name =
'test_metrics_H'
1493 integer :: nchi_full
1494 real(
dp),
allocatable :: f_loc(:,:)
1495 real(
dp),
allocatable :: chi_full(:)
1496 real(
dp),
allocatable :: r_h_full(:,:)
1497 real(
dp),
allocatable :: z_h_full(:,:)
1498 real(
dp),
allocatable :: r_h_f(:,:,:,:)
1499 real(
dp),
allocatable :: z_h_f(:,:,:,:)
1500 character(len=max_str_ln) :: plot_name
1501 character(len=2) :: loc_str(2)
1508 nchi_full = 2*(
nchi-1)
1509 allocate(chi_full(nchi_full))
1510 allocate(r_h_full(nchi_full,
n_r_eq))
1511 allocate(z_h_full(nchi_full,
n_r_eq))
1520 allocate(chi_full(nchi_full))
1521 allocate(r_h_full(nchi_full,
n_r_eq))
1522 allocate(z_h_full(nchi_full,
n_r_eq))
1523 chi_full(1:nchi_full) =
chi_h(1:nchi_full)
1524 r_h_full(1:nchi_full,:) =
r_h(1:nchi_full,:)
1525 z_h_full(1:nchi_full,:) =
z_h(1:nchi_full,:)
1530 ierr =
nufft(chi_full,r_h_full(:,kd),f_loc)
1532 if (kd.eq.1)
allocate(r_h_f(
size(f_loc,1),1,
n_r_eq,2))
1533 r_h_f(:,1,kd,:) = f_loc
1534 ierr =
nufft(chi_full,z_h_full(:,kd),f_loc)
1536 if (kd.eq.1)
allocate(z_h_f(
size(f_loc,1),1,
n_r_eq,2))
1537 z_h_f(:,1,kd,:) = f_loc
1544 plot_name = loc_str(kd)//
'_R_H_F'
1545 call print_ex_2d([
'1'],plot_name,r_h_f(:,1,:,kd),draw=.false.)
1547 plot_name = loc_str(kd)//
'_Z_H_F'
1548 call print_ex_2d([
'1'],plot_name,z_h_f(:,1,:,kd),draw=.false.)
1551 plot_name = loc_str(kd)//
'_R_H_F_log'
1553 &log10(max(1.e-10_dp,abs(r_h_f(:,1,:,kd)))),&
1556 plot_name = loc_str(kd)//
'_Z_H_F_log'
1558 &log10(max(1.e-10_dp,abs(z_h_f(:,1,:,kd)))),&
1562 call plot_hdf5([
'real',
'imag'],
'R_H_F',r_h_f)
1563 call plot_hdf5([
'real',
'imag'],
'R_H_F_log',&
1564 &log10(max(1.e-10_dp,abs(r_h_f))))
1565 call plot_hdf5([
'real',
'imag'],
'Z_H_F',z_h_f)
1566 call plot_hdf5([
'real',
'imag'],
'Z_H_F_log',&
1567 &log10(max(1.e-10_dp,abs(z_h_f))))