5 #include <PB3D_macros.h>
38 module procedure calc_f_derivs_1
40 module procedure calc_f_derivs_2
63 module procedure calc_inv_met_ind
65 module procedure calc_inv_met_arr
67 module procedure calc_inv_met_ind_0d
69 module procedure calc_inv_met_arr_0d
120 module procedure transf_deriv_3_ind
122 module procedure transf_deriv_3_arr
124 module procedure transf_deriv_3_arr_2d
126 module procedure transf_deriv_1_ind
131 integer function calc_inv_met_ind(X,Y,deriv)
result(ierr)
137 character(*),
parameter :: rout_name =
'calc_inv_met_ind'
140 real(dp),
intent(inout) :: x(1:,1:,1:,1:,0:,0:,0:)
141 real(dp),
intent(in) :: y(1:,1:,1:,1:,0:,0:,0:)
142 integer,
intent(in) :: deriv(:)
146 integer :: m1, m2, m3
148 real(dp) :: bin_fac(3)
149 real(dp),
allocatable :: dum1(:,:,:,:)
150 real(dp),
allocatable :: dum2(:,:,:,:)
152 character(len=max_str_ln) :: err_msg
154 real(dp),
allocatable :: xy(:,:,:,:)
164 if (
size(y,4).ne.nn)
then
166 err_msg =
'Both matrices X and Y have to be either in full or &
167 &lower diagonal storage'
177 dims = [
size(x,1),
size(x,2),
size(x,3)]
180 x(:,:,:,:,m1,m2,m3) = 0._dp
183 allocate(dum1(dims(1),dims(2),dims(3),9))
184 allocate(dum2(dims(1),dims(2),dims(3),9))
190 if (m1.eq.0 .and. m2.eq.0 .and. m3.eq.0)
then
191 ierr =
calc_inv(x(:,:,:,:,0,0,0),y(:,:,:,:,0,0,0),3)
197 if (
n_procs.gt.1)
call writo(
'Debugging of calc_inv_met_ind &
198 &should be done with one processor only',warning=.true.)
199 call writo(
'checking if X*Y = 1')
201 allocate(xy(dims(1),dims(2),dims(3),9))
202 ierr =
calc_mult(x(:,:,:,:,0,0,0),y(:,:,:,:,0,0,0),xy,3)
207 &trim(
r2strt(minval(xy(:,1,:,
c([r,t],.false.)))))//&
208 &
' < element ('//trim(
i2str(t))//
','//&
209 &trim(
i2str(r))//
') < '//&
210 &trim(
r2strt(maxval(xy(:,1,:,
c([r,t],.false.))))))
222 bin_fac(3) = bin_fac(3)*(m3-(z-1))/z
228 bin_fac(2) = bin_fac(2)*(m2-(t-1))/t
234 bin_fac(1) = bin_fac(1)*(m1-(r-1))/r
236 if (z+t+r .lt. m1+m2+m3)
then
239 &y(:,:,:,:,m1-r,m2-t,m3-z),dum1,3)
242 dum2 = dum2 - product(bin_fac)*dum1
249 ierr =
calc_mult(dum2,x(:,:,:,:,0,0,0),dum1,3)
252 ierr =
conv_mat(dum1,x(:,:,:,:,m1,m2,m3),3)
256 deallocate(dum1,dum2)
258 end function calc_inv_met_ind
260 integer function calc_inv_met_ind_0d(X,Y,deriv)
result(ierr)
261 character(*),
parameter :: rout_name =
'calc_inv_met_ind_0D'
264 real(
dp),
intent(inout) :: x(1:,1:,1:,0:,0:,0:)
265 real(
dp),
intent(in) :: y(1:,1:,1:,0:,0:,0:)
266 integer,
intent(in) :: deriv(:)
270 integer :: m1, m2, m3
271 real(
dp) :: bin_fac(3)
281 x(:,:,:,m1,m2,m3) = 0.0_dp
284 if (m1.eq.0 .and. m2.eq.0 .and. m3.eq.0)
then
285 x(:,:,:,0,0,0) = 1._dp/y(:,:,:,0,0,0)
291 bin_fac(3) = bin_fac(3)*(m3-(z-1))/z
299 bin_fac(2) = bin_fac(2)*(m2-(t-1))/t
305 bin_fac(1) = bin_fac(1)*(m1-(r-1))/r
307 if (z+t+r .lt. m1+m2+m3)
then
308 x(:,:,:,m1,m2,m3) = x(:,:,:,m1,m2,m3)-&
309 &bin_fac(1)*bin_fac(2)*bin_fac(3)* &
310 &x(:,:,:,r,t,z)*y(:,:,:,m1-r,m2-t,m3-z)
317 x(:,:,:,m1,m2,m3) = x(:,:,:,m1,m2,m3)*x(:,:,:,0,0,0)
319 end function calc_inv_met_ind_0d
321 integer function calc_inv_met_arr(X,Y,deriv)
result(ierr)
322 character(*),
parameter :: rout_name =
'calc_inv_met_arr'
325 real(
dp),
intent(inout) :: x(1:,1:,1:,1:,0:,0:,0:)
326 real(
dp),
intent(in) :: y(1:,1:,1:,1:,0:,0:,0:)
327 integer,
intent(in) :: deriv(:,:)
335 do id = 1,
size(deriv,2)
336 ierr = calc_inv_met_ind(x,y,deriv(:,id))
339 end function calc_inv_met_arr
341 integer function calc_inv_met_arr_0d(X,Y,deriv)
result(ierr)
342 character(*),
parameter :: rout_name =
'calc_inv_met_arr_0D'
345 real(
dp),
intent(inout) :: x(1:,1:,1:,0:,0:,0:)
346 real(
dp),
intent(in) :: y(1:,1:,1:,0:,0:,0:)
347 integer,
intent(in) :: deriv(:,:)
355 do id = 1,
size(deriv,2)
356 ierr = calc_inv_met_ind_0d(x,y,deriv(:,id))
359 end function calc_inv_met_arr_0d
386 integer function calc_g(g_A,T_BA,g_B,deriv,max_deriv)
result(ierr)
389 character(*),
parameter :: rout_name =
'calc_g'
392 real(
dp),
intent(in) :: g_a(:,:,:,:,0:,0:,0:)
393 real(
dp),
intent(in) :: t_ba(:,:,:,:,0:,0:,0:)
394 real(
dp),
intent(inout) :: g_b(:,:,:,:,0:,0:,0:)
395 integer,
intent(in) :: deriv(3)
399 integer :: i1, j1, i2, j2, i3, j3, k1, k2, k3
400 integer :: m1, m2, m3
401 real(
dp),
allocatable :: c1(:), c2(:), c3(:)
402 real(
dp),
allocatable :: dum1(:,:,:,:)
403 real(
dp),
allocatable :: dum2(:,:,:,:)
410 ierr = check_deriv(deriv,
max_deriv,
'calc_g')
420 allocate(dum1(
size(g_a,1),
size(g_a,2),
size(g_a,3),9))
421 allocate(dum2(
size(g_a,1),
size(g_a,2),
size(g_a,3),9))
424 g_b(:,:,:,:,m1,m2,m3) = 0.0_dp
428 call calc_c(m1,j1,c1)
431 call calc_c(m2,j2,c2)
434 call calc_c(m3,j3,c3)
442 &t_ba(:,:,:,:,k1,k2,k3),dum1,3,&
443 &transp=[.false.,.true.])
445 ierr =
calc_mult(t_ba(:,:,:,:,i1,i2,i3),&
449 ierr =
conv_mat(dum2,dum1(:,:,:,1:6),3)
451 g_b(:,:,:,:,m1,m2,m3) = g_b(:,:,:,:,m1,m2,m3) &
452 &+c1(i1)*c2(i2)*c3(i3)*dum1(:,:,:,1:6)
461 deallocate(dum1,dum2)
475 subroutine calc_c(m,j,C)
477 integer,
intent(in) :: m, j
478 real(
dp),
intent(inout),
allocatable :: c(:)
485 if (j.gt.0) cm_prev = c(m-j+1)
488 if (
allocated(c))
deallocate (c)
495 c(m-j) = (m-j+1.0_dp)/j * cm_prev
500 c(i) = (i+1.0_dp)/(m-i-j) * c(i+1)
506 integer recursive function transf_deriv_3_ind(x_a,t_ba,x_b,
max_deriv,&
507 &deriv_B,deriv_A_input) result(ierr)
510 character(*),
parameter :: rout_name =
'transf_deriv_3_ind'
513 real(
dp),
intent(in) :: x_a(1:,1:,1:,0:,0:,0:)
514 real(
dp),
intent(in) :: t_ba(1:,1:,1:,1:,0:,0:,0:)
515 real(
dp),
intent(inout) :: x_b(1:,1:,1:)
517 integer,
intent(in) :: deriv_b(:)
518 integer,
intent(in),
optional :: deriv_a_input(:)
521 integer :: id, jd, kd, ld
522 integer :: deriv_id_b
523 integer,
allocatable :: deriv_a(:)
524 real(
dp),
allocatable :: x_b_x(:,:,:,:,:,:)
525 integer,
allocatable :: deriv_a_x(:)
526 integer,
allocatable :: deriv_b_x(:)
532 allocate(deriv_a(
size(deriv_b)))
533 if (
present(deriv_a_input))
then
534 deriv_a = deriv_a_input
553 if (deriv_b(id).gt.0)
then
562 if (deriv_id_b.eq.0)
then
563 x_b = x_a(:,:,:,deriv_a(1),deriv_a(2),deriv_a(3))
567 allocate(x_b_x(
size(x_b,1),
size(x_b,2),
size(x_b,3),&
568 &0:deriv_a(1),0:deriv_a(2),0:deriv_a(3)))
569 allocate(deriv_a_x(
size(deriv_a)))
570 allocate(deriv_b_x(
size(deriv_b)))
585 deriv_a_x = [jd,kd,ld]
586 deriv_a_x(id) = deriv_a_x(id) + 1
591 deriv_b_x(deriv_id_b) = deriv_b_x(deriv_id_b) - 1
595 ierr = transf_deriv_3_ind(x_a,t_ba,&
596 &x_b_x(:,:,:,jd,kd,ld),
max_deriv,deriv_b_x,&
606 &t_ba(:,:,:,c([deriv_id_b,id],.false.),0:,0:,0:),&
607 &x_b_x(:,:,:,0:,0:,0:),x_b,deriv_a)
611 end function transf_deriv_3_ind
613 integer function transf_deriv_3_arr(X_A,T_BA,X_B,max_deriv,derivs) &
615 character(*),
parameter :: rout_name =
'transf_deriv_3_arr'
618 real(dp),
intent(in) :: x_a(1:,1:,1:,0:,0:,0:)
619 real(dp),
intent(in) :: t_ba(1:,1:,1:,1:,0:,0:,0:)
620 real(dp),
intent(inout) :: x_b(1:,1:,1:,0:,0:,0:)
621 integer,
intent(in) :: max_deriv
622 integer,
intent(in) :: derivs(:,:)
630 do id = 1,
size(derivs,2)
631 ierr = transf_deriv_3_ind(x_a,t_ba,&
632 &x_b(:,:,:,derivs(1,id),derivs(2,id),derivs(3,id)),&
633 &max_deriv,derivs(:,id))
636 end function transf_deriv_3_arr
638 integer function transf_deriv_3_arr_2d(X_A,T_BA,X_B,max_deriv,derivs) &
642 character(*),
parameter :: rout_name =
'transf_deriv_3_arr_2D'
645 real(dp),
intent(in) :: x_a(1:,1:,1:,1:,0:,0:,0:)
646 real(dp),
intent(in) :: t_ba(1:,1:,1:,1:,0:,0:,0:)
647 real(dp),
intent(inout) :: x_b(1:,1:,1:,1:,0:,0:,0:)
648 integer,
intent(in) :: max_deriv
649 integer,
intent(in) :: derivs(:,:)
653 character(len=max_str_ln) :: err_msg
660 if (
size(x_a,4).ne.
size(x_b,4))
then
661 err_msg =
'X_A and X_B need to have the same sizes'
666 ierr =
is_sym(3,
size(x_a,4),sym)
669 do kd = 1,
size(x_a,4)
670 do id = 1,
size(derivs,2)
671 ierr = transf_deriv_3_ind(x_a(:,:,:,kd,:,:,:),t_ba,&
672 &x_b(:,:,:,kd,derivs(1,id),derivs(2,id),derivs(3,id)),&
673 &max_deriv,derivs(:,id))
677 end function transf_deriv_3_arr_2d
679 integer recursive function transf_deriv_1_ind(x_a,t_ba,x_b,max_deriv,&
680 &deriv_B,deriv_A_input) result(ierr)
683 character(*),
parameter :: rout_name =
'transf_deriv_1_ind'
686 real(dp),
intent(in) :: x_a(1:,0:)
687 real(dp),
intent(inout) :: x_b(1:)
688 real(dp),
intent(in) :: t_ba(1:,0:)
689 integer,
intent(in),
optional :: deriv_a_input
690 integer,
intent(in) :: deriv_b
691 integer,
intent(in) :: max_deriv
696 real(dp),
allocatable :: x_b_x(:,:)
704 if (
present(deriv_a_input))
then
705 deriv_a = deriv_a_input
713 ierr = check_deriv([deriv_a+deriv_b,0,0],max_deriv,
'transf_deriv')
720 if (deriv_b.eq.0)
then
725 allocate(x_b_x(
size(x_b,1),0:deriv_a))
738 deriv_b_x = deriv_b-1
742 ierr = transf_deriv_1_ind(x_a,t_ba,x_b_x(:,jd),max_deriv,&
743 &deriv_b_x,deriv_a_input=deriv_a_x)
748 ierr = add_arr_mult(t_ba(:,0:),x_b_x(:,0:),x_b,[deriv_a,0,0])
751 end function transf_deriv_1_ind
754 integer function calc_f_derivs_1(grid_eq,eq)
result(ierr)
759 character(*),
parameter :: rout_name =
'calc_F_derivs_1'
762 type(grid_type),
intent(in) :: grid_eq
767 real(dp),
allocatable :: t_fe_loc(:,:)
778 call writo(
'Transform flux equilibrium quantities to flux &
784 allocate(t_fe_loc(grid_eq%loc_n_r,0:
max_deriv+1))
787 t_fe_loc(:,id) = 2*pi/
max_flux_e*eq%q_saf_E(:,id)
798 ierr =
transf_deriv(eq%pres_E,t_fe_loc,eq%pres_FD(:,id),&
811 eq%flux_t_FD(:,id) = -eq%flux_t_FD(:,id)
814 ierr =
transf_deriv(eq%q_saf_E,t_fe_loc,eq%q_saf_FD(:,id),&
817 eq%q_saf_FD(:,id) = -eq%q_saf_FD(:,id)
820 ierr =
transf_deriv(eq%rot_t_E,t_fe_loc,eq%rot_t_FD(:,id),&
823 eq%rot_t_FD(:,id) = -eq%rot_t_FD(:,id)
829 eq%flux_p_FD = eq%flux_p_E
830 eq%flux_t_FD = eq%flux_t_E
831 eq%pres_FD = eq%pres_E
832 eq%q_saf_FD = eq%q_saf_E
833 eq%rot_t_FD = eq%rot_t_E
835 end function calc_f_derivs_1
837 integer function calc_f_derivs_2(eq)
result(ierr)
841 character(*),
parameter :: rout_name =
'calc_F_derivs_2'
844 type(eq_2_type),
intent(inout) :: eq
864 call writo(
'Transform metric equilibrium quantities to flux &
881 ierr =
transf_deriv(eq%jac_F,eq%T_FE,eq%jac_FD,max_deriv,&
887 end function calc_f_derivs_2
906 integer function calc_memory_eq(arr_size,n_par,mem_size)
result(ierr)
909 character(*),
parameter :: rout_name =
'calc_memory_eq'
912 integer,
intent(in) :: arr_size
913 integer,
intent(in) :: n_par
914 real(dp),
intent(inout) :: mem_size
917 integer(C_SIZE_T) :: dp_size
925 dp_size = sizeof(1._dp)
928 mem_size = 13._dp*arr_size
929 mem_size = mem_size*n_par*(1+max_deriv)**3
930 mem_size = mem_size*dp_size
933 mem_size = mem_size*1.e-6_dp
936 mem_size = mem_size*1.5_dp
939 if (mem_size.lt.0)
then
941 chckerr(
'Overflow occured')
948 logical function do_eq()
973 elemental character(len=max_str_ln) function eq_info()
989 integer,
intent(in) :: n_par_x_rich
993 call writo(
'but parallel limits for this job only ['//&
996 &
'] of [1..'//trim(i2str(n_par_x_rich))//
']')