5 #include <PB3D_macros.h>
23 logical :: debug_run_driver_sol = .false.
24 logical :: debug_interp_V = .false.
25 integer :: ivs_stats(3)
41 integer function run_driver_sol(grid_eq,grid_X,grid_sol,X,vac,sol) &
61 character(*),
parameter :: rout_name =
'run_driver_sol'
65 type(
grid_type),
intent(in),
target :: grid_x
66 type(
grid_type),
intent(inout) :: grid_sol
77 integer :: sol_limits(2)
78 integer :: rich_lvl_name
79 real(dp),
allocatable :: r_f_sol(:)
81 character(len=max_str_ln) :: err_msg
96 call writo(
'Set up solution grid')
99 call writo(
'Calculate the grid')
106 call writo(
'Write to output file')
115 ierr = setup_modes(
mds_sol,grid_eq,grid_sol,plot_name=
'sol')
122 &grid_limits=sol_limits)
128 ierr = setup_modes(
mds_sol,grid_eq,grid_sol,plot_name=
'sol')
137 call grid_sol_trim%dealloc()
163 call writo(
'Write to output file')
174 ierr = grid_x_sol%init([1,
n_alpha,grid_sol%n(3)],&
175 &[grid_sol%i_min,grid_sol%i_max],grid_sol%divided)
177 grid_x_sol%r_F = grid_sol%r_F
178 grid_x_sol%r_E = grid_sol%r_E
179 grid_x_sol%loc_r_F = grid_sol%loc_r_F
180 grid_x_sol%loc_r_E = grid_sol%loc_r_E
186 call writo(
'Redistribute and interpolate the perturbation &
187 &variables to solution grid')
197 call x_sol%init(
mds_sol,grid_x_sol,is_field_averaged=.true.)
205 call x_rdst%dealloc()
206 call grid_x_rdst%dealloc()
211 call writo(
'Copy the perturbation variables to solution grid')
215 call x%copy(
mds_sol,grid_x,x_sol)
223 if (debug_run_driver_sol)
then
230 call grid_x_sol%dealloc()
233 call writo(
'Solving the system')
241 err_msg =
'No EV solver style associated with '//&
247 call writo(
'System solved')
251 &remove_previous_arrs=&
283 integer function interp_v(mds_i,grid_i,X_i,mds_o,grid_o,X_o)
result(ierr)
294 character(*),
parameter :: rout_name =
'interp_V'
299 type(
x_2_type),
intent(in),
target :: x_i
302 type(
x_2_type),
intent(inout),
target :: x_o
307 integer :: c_loc_i(2)
308 integer :: c_loc_o(2)
310 integer :: kdl_i(2), kdl_o(2)
311 integer :: id_lim_i(2), id_lim_o(2)
312 integer :: ivs_stat(6)
313 integer,
pointer :: sec_i_loc(:,:), sec_o_loc(:,:)
314 real(dp),
pointer :: r_i_loc(:), r_o_loc(:)
315 complex(dp),
pointer :: v_i(:,:,:), v_o(:,:,:)
316 logical :: calc_this(2)
317 logical :: extrap = .true.
318 character(len=max_str_ln) :: err_msg
321 integer,
allocatable :: norm_ext_i(:,:)
322 real(dp),
allocatable :: r_loc_tot(:,:,:)
323 character(len=max_str_ln) :: ivs_stats_names(3)
331 if (grid_i%n(2).ne.grid_o%n(2))
then
333 err_msg =
'input and output grid are not compatible in the &
334 &geodesic coordinate: '//trim(
i2str(grid_i%n(2)))//
' vs. '//&
335 &trim(
i2str(grid_o%n(2)))
349 ierr =
trim_modes(mds_i,mds_o,id_lim_i,id_lim_o)
351 sec_i_loc => mds_i%sec(id_lim_i(1):id_lim_i(2),:)
352 sec_o_loc => mds_o%sec(id_lim_o(1):id_lim_o(2),:)
355 n_mod_tot =
size(sec_o_loc,1)
357 allocate(r_loc_tot(2,n_mod_tot**2,3))
358 allocate(norm_ext_i(n_mod_tot,n_mod_tot))
366 if (sec_i_loc(k,1).ne.sec_o_loc(k,1) .or. &
367 &sec_i_loc(m,1).ne.sec_o_loc(m,1))
then
369 err_msg =
'For ('//trim(
i2str(k))//
','//trim(
i2str(m))//&
370 &
'), no consistency for modes in grid_i and grid_o'
376 kdl_i(1) = max(sec_i_loc(k,2),sec_i_loc(m,2))
377 kdl_i(2) = min(sec_i_loc(k,3),sec_i_loc(m,3))
378 kdl_o(1) = max(sec_o_loc(k,2),sec_o_loc(m,2))
379 kdl_o(2) = min(sec_o_loc(k,3),sec_o_loc(m,3))
382 kdl_i(1) = max(kdl_i(1),grid_i%i_min)
383 kdl_i(2) = min(kdl_i(2),grid_i%i_max)
384 kdl_o(1) = max(kdl_o(1),grid_o%i_min)
385 kdl_o(2) = min(kdl_o(2),grid_o%i_max)
388 if (.not.extrap)
then
389 do kd = kdl_o(1),kdl_o(2)
390 if (grid_o%r_F(kd).ge.grid_i%r_F(kdl_i(1)))
exit
394 do kd = kdl_o(2),kdl_o(1),-1
395 if (grid_o%r_F(kd).le.grid_i%r_F(kdl_i(2)))
exit
401 if (kdl_i(1).gt.kdl_i(2) .or. kdl_o(1).gt.kdl_o(2)) cycle
404 kdl_i = kdl_i - grid_i%i_min + 1
405 kdl_o = kdl_o - grid_o%i_min + 1
408 r_i_loc => grid_i%loc_r_F(kdl_i(1):kdl_i(2))
409 r_o_loc => grid_o%loc_r_F(kdl_o(1):kdl_o(2))
413 &[sec_o_loc(k,1),sec_o_loc(m,1)])
415 &[sec_o_loc(k,1),sec_o_loc(m,1)])
419 r_loc_tot(:,km_id,1) = [r_i_loc(1),r_i_loc(
size(r_i_loc))]
420 r_loc_tot(:,km_id,2) = [r_o_loc(1),r_o_loc(
size(r_o_loc))]
421 r_loc_tot(:,km_id,3) = km_id
422 norm_ext_i(k,m) =
size(r_i_loc)
423 if (debug_interp_v)
write(*,*)
'k, m', k, m,
'of', n_mod_tot, &
424 &
'with calc_this = ', calc_this
428 c_loc_i(1) =
c([sec_i_loc(k,4),sec_i_loc(m,4)],.true.,
n_mod_x)
429 c_loc_i(2) =
c([sec_i_loc(k,4),sec_i_loc(m,4)],.false.,
n_mod_x)
430 c_loc_o(1) =
c([sec_o_loc(k,4),sec_o_loc(m,4)],.true.,
n_mod_x)
431 c_loc_o(2) =
c([sec_o_loc(k,4),sec_o_loc(m,4)],.false.,
n_mod_x)
433 if (calc_this(1))
then
434 v_i => x_i%PV_0(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
435 v_o => x_o%PV_0(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
440 v_i => x_i%PV_2(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
441 v_o => x_o%PV_2(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
446 v_i => x_i%KV_0(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
447 v_o => x_o%KV_0(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
452 v_i => x_i%KV_2(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
453 v_o => x_o%KV_2(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
459 if (debug_interp_v)
then
492 if (calc_this(2))
then
493 v_i => x_i%PV_1(:,:,kdl_i(1):kdl_i(2),c_loc_i(2))
494 v_o => x_o%PV_1(:,:,kdl_o(1):kdl_o(2),c_loc_o(2))
499 v_i => x_i%KV_1(:,:,kdl_i(1):kdl_i(2),c_loc_i(2))
500 v_o => x_o%KV_1(:,:,kdl_o(1):kdl_o(2),c_loc_o(2))
506 do kd = 1,
size(ivs_stat)
511 ivs_stats(ivs_stat(kd)) = ivs_stats(ivs_stat(kd)) + 1
518 call writo(
'interp_V_spline statistics:')
520 ivs_stats_names(1) =
'direct copy'
521 ivs_stats_names(2) =
'linear interpolation'
522 ivs_stats_names(3) =
'spline interpolation'
524 call writo(trim(ivs_stats_names(kd))//
' was performed '//&
525 &trim(
i2str(ivs_stats(kd)))//
' times: '//&
526 &trim(
r2strt(100._dp*ivs_stats(kd)/sum(ivs_stats)))//
'%')
528 if (ivs_stats(1).gt.0)
then
529 call writo(
'It is possible that more secondary modes and/or a &
530 &lower max_njq_change are needed.',warning=.true.)
531 call writo(
'If unphysical modes appear, consider changing these &
532 &variables.',warning=.true.)
536 &r_loc_tot(:,1:km_id,1)/
max_flux_f*2*pi,x=r_loc_tot(:,1:km_id,3),&
541 &r_loc_tot(:,1:km_id,2)/
max_flux_f*2*pi,x=r_loc_tot(:,1:km_id,3),&
546 &reshape(norm_ext_i*1._dp,[n_mod_tot,n_mod_tot,1]))
550 nullify(r_i_loc,r_o_loc)
551 nullify(sec_i_loc,sec_o_loc)