7 #include <PB3D_macros.h>
9 use strumpackdensepackage
32 subroutine calc_gh_int_1(G,H,x_s,x_in,norm_s,h_fac_in,step_size,tol)
34 real(
dp),
intent(inout) :: g(2)
35 real(
dp),
intent(inout) :: h(2)
36 real(
dp),
intent(in) :: x_s(2,3)
37 real(
dp),
intent(in) :: x_in(3)
38 real(
dp),
intent(in) :: norm_s(2,3)
39 real(
dp),
intent(in) :: h_fac_in(4)
40 real(
dp),
intent(in) :: step_size(2)
41 real(
dp),
intent(in) :: tol
48 real(
dp) :: dum_fac(2)
56 r2(kd) = sum((x_s(kd,:)-x_in)**2)
60 if (minval(r2).le.tol)
then
61 e_fac = sqrt(h_fac_in(1)/h_fac_in(3))*step_size(2)/step_size(1)
62 sineps = h_fac_in(2)/sqrt(h_fac_in(1)*h_fac_in(3))
63 dum_fac(1) = sqrt(1+2*e_fac*sineps+e_fac**2)
64 dum_fac(2) = sqrt(1-2*e_fac*sineps+e_fac**2)
65 g = -0.5_dp/sqrt(h_fac_in(1)) * step_size(1) * (&
66 &log(abs((dum_fac(2) + e_fac + sineps)/&
67 &(dum_fac(1) - e_fac + sineps))) &
69 &log(abs((dum_fac(2) + e_fac + sineps)/&
70 &(dum_fac(1) - e_fac + sineps))) &
76 h(kd) = sum(norm_s(kd,:)*(x_s(kd,:)-x_in))*(-g(kd))**(-3)
97 subroutine calc_gh_int_2(G,H,t_s,t_in,x_s,x_in,norm_s,norm_in,Aij,ql,tol,&
100 real(
dp),
intent(inout) :: g(2)
101 real(
dp),
intent(inout) :: h(2)
102 real(
dp),
intent(in) :: t_s(2)
103 real(
dp),
intent(in) :: t_in
104 real(
dp),
intent(in) :: x_s(2,2)
105 real(
dp),
intent(in) :: x_in(2)
106 real(
dp),
intent(in) :: norm_s(2,2)
107 real(
dp),
intent(in) :: norm_in(2)
108 real(
dp),
intent(in) :: aij(2)
109 real(
dp),
intent(in) :: ql(2,2)
110 real(
dp),
intent(in) :: tol
111 real(
dp),
intent(in) :: b_coeff(2)
112 integer,
intent(in) :: n_tor
119 real(
dp) :: delta_t(2)
123 real(
dp) :: dn_loc(2)
129 rho2(kd) = sum((x_s(kd,:)-x_in)**2)
131 if (
pi .lt. sum(t_s)/2 - t_in)
then
132 t_in_loc = t_in + 2*
pi
133 else if (-
pi .gt. sum(t_s)/2 - t_in)
then
134 t_in_loc = t_in - 2*
pi
138 n_loc = (norm_s(2,:)/sqrt(sum(norm_s(2,:)**2))+&
139 &norm_s(1,:)/sqrt(sum(norm_s(1,:)**2))) / 2._dp
140 dn_loc = (norm_s(2,:)/sqrt(sum(norm_s(2,:)**2))-&
141 &norm_s(1,:)/sqrt(sum(norm_s(1,:)**2))) / (t_s(2)-t_s(1))
144 if (minval(rho2).le.tol)
then
146 a_coeff = sqrt(sum(norm_in**2))/(8._dp*x_in(1)**2)
149 delta_t(1) = t_s(1) - t_in_loc
150 delta_t(2) = t_s(2) - t_in_loc
152 delta_t(1) = -(t_s(2) - t_in_loc)
153 delta_t(2) = -(t_s(1) - t_in_loc)
156 if (abs(delta_t(jd)).le.0._dp)
then
159 dlogd(jd) = log(a_coeff*abs(delta_t(jd)))
162 g(kd) = 1._dp/sqrt(x_in(1)*x_s(kd,1)) * (&
163 &b_coeff(2)*(delta_t(2)-delta_t(1)) + &
164 &0.5_dp*delta_t(1) - 1.5_dp*delta_t(2) + &
165 &1._dp/(delta_t(2)-delta_t(1)) * &
166 &(delta_t(1)*(delta_t(1)-2*delta_t(2))*dlogd(1) + &
167 &delta_t(2)**2 * dlogd(2)) &
169 h(kd) = 0.5*norm_s(kd,1)/x_s(kd,1) * g(kd) + &
170 &(delta_t(2)-delta_t(1)) * (n_tor-0.5_dp)**(-1) * &
171 &aij(kd)/sqrt(x_in(1)*x_s(kd,1))
179 if (maxval(rho2).gt.tol)
then
181 if (rho2(2).gt.rho2(1))
then
186 g(kd_bound) = g(kd_bound) - 0.5_dp*(t_s(2)-t_s(1))*2._dp/&
187 &sqrt(x_in(1)*x_s(kd_bound,1)) * (ql(kd_bound,2)+&
188 &log(a_coeff*abs(t_s(kd_bound)-t_in_loc))+b_coeff(2))
189 h(kd_bound) = h(kd_bound) + 0.5_dp*(t_s(2)-t_s(1))*2._dp/&
190 &sqrt(x_in(1)*x_s(kd_bound,1)) * &
191 &( (-0.5_dp*norm_s(kd_bound,1)/x_s(kd_bound,1) - &
192 &(1._dp+rho2(kd_bound)/(2*x_in(1)*x_s(kd_bound,1)))*&
193 &aij(kd_bound)) * (ql(kd_bound,2)+&
194 &log(a_coeff*abs(t_s(kd_bound)-t_in_loc))+b_coeff(2)) + &
195 &aij(kd_bound) * (ql(kd_bound,1)+&
196 &log(a_coeff*abs(t_s(kd_bound)-t_in_loc))+b_coeff(1)))
201 g(kd) = - (t_s(2)-t_s(1))/sqrt(x_in(1)*x_s(kd,1)) * &
203 h(kd) = (t_s(2)-t_s(1))/sqrt(x_in(1)*x_s(kd,1)) * &
204 &( (-0.5_dp*norm_s(kd,1)/x_s(kd,1) - &
205 &(1._dp+rho2(kd)/(2*x_in(1)*x_s(kd,1)))*&
206 &aij(kd))*ql(kd,2) + aij(kd)*ql(kd,1) )
222 integer function vec_dis2loc(ctxt,vec_dis,lims,vec_loc,proc)
result(ierr)
226 character(*),
parameter :: rout_name =
'vec_dis2loc'
229 integer,
intent(in) :: ctxt
230 real(dp),
intent(in) :: vec_dis(:)
231 integer,
intent(in) :: lims(:,:)
232 real(dp),
intent(inout) :: vec_loc(:)
233 integer,
intent(in),
optional :: proc
239 integer :: proc_dest(2)
249 if (
present(proc)) proc_loc = proc
250 if (proc_loc.gt.0 .and. proc_loc.lt.
n_procs)
then
251 call blacs_pcoord(ctxt,proc_loc,proc_dest(1),proc_dest(2))
258 do id = 1,
size(lims,2)
260 if (
size(vec_dis) .gt. 0)
then
261 limsl = sum(lims(2,1:id-1)-lims(1,1:id-1)+1) + &
262 &lims(:,id)-lims(1,id)+1
263 vec_loc(lims(1,id):lims(2,id)) = vec_dis(limsl(1):limsl(2))
268 call dgsum2d(ctxt,
'all',
' ',
size(vec_loc),1,vec_loc,
size(vec_loc),&
269 &proc_dest(1),proc_dest(2))
275 integer function mat_dis2loc(ctxt,mat_dis,lims_r,lims_c,mat_loc,proc) &
280 character(*),
parameter :: rout_name =
'mat_dis2loc'
283 integer,
intent(in) :: ctxt
284 real(dp),
intent(in) :: mat_dis(:,:)
285 integer,
intent(in) :: lims_r(:,:)
286 integer,
intent(in) :: lims_c(:,:)
287 real(dp),
intent(inout) :: mat_loc(:,:)
288 integer,
intent(in),
optional :: proc
291 integer :: i_rd, i_cd
292 integer :: limsl_r(2)
293 integer :: limsl_c(2)
295 integer :: proc_dest(2)
305 if (
present(proc)) proc_loc = proc
306 if (proc_loc.gt.0 .and. proc_loc.lt.
n_procs)
then
307 call blacs_pcoord(ctxt,proc_loc,proc_dest(1),proc_dest(2))
314 do i_rd = 1,
size(lims_r,2)
315 if (
size(mat_dis,1) .gt. 0)
then
317 &lims_r(2,1:i_rd-1)-lims_r(1,1:i_rd-1)+1) + &
318 &lims_r(:,i_rd)-lims_r(1,i_rd)+1
319 do i_cd = 1,
size(lims_c,2)
320 if (
size(mat_dis,2) .gt. 0)
then
322 &lims_c(2,1:i_cd-1)-lims_c(1,1:i_cd-1)+1) + &
323 &lims_c(:,i_cd)-lims_c(1,i_cd)+1
324 mat_loc(lims_r(1,i_rd):lims_r(2,i_rd),&
325 &lims_c(1,i_cd):lims_c(2,i_cd)) = mat_dis(&
326 &limsl_r(1):limsl_r(2),limsl_c(1):limsl_c(2))
333 call dgsum2d(ctxt,
'all',
' ',
size(mat_loc,1),
size(mat_loc,2),mat_loc,&
334 &
size(mat_loc,1),proc_dest(1),proc_dest(2))
360 character(*),
parameter :: rout_name =
'interlaced_vac_copy'
363 type(
vac_type),
intent(in) :: vac_old
364 type(
vac_type),
intent(inout) :: vac
375 integer :: n_ang_old(2)
376 real(dp),
allocatable :: loc_a(:,:)
377 real(dp),
allocatable :: loc_b(:,:)
378 integer :: desc_loc(blacsctxtsize)
379 integer :: desc_loc_old(blacsctxtsize)
380 character(len=max_str_ln) :: err_msg
382 logical :: test_redist
383 real(dp),
allocatable :: hg_ser(:,:)
384 real(dp),
allocatable :: hg_ser_old(:,:)
392 n_ang_old = vac_old%n_ang
395 if (n_ang(2).ne.n_ang_old(2))
then
397 err_msg =
'Old and new vacuum need to have an equal number of &
401 if (n_ang(1).ne.2*n_ang_old(1)-1)
then
403 err_msg =
'Old and new vacuum need to have a compatible number of &
404 &points along the field lines'
411 vac%norm((id-1)*n_ang(1)+1:id*n_ang(1):2,:) = &
412 &vac_old%norm((id-1)*n_ang_old(1)+1:id*n_ang_old(1):1,:)
413 vac%x_vec((id-1)*n_ang(1)+1:id*n_ang(1):2,:) = &
414 &vac_old%x_vec((id-1)*n_ang_old(1)+1:id*n_ang_old(1):1,:)
417 select case (vac%style)
419 vac%h_fac((id-1)*n_ang(1)+1:id*n_ang(1):2,:) = vac_old%&
420 &h_fac((id-1)*n_ang_old(1)+1:id*n_ang_old(1):1,:)
422 vac%dnorm((id-1)*n_ang(1)+1:id*n_ang(1):2,:) = &
423 &vac_old%dnorm((id-1)*n_ang_old(1)+1:id*n_ang_old(1):1,:)
424 vac%ang((id-1)*n_ang(1)+1:id*n_ang(1):2,:) = &
425 &vac_old%ang((id-1)*n_ang_old(1)+1:id*n_ang_old(1):1,:)
430 allocate(loc_a(vac%n_loc(1),vac_old%n_loc(2)))
431 allocate(loc_b(vac%n_loc(1),vac_old%n_loc(2)))
434 subcols:
do i_cd = 1,
size(vac_old%lims_c,2)
435 col:
do cd = vac_old%lims_c(1,i_cd),vac_old%lims_c(2,i_cd)
437 alpha_id = (cd-1)/n_ang_old(1)+1
438 par_id = mod(cd-1,n_ang_old(1))+1
439 rd = 2*par_id-1 + (alpha_id-1)*n_ang(1)
442 cdl = sum(vac_old%lims_c(2,1:i_cd-1)-&
443 &vac_old%lims_c(1,1:i_cd-1)+1) + &
444 &cd-vac_old%lims_c(1,i_cd)+1
446 subrows:
do i_rd = 1,
size(vac%lims_r,2)
448 if (rd.ge.vac%lims_r(1,i_rd) .and. &
449 &rd.le.vac%lims_r(2,i_rd))
then
450 rdl = sum(vac%lims_r(2,1:i_rd-1)-&
451 &vac%lims_r(1,1:i_rd-1)+1) + &
452 &rd-vac%lims_r(1,i_rd)+1
454 loc_a(rdl,cdl) = 1._dp
459 call descinit(desc_loc,vac%n_bnd,vac_old%n_bnd,vac%bs,&
460 &vac%bs,0,0,vac%ctxt_HG,max(1,vac%n_loc(1)),ierr)
461 chckerr(
'descinit failed for loc')
462 call descinit(desc_loc_old,vac%n_bnd,vac_old%n_bnd,vac%bs,&
463 &vac%bs,0,0,vac_old%ctxt_HG,max(1,vac%n_loc(1)),ierr)
464 chckerr(
'descinit failed for loc_old')
468 call pdgemm(
'N',
'N',vac%n_bnd,vac_old%n_bnd,vac_old%n_bnd,&
469 &1._dp,loc_a,1,1,desc_loc_old,vac_old%H,1,1,&
470 &vac_old%desc_H,0._dp,loc_b,1,1,desc_loc_old)
471 call pdgemm(
'N',
'T',vac%n_bnd,vac%n_bnd,vac_old%n_bnd,&
472 &1._dp,loc_b,1,1,desc_loc,loc_a,1,1,&
473 &desc_loc,0._dp,vac%H,1,1,vac%desc_H)
476 call pdgemm(
'N',
'N',vac%n_bnd,vac_old%n_bnd,vac_old%n_bnd,&
477 &1._dp,loc_a,1,1,desc_loc_old,vac_old%G,1,1,&
478 &vac_old%desc_G,0._dp,loc_b,1,1,desc_loc_old)
479 call pdgemm(
'N',
'T',vac%n_bnd,vac%n_bnd,vac_old%n_bnd,&
480 &1._dp,loc_b,1,1,desc_loc,loc_a,1,1,&
481 &desc_loc,0._dp,vac%G,1,1,vac%desc_G)
486 call writo(
'test resdistribution of H?')
489 test_redist = .false.
491 if (test_redist)
then
492 allocate(hg_ser(vac%n_bnd,vac%n_bnd))
493 allocate(hg_ser_old(vac_old%n_bnd,vac_old%n_bnd))
495 &vac_old%lims_r,vac_old%lims_c,hg_ser_old,&
499 &vac%lims_r,vac%lims_c,hg_ser,&
507 call plot_hdf5(
'HG_ser_old',
'HG_ser_old',&
508 &reshape(hg_ser_old,[vac_old%n_bnd,vac_old%n_bnd,1]))
510 &reshape(hg_ser,[vac%n_bnd,vac%n_bnd,1]))
516 deallocate(loc_a,loc_b)