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, bc_lo_thermal)
304 if(wv_bj(iblk)==wv_nbxv)
call copy_edge_row(imhi_v+1, ighi_v, imhi_v, bc_hi_thermal)
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")
324 integer,
intent(in) :: iv_lo, iv_hi, iv_src
325 logical,
intent(in) :: thermal
326 integer :: ih, iv, i1, i2, j1, j2
328 do ih = iglo_h, ighi_h
329 call hv(ih, iv, i1, i2)
330 call hv(ih, iv_src, j1, j2)
331 rtw_chib(i1,i2,iblk) = merge(rtw_chib(j1,j2,iblk), 0.0d0, thermal)
332 if(.not.thermal) rtw_bb(i1,i2,iblk) = rtw_bb(j1,j2,iblk)
343 double precision,
intent(out) :: tautop(rg_nh,wv_nbxv)
344 double precision :: colthk(rg_nh,wv_nbxv), s
345 integer :: iblk, ih, iv, i1, i2, ig, bj, jb, ierr
348 do ih = imlo_h, imhi_h
349 ig = (wv_bi(iblk)-1)*rg_bh + (ih - imlo_h + 1)
352 do iv = imlo_v, imhi_v
353 call hv(ih, iv, i1, i2)
354 s = s + rtw_chib(i1,i2,iblk)
356 colthk(ig,wv_bj(iblk)) = s*rg_dv
359 call mpi_allreduce(mpi_in_place, colthk, rg_nh*wv_nbxv, mpi_double_precision, mpi_sum,
icomm, ierr)
363 do jb = bj+1, wv_nbxv; tautop(:,bj) = tautop(:,bj) + colthk(:,jb);
end do
371 integer,
intent(in) :: iblk
372 double precision,
intent(in) :: tautop(rg_nh,wv_nbxv)
373 double precision,
intent(out) :: taub(ixG^T)
374 integer :: ih, iv, i1, i2, j1, j2, ig
375 do ih = imlo_h, imhi_h
376 ig = (wv_bi(iblk)-1)*rg_bh + (ih - imlo_h + 1)
378 call hv(ih, imhi_v, i1, i2)
379 taub(i1,i2) = tautop(ig,wv_bj(iblk)) + 0.5d0*rtw_chib(i1,i2,iblk)*rg_dv
380 do iv = imhi_v-1, imlo_v, -1
381 call hv(ih, iv, i1, i2)
382 call hv(ih, iv+1, j1, j2)
383 taub(i1,i2) = taub(j1,j2) + 0.5d0*(rtw_chib(j1,j2,iblk)+rtw_chib(i1,i2,iblk))*rg_dv
398 integer,
intent(in) :: nslot
399 if(.not.rt_sc_ready)
call mpistop(
"rt_wave_begin: rt_sc_setup not called")
400 if(i_isw < 0)
call mpistop(
"rt_wave_begin: wavefront slot not reserved")
401 if(i_qrad < 0 .or. i_frad < 0)
call mpistop(
"rt_wave_begin: the wave needs i_qrad and i_frad")
405 wv_xwrap = (rg_nbh == 1)
406 if(.not.wv_xwrap .and.
mype==0 .and. .not.rt_sc_seam_warned)
then
407 write(*,*)
'rt_wave_begin: periodic seam closed by the lagged wrap'
408 rt_sc_seam_warned = .true.
412 call rt_sc_alloc_state()
414 wv_seam = rt_sc_seam_on .and. .not.wv_xwrap .and. bc_h_periodic
415 if(wv_seam)
call rt_sc_seam_alloc(rg_nv, rt_sc_nray)
423 integer,
intent(in) :: ib
424 integer :: iblk, igrid
426 bc_lo_thermal = (trim(rt_sc_bc_min(ib)) ==
'thermal')
427 bc_hi_thermal = (trim(rt_sc_bc_max(ib)) ==
'thermal')
432 ps(igrid)%w(ixg^t,i_qrad) = 0.0d0
433 ps(igrid)%w(ixg^t,i_frad) = 0.0d0
434 rtw_fx(:,:,iblk) = 0.0d0
443 integer,
intent(in) :: nslot
444 integer :: iblk, igrid, ix1, ix2, ih, iv, i1, i2
445 double precision :: taub(ixG^T), dfxdx, dfydy
446 double precision,
allocatable :: tautop(:,:)
450 ps(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_frad) =
c_norm*ps(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_frad)
451 rtw_fx(ixmlo1:ixmhi1,ixmlo2:ixmhi2,iblk) =
c_norm*rtw_fx(ixmlo1:ixmhi1,ixmlo2:ixmhi2,iblk)
454 if(.not.rt_sc_flux_blend)
then
459 do ix2=ixmlo2,ixmhi2;
do ix1=ixmlo1,ixmhi1
461 ps(igrid)%w(ix1,ix2,i_qrad) =
c_norm*rtw_chib(ix1,ix2,iblk)* &
462 (ps(igrid)%w(ix1,ix2,i_qrad) - rtw_bb(ix1,ix2,iblk))
473 ps_rt(wv_ig(iblk))%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw) = rtw_fx(ixmlo1:ixmhi1,ixmlo2:ixmhi2,iblk)
475 call create_bc_mpi_datatype(i_isw, 1)
477 call create_bc_mpi_datatype(i_frad, 1)
478 call getbc(global_time, 0.0d0, ps, i_frad, 1)
479 allocate(tautop(rg_nh,wv_nbxv))
484 do iv = imlo_v, imhi_v
485 do ih = imlo_h, imhi_h
486 call hv(ih, iv, i1, i2)
489 dfxdx = (ps_rt(igrid)%w(i1+eh(1),i2+eh(2),i_isw) &
490 -ps_rt(igrid)%w(i1-eh(1),i2-eh(2),i_isw))/(2.0d0*rg_dh)
493 if(wv_bj(iblk)==1 .and. iv==imlo_v)
then
494 dfydy = (ps(igrid)%w(i1+ev(1),i2+ev(2),i_frad)-ps(igrid)%w(i1,i2,i_frad))/rg_dv
495 else if(wv_bj(iblk)==wv_nbxv .and. iv==imhi_v)
then
496 dfydy = (ps(igrid)%w(i1,i2,i_frad)-ps(igrid)%w(i1-ev(1),i2-ev(2),i_frad))/rg_dv
498 dfydy = (ps(igrid)%w(i1+ev(1),i2+ev(2),i_frad) &
499 -ps(igrid)%w(i1-ev(1),i2-ev(2),i_frad))/(2.0d0*rg_dv)
501 ps(igrid)%w(i1,i2,i_qrad) = blend_heating(rtw_chib(i1,i2,iblk), &
502 ps(igrid)%w(i1,i2,i_qrad), rtw_bb(i1,i2,iblk), dfxdx+dfydy, taub(i1,i2))
508 call create_bc_mpi_datatype(i_isw, nslot)
519 integer,
intent(in) :: iblk, k
520 double precision,
intent(inout) :: iib(ixG^T)
521 if(wv_bj(iblk)==1 .and. bc_lo_thermal .and. mu_v(k) > 0.0d0) &
522 call fill_rows(iglo_v, imlo_v-1, imlo_v-1, imlo_v-2)
523 if(wv_bj(iblk)==wv_nbxv .and. bc_hi_thermal .and. mu_v(k) < 0.0d0) &
524 call fill_rows(imhi_v+1, ighi_v, imhi_v+1, imhi_v+2)
529 integer,
intent(in) :: iv_lo, iv_hi, g1, g2
530 integer :: ih, iv, i1, i2, a1, a2, b1, b2
531 double precision :: dbdtau
532 do ih = iglo_h, ighi_h
534 call hv(ih, g1, a1, a2)
537 if(iv_hi > iv_lo .and. rtw_chib(a1,a2,iblk) > 0.0d0)
then
538 call hv(ih, g2, b1, b2)
539 dbdtau = (rtw_bb(b1,b2,iblk) - rtw_bb(a1,a2,iblk))/(rtw_chib(a1,a2,iblk)*rg_dv)
542 call hv(ih, iv, i1, i2)
544 iib(i1,i2) = rtw_bb(i1,i2,iblk) + dabs(mu_v(k))*dbdtau
554 integer,
intent(in) :: iblk, k
555 double precision,
intent(in) :: iib(ixG^T)
559 ps(igrid)%w(
ixm^t,i_qrad) = ps(igrid)%w(
ixm^t,i_qrad) + wmu(k)*iib(
ixm^t)
560 ps(igrid)%w(
ixm^t,i_frad) = ps(igrid)%w(
ixm^t,i_frad) + wmu(k)*mu_v(k)*iib(
ixm^t)
561 rtw_fx(
ixm^t,iblk) = rtw_fx(
ixm^t,iblk) + wmu(k)*mu_h(k)*iib(
ixm^t)
569 integer,
intent(in) :: nslot
581 if(wv_seam)
call rt_sc_seam_finalize(rg_nv, rt_sc_nray)
583 if(
allocated(wv_ig))
deallocate(wv_ig,wv_bi,wv_bj)
593 double precision,
intent(inout) :: iib(ixG^T)
594 integer,
intent(in) :: igrid, ibi, ibj, sx, k
595 integer :: iv, ivlo, ivhi, i1, i2, gy0
598 ivlo = merge(imlo_v, imlo_v-1, ibj==1)
599 ivhi = merge(imhi_v, imhi_v+1, ibj==wv_nbxv)
600 if(ibi==1 .and. sx>0)
then
602 call hv(imlo_h-1, iv, i1, i2); iib(i1,i2) = rt_sc_seamr_prev(gy0+(iv-imlo_v)+1,k)
604 else if(ibi==rg_nbh .and. sx<0)
then
606 call hv(imhi_h+1, iv, i1, i2); iib(i1,i2) = rt_sc_seaml_prev(gy0+(iv-imlo_v)+1,k)
616 double precision,
intent(in) :: iib(ixG^T)
617 integer,
intent(in) :: igrid, ibi, sx, k
618 integer :: iv, i1, i2, gy0
620 if(ibi==rg_nbh .and. sx>0)
then
621 do iv = imlo_v, imhi_v
622 call hv(imhi_h, iv, i1, i2); rt_sc_seamr_cur(gy0+(iv-imlo_v)+1,k) = iib(i1,i2)
624 else if(ibi==1 .and. sx<0)
then
625 do iv = imlo_v, imhi_v
626 call hv(imlo_h, iv, i1, i2); rt_sc_seaml_cur(gy0+(iv-imlo_v)+1,k) = iib(i1,i2)
636 integer,
intent(in) :: islot
637 integer :: iblk, igrid
640 if(wv_bj(iblk)==1)
call fill_rows(iglo_v, imlo_v-1, imlo_v, bc_lo_thermal)
641 if(wv_bj(iblk)==wv_nbxv)
call fill_rows(imhi_v+1, ighi_v, imhi_v, bc_hi_thermal)
643 if(bc_h_periodic)
return
646 if(wv_bi(iblk)==1)
call fill_columns(iglo_h, imlo_h-1, imlo_h, bc_hlo_thermal)
647 if(wv_bi(iblk)==rg_nbh)
call fill_columns(imhi_h+1, ighi_h, imhi_h, bc_hhi_thermal)
652 integer,
intent(in) :: iv_lo, iv_hi, iv_src
653 logical,
intent(in) :: thermal
654 integer :: ih, iv, i1, i2, j1, j2
656 do ih = iglo_h, ighi_h
657 call hv(ih, iv, i1, i2)
658 call hv(ih, iv_src, j1, j2)
659 ps_rt(igrid)%w(i1,i2,islot) = merge(rtw_bb(j1,j2,iblk), 0.0d0, thermal)
664 subroutine fill_columns(ih_lo, ih_hi, ih_src, thermal)
665 integer,
intent(in) :: ih_lo, ih_hi, ih_src
666 logical,
intent(in) :: thermal
667 integer :: ih, iv, i1, i2, j1, j2
669 do iv = iglo_v, ighi_v
670 call hv(ih, iv, i1, i2)
671 call hv(ih_src, iv, j1, j2)
672 ps_rt(igrid)%w(i1,i2,islot) = merge(rtw_bb(j1,j2,iblk), 0.0d0, thermal)
675 end subroutine fill_columns
683 integer,
intent(in) :: iblk, k
684 double precision,
intent(inout) :: iib(ixG^T)
685 double precision :: tii(ixGlo2:ixGhi2,ixGlo1:ixGhi1), t0
690 call sc_sweep_block(mu_h(k), mu_v(k), rg_dh, rg_dv, wv_xwrap, ixg^
ll,
ixm^
ll, &
691 rtw_chib(:,:,iblk), rtw_bb(:,:,iblk), iib)
694 call sc_sweep_block(mu_h(k), mu_v(k), rg_dh, rg_dv, wv_xwrap, &
695 ixglo2,ixglo1,ixghi2,ixghi1, ixmlo2,ixmlo1,ixmhi2,ixmhi1, &
696 transpose(rtw_chib(:,:,iblk)), transpose(rtw_bb(:,:,iblk)), tii)
706 integer,
intent(in) :: b, n, s
707 wave_stage = merge(b, merge(n+1-b, 1, s<0), s>0)
713 integer :: ib, k, sx, sy, d, iblk, igrid
714 double precision :: iib(ixG^T)
716 do ib = 1, rt_sc_nband
720 sx = ray_sign(mu_h(k)); sy = ray_sign(mu_v(k))
723 ps_rt(wv_ig(iblk))%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw) = 0.0d0
736 iib = ps_rt(igrid)%w(:,:,i_isw)
737 if(wv_seam)
call rt_seam_read(iib, igrid, wv_bi(iblk), wv_bj(iblk), sx, k)
740 ps_rt(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw) = iib(ixmlo1:ixmhi1,ixmlo2:ixmhi2)
741 if(wv_seam)
call rt_seam_write(iib, igrid, wv_bi(iblk), sx, k)
763 integer :: ib, k, sx, sy, iblk, igrid, islot, nslot
764 integer :: ng, gidx, g, jj, tt_clk, tmax, gbase, gend, gg, npb
765 integer :: grp_sx(9), grp_sy(9), grp_n(9)
766 integer,
allocatable :: grp_ray(:,:)
767 double precision :: iib(ixG^T)
772 allocate(grp_ray(9, max(rt_sc_nray,1)))
775 sx = ray_sign(mu_h(k)); sy = ray_sign(mu_v(k))
778 if(grp_sx(g)==sx .and. grp_sy(g)==sy) then; gidx = g; exit;
end if
782 grp_sx(ng)=sx; grp_sy(ng)=sy; grp_n(ng)=0; gidx=ng
784 grp_n(gidx) = grp_n(gidx) + 1
785 grp_ray(gidx, grp_n(gidx)) = k
788 npb = max(1, min(nisw, nw/2))
790 do ib = 1, rt_sc_nband
796 do gbase = 1, ng, npb
797 gend = min(gbase+npb-1, ng)
798 nslot = 2*(gend-gbase+1)
801 ps_rt(wv_ig(iblk))%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,i_isw:i_isw+2*npb-1) = 0.0d0
806 do gg = gbase, gend; tmax = max(tmax, grp_n(gg) + wv_dmax - 2);
end do
821 jj = tt_clk - (
wave_stage(wv_bi(iblk),rg_nbh,grp_sx(gg)) &
822 +
wave_stage(wv_bj(iblk),wv_nbxv,grp_sy(gg))) + 2
823 if(jj < 1 .or. jj > grp_n(gg)) cycle
825 islot = i_isw+2*(gg-gbase)+mod(jj,2)
828 iib = ps_rt(igrid)%w(:,:,islot)
829 iib(ixmlo1:ixmhi1,ixmlo2:ixmhi2) = 0.0d0
830 if(wv_seam)
call rt_seam_read(iib, igrid, wv_bi(iblk), wv_bj(iblk), grp_sx(gg), k)
835 ps_rt(igrid)%w(ixmlo1:ixmhi1,ixmlo2:ixmhi2,islot) = iib(ixmlo1:ixmhi1,ixmlo2:ixmhi2)
836 if(wv_seam)
call rt_seam_write(iib, igrid, wv_bi(iblk), grp_sx(gg), k)
subroutine fill_rows(iv_lo, iv_hi, g1, g2)
Ghost rows iv_lo to iv_hi, with the gradient from the ghost row g1 next to the band to the one beyond...
subroutine copy_edge_row(iv_lo, iv_hi, iv_src, thermal)
Ghost rows iv_lo to iv_hi of the chi and B caches of block iblk beyond 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_thermal_inflow(iblk, k, iib)
Diffusion inflow of ray k at a thermal band end, written into the ghosts of the block copy iib....
subroutine rt_seam_read(iib, igrid, ibi, ibj, sx, k)
Seam read. At the domain edge where ray k enters, the wrapped upwind ghost column of the block takes ...
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_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 up to nisw, 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.