24 #include <PB3D_macros.h>
26 use strumpackdensepackage
112 integer function store_vac(grid,eq_1,eq_2,vac)
result(ierr)
122 character(*),
parameter :: rout_name =
'store_vac'
128 type(
vac_type),
intent(inout) :: vac
134 character(len=max_str_ln) :: err_msg
141 jq = eq_1%q_saf_FD(grid%loc_n_r,0)
143 jq = eq_1%rot_t_FD(grid%loc_n_r,0)
145 err_msg =
'TOR. FLUX HAS NOT BEEN TESTED AND IS MOST PROBABLY NOT &
155 ierr = store_vac_vmec()
158 ierr = store_vac_hel()
164 integer function store_vac_vmec()
result(ierr)
171 character(*),
parameter :: rout_name =
'store_vac_VMEC'
175 real(dp),
allocatable :: norm_com_c(:,:,:)
176 real(dp),
allocatable :: t_cv_loc(:,:,:,:,:,:,:)
178 logical :: interlaced_vac_copy_needed
184 call writo(
'Start storing vacuum quantities')
190 if (eq_job_nr.eq.1)
then
191 if (rich_lvl.eq.rich_restart_lvl)
then
196 if (rich_restart_lvl.eq.1)
then
198 interlaced_vac_copy_needed = .false.
202 &rich_lvl=rich_lvl-1)
206 interlaced_vac_copy_needed = .true.
218 interlaced_vac_copy_needed = .true.
226 if (interlaced_vac_copy_needed)
then
233 if (rank.eq.n_procs-1)
then
240 allocate(norm_com_c(grid%n(1),grid%n(2),3))
242 allocate(t_cv_loc(
size(eq_2%T_VC,1),
size(eq_2%T_VC,2),1:1,&
243 &
size(eq_2%T_VC,4),0:0,0:0,0:0))
244 ierr =
calc_inv_met(t_cv_loc,eq_2%T_VC(:,:,r_id:r_id,:,:,:,:),&
248 norm_com_c(:,:,id) = eq_2%jac_FD(:,:,r_id,0,0,0) * &
249 &eq_2%T_EF(:,:,r_id,
c([1,2],.false.),0,0,0)*&
250 &t_cv_loc(:,:,1,
c([id,1],.false.),0,0,0)
257 if (rich_lvl.eq.1)
then
258 par_id = [eq_jobs_lims(:,eq_job_nr),1]
260 par_id = [2*eq_jobs_lims(:,eq_job_nr),2]
262 par_id(1:2) = par_id(1:2) + (jd-1)*
n_par_x
265 vac%x_vec(par_id(1):par_id(2):par_id(3),1) = &
266 &eq_2%R_E(:,jd,r_id,0,0,0) * cos(grid%zeta_E(:,jd,r_id))
267 vac%x_vec(par_id(1):par_id(2):par_id(3),2) = &
268 &eq_2%R_E(:,jd,r_id,0,0,0) * sin(grid%zeta_E(:,jd,r_id))
269 vac%x_vec(par_id(1):par_id(2):par_id(3),3) = &
270 &eq_2%Z_E(:,jd,r_id,0,0,0)
273 vac%norm(par_id(1):par_id(2):par_id(3),1) = &
274 &norm_com_c(:,jd,1)*cos(grid%zeta_E(:,jd,r_id)) - &
275 &norm_com_c(:,jd,2)*sin(grid%zeta_E(:,jd,r_id)) / &
276 &eq_2%R_E(:,jd,r_id,0,0,0)
277 vac%norm(par_id(1):par_id(2):par_id(3),2) = &
278 &norm_com_c(:,jd,1)*sin(grid%zeta_E(:,jd,r_id)) + &
279 &norm_com_c(:,jd,2)*cos(grid%zeta_E(:,jd,r_id)) / &
280 &eq_2%R_E(:,jd,r_id,0,0,0)
281 vac%norm(par_id(1):par_id(2):par_id(3),3) = &
285 vac%h_fac(par_id(1):par_id(2):par_id(3),1) = &
286 &eq_2%g_FD(:,jd,r_id,
c([1,1],.true.),0,0,0)
287 vac%h_fac(par_id(1):par_id(2):par_id(3),2) = &
288 &eq_2%g_FD(:,jd,r_id,
c([1,3],.true.),0,0,0)
289 vac%h_fac(par_id(1):par_id(2):par_id(3),3) = &
290 &eq_2%g_FD(:,jd,r_id,
c([3,3],.true.),0,0,0)
291 vac%h_fac(par_id(1):par_id(2):par_id(3),4) = 0.5_dp* &
292 &eq_2%jac_FD(:,jd,r_id,0,0,0)**2 * &
293 &(eq_2%h_FD(:,jd,r_id,
c([2,2],.true.),0,0,0) / &
294 &eq_2%g_FD(:,jd,r_id,
c([1,1],.true.),0,0,0))**1.5 * ( &
295 &eq_2%jac_FD(:,jd,r_id,0,1,0)/&
296 &eq_2%jac_FD(:,jd,r_id,0,0,0) + &
297 &0.5_dp*eq_2%h_FD(:,jd,r_id,
c([2,2],.true.),0,1,0)/&
298 &eq_2%h_FD(:,jd,r_id,
c([2,2],.true.),0,0,0) - &
299 &0.5_dp*eq_2%g_FD(:,jd,r_id,
c([1,1],.true.),0,1,0)/&
300 &eq_2%g_FD(:,jd,r_id,
c([1,1],.true.),0,0,0) &
310 do id = 1,
size(vac%x_vec,2)
316 do id = 1,
size(vac%h_fac,2)
323 call writo(
'Done storing vacuum quantities')
324 end function store_vac_vmec
327 integer function store_vac_hel()
result(ierr)
331 character(*),
parameter :: rout_name =
'store_vac_HEL'
335 real(dp),
allocatable :: x_vec_f(:,:)
336 character(len=max_str_ln) :: err_msg
342 chckerr(
'Vacuum has not been implemented yet!')
345 call writo(
'Start storing vacuum quantities')
357 err_msg =
'HELENA should only have 1 equilibrium job &
358 &for Richardson level 1'
363 n_theta = 2*(
nchi-1)+1
381 vac%x_vec(
nchi+1:n_theta,1) =
r_h(
nchi-1:1:-1,r_id)
382 vac%x_vec(
nchi+1:n_theta,2) = -
z_h(
nchi-1:1:-1,r_id)
385 vac%x_vec(:,1) =
r_h(:,r_id)
386 vac%x_vec(:,2) =
z_h(:,r_id)
400 ierr =
nufft(vac%ang(1:n_theta-1,1),&
401 &vac%x_vec(1:n_theta-1,2),x_vec_f)
404 do id = 1,
size(x_vec_f,1)
405 vac%norm(1:n_theta-1,1) = &
406 &vac%norm(1:n_theta-1,1) + (id-1) * &
407 &(-x_vec_f(id,1)*sin((id-1)*&
408 &vac%ang(1:n_theta-1,1))&
409 &+x_vec_f(id,2)*cos((id-1)*&
410 &vac%ang(1:n_theta-1,1)))
413 ierr =
nufft(vac%ang(1:n_theta-1,1),&
414 &-vac%x_vec(1:n_theta-1,1),x_vec_f)
417 do id = 1,
size(x_vec_f,1)
418 vac%norm(1:n_theta-1,2) = &
419 &vac%norm(1:n_theta-1,2) + (id-1) * &
420 &(-x_vec_f(id,1)*sin((id-1)*&
421 &vac%ang(1:n_theta-1,1))&
422 &+x_vec_f(id,2)*cos((id-1)*&
423 &vac%ang(1:n_theta-1,1)))
425 vac%norm(n_theta,:) = vac%norm(1,:)
428 vac%norm(:,id) = - vac%x_vec(:,1)*vac%norm(:,id)
432 ierr =
nufft(vac%ang(1:n_theta-1,1),&
433 &vac%norm(1:n_theta-1,jd),x_vec_f)
435 do id = 1,
size(x_vec_f,1)
436 vac%dnorm(1:n_theta-1,jd) = &
437 &vac%dnorm(1:n_theta-1,jd) + (id-1) * &
438 &(-x_vec_f(id,1)*sin((id-1)*&
439 &vac%ang(1:n_theta-1,1))&
440 &+x_vec_f(id,2)*cos((id-1)*&
441 &vac%ang(1:n_theta-1,1)))
444 vac%dnorm(n_theta,:) = vac%dnorm(1,:)
467 call writo(
'Done storing vacuum quantities')
468 end function store_vac_hel
499 integer function calc_gh(vac,n_r_in,lims_r_in,x_vec_in,G_in,H_in) &
510 character(*),
parameter :: rout_name =
'calc_GH'
513 type(
vac_type),
intent(inout),
target :: vac
514 integer,
intent(in),
optional :: n_r_in
515 integer,
intent(in),
optional,
target :: lims_r_in(:,:)
516 real(dp),
intent(in),
optional,
target :: x_vec_in(:,:)
517 real(dp),
intent(in),
optional,
target :: g_in(:,:)
518 real(dp),
intent(in),
optional,
target :: h_in(:,:)
523 integer,
pointer :: lims_r(:,:)
524 real(dp),
pointer :: g(:,:)
525 real(dp),
pointer :: h(:,:)
526 real(dp),
pointer :: x_vec(:,:)
527 character(len=max_str_ln) :: err_msg
533 integer :: desc_res(blacsctxtsize)
534 real(dp),
allocatable :: loc_ser(:,:)
535 real(dp),
allocatable :: r_sph(:)
536 real(dp),
allocatable :: phi(:,:)
537 real(dp),
allocatable :: dphi(:,:)
538 real(dp),
allocatable :: res(:,:,:)
539 character(len=max_str_ln) :: plot_title(3)
540 character(len=max_str_ln) :: plot_name
547 call writo(
'Calculate the G and H matrices')
551 if (
present(n_r_in) .and. .not.
present(x_vec_in) .or. &
552 &
present(n_r_in) .and. .not.
present(lims_r_in) .or. &
553 &
present(n_r_in) .and. .not.
present(g_in) .or. &
554 &
present(n_r_in) .and. .not.
present(h_in))
then
556 chckerr(
'Need all optional variables')
560 if (
present(lims_r_in))
then
569 allocate(lims_r(2,
size(vac%lims_r,2)))
570 allocate(x_vec(vac%n_bnd,
size(vac%x_vec,2)))
579 select case (vac%style)
581 ierr =
calc_gh_1(vac,n_r,lims_r,x_vec,g,h,ext_in)
584 ierr =
calc_gh_2(vac,n_r,lims_r,x_vec,g,h,ext_in)
588 err_msg =
'No vacuum style '//trim(
i2str(vac%style))//&
594 if (.not.
present(lims_r_in))
then
606 call descinit(desc_res,vac%n_bnd,1,vac%bs,vac%bs,0,0,&
607 &vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
608 chckerr(
'descinit failed for res')
611 allocate(loc_ser(vac%n_bnd,vac%n_bnd))
612 ierr =
mat_dis2loc(vac%ctxt_HG,vac%H,vac%lims_r,vac%lims_c,loc_ser,&
616 call plot_hdf5(
'H',
'H',reshape(loc_ser,[vac%n_bnd,vac%n_bnd,1]))
618 &reshape(transpose(loc_ser),[vac%n_bnd,vac%n_bnd,1]),&
621 ierr =
mat_dis2loc(vac%ctxt_HG,vac%G,vac%lims_r,vac%lims_c,loc_ser,&
625 call plot_hdf5(
'G',
'G',reshape(loc_ser,[vac%n_bnd,vac%n_bnd,1]))
627 &reshape(transpose(loc_ser),[vac%n_bnd,vac%n_bnd,1]),&
633 if (vac%style.eq.2)
then
635 if (vac%lims_c(1,1).eq.1)
then
637 allocate(res(vac%n_loc(1),3,2))
638 allocate(r_sph(vac%n_loc(1)))
639 allocate(phi(vac%n_loc(1),2))
640 allocate(dphi(vac%n_loc(1),2))
643 subrows:
do i_rd = 1,
size(vac%lims_r,2)
644 row:
do rd = vac%lims_r(1,i_rd),vac%lims_r(2,i_rd)
646 rdl = sum(vac%lims_r(2,1:i_rd-1)-&
647 &vac%lims_r(1,1:i_rd-1)+1) + &
648 &rd-vac%lims_r(1,i_rd)+1
651 r_sph(rdl) = sqrt(sum(vac%x_vec(rd,:)**2))
654 phi(rdl,1) = vac%x_vec(rd,1)**vac%prim_X
655 dphi(rdl,1) = - vac%prim_X*vac%norm(rd,1)/&
656 &vac%x_vec(rd,1) * phi(rdl,1)
659 phi(rdl,2) = (vac%x_vec(rd,1)/&
660 &(r_sph(rdl)+abs(vac%x_vec(rd,2))))**vac%prim_X
661 dphi(rdl,2) = vac%prim_X*(vac%norm(rd,2)-&
662 &vac%norm(rd,1)*vac%x_vec(rd,2)/&
663 &vac%x_vec(rd,1)) / &
664 &r_sph(rdl)*sign(1._dp,vac%x_vec(rd,2)) * &
676 allocate(loc_ser(vac%n_bnd,3))
677 ierr = vec_dis2loc(vac%ctxt_HG,r_sph,vac%lims_r,loc_ser(:,1),&
681 plot_title(1) =
'spherical r'
683 call print_ex_2d(plot_title(1),plot_name,loc_ser(:,1),&
684 &x=vac%ang(:,1),draw=.false.)
685 call draw_ex([plot_title],plot_name,1,1,.false.)
687 do jd = 1,
size(phi,2)
688 ierr = vec_dis2loc(vac%ctxt_HG,phi(:,jd),vac%lims_r,&
693 plot_title(1) =
'test potential Ï•'
696 &loc_ser(:,1:
size(phi,2)),x=vac%ang(:,1:1),draw=.false.)
697 call draw_ex([plot_title(1)],plot_name,
size(phi,2),1,&
700 do jd = 1,
size(dphi,2)
701 ierr = vec_dis2loc(vac%ctxt_HG,dphi(:,jd),vac%lims_r,&
706 plot_title(1) =
'normal derivative of test potential dϕ/dn'
709 &loc_ser(:,1:
size(dphi,2)),x=vac%ang(:,1:1),&
711 call draw_ex([plot_title(1)],plot_name,
size(dphi,2),1,&
717 do jd = 1,
size(phi,2)
719 call pdgemv(
'N',vac%n_bnd,vac%n_bnd,1._dp,vac%H,1,1,&
720 &vac%desc_H,phi(:,jd),1,1,desc_res,1,0._dp,res(:,1,jd),&
724 call pdgemv(
'N',vac%n_bnd,vac%n_bnd,-1._dp,vac%G,1,1,&
725 &vac%desc_G,dphi(:,jd),1,1,desc_res,1,0._dp,&
726 &res(:,2,jd),1,1,desc_res,1)
729 res(:,3,jd) = sum(res(:,1:2,jd),2)
733 allocate(loc_ser(vac%n_bnd,3))
734 do id = 1,
size(phi,2)
736 ierr = vec_dis2loc(vac%ctxt_HG,res(:,jd,id),vac%lims_r,&
743 plot_title(1) =
'H R^n'
744 plot_title(2) =
'-G n Z_θ R^n'
745 plot_title(3) =
'(H - G n Z_θ) R^n'
746 plot_name =
'test_vac_1'
748 plot_title(1) =
'H (R/(r+|Z|))^n'
750 &
'- G |Z|/Z n dr/dθ (R/(r+|Z|))^n'
751 plot_title(3) =
'(H - G |Z|/Z n dr/dθ) &
753 plot_name =
'test_vac_2'
755 call print_ex_2d(plot_title,trim(plot_name)//
'_all',&
756 &loc_ser(:,:),x=vac%ang(:,1:1),&
758 call draw_ex(plot_title,trim(plot_name)//
'_all',3,1,&
761 &loc_ser(:,3),x=vac%ang(:,1),&
763 call draw_ex(plot_title(3:3),plot_name,1,1,.false.)
777 integer function calc_gh_1(vac,n_r_in,lims_r_in,x_vec_in,G_in,H_in,ext_in) &
787 character(*),
parameter :: rout_name =
'calc_GH_1'
790 type(
vac_type),
intent(inout) :: vac
791 integer,
intent(in) :: n_r_in
792 integer,
intent(in) :: lims_r_in(:,:)
793 real(dp),
intent(in) :: x_vec_in(:,:)
794 real(dp),
intent(in),
pointer :: g_in(:,:)
795 real(dp),
intent(in),
pointer :: h_in(:,:)
796 logical,
intent(in) :: ext_in
800 integer :: i_rd, i_cd
803 integer :: lims_c_loc(2)
804 integer :: desc_res(blacsctxtsize)
810 real(dp),
allocatable :: res(:,:)
811 real(dp),
allocatable :: loc_res(:)
816 call writo(
'Using field-line 3-D Boundary Element Method')
830 subrows:
do i_rd = 1,
size(lims_r_in,2)
832 row:
do rd = lims_r_in(1,i_rd),lims_r_in(2,i_rd)
834 rdl = sum(lims_r_in(2,1:i_rd-1)-lims_r_in(1,1:i_rd-1)+1) + &
835 &rd-lims_r_in(1,i_rd)+1
838 subcols:
do i_cd = 1,
size(vac%lims_c,2)
840 lims_c_loc(1) = max(1,vac%lims_c(1,i_cd)-1)
841 lims_c_loc(2) = min(vac%n_bnd,vac%lims_c(2,i_cd)+1)
845 col:
do cd = lims_c_loc(1),lims_c_loc(2)-1
847 cdl = sum(vac%lims_c(2,1:i_cd-1)-&
848 &vac%lims_c(1,1:i_cd-1)+1) + &
849 &cd-vac%lims_c(1,i_cd)+1
852 call calc_gh_int_1(g_loc,h_loc,&
853 &vac%x_vec(cd:cd+1,:),x_vec_in(rd,:),&
854 &vac%norm(cd:cd+1,:),vac%h_fac(rd,:),&
855 &[dpar_x,dalpha],tol_loc**2)
859 if (cd+kd.ge.vac%lims_c(1,i_cd) .and. &
860 &cd+kd.le.vac%lims_c(2,i_cd))
then
864 g_in(rdl,cdl+kd) = g_in(rdl,cdl+kd) + &
866 h_in(rdl,cdl+kd) = h_in(rdl,cdl+kd) + &
877 if (
in_context(vac%ctxt_HG) .and. .not.ext_in)
then
878 if (vac%lims_c(1,1).eq.1)
then
879 allocate(res(vac%n_loc(1),2))
883 call descinit(desc_res,vac%n_bnd,1,vac%bs,vac%bs,0,0,&
884 &vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
885 chckerr(
'descinit failed for res')
889 subrows2:
do i_rd = 1,
size(lims_r_in,2)
891 row2:
do rd = lims_r_in(1,i_rd),lims_r_in(2,i_rd)
893 rdl = sum(lims_r_in(2,1:i_rd-1)-&
894 &lims_r_in(1,1:i_rd-1)+1) + &
895 &rd-lims_r_in(1,i_rd)+1
898 subcols2:
do i_cd = 1,
size(vac%lims_c,2)
900 if (vac%lims_c(1,i_cd).le.cd .and. &
901 &cd.le.vac%lims_c(2,i_cd))
then
903 cdl = sum(vac%lims_c(2,1:i_cd-1)-&
904 &vac%lims_c(1,1:i_cd-1)+1) + &
905 &cd-vac%lims_c(1,i_cd)+1
908 h_in(rdl,cdl) = 0._dp
918 call pdgemv(
'N',vac%n_bnd,vac%n_bnd,1._dp,vac%H,1,1,&
919 &vac%desc_H,res(:,1),1,1,desc_res,1,0._dp,res(:,2),&
923 res(:,2) = res(:,2) + 4*pi
926 allocate(loc_res(vac%n_bnd))
927 ierr =
vec_dis2loc(vac%ctxt_HG,res(:,2),vac%lims_r,loc_res,&
933 subrows3:
do i_rd = 1,
size(lims_r_in,2)
935 row3:
do rd = lims_r_in(1,i_rd),lims_r_in(2,i_rd)
937 rdl = sum(lims_r_in(2,1:i_rd-1)-&
938 &lims_r_in(1,1:i_rd-1)+1) + &
939 &rd-lims_r_in(1,i_rd)+1
942 subcols3:
do i_cd = 1,
size(vac%lims_c,2)
944 if (vac%lims_c(1,i_cd).le.cd .and. &
945 &cd.le.vac%lims_c(2,i_cd))
then
947 cdl = sum(vac%lims_c(2,1:i_cd-1)-&
948 &vac%lims_c(1,1:i_cd-1)+1) + &
949 &cd-vac%lims_c(1,i_cd)+1
952 h_in(rdl,cdl) = - loc_res(rd)
966 integer,
intent(in) :: cd
967 integer,
intent(in) :: kd
968 integer,
intent(in) :: n_ang
971 if (mod(cd,n_ang).eq.1 .and. kd.eq.0) res = .false.
972 if (mod(cd,n_ang).eq.0 .and. kd.eq.1) res = .false.
981 integer function calc_gh_2(vac,n_r_in,lims_r_in,x_vec_in,G_in,H_in,ext_in) &
990 character(*),
parameter :: rout_name =
'calc_GH_2'
993 type(
vac_type),
intent(inout) :: vac
994 integer,
intent(in) :: n_r_in
995 integer,
intent(in) :: lims_r_in(:,:)
996 real(dp),
intent(in) :: x_vec_in(:,:)
997 real(dp),
intent(in),
pointer :: g_in(:,:)
998 real(dp),
intent(in),
pointer :: h_in(:,:)
999 logical,
intent(in) :: ext_in
1003 integer :: i_rd, i_cd
1007 integer :: lims_c_loc(2)
1008 real(dp) :: b_coeff(2)
1010 real(dp) :: del_r(2,2)
1011 real(dp) :: g_loc(2)
1012 real(dp) :: h_loc(2)
1013 real(dp) :: beta_comp
1015 real(dp),
parameter :: tol_q = 1.e-6_dp
1016 real(dp),
allocatable :: beta(:)
1017 real(dp),
allocatable :: loc_ser(:)
1018 real(dp),
allocatable :: rho2(:)
1019 real(dp),
allocatable :: arg(:)
1020 real(dp),
allocatable :: aij(:)
1021 real(dp),
allocatable :: ql(:,:,:)
1022 real(dp),
allocatable :: pl_loc(:), ql_loc(:)
1023 logical,
allocatable :: was_calc(:,:)
1024 logical,
allocatable :: sing_col(:)
1025 logical :: was_calc_sym
1026 character(len=max_str_ln) :: err_msg
1028 real(dp) :: rho2_lims(2)
1029 real(dp) :: gamma_lims(2)
1030 integer :: beta_lims(2)
1039 call writo(
'Using axisymmetric Boundary Element Method')
1043 do kd = 1,vac%prim_X
1044 b_coeff(2) = b_coeff(2) + 2._dp/(2*kd-1)
1046 b_coeff(1) = b_coeff(2) - 2._dp/(2*vac%prim_X-1)
1049 &exp(-2*b_coeff(2))])
1050 if (trim(err_msg).ne.
'')
then
1052 chckerr(trim(err_msg))
1054 tol_loc = 8*minval(vac%x_vec(:,1))*tol_loc
1055 ierr =
get_ser_var([tol_loc],loc_ser,scatter=.true.)
1057 tol_loc = maxval(loc_ser)
1059 call writo(
'Tolerance on rho for analytical integral: '//&
1060 &trim(
r2str(tol_loc)))
1063 allocate(was_calc(1:n_r_in,1:vac%n_bnd))
1065 allocate(ql(1:n_r_in,1:vac%n_bnd,2))
1066 allocate(pl_loc(0:max(vac%prim_X,1)))
1067 allocate(ql_loc(0:max(vac%prim_X,1)))
1069 rho2_lims = [huge(1._dp),-huge(1._dp)]
1070 gamma_lims = [huge(1._dp),-huge(1._dp)]
1074 subrows:
do i_rd = 1,
size(lims_r_in,2)
1076 allocate(beta(lims_r_in(1,i_rd):lims_r_in(2,i_rd)))
1078 beta_lims = [lims_r_in(2,i_rd)+1,lims_r_in(1,i_rd)-1]
1082 row:
do rd = lims_r_in(1,i_rd),lims_r_in(2,i_rd)
1084 rdl = sum(lims_r_in(2,1:i_rd-1)-lims_r_in(1,1:i_rd-1)+1) + &
1085 &rd-lims_r_in(1,i_rd)+1
1088 subcols:
do i_cd = 1,
size(vac%lims_c,2)
1090 lims_c_loc(1) = max(1,vac%lims_c(1,i_cd)-1)
1091 lims_c_loc(2) = min(vac%n_bnd,vac%lims_c(2,i_cd)+1)
1094 allocate(rho2(lims_c_loc(1):lims_c_loc(2)))
1095 allocate(arg(lims_c_loc(1):lims_c_loc(2)))
1096 allocate(aij(lims_c_loc(1):lims_c_loc(2)))
1100 if (
allocated(sing_col))
deallocate(sing_col)
1102 &vac%lims_c(1,i_cd):vac%lims_c(2,i_cd)))
1108 col:
do cd = lims_c_loc(1),lims_c_loc(2)
1110 rho2(cd) = sum((vac%x_vec(cd,:)-x_vec_in(rd,:))**2)
1112 &rho2(cd)/(2*vac%x_vec(cd,1)*x_vec_in(rd,1))
1113 was_calc_sym = .false.
1114 if (.not.ext_in) was_calc_sym = was_calc(cd,rd)
1115 if (rho2(cd).le.tol_loc**2)
then
1117 else if (was_calc_sym)
then
1118 ql(rd,cd,:) = ql(cd,rd,:)
1122 if (rho2(cd).lt.rho2_lims(1)) &
1123 &rho2_lims(1) = rho2(cd)
1124 if (rho2(cd).gt.rho2_lims(2)) &
1125 &rho2_lims(2) = rho2(cd)
1126 if (arg(cd).lt.gamma_lims(1)) &
1127 &gamma_lims(1) = arg(cd)
1128 if (arg(cd).gt.gamma_lims(2)) &
1129 &gamma_lims(2) = arg(cd)
1131 err_msg =
'The solutions did not converge for &
1132 &rho^2 = '//trim(
r2str(rho2(cd)))//&
1133 &
' and n = '//trim(
i2str(vac%prim_X))
1134 if (vac%prim_X.gt.0)
then
1135 ierr =
dtorh1(arg(cd),0,vac%prim_X,pl_loc,&
1138 if (max_n.lt.vac%prim_X)
then
1142 ql(rd,cd,:) = ql_loc(vac%prim_X-1:vac%prim_X)
1143 else if (vac%prim_X.eq.0)
then
1144 ierr =
dtorh1(arg(cd),0,1,pl_loc,ql_loc,max_n)
1146 if (max_n.lt.vac%prim_X)
then
1150 ql(rd,cd,1) = ql_loc(1)
1151 ql(rd,cd,2) = ql_loc(0)
1154 err_msg =
'negative n not yet implemented'
1157 if (.not.ext_in) was_calc(rd,cd) = .true.
1161 if (rho2(cd).le.tol_loc**2)
then
1163 if (cd.ge.vac%lims_c(1,i_cd) .and. &
1164 &cd.le.vac%lims_c(2,i_cd)) &
1165 &sing_col(cd) = .true.
1168 aij(cd) = 0.5_dp*(vac%prim_X - 0.5_dp) * &
1169 &(x_vec_in(rd,1) * &
1170 &(vac%norm(rd,1)*vac%dnorm(rd,2)-&
1171 &vac%norm(rd,2)*vac%dnorm(rd,1))/&
1172 &sum(vac%norm(rd,:)**2) &
1173 &+vac%norm(rd,1)/x_vec_in(rd,1))
1176 aij(cd) = 2._dp*x_vec_in(rd,1)*vac%x_vec(cd,1) / &
1177 &(4._dp*x_vec_in(rd,1)*vac%x_vec(cd,1)+&
1178 &rho2(cd)) *(vac%prim_X - 0.5_dp) * &
1179 &(- 2._dp/rho2(cd) * sum(vac%norm(cd,:)*&
1180 &(vac%x_vec(cd,:)-x_vec_in(rd,:))) + &
1181 &vac%norm(cd,1)/vac%x_vec(cd,1))
1215 col2:
do cd = lims_c_loc(1),lims_c_loc(2)-1
1217 cdl = sum(vac%lims_c(2,1:i_cd-1)-&
1218 &vac%lims_c(1,1:i_cd-1)+1) + &
1219 &cd-vac%lims_c(1,i_cd)+1
1223 if (any(sing_col))
then
1225 if (cd+kd.ge.vac%lims_c(1,i_cd) .and. &
1226 &cd+kd.le.vac%lims_c(2,i_cd))
then
1227 g_in(rdl,cdl+kd) = 0._dp
1228 h_in(rdl,cdl+kd) = 4*pi
1244 &vac%ang(cd:cd+1,1),ang,&
1245 &vac%x_vec(cd:cd+1,:),x_vec_in(rd,:),&
1246 &vac%norm(cd:cd+1,:),vac%norm(rd,:),&
1247 &aij(cd:cd+1),ql(rd,cd:cd+1,:),&
1248 &tol_loc**2,b_coeff,vac%prim_X)
1251 if (cd+kd.ge.vac%lims_c(1,i_cd) .and. &
1252 &cd+kd.le.vac%lims_c(2,i_cd))
then
1253 g_in(rdl,cdl+kd) = g_in(rdl,cdl+kd) + &
1255 h_in(rdl,cdl+kd) = h_in(rdl,cdl+kd) + &
1287 if (.not.ext_in .and. vac%lims_c(1,i_cd).le.rd .and. &
1288 &rd.le.vac%lims_c(2,i_cd))
then
1290 cdl = sum(vac%lims_c(2,1:i_cd-1)-&
1291 &vac%lims_c(1,1:i_cd-1)+1) + &
1292 &rd-vac%lims_c(1,i_cd)+1
1294 if (rd.eq.1 .or. rd.eq.vac%n_bnd)
then
1296 del_r(1,:) = vac%x_vec(vac%n_bnd,:)-&
1297 &vac%x_vec(vac%n_bnd-1,:)
1298 del_r(2,:) = vac%x_vec(2,:)-vac%x_vec(1,:)
1300 del_r(1,:) = vac%x_vec(rd,:)-vac%x_vec(rd-1,:)
1301 del_r(2,:) = vac%x_vec(rd+1,:)-vac%x_vec(rd,:)
1304 del_r(kd,:) = del_r(kd,:)/sqrt(sum(del_r(kd,:)**2))
1306 beta_comp = acos(sum(product(del_r,1)))
1307 if (del_r(1,1)*del_r(2,2) .lt. &
1308 &del_r(1,2)*del_r(2,1)) beta_comp = - beta_comp
1309 beta(rd) = beta_comp + pi
1312 if (rd.lt.beta_lims(1)) beta_lims(1) = rd
1313 if (rd.gt.beta_lims(2)) beta_lims(2) = rd
1317 h_in(rdl,cdl) = h_in(rdl,cdl) - 2*beta(rd)
1321 deallocate(arg,rho2,aij)
1349 if (
rank.eq.0) rho2_lims(1) = minval(loc_ser)
1353 if (
rank.eq.0) rho2_lims(2) = maxval(loc_ser)
1357 if (
rank.eq.0) gamma_lims(1) = minval(loc_ser)
1361 if (
rank.eq.0) gamma_lims(2) = maxval(loc_ser)
1364 call writo(
'limits in rho: '//trim(
r2str(sqrt(rho2_lims(1))))//&
1365 &
'..'//trim(
r2str(sqrt(rho2_lims(2)))))
1366 call writo(
'limits in gamma: '//trim(
r2str(gamma_lims(1)))//&
1367 &
'..'//trim(
r2str(gamma_lims(2))))
1378 function fun_tol(val)
1380 real(dp),
intent(in) :: val
1383 fun_tol = -0.5_dp*log(val)-b_coeff(2)-val/tol_q
1384 end function fun_tol
1430 character(*),
parameter :: rout_name =
'calc_vac_res'
1434 type(
vac_type),
intent(inout) :: vac
1440 integer :: i_rd, i_cd
1441 integer :: rich_lvl_name
1442 integer :: sec_x_loc
1444 integer :: lims_cl(2)
1447 integer,
allocatable :: lims_r_loc(:,:)
1448 integer,
allocatable :: lims_c_loc(:,:)
1449 integer,
target :: desc_phiep(blacsctxtsize)
1450 integer,
target :: desc_gep(blacsctxtsize)
1451 integer,
target :: desc_res2(blacsctxtsize)
1457 real(dp) :: alpha_loc
1458 real(dp),
allocatable,
target :: ep(:,:)
1459 real(dp),
allocatable,
target :: gep(:,:)
1460 real(dp),
allocatable,
target :: phi(:,:)
1461 real(dp),
allocatable,
target :: res2(:,:)
1462 real(dp),
allocatable,
target :: res2_loc(:,:)
1466 real(dp),
allocatable :: res2_ev(:,:)
1467 real(dp),
allocatable :: tau(:)
1468 real(dp),
allocatable :: work(:)
1469 real(dp),
allocatable :: x_plot(:,:)
1470 real(dp),
allocatable :: y_plot(:,:)
1471 complex(dp),
allocatable :: res_loc(:,:)
1472 complex(dp),
allocatable :: res_ev(:)
1473 complex(dp),
allocatable :: work_c(:)
1474 complex(dp),
allocatable :: tau_c(:)
1495 call writo(
'Start calculation of vacuum quantities')
1513 call writo(
'Use STRUMPack to solve system',persistent=rank_o)
1517 if (vac%style.eq.1)
then
1529 vac%sec_X = mds%m(
size(mds%m,1),:)
1531 vac%sec_X = mds%n(
size(mds%n,1),:)
1536 n_loc(jd) = numroc(2*
n_mod_x,vac%bs,vac%ind_p(jd),0,vac%n_p(jd))
1538 call set_loc_lims(n_loc(1),vac%bs,vac%ind_p(1),vac%n_p(1),&
1540 call set_loc_lims(n_loc(2),vac%bs,vac%ind_p(2),vac%n_p(2),&
1544 call descinit(desc_phiep,vac%n_bnd,2*
n_mod_x,vac%bs,vac%bs,0,0,&
1545 &vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
1546 chckerr(
'descinit failed for EP')
1547 call descinit(desc_gep,vac%n_bnd,2*
n_mod_x,vac%bs,vac%bs,0,0,&
1548 &vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
1549 chckerr(
'descinit failed for GEP')
1551 &vac%ctxt_HG,max(1,n_loc(1)),ierr)
1552 chckerr(
'descinit failed for res2')
1555 allocate(ep(vac%n_loc(1),n_loc(2)))
1556 allocate(gep(vac%n_loc(1),n_loc(2)))
1557 allocate(phi(vac%n_loc(1),n_loc(2)))
1558 allocate(res2(n_loc(1),n_loc(2)))
1563 subcols:
do i_cd = 1,
size(lims_c_loc,2)
1564 col:
do cd = lims_c_loc(1,i_cd),lims_c_loc(2,i_cd)
1566 cdl = sum(lims_c_loc(2,1:i_cd-1)-&
1567 &lims_c_loc(1,1:i_cd-1)+1) + &
1568 &cd-lims_c_loc(1,i_cd)+1
1571 sec_x_loc = vac%sec_X(mod(cd-1,
n_mod_x)+1)
1574 subrows:
do i_rd = 1,
size(vac%lims_r,2)
1575 row:
do rd = vac%lims_r(1,i_rd),vac%lims_r(2,i_rd)
1577 rdl = sum(vac%lims_r(2,1:i_rd-1)-&
1578 &vac%lims_r(1,1:i_rd-1)+1) + &
1579 &rd-vac%lims_r(1,i_rd)+1
1582 par_id = mod(rd-1,vac%n_ang(1))+1
1583 alpha_id = (rd-1)/vac%n_ang(1) + 1
1586 select case (vac%style)
1591 &(alpha_id-1)*dalpha
1593 arg_loc = vac%prim_X*alpha_loc + &
1594 &(vac%prim_X*vac%jq-sec_x_loc)*&
1597 arg_loc = vac%prim_X*alpha_loc + &
1598 &(sec_x_loc-vac%prim_X*vac%jq)*&
1602 arg_loc = -sec_x_loc*&
1603 &vac%ang(par_id,alpha_id)
1610 ep(rdl,cdl) = cos(arg_loc)
1612 ep(rdl,cdl) = sin(arg_loc)
1615 ep(rdl,cdl) = (vac%prim_X*vac%jq-sec_x_loc)*&
1618 ep(rdl,cdl) = (sec_x_loc-vac%prim_X*vac%jq)*&
1625 call plot_hdf5(
'EP',
'EP',reshape(ep,[vac%n_bnd,n_loc(2),1]))
1629 &[vac%n_loc(1),n_loc(2)],lims_c_loc,desc_phiep)
1633 call pdgemm(
'N',
'N',vac%n_bnd,2*
n_mod_x,vac%n_bnd,1._dp,vac%G,1,1,&
1634 &vac%desc_G,ep,1,1,desc_phiep,0._dp,gep,1,1,desc_gep)
1639 call writo(
'Combine results into vacuum response',persistent=rank_o)
1649 subrows3:
do i_rd = 1,
size(vac%lims_r,2)
1650 row3:
do rd = vac%lims_r(1,i_rd),vac%lims_r(2,i_rd)
1652 rdl = sum(vac%lims_r(2,1:i_rd-1)-&
1653 &vac%lims_r(1,1:i_rd-1)+1) + &
1654 &rd-vac%lims_r(1,i_rd)+1
1656 subcols3:
do i_cd = 1,
size(lims_c_loc,2)
1658 lims_cl = sum(lims_c_loc(2,1:i_cd-1)-&
1659 &lims_c_loc(1,1:i_cd-1)+1) + &
1660 &lims_c_loc(:,i_cd)-lims_c_loc(1,i_cd)+1
1662 select case (vac%style)
1664 i_loc = dpar_x*dalpha
1665 if ((rd-1)/vac%n_ang(1).eq.0 .or. &
1666 &(rd-1)/vac%n_ang(1).eq.vac%n_ang(1)-1) &
1667 &i_loc = i_loc*0.5_dp
1670 &(vac%ang(min(rd+1,vac%n_bnd),1)-&
1671 &vac%ang(max(rd-1,1),1))
1674 ep(rdl,lims_cl(1):lims_cl(2)) = &
1675 &ep(rdl,lims_cl(1):lims_cl(2)) * i_loc
1685 &desc_phiep,phi,1,1,desc_phiep,0._dp,res2,1,1,desc_res2)
1688 ierr =
mat_dis2loc(vac%ctxt_HG,res2,lims_r_loc,lims_c_loc,res2_loc,&
1695 call writo(
'Calculate the eigenvalues of res_loc to &
1696 &investigate whether it is positive definite',&
1706 vac%res = vac%res + iu * &
1714 x_plot(jd,:) = vac%sec_X(jd)
1715 y_plot(:, jd) = vac%sec_X(jd)
1717 call print_ex_2d([
'real vacuum response'],
'vac_res_Re',&
1718 &rp(vac%res),x=x_plot,draw=.false.)
1721 call print_ex_2d([
'imag vacuum response'],
'vac_res_Im',&
1722 &ip(vac%res),x=x_plot,draw=.false.)
1725 call plot_hdf5([
'real part',
'imag part',
'imag diff'],
'vac_res',&
1726 &reshape([rp(vac%res),ip(vac%res),&
1730 deallocate(x_plot,y_plot)
1742 chckerr(
'zgehrd failed')
1743 lwork = nint(rp(work_c(1)))
1745 allocate(work_c(lwork))
1750 chckerr(
'zgehrd failed')
1757 &res_ev,0._dp,
n_mod_x,work_c,-1,ierr)
1758 chckerr(
'zhseqr failed')
1759 lwork = nint(rp(work_c(1)))
1761 allocate(work_c(lwork))
1765 &res_ev,0._dp,
n_mod_x,work_c,lwork,ierr)
1766 chckerr(
'zhseqr failed')
1767 call print_ex_2d([
'real part',
'imag part'],
'res_ev',&
1768 &reshape([rp(res_ev),ip(res_ev)],[
n_mod_x,2]),&
1770 call draw_ex([
'real part',
'imag part'],
'res_ev',2,1,&
1786 chckerr(
'pdgehrd failed')
1787 lwork = nint(work(1))
1789 allocate(work(lwork))
1794 chckerr(
'pdgehrd failed')
1800 if (lwork*vac%bs.lt.2*
n_mod_x) lwork = lwork + 1
1801 lwork = 7*lwork /
lcm(vac%n_p(1),vac%n_p(2))
1803 allocate(work(lwork))
1804 allocate(res2_ev(2*
n_mod_x,2))
1806 &desc_res2,res2_ev(:,1),res2_ev(:,2),1,2*
n_mod_x,[0._dp],&
1807 &desc_res2,work,lwork,[0],1,ierr)
1808 chckerr(
'pdlahqr failed')
1809 call print_ex_2d([
'real part',
'imag part'],
'res2_ev',&
1810 &res2_ev,draw=.false.)
1811 call draw_ex([
'real part',
'imag part'],
'res2_ev',2,1,.false.)
1817 call writo(
'They should all be positive',persistent=rank_o)
1826 call writo(
'Done calculating vacuum quantities')
1856 integer function vac_pot_plot(grid_sol,vac,sol,X_id)
result(ierr)
1870 type(
vac_type),
intent(inout) :: vac
1872 integer,
intent(in) :: x_id
1875 integer :: id, jd, kd
1877 integer :: i_rd, i_cd
1879 integer :: desc_rhs(blacsctxtsize)
1880 integer :: desc_gh_loc(blacsctxtsize)
1881 integer :: desc_phi(blacsctxtsize)
1882 integer :: n_row_plot
1884 integer :: lims_cl(2)
1885 integer,
allocatable :: lims_r_loc(:,:)
1886 integer,
allocatable :: lims_c_loc(:,:)
1887 integer :: sec_x_loc
1889 real(dp) :: zeta_loc
1890 real(dp),
allocatable :: x_vec(:,:)
1891 real(dp),
allocatable :: g_loc(:,:)
1892 real(dp),
allocatable :: h_loc(:,:)
1893 real(dp),
allocatable :: rhs(:,:,:)
1894 real(dp),
allocatable :: phi(:,:)
1895 real(dp),
allocatable :: phi_ser(:,:)
1896 real(dp),
allocatable :: phi_2d(:,:)
1897 complex(dp),
allocatable :: sol_vec(:)
1898 complex(dp) :: rhs_complex
1899 character(len=max_str_ln) :: err_msg
1901 real(dp),
allocatable :: rhs_loc(:,:)
1906 character(*),
parameter :: rout_name =
'vac_pot_plot'
1913 if (
rank.eq.
n_procs-1) sol_vec = sol%vec(:,grid_sol%loc_n_r,x_id)
1922 if (in_context(vac%ctxt_HG))
then
1924 n_row_plot = numroc(product(
n_vac_plot),vac%bs,vac%ind_p(1),0,&
1926 n_col_2 = numroc(2,vac%bs,vac%ind_p(2),0,vac%n_p(2))
1927 call set_loc_lims(n_row_plot,vac%bs,vac%ind_p(1),vac%n_p(1),&
1929 call set_loc_lims(n_col_2,vac%bs,vac%ind_p(2),vac%n_p(2),&
1933 allocate(rhs(vac%n_loc(1),n_col_2,2))
1935 call descinit(desc_rhs,vac%n_bnd,2,vac%bs,vac%bs,0,0,&
1936 &vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
1937 chckerr(
'descinit failed for RHS')
1941 subcols:
do i_cd = 1,
size(lims_c_loc,2)
1942 col:
do cd = lims_c_loc(1,i_cd),lims_c_loc(2,i_cd)
1944 cdl = sum(lims_c_loc(2,1:i_cd-1)-&
1945 &lims_c_loc(1,1:i_cd-1)+1) + &
1946 &cd-lims_c_loc(1,i_cd)+1
1949 subrows:
do i_rd = 1,
size(vac%lims_r,2)
1950 row:
do rd = vac%lims_r(1,i_rd),vac%lims_r(2,i_rd)
1952 rdl = sum(vac%lims_r(2,1:i_rd-1)-&
1953 &vac%lims_r(1,1:i_rd-1)+1) + &
1954 &rd-vac%lims_r(1,i_rd)+1
1958 sec_x_loc = vac%sec_X(jd)
1960 fac_x = [
prim_x,-sec_x_loc]
1963 err_msg =
'Currently must use poloidal flux'
1968 rhs_complex = iu*(fac_x(1)*vac%jq+fac_x(2))*&
1969 &exp(iu*fac_x(2)*vac%ang(rd,1))*sol_vec(jd)
1970 if (cd.eq.1) rhs(rdl,cdl,:) = &
1971 &rhs(rdl,cdl,:) + rp(rhs_complex)
1972 if (cd.eq.2) rhs(rdl,cdl,:) = &
1973 &rhs(rdl,cdl,:) + ip(rhs_complex)
1981 ierr =
solve_phi_bem(vac,rhs(:,:,1),rhs(:,:,2),[vac%n_bnd,2],&
1982 &[vac%n_loc(1),n_col_2],lims_c_loc,desc_rhs)
1987 allocate(rhs_loc(vac%n_bnd,2))
1989 ierr =
mat_dis2loc(vac%ctxt_HG,rhs(:,:,jd),vac%lims_r,&
1990 &lims_c_loc,rhs_loc,proc=
n_procs-1)
1994 &rhs_loc,x=vac%ang(:,1:1),draw=.false.)
1995 call draw_ex([
'dphi',
'phi '],
'RHS_'//trim(
i2str(jd)),2,1,&
2007 subrows2:
do i_rd = 1,
size(vac%lims_r,2)
2008 row2:
do rd = vac%lims_r(1,i_rd),vac%lims_r(2,i_rd)
2010 rdl = sum(vac%lims_r(2,1:i_rd-1)-&
2011 &vac%lims_r(1,1:i_rd-1)+1) + &
2012 &rd-vac%lims_r(1,i_rd)+1
2014 subcols2:
do i_cd = 1,
size(lims_c_loc,2)
2016 lims_cl = sum(lims_c_loc(2,1:i_cd-1)-&
2017 &lims_c_loc(1,1:i_cd-1)+1) + &
2018 &lims_c_loc(:,i_cd)-lims_c_loc(1,i_cd)+1
2020 rhs(rdl,lims_cl(1):lims_cl(2),:) = &
2021 &rhs(rdl,lims_cl(1):lims_cl(2),:) * 0.5_dp*&
2022 &(vac%ang(min(rd+1,vac%n_bnd),1)-&
2023 &vac%ang(max(rd-1,1),1))
2029 allocate(g_loc(n_row_plot,vac%n_loc(2)))
2030 allocate(h_loc(n_row_plot,vac%n_loc(2)))
2034 call descinit(desc_gh_loc,product(
n_vac_plot),vac%n_bnd,vac%bs,&
2035 &vac%bs,0,0,vac%ctxt_HG,max(1,n_row_plot),ierr)
2036 chckerr(
'descinit failed for GH_loc')
2063 &lims_r_in=lims_r_loc,x_vec_in=x_vec,g_in=g_loc,h_in=h_loc)
2106 allocate(phi(n_row_plot,n_col_2))
2107 call descinit(desc_phi,product(
n_vac_plot),2,vac%bs,&
2108 &vac%bs,0,0,vac%ctxt_HG,max(1,n_row_plot),ierr)
2109 chckerr(
'descinit failed for Phi')
2110 call pdgemm(
'N',
'N',product(
n_vac_plot),2,vac%n_bnd,1._dp,&
2111 &g_loc,1,1,desc_gh_loc,rhs(:,:,1),1,1,desc_rhs,0._dp,&
2115 call pdgemm(
'N',
'N',product(
n_vac_plot),2,vac%n_bnd,-1._dp,&
2116 &h_loc,1,1,desc_gh_loc,rhs(:,:,2),1,1,desc_rhs,1._dp,&
2122 &lims_c_loc,phi_ser,proc=
n_procs-1)
2127 &phi_ser,draw=.false.)
2128 call draw_ex([
'dphi',
'phi '],
'Phi'//trim(
i2str(kd)),2,1,&
2137 phi_2d = -1./(4*pi)*reshape(&
2138 &phi_ser(:,1)*cos(vac%prim_X*zeta_loc) + &
2139 &phi_ser(:,2)*sin(vac%prim_X*zeta_loc),
n_vac_plot)
2141 &x=cos(vac%prim_X*zeta_loc)*&
2143 &y=sin(vac%prim_X*zeta_loc)*&
2161 integer function solve_phi_bem(vac,R,Phi,n_RPhi,n_loc_RPhi,lims_c_RPhi,&
2162 &desc_RPhi)
result(ierr)
2170 character(*),
parameter :: rout_name =
'solve_Phi_BEM'
2173 type(
vac_type),
intent(in),
target :: vac
2174 real(
dp),
intent(inout),
target :: phi(:,:)
2175 real(
dp),
intent(in) :: r(:,:)
2176 integer,
intent(in) :: n_rphi(2)
2177 integer,
intent(in) :: n_loc_rphi(2)
2178 integer,
intent(in) :: lims_c_rphi(:,:)
2179 integer,
intent(in),
target :: desc_rphi(blacsctxtsize)
2182 integer,
target :: desc_gr(blacsctxtsize)
2184 real(
dp),
allocatable,
target :: gr(:,:)
2185 type(c_ptr) :: cdesch, ch
2186 type(c_ptr) :: cdescgr, cgr
2187 type(c_ptr) :: cdescphi, cphi
2188 type(strumpackdensepackage_f90_double) :: sdp_loc
2190 integer :: lims_rl(2)
2194 integer :: i_rd, i_cd
2195 character(len=max_str_ln) :: plot_title
2196 character(len=max_str_ln) :: plot_name
2197 real(
dp),
allocatable :: ang(:)
2206 allocate(gr(vac%n_loc(1),n_loc_rphi(2)))
2209 call descinit(desc_gr,vac%n_bnd,n_rphi(2),vac%bs,vac%bs,0,0,&
2210 &vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
2211 chckerr(
'descinit failed for GR')
2214 call pdgemm(
'N',
'N',vac%n_bnd,n_rphi(2),vac%n_bnd,1._dp,vac%G,1,1,&
2215 &vac%desc_G,r,1,1,desc_rphi,0._dp,gr,1,1,desc_gr)
2219 cdesch = c_loc(vac%desc_H)
2221 cdescgr = c_loc(desc_gr)
2223 cdescphi = c_loc(desc_rphi)
2226 call sdp_f90_double_init(sdp_loc,vac%MPI_Comm)
2228 sdp_loc%levels_HSS=4
2229 sdp_loc%min_rand_HSS=10
2230 sdp_loc%lim_rand_HSS=5
2231 sdp_loc%inc_rand_HSS=10
2232 sdp_loc%max_rand_HSS=100
2233 sdp_loc%tol_HSS=1d-12
2235 sdp_loc%tol_IR=1d-10
2238 call sdp_f90_double_compress_a(sdp_loc,ch,cdesch)
2242 sdp_err = sdp_f90_double_check_compression(sdp_loc,ch,cdesch)
2246 call sdp_f90_double_factor(sdp_loc,ch,cdesch)
2249 call sdp_f90_double_solve(sdp_loc,cphi,cdescphi,cgr,cdescgr)
2253 sdp_err = sdp_f90_double_check_solution(sdp_loc,ch,cdesch,cphi,&
2254 &cdescphi,cgr,cdescgr)
2258 sdp_err = sdp_f90_double_refine(sdp_loc,ch,cdesch,cphi,cdescphi,&
2263 call sdp_f90_double_print_statistics(sdp_loc)
2266 subcols:
do i_cd = 1,
size(lims_c_rphi,2)
2267 col:
do cd = lims_c_rphi(1,i_cd),lims_c_rphi(2,i_cd)
2269 cdl = sum(lims_c_rphi(2,1:i_cd-1)-&
2270 &lims_c_rphi(1,1:i_cd-1)+1) + &
2271 &cd-lims_c_rphi(1,i_cd)+1
2273 subrows2:
do i_rd = 1,
size(vac%lims_r,2)
2275 lims_rl = sum(vac%lims_r(2,1:i_rd-1)-&
2276 &vac%lims_r(1,1:i_rd-1)+1) + &
2277 &vac%lims_r(:,i_rd)-vac%lims_r(1,i_rd)+1
2280 allocate(ang(vac%lims_r(2,i_rd)-vac%lims_r(1,i_rd)+1))
2281 select case (vac%style)
2283 do id = 1,vac%n_ang(1)
2285 &id+vac%n_ang(1)*(vac%n_ang(2)-1):&
2291 ang = reshape(vac%ang,[vac%n_bnd])
2295 plot_title =
'for column '//trim(
i2str(cd))//&
2296 &
' and starting row '//&
2297 &trim(
i2str(vac%lims_r(1,i_rd)))
2298 plot_name =
'_'//trim(
i2str(cd))//
'_'//&
2299 &trim(
i2str(vac%lims_r(1,i_rd)))
2301 &
'Phi'//trim(plot_name),&
2302 &phi(lims_rl(1):lims_rl(2),cdl),&
2303 &x=ang(vac%lims_r(1,i_rd):vac%lims_r(2,i_rd)),&
2305 call draw_ex([
'Phi '//trim(plot_title)],&
2306 &
'Phi'//trim(plot_name),1,1,.false.)
2316 call sdp_f90_double_destroy(sdp_loc)
2353 character(*),
parameter :: rout_name =
'print_output_vac'
2357 character(len=*),
intent(in) :: data_name
2358 integer,
intent(in),
optional :: rich_lvl
2361 type(
var_1d_type),
allocatable,
target :: vac_1d(:)
2362 type(
var_1d_type),
pointer :: vac_1d_loc => null()
2369 call writo(
'Write vacuum variables to output file')
2379 vac_1d_loc => vac_1d(id); id = id+1
2380 vac_1d_loc%var_name =
'misc_vac'
2381 allocate(vac_1d_loc%tot_i_min(1),vac_1d_loc%tot_i_max(1))
2382 allocate(vac_1d_loc%loc_i_min(1),vac_1d_loc%loc_i_max(1))
2383 vac_1d_loc%loc_i_min = [1]
2384 vac_1d_loc%loc_i_max = [6]
2385 vac_1d_loc%tot_i_min = vac_1d_loc%loc_i_min
2386 vac_1d_loc%tot_i_max = vac_1d_loc%loc_i_max
2387 allocate(vac_1d_loc%p(6))
2388 vac_1d_loc%p = [vac%style*1._dp,vac%n_bnd*1._dp,vac%prim_X*1._dp,&
2389 &vac%n_ang*1._dp,vac%jq]
2392 vac_1d_loc => vac_1d(id); id = id+1
2393 vac_1d_loc%var_name =
'sec_X'
2394 allocate(vac_1d_loc%tot_i_min(1),vac_1d_loc%tot_i_max(1))
2395 allocate(vac_1d_loc%loc_i_min(1),vac_1d_loc%loc_i_max(1))
2396 vac_1d_loc%tot_i_min = [1]
2397 vac_1d_loc%tot_i_max =
n_mod_x
2398 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2399 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2400 allocate(vac_1d_loc%p(
n_mod_x))
2401 vac_1d_loc%p = vac%sec_X*1._dp
2404 vac_1d_loc => vac_1d(id); id = id+1
2405 vac_1d_loc%var_name =
'norm'
2406 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2407 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2408 vac_1d_loc%tot_i_min = [1,1]
2409 vac_1d_loc%tot_i_max = shape(vac%norm)
2410 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2411 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2412 allocate(vac_1d_loc%p(
size(vac%norm)))
2413 vac_1d_loc%p = reshape(vac%norm,[
size(vac%norm)])
2416 vac_1d_loc => vac_1d(id); id = id+1
2417 vac_1d_loc%var_name =
'x_vec'
2418 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2419 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2420 vac_1d_loc%tot_i_min = [1,1]
2421 vac_1d_loc%tot_i_max = shape(vac%x_vec)
2422 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2423 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2424 allocate(vac_1d_loc%p(
size(vac%x_vec)))
2425 vac_1d_loc%p = reshape(vac%x_vec,[
size(vac%x_vec)])
2428 vac_1d_loc => vac_1d(id); id = id+1
2429 vac_1d_loc%var_name =
'RE_res'
2430 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2431 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2432 vac_1d_loc%tot_i_min = [1,1]
2434 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2435 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2436 allocate(vac_1d_loc%p(
size(vac%res)))
2437 vac_1d_loc%p = reshape(rp(vac%res),[
size(vac%res)])
2440 vac_1d_loc => vac_1d(id); id = id+1
2441 vac_1d_loc%var_name =
'IM_res'
2442 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2443 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2444 vac_1d_loc%tot_i_min = [1,1]
2446 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2447 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2448 allocate(vac_1d_loc%p(
size(vac%res)))
2449 vac_1d_loc%p = reshape(ip(vac%res),[
size(vac%res)])
2452 select case (vac%style)
2455 vac_1d_loc => vac_1d(id); id = id+1
2456 vac_1d_loc%var_name =
'h_fac'
2457 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2458 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2459 vac_1d_loc%tot_i_min = [1,1]
2460 vac_1d_loc%tot_i_max = shape(vac%h_fac)
2461 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2462 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2463 allocate(vac_1d_loc%p(
size(vac%h_fac)))
2464 vac_1d_loc%p = reshape(vac%h_fac,[
size(vac%h_fac)])
2467 vac_1d_loc => vac_1d(id); id = id+1
2468 vac_1d_loc%var_name =
'ang'
2469 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2470 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2471 vac_1d_loc%tot_i_min = [1,1]
2472 vac_1d_loc%tot_i_max = shape(vac%ang)
2473 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2474 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2475 allocate(vac_1d_loc%p(
size(vac%ang)))
2476 vac_1d_loc%p = reshape(vac%ang,[
size(vac%ang)])
2479 vac_1d_loc => vac_1d(id); id = id+1
2480 vac_1d_loc%var_name =
'dnorm'
2481 allocate(vac_1d_loc%tot_i_min(2),vac_1d_loc%tot_i_max(2))
2482 allocate(vac_1d_loc%loc_i_min(2),vac_1d_loc%loc_i_max(2))
2483 vac_1d_loc%tot_i_min = [1,1]
2484 vac_1d_loc%tot_i_max = shape(vac%dnorm)
2485 vac_1d_loc%loc_i_min = vac_1d_loc%tot_i_min
2486 vac_1d_loc%loc_i_max = vac_1d_loc%tot_i_max
2487 allocate(vac_1d_loc%p(
size(vac%dnorm)))
2488 vac_1d_loc%p = reshape(vac%dnorm,[
size(vac%dnorm)])
2493 &rich_lvl=rich_lvl,ind_print=.true.)