46 double precision :: tw(3)
82 double precision :: chi_l(ixG^T), b_l(ixG^T), tw
83 double precision,
allocatable :: fill_g(:,:)
84 integer :: iigrid, igrid, ix1, ix2, ig, jg, k, ierr, ib
87 if(
i_qrad < 0)
call mpistop(
"rt_sc_solve_gather: i_qrad not registered")
88 if(.not.
associated(rt_sc_chib))
call mpistop(
"rt_sc_solve_gather: opacity callback not set")
93 call mpi_comm_split_type(
icomm, mpi_comm_type_shared, 0, mpi_info_null,
rt_node_comm, ierr)
106 do iigrid=1,igridstail; igrid=igrids(iigrid)
107 ps(igrid)%w(ixg^t,
i_qrad) = 0.0d0
117 allocate(fill_g(nxg,nyg)); fill_g = 0.0d0
118 chi_g = 0.0d0; b_g = 0.0d0
122 do iigrid=1,igridstail; igrid=igrids(iigrid)
124 call rt_sc_chib(ixg^
ll,
ixm^
ll, ps(igrid)%w, ps(igrid)%x, chi_l, b_l)
125 do ix2=ixmlo2,ixmhi2;
do ix1=ixmlo1,ixmhi1
127 chi_g(ig,jg) = chi_l(ix1,ix2); b_g(ig,jg) = b_l(ix1,ix2); fill_g(ig,jg) = 1.0d0
141 call mpi_bcast(chi_g, nxg*nyg, mpi_double_precision, 0,
rt_node_comm, ierr)
142 call mpi_bcast(b_g, nxg*nyg, mpi_double_precision, 0,
rt_node_comm, ierr)
143 call mpi_bcast(fill_g, nxg*nyg, mpi_double_precision, 0,
rt_node_comm, ierr)
147 if(minval(fill_g) /= 1.0d0 .or. maxval(fill_g) /= 1.0d0)
then
148 if(mype==0) print *,
'rt_sc_solve_gather: band',ib,
' not a complete single level ', &
149 rt_sc_amr_level,
' (minfill',minval(fill_g),
' maxfill',maxval(fill_g),
')'
150 call mpistop(
"rt_sc_solve_gather: RT band is not a complete single AMR level")
159 jm_g = 0.0d0; fx_g = 0.0d0; fy_g = 0.0d0
163 jm_g = jm_g + wmu(k)*ii_g
164 fx_g = fx_g + wmu(k)*
mu_h(k)*ii_g
165 fy_g = fy_g + wmu(k)*
mu_v(k)*ii_g
175 fx_g = c_norm*fx_g; fy_g = c_norm*fy_g
177 call rt_sc_heat_blend()
180 q_g = c_norm*chi_g*(jm_g - b_g)
183 call sc_sweep_2d(0.0d0, 1.0d0)
186 do iigrid=1,igridstail; igrid=igrids(iigrid)
188 do ix2=ixmlo2,ixmhi2;
do ix1=ixmlo1,ixmhi1
190 ps(igrid)%w(ix1,ix2,
i_qrad) = q_g(ig,jg)
195 rt_wt_scat = rt_wt_scat + (mpi_wtime()-tw)
197 rt_nsolve = rt_nsolve + 1
198 if(rt_sc_debug .and. mype==0 .and. mod(rt_nsolve,10)==0) &
199 write(*,
'(a,i5,4(a,f8.3),a,f8.3,a)')
' RT timing nsolve=',rt_nsolve, &
200 ' | gather+fieldreduce=',rt_wt_gath,
' sweep=',rt_wt_swp,
' momentreduce=',rt_wt_red, &
201 ' blend+scatter=',rt_wt_scat,
' | total=',rt_wt_gath+rt_wt_swp+rt_wt_red+rt_wt_scat,
' s (cumulative)'
208 double precision,
intent(in) :: xh, xv
209 integer,
intent(in) :: ib
210 integer,
intent(out) :: ig, jg
212 if(xv <= band_lo_c(ib) .or. xv >= band_hi_c(ib))
return
214 ig = nint((xh - rg_hlo)/rg_dh + 0.5d0)
215 jg = nint((xv - band_lo_c(ib))/rg_dv + 0.5d0)
216 inside = ig >= 1 .and. ig <= rg_nh .and. jg >= 1 .and. jg <= band_nv(ib)
226 integer :: iigrid, igrid, ierr, ix1, ix2
227 double precision :: dd, dmx, qmx, dmi, xedge, gbuf(3), gout(3)
228 double precision,
allocatable :: seamL0(:,:), seamR0(:,:)
230 had_seam =
allocated(rt_sc_seaml_prev)
232 seaml0 = rt_sc_seaml_prev; seamr0 = rt_sc_seamr_prev
235 if(
allocated(rt_sc_seaml_prev))
then
237 rt_sc_seaml_prev = seaml0; rt_sc_seamr_prev = seamr0
239 rt_sc_seaml_prev = 0.0d0; rt_sc_seamr_prev = 0.0d0
242 do iigrid=1,igridstail; igrid=igrids(iigrid)
243 ps(igrid)%w(ixg^t,i_iout) = ps(igrid)%w(ixg^t,i_qrad)
246 dmx=0.0d0; qmx=0.0d0; dmi=0.0d0
247 xedge = block_nx1*(xprobmax1-xprobmin1)/dble(domain_nx1)
248 do iigrid=1,igridstail; igrid=igrids(iigrid)
249 qmx=max(qmx, maxval(dabs(ps(igrid)%w(
ixm^t,i_qrad))))
250 do ix2=ixmlo2,ixmhi2;
do ix1=ixmlo1,ixmhi1
251 dd=dabs(ps(igrid)%w(ix1,ix2,i_qrad)-ps(igrid)%w(ix1,ix2,i_iout))
253 if(ps(igrid)%x(ix1,ix2,1) > xprobmin1+xedge .and. &
254 ps(igrid)%x(ix1,ix2,1) < xprobmax1-xedge) dmi=max(dmi,dd)
258 gbuf = (/ dmx, qmx, dmi /)
259 call mpi_allreduce(gbuf, gout, 3, mpi_double_precision, mpi_max, icomm, ierr)
260 if(mype==0)
write(*,
'(a,es12.5,a,es12.5,a,es12.5,a,es12.5)') &
261 ' rt_valpipe rel=',gout(1)/max(gout(2),1.0d-300),
' rel(x-interior,no seam)=', &
262 gout(3)/max(gout(2),1.0d-300),
' max|dQ|=',gout(1),
' max|Q|=',gout(2)
270 integer,
intent(in) :: ib
271 integer :: iigrid, igrid, iblk, ierr
272 integer,
allocatable :: cover(:,:)
275 wv_nbxv = band_nbv(ib)
276 wv_dmax = rg_nbh + wv_nbxv
277 if(
allocated(wv_ig))
deallocate(wv_ig,wv_bi,wv_bj)
278 allocate(wv_ig(max(igridstail,1)),wv_bi(max(igridstail,1)),wv_bj(max(igridstail,1)))
280 do iigrid=1,igridstail; igrid=igrids(iigrid)
282 if(
rnode(
rpxmin0_+updim,igrid) < band_lo_c(ib)-0.5d0*rg_dv) cycle
283 if(
rnode(
rpxmin0_+updim,igrid)+rg_bv*rg_dv > band_hi_c(ib)+0.5d0*rg_dv) cycle
284 wv_nblk = wv_nblk + 1
285 wv_ig(wv_nblk) = igrid
286 wv_bi(wv_nblk) = nint((
rnode(
rpxmin0_+hdim,igrid) -rg_hlo)/(rg_bh*rg_dh)) + 1
287 wv_bj(wv_nblk) = nint((
rnode(
rpxmin0_+updim,igrid)-band_lo_c(ib))/(rg_bv*rg_dv)) + 1
290 if(
allocated(rtw_chib))
then
291 if(
size(rtw_chib,3) < max(wv_nblk,1))
deallocate(rtw_chib,rtw_bb,rtw_fx)
293 if(.not.
allocated(rtw_chib))
allocate(rtw_chib(ixglo1:ixghi1,ixglo2:ixghi2,max(wv_nblk,1)), &
294 rtw_bb(ixglo1:ixghi1,ixglo2:ixghi2,max(wv_nblk,1)), &
295 rtw_fx(ixglo1:ixghi1,ixglo2:ixghi2,max(wv_nblk,1)))
297 allocate(cover(rg_nbh, wv_nbxv)); cover = 0
300 call rt_sc_chib(ixg^
ll, ixg^
ll, ps(igrid)%w, ps(igrid)%x, rtw_chib(:,:,iblk), rtw_bb(:,:,iblk))
303 if(wv_bj(iblk)==1)
call copy_edge_row(iglo_v, imlo_v-1, imlo_v)
304 if(wv_bj(iblk)==wv_nbxv)
call copy_edge_row(imhi_v+1, ighi_v, imhi_v)
305 cover(wv_bi(iblk), wv_bj(iblk)) = cover(wv_bi(iblk), wv_bj(iblk)) + 1
308 call mpi_allreduce(mpi_in_place, cover, rg_nbh*wv_nbxv, mpi_integer, mpi_sum,
icomm, ierr)
309 if(minval(cover) /= 1 .or. maxval(cover) /= 1)
then
310 if(
mype==0) print *,
'rt_band_blocks: band',ib,
' not a complete single level ', &
311 rt_sc_amr_level,
' (mincover',minval(cover),
' maxcover',maxval(cover),
')'
312 call mpistop(
"rt_band_blocks: RT band is not a complete single AMR level")
317 integer,
intent(in) :: iv_lo, iv_hi, iv_src
318 integer :: ih, iv, i1, i2, j1, j2
320 do ih = iglo_h, ighi_h
321 call hv(ih, iv, i1, i2)
322 call hv(ih, iv_src, j1, j2)
323 rtw_chib(i1,i2,iblk) = rtw_chib(j1,j2,iblk)
324 rtw_bb(i1,i2,iblk) = rtw_bb(j1,j2,iblk)
335 double precision,
intent(out) :: tautop(rg_nh,wv_nbxv)
336 double precision :: colthk(rg_nh,wv_nbxv), s
337 integer :: iblk, ih, iv, i1, i2, ig, bj, jb, ierr
340 do ih = imlo_h, imhi_h
341 ig = (wv_bi(iblk)-1)*rg_bh + (ih - imlo_h + 1)
344 do iv = imlo_v, imhi_v
345 call hv(ih, iv, i1, i2)
346 s = s + rtw_chib(i1,i2,iblk)
348 colthk(ig,wv_bj(iblk)) = s*rg_dv
351 call mpi_allreduce(mpi_in_place, colthk, rg_nh*wv_nbxv, mpi_double_precision, mpi_sum,
icomm, ierr)
355 do jb = bj+1, wv_nbxv; tautop(:,bj) = tautop(:,bj) + colthk(:,jb);
end do
363 integer,
intent(in) :: iblk
364 double precision,
intent(in) :: tautop(rg_nh,wv_nbxv)
365 double precision,
intent(out) :: taub(ixG^T)
366 integer :: ih, iv, i1, i2, j1, j2, ig
367 do ih = imlo_h, imhi_h
368 ig = (wv_bi(iblk)-1)*rg_bh + (ih - imlo_h + 1)
370 call hv(ih, imhi_v, i1, i2)
371 taub(i1,i2) = tautop(ig,wv_bj(iblk)) + 0.5d0*rtw_chib(i1,i2,iblk)*rg_dv
372 do iv = imhi_v-1, imlo_v, -1
373 call hv(ih, iv, i1, i2)
374 call hv(ih, iv+1, j1, j2)
375 taub(i1,i2) = taub(j1,j2) + 0.5d0*(rtw_chib(j1,j2,iblk)+rtw_chib(i1,i2,iblk))*rg_dv
390 integer,
intent(in) :: nslot
391 if(.not.rt_sc_ready)
call mpistop(
"rt_wave_begin: rt_sc_setup not called")
392 if(i_isw < 0)
call mpistop(
"rt_wave_begin: wavefront slot not reserved")
393 if(i_qrad < 0 .or. i_frad < 0)
call mpistop(
"rt_wave_begin: the wave needs i_qrad and i_frad")
397 wv_xwrap = (rg_nbh == 1)
398 if(.not.wv_xwrap .and.
mype==0 .and. .not.rt_sc_seam_warned)
then
399 write(*,*)
'rt_wave_begin: periodic seam closed by the lagged wrap'
400 rt_sc_seam_warned = .true.
404 call rt_sc_alloc_state()
406 wv_seam = rt_sc_seam_on .and. .not.wv_xwrap .and. bc_h_periodic
407 if(wv_seam)
call rt_sc_seam_alloc(rg_nv, rt_sc_nray)
415 integer,
intent(in) :: ib
416 integer :: iblk, igrid
418 bc_lo_thermal = (trim(rt_sc_bc_min(ib)) ==
'thermal')
419 bc_hi_thermal = (trim(rt_sc_bc_max(ib)) ==
'thermal')
424 ps(igrid)%w(ixg^t,i_qrad) = 0.0d0
425 ps(igrid)%w(ixg^t,i_frad) = 0.0d0
426 rtw_fx(:,:,iblk) = 0.0d0
435 integer,
intent(in) :: nslot
436 integer :: iblk, igrid, ix1, ix2, ih, iv, i1, i2
437 double precision :: taub(ixG^T), dfxdx, dfydy
438 double precision,
allocatable :: tautop(:,:)
442 ps(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_frad) =
c_norm*ps(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_frad)
443 rtw_fx(ixmlo1:ixmhi1,ixmlo2:ixmhi2,iblk) =
c_norm*rtw_fx(ixmlo1:ixmhi1,ixmlo2:ixmhi2,iblk)
446 if(.not.rt_sc_flux_blend)
then
451 do ix2=ixmlo2,ixmhi2;
do ix1=ixmlo1,ixmhi1
453 ps(igrid)%w(ix1,ix2,i_qrad) =
c_norm*rtw_chib(ix1,ix2,iblk)* &
454 (ps(igrid)%w(ix1,ix2,i_qrad) - rtw_bb(ix1,ix2,iblk))
465 ps_rt(wv_ig(iblk))%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw) = rtw_fx(ixmlo1:ixmhi1,ixmlo2:ixmhi2,iblk)
467 call create_bc_mpi_datatype(i_isw, 1)
469 call create_bc_mpi_datatype(i_frad, 1)
470 call getbc(global_time, 0.0d0, ps, i_frad, 1)
471 allocate(tautop(rg_nh,wv_nbxv))
476 do iv = imlo_v, imhi_v
477 do ih = imlo_h, imhi_h
478 call hv(ih, iv, i1, i2)
481 dfxdx = (ps_rt(igrid)%w(i1+eh(1),i2+eh(2),i_isw) &
482 -ps_rt(igrid)%w(i1-eh(1),i2-eh(2),i_isw))/(2.0d0*rg_dh)
485 if(wv_bj(iblk)==1 .and. iv==imlo_v)
then
486 dfydy = (ps(igrid)%w(i1+ev(1),i2+ev(2),i_frad)-ps(igrid)%w(i1,i2,i_frad))/rg_dv
487 else if(wv_bj(iblk)==wv_nbxv .and. iv==imhi_v)
then
488 dfydy = (ps(igrid)%w(i1,i2,i_frad)-ps(igrid)%w(i1-ev(1),i2-ev(2),i_frad))/rg_dv
490 dfydy = (ps(igrid)%w(i1+ev(1),i2+ev(2),i_frad) &
491 -ps(igrid)%w(i1-ev(1),i2-ev(2),i_frad))/(2.0d0*rg_dv)
493 ps(igrid)%w(i1,i2,i_qrad) = blend_heating(rtw_chib(i1,i2,iblk), &
494 ps(igrid)%w(i1,i2,i_qrad), rtw_bb(i1,i2,iblk), dfxdx+dfydy, taub(i1,i2))
500 call create_bc_mpi_datatype(i_isw, nslot)
507 integer,
intent(in) :: iblk, k
508 double precision,
intent(in) :: iib(ixG^T)
512 ps(igrid)%w(
ixm^t,i_qrad) = ps(igrid)%w(
ixm^t,i_qrad) + wmu(k)*iib(
ixm^t)
513 ps(igrid)%w(
ixm^t,i_frad) = ps(igrid)%w(
ixm^t,i_frad) + wmu(k)*mu_v(k)*iib(
ixm^t)
514 rtw_fx(
ixm^t,iblk) = rtw_fx(
ixm^t,iblk) + wmu(k)*mu_h(k)*iib(
ixm^t)
522 integer,
intent(in) :: nslot
534 if(wv_seam)
call rt_sc_seam_finalize(rg_nv, rt_sc_nray)
536 if(
allocated(wv_ig))
deallocate(wv_ig,wv_bi,wv_bj)
545 double precision,
intent(inout) :: iib(ixG^T)
546 integer,
intent(in) :: igrid, ibi, sx, k
547 integer :: iv, i1, i2, gy0
550 if(ibi==1 .and. sx>0)
then
551 do iv = imlo_v, imhi_v
552 call hv(imlo_h-1, iv, i1, i2); iib(i1,i2) = rt_sc_seamr_prev(gy0+(iv-imlo_v)+1,k)
554 else if(ibi==rg_nbh .and. sx<0)
then
555 do iv = imlo_v, imhi_v
556 call hv(imhi_h+1, iv, i1, i2); iib(i1,i2) = rt_sc_seaml_prev(gy0+(iv-imlo_v)+1,k)
566 double precision,
intent(in) :: iib(ixG^T)
567 integer,
intent(in) :: igrid, ibi, sx, k
568 integer :: iv, i1, i2, gy0
570 if(ibi==rg_nbh .and. sx>0)
then
571 do iv = imlo_v, imhi_v
572 call hv(imhi_h, iv, i1, i2); rt_sc_seamr_cur(gy0+(iv-imlo_v)+1,k) = iib(i1,i2)
574 else if(ibi==1 .and. sx<0)
then
575 do iv = imlo_v, imhi_v
576 call hv(imlo_h, iv, i1, i2); rt_sc_seaml_cur(gy0+(iv-imlo_v)+1,k) = iib(i1,i2)
586 integer,
intent(in) :: islot
587 integer :: iblk, igrid
590 if(wv_bj(iblk)==1)
call fill_rows(iglo_v, imlo_v-1, imlo_v, bc_lo_thermal)
591 if(wv_bj(iblk)==wv_nbxv)
call fill_rows(imhi_v+1, ighi_v, imhi_v, bc_hi_thermal)
593 if(bc_h_periodic)
return
596 if(wv_bi(iblk)==1)
call fill_columns(iglo_h, imlo_h-1, imlo_h, bc_hlo_thermal)
597 if(wv_bi(iblk)==rg_nbh)
call fill_columns(imhi_h+1, ighi_h, imhi_h, bc_hhi_thermal)
602 integer,
intent(in) :: iv_lo, iv_hi, iv_src
603 logical,
intent(in) :: thermal
604 integer :: ih, iv, i1, i2, j1, j2
606 do ih = iglo_h, ighi_h
607 call hv(ih, iv, i1, i2)
608 call hv(ih, iv_src, j1, j2)
609 ps_rt(igrid)%w(i1,i2,islot) = merge(rtw_bb(j1,j2,iblk), 0.0d0, thermal)
614 subroutine fill_columns(ih_lo, ih_hi, ih_src, thermal)
615 integer,
intent(in) :: ih_lo, ih_hi, ih_src
616 logical,
intent(in) :: thermal
617 integer :: ih, iv, i1, i2, j1, j2
619 do iv = iglo_v, ighi_v
620 call hv(ih, iv, i1, i2)
621 call hv(ih_src, iv, j1, j2)
622 ps_rt(igrid)%w(i1,i2,islot) = merge(rtw_bb(j1,j2,iblk), 0.0d0, thermal)
625 end subroutine fill_columns
633 integer,
intent(in) :: iblk, k
634 double precision,
intent(inout) :: iib(ixG^T)
635 double precision :: tii(ixGlo2:ixGhi2,ixGlo1:ixGhi1), t0
640 call sc_sweep_block(mu_h(k), mu_v(k), rg_dh, rg_dv, wv_xwrap, ixg^
ll,
ixm^
ll, &
641 rtw_chib(:,:,iblk), rtw_bb(:,:,iblk), iib)
644 call sc_sweep_block(mu_h(k), mu_v(k), rg_dh, rg_dv, wv_xwrap, &
645 ixglo2,ixglo1,ixghi2,ixghi1, ixmlo2,ixmlo1,ixmhi2,ixmhi1, &
646 transpose(rtw_chib(:,:,iblk)), transpose(rtw_bb(:,:,iblk)), tii)
656 integer,
intent(in) :: b, n, s
657 wave_stage = merge(b, merge(n+1-b, 1, s<0), s>0)
663 integer :: ib, k, sx, sy, d, iblk, igrid
664 double precision :: iib(ixG^T)
666 do ib = 1, rt_sc_nband
670 sx = ray_sign(mu_h(k)); sy = ray_sign(mu_v(k))
673 ps_rt(wv_ig(iblk))%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw) = 0.0d0
686 iib = ps_rt(igrid)%w(:,:,i_isw)
687 if(wv_seam)
call rt_seam_read(iib, igrid, wv_bi(iblk), sx, k)
689 ps_rt(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw) = iib(ixmlo1:ixmhi1,ixmlo2:ixmhi2)
690 if(wv_seam)
call rt_seam_write(iib, igrid, wv_bi(iblk), sx, k)
709 integer :: ib, k, sx, sy, iblk, igrid, islot, nslot
710 integer :: ng, gidx, g, jj, tt_clk, tmax, gbase, gend, gg
711 integer :: grp_sx(9), grp_sy(9), grp_n(9)
712 integer,
allocatable :: grp_ray(:,:)
713 double precision :: iib(ixG^T)
718 allocate(grp_ray(9, max(rt_sc_nray,1)))
721 sx = ray_sign(mu_h(k)); sy = ray_sign(mu_v(k))
724 if(grp_sx(g)==sx .and. grp_sy(g)==sy) then; gidx = g; exit;
end if
728 grp_sx(ng)=sx; grp_sy(ng)=sy; grp_n(ng)=0; gidx=ng
730 grp_n(gidx) = grp_n(gidx) + 1
731 grp_ray(gidx, grp_n(gidx)) = k
734 do ib = 1, rt_sc_nband
740 do gbase = 1, ng, nisw
741 gend = min(gbase+nisw-1, ng)
745 ps_rt(wv_ig(iblk))%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw:i_isw+nisw-1) = 0.0d0
750 do gg = gbase, gend; tmax = max(tmax, grp_n(gg) + wv_dmax - 2);
end do
761 islot = i_isw+(gg-gbase)
765 jj = tt_clk - (
wave_stage(wv_bi(iblk),rg_nbh,grp_sx(gg)) &
766 +
wave_stage(wv_bj(iblk),wv_nbxv,grp_sy(gg))) + 2
767 if(jj < 1 .or. jj > grp_n(gg)) cycle
771 iib = ps_rt(igrid)%w(:,:,islot)
772 iib(ixmlo1:ixmhi1,ixmlo2:ixmhi2) = 0.0d0
773 if(wv_seam)
call rt_seam_read(iib, igrid, wv_bi(iblk), grp_sx(gg), k)
777 ps_rt(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,islot) = iib(ixmlo1:ixmhi1,ixmlo2:ixmhi2)
778 if(wv_seam)
call rt_seam_write(iib, igrid, wv_bi(iblk), grp_sx(gg), k)
subroutine copy_edge_row(iv_lo, iv_hi, iv_src)
Rows iv_lo to iv_hi of the chi and B caches of block iblk take row iv_src.
subroutine fill_rows(iv_lo, iv_hi, iv_src, thermal)
Ghost rows iv_lo to iv_hi, from the edge row iv_src.
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
update ghost cells of all blocks including physical boundaries
subroutine getbc(time, qdt, psb, nwstart, nwbc)
do update ghost cells of all blocks including physical boundaries
subroutine create_bc_mpi_datatype(nwstart, nwbc, nwfull)
This module contains definitions of global parameters and variables and some generic functions/subrou...
logical lb_diagnose
Per-rank load-balance timing diagnostic toggle (off by default). When .true., per-rank wall times are...
double precision global_time
The global simulation time.
integer icomm
The MPI communicator.
integer mype
The rank of the current MPI task.
integer, parameter plevel_
integer ixm
the mesh range of a physical block without ghost cells
logical lb_automatic
Cost-weighted automatic load balancer toggle (off by default). When .true., the SFC partitioner cuts ...
double precision c_norm
Normalised speed of light.
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision, dimension(:), allocatable block_cost_rt
Per-step per-block cost of the short-characteristics sweep, indexed by igrid. Separate from block_cos...
integer, parameter rpxmin0_
double precision lb_rt_accum
Per-rank wall time spent in the SC radiative-transfer KBA sweep this step, for the lb_diagnose rank-t...
integer, dimension(:,:), allocatable node
Solvers of the short-characteristics (SC) radiative transfer and their dispatch.
subroutine rt_wave_band_close(nslot)
Close the band. The fluxes are scaled by c_norm, Q is formed as the imbalance or as the -div F blend ...
subroutine rt_tau_tops(tautop)
Tau at the top face of every block row of the current band, per global column along hdim....
subroutine rt_band_blocks(ib)
List the blocks of this rank that lie in band ib, with their block position (bi, bj),...
subroutine rt_sc_solve_wave()
Ray-by-ray KBA, with one ray at a time passing through the diagonal wavefront.
subroutine rt_wave_begin(nslot)
Prologue of both KBA schedules on level rt_sc_amr_level. It checks the setup, sets the x-distribution...
subroutine rt_sc_solve_gather()
Replicated gather, the original implementation, kept for comparison and not for production....
logical function rt_grid_index(xh, xv, ib, ig, jg)
Indices (ig, jg) on the replicated grid of band ib of the cell centred at xh along hdim and xv along ...
subroutine rt_wave_band_open(ib)
Open band ib. It lists and caches the band blocks and zeroes the accumulators.
subroutine, public rt_sc_solve()
Collective, once per step. For each band on rt_sc_amr_level it sweeps all rays and forms the heating ...
subroutine rt_sweep_one(iblk, k, iib)
Sweep block iblk for ray k in place on iib. With updim = 1 the block is transposed around the kernel,...
subroutine rt_seam_write(iib, igrid, ibi, sx, k)
Seam write. At the far domain edge the outflow of ray k is kept for the next solve....
subroutine rt_inflow_ghosts(islot)
Inflow intensity in slot islot. The ghosts beyond the band ends, and beyond the horizontal edges wher...
subroutine rt_exchange(nslot)
Ghost exchange of the nslot intensity columns of ps_rt from i_isw, with the physical boundaries left ...
subroutine rt_seam_read(iib, igrid, ibi, sx, k)
Seam read. At the domain edge where ray k enters, the wrapped upwind ghost column of the block takes ...
subroutine rt_sc_validate_pipe()
Validation of the pipelined KBA. The ray-by-ray Q is copied into i_iout and the pipelined Q left in i...
pure integer function wave_stage(b, n, s)
Position of a block counted from the upwind end of a row of n blocks, for a ray whose cosine along th...
subroutine rt_wave_end()
Epilogue. It hands the seam edges over to the next solve, restores the hydro datatype and releases th...
subroutine rt_sc_solve_wave_pipe()
Pipelined KBA. The direction-sign corners run together in batches of nisw slots, and within each corn...
subroutine rt_block_tau(iblk, tautop, taub)
Tau from the band top to every cell centre of block iblk, integrated down from the top face of the bl...
subroutine rt_add_moments(iblk, k, iib)
Add the weighted intensity iib of ray k on block iblk to J in i_qrad, Fy in i_frad and Fx in rtw_fx.
Parameters, resolved state and lifecycle of the short-characteristics (SC) radiative transfer,...
double precision, dimension(:), allocatable mu_h
Ray cosines along the RT grid axes (hdim, updim). They are (mux, muy) for updim = 2 and the swapped p...
integer, public rt_sc_nband
double precision, dimension(:), allocatable mu_v
integer, dimension(rt_sc_maxband) band_nv
integer rt_node_comm
Node-local communicator for the moment reduction of the gather. The ranks reach that reduction far ou...
logical, public rt_sc_distributed
The distributed KBA wavefront. Each rank sweeps only its own band blocks, one diagonal at a time,...
integer, public rt_sc_amr_level
The AMR level the RT runs on. The bands are held at this level so that the RT sees a uniform grid,...
double precision, public rt_wt_swp
integer, public rt_nsolve
double precision, public rt_wt_wave
logical, public rt_sc_active
True when the physics module has switched the RT on, with hd_radiative_transfer or mhd_radiative_tran...
logical, public rt_sc_flux_blend
rt_sc_flux_blend blends the thin heating c chi (J - B) with the thick -div F. rt_sc_cfl limits the he...
integer rg_nh
The RT grid on rt_sc_amr_level along (hdim, updim): cells across the domain, cells per block,...
subroutine rt_allreduce_chunk(a, n1, n2, comm)
In-place sum allreduce of a 2D array in chunks of whole columns of about 1 MB.
double precision, public rt_wt_red
integer rt_lead_comm
Communicator of one leader rank per node. The field gather sums within each node, then over the leade...
character(len=10), dimension(rt_sc_maxband), public rt_sc_bc_min
double precision, public rt_wt_gath
Cumulative wall time of the field gather, the sweep, the moment reduction and the scatter,...
integer, public i_qrad
Extra-variable indices of the heating Q, the vertical flux F and the emergent intensity Iout,...
logical, public rt_sc_pipeline
The pipelined KBA. The four sweep corners run at once, each with its own intensity slot,...
character(len=10), dimension(rt_sc_maxband), public rt_sc_bc_max
logical, public rt_sc_debug
Prints the cumulative RT timing every 10 solves.
logical, public rt_sc_valpipe
For validation, runs the ray-by-ray and pipelined waves on the same state and prints max|dQ|.
subroutine timer_open(t0)
Open a timing window, whose length leaves out the EoS and ghost-cell time spent inside it,...
double precision function timer_close(t0)
Wall time since timer_open, less the EoS and ghost-cell time spent in between.
integer nwgc
Number of variables which need to be updated in ghost cells.