10 integer :: numFL,numLP
11 double precision :: dL,Tmax,trac_delta,T_bott
12 double precision,
allocatable :: xFi(:,:)
15 double precision :: dxT^D
16 double precision :: xTmin(ndim),xTmax(ndim)
17 double precision,
allocatable :: xT(:^D&,:)
19 integer,
allocatable :: trac_grid(:),ground_grid(:)
20 integer :: ngrid_trac,ngrid_ground
21 logical,
allocatable :: trac_pe(:)
27 subroutine init_trac_line(mask)
28 logical,
intent(in) :: mask
29 integer :: refine_factor,ix^D,ix(ndim),j,iFL,numL(ndim),finegrid
30 double precision :: lengthFL
31 double precision :: xprobmin(ndim),xprobmax(ndim),domain_nx(ndim)
37 ^d&xprobmin(^d)=xprobmin^d\
38 ^d&xprobmax(^d)=xprobmax^d\
39 ^d&domain_nx(^d)=domain_nx^d\
40 dl=(xprobmax(ndim)-xprobmin(ndim))/(domain_nx(ndim)*refine_factor)
50 numlp=floor(lengthfl/dl)
55 finegrid=mhd_trac_finegrid
56 numl(j)=floor((xprobmax(j)-xprobmin(j))/dl/finegrid)
59 allocate(xfi(numfl,ndim))
60 xfi(:,ndim)=xprobmin(ndim)+dl/50.d0
61 {
do ix^db=1,numl(^db)\}
65 ifl=ifl+(ix(j)-(ndim-1-j))*(numl(j))**(ndim-1-j)
67 xfi(ifl,1:ndim-1)=xprobmin(1:ndim-1)+finegrid*dl*ix(1:ndim-1)-finegrid*dl/2.d0
70 if(
mype .eq. 0)
write(*,*)
'NOTE: 2D TRAC method take the y-dir == grav-dir'
73 if(
mype .eq. 0)
write(*,*)
'NOTE: 3D TRAC method take the z-dir == grav-dir'
76 memxfi=floor(8*numfl*numlp*ndim/1e6)
77 if (
mype==0)
write(*,*)
'Memory requirement for each processor in TRAC:'
78 if (
mype==0)
write(*,*) memxfi,
' MB'
82 end subroutine init_trac_line
84 subroutine init_trac_block(mask)
85 logical,
intent(in) :: mask
86 integer :: refine_factor,finegrid,iFL,j
88 integer :: numL(ndim),ix(ndim)
89 double precision :: lengthFL
90 double precision :: ration,a0
91 double precision :: xprobmin(ndim),xprobmax(ndim),dxT(ndim)
93 refine_factor=2**(refine_max_level-1)
94 ^d&xprobmin(^d)=xprobmin^d\
95 ^d&xprobmax(^d)=xprobmax^d\
96 ^d&dxt^d=(xprobmax^d-xprobmin^d)/(domain_nx^d*refine_factor/block_nx^d)\
98 finegrid=mhd_trac_finegrid
103 dl=min(dxt^d)/finegrid
106 ^d&xtmin(^d)=xprobmin^d\
107 ^d&xtmax(^d)=xprobmax^d\
108 if(mask) xtmax(ndim)=phys_trac_mask
111 lengthfl=maxval(xtmax-xprobmin)*3.d0
113 lengthfl=maxval(xprobmax-xprobmin)*3.d0
115 numlp=floor(lengthfl/dl)
116 ^d&numxt^d=ceiling((xtmax(^d)-xtmin(^d)-smalldouble)/dxt^d)\
117 allocate(xt(numxt^d,ndim))
121 xt(j^d%ixT^s,^d)=(j-0.5d0)*dxt^d+xtmin(^d)
123 if(mask) xtmax(ndim)=maxval(xt(:^d&,ndim))+half*dxt(ndim)
128 numl(j)=floor((xprobmax(j)-xprobmin(j))/dl)
131 allocate(xfi(numfl,ndim))
132 xfi(:,ndim)=xprobmin(ndim)+dl/50.d0
133 {
do ix^db=1,numl(^db)\}
137 ifl=ifl+(ix(j)-(ndim-1-j))*(numl(j))**(ndim-1-j)
139 xfi(ifl,1:ndim-1)=xprobmin(1:ndim-1)+dl*ix(1:ndim-1)-dl/2.d0
142 if(mype .eq. 0)
write(*,*)
'NOTE: 2D TRAC method take the y-dir == grav-dir'
145 if(mype .eq. 0)
write(*,*)
'NOTE: 3D TRAC method take the z-dir == grav-dir'
147 end subroutine init_trac_block
149 subroutine trac_simple(tco_global,trac_alfa,T_peak)
150 double precision,
intent(in) :: tco_global, trac_alfa,T_peak
151 integer :: iigrid, igrid
153 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
155 ps(igrid)%special_values(1)=tco_global
157 if(ps(igrid)%special_values(1)<trac_alfa*ps(igrid)%special_values(2))
then
158 ps(igrid)%special_values(1)=trac_alfa*ps(igrid)%special_values(2)
160 if(ps(igrid)%special_values(1) .lt. t_bott)
then
161 ps(igrid)%special_values(1)=t_bott
162 else if(ps(igrid)%special_values(1) .gt. 0.2d0*t_peak)
then
163 ps(igrid)%special_values(1)=0.2d0*t_peak
165 ps(igrid)%wextra(ixg^t,iw_tcoff)=ps(igrid)%special_values(1)
167 ps(igrid)%special_values(2)=ps(igrid)%special_values(1)
169 end subroutine trac_simple
171 subroutine ltrac(T_peak)
172 double precision,
intent(in) :: T_peak
173 integer :: iigrid, igrid
174 integer :: ixO^L,trac_tcoff
178 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
179 where(ps(igrid)%wextra(ixo^s,trac_tcoff) .lt. t_bott)
180 ps(igrid)%wextra(ixo^s,trac_tcoff)=t_bott
181 else where(ps(igrid)%wextra(ixo^s,trac_tcoff) .gt. 0.2d0*t_peak)
182 ps(igrid)%wextra(ixo^s,trac_tcoff)=0.2d0*t_peak
187 subroutine tracl(mask,T_peak)
188 logical,
intent(in) :: mask
189 double precision,
intent(in) :: T_peak
191 integer :: iigrid, igrid
192 double precision :: xF(numFL,numLP,ndim)
193 integer :: numR(numFL),ix^L
194 double precision :: Tlcoff(numFL)
195 integer :: ipel(numFL,numLP),igridl(numFL,numLP)
196 logical :: forwardl(numFL)
205 call mpi_barrier(icomm,ierrmpi)
212 call get_btracing_dir(ipel,igridl,forwardl)
214 call get_tcoff_line(xf,numr,tlcoff,ipel,igridl,forwardl,mask)
216 call init_trac_tcoff()
220 call mpi_barrier(icomm,ierrmpi)
225 subroutine tracb(mask,T_peak)
226 logical,
intent(in) :: mask
227 double precision,
intent(in) :: T_peak
228 integer :: peArr(numxT^D),gdArr(numxT^D),numR(numFL)
229 double precision :: Tcoff(numxT^D),Tcmax(numxT^D),Bdir(numxT^D,ndim)
230 double precision :: xF(numFL,numLP,ndim),Tcoff_line(numFL)
231 integer :: xpe(numFL,numLP,2**ndim)
232 integer :: xgd(numFL,numLP,2**ndim)
240 call block_estable(mask,tcoff,tcmax,bdir,pearr,gdarr)
244 call block_trace_mfl(mask,tcoff,tcoff_line,tcmax,bdir,pearr,gdarr,xf,numr,xpe,xgd)
245 call block_interp_grid(mask,xf,numr,xpe,xgd,tcoff_line)
248 subroutine block_estable(mask,Tcoff,Tcmax,Bdir,peArr,gdArr)
250 double precision :: Tcoff(numxT^D),Tcoff_recv(numxT^D)
251 double precision :: Tcmax(numxT^D),Tcmax_recv(numxT^D)
252 double precision :: Bdir(numxT^D,ndim),Bdir_recv(numxT^D,ndim)
253 integer :: peArr(numxT^D),peArr_recv(numxT^D)
254 integer :: gdArr(numxT^D),gdArr_recv(numxT^D)
255 integer :: xc^L,xd^L,ix^D
256 integer :: iigrid,igrid,numxT,intab
257 double precision :: xb^L
265 xcmin^d=nghostcells+1\
266 xcmax^d=block_nx^d+nghostcells\
267 do iigrid=1,igridstail; igrid=igrids(iigrid);
268 ps(igrid)%wextra(:^d&,tweight_)=zero
269 ps(igrid)%wextra(:^d&,tcoff_)=zero
270 ^d&xbmin^d=rnode(rpxmin^d_,igrid)-xtmin(^d)\
271 ^d&xbmax^d=rnode(rpxmax^d_,igrid)-xtmin(^d)\
272 xdmin^d=nint(xbmin^d/dxt^d)+1\
273 xdmax^d=ceiling((xbmax^d-smalldouble)/dxt^d)\
274 {
do ix^d=xdmin^d,xdmax^d \}
276 {
if (ix^d .le. numxt^d) intab=intab+1 \}
277 if(intab .eq. ndim)
then
279 tcoff(ix^d)=max(tcoff(ix^d),ps(igrid)%special_values(1))
280 tcmax(ix^d)=ps(igrid)%special_values(2)
282 bdir(ix^d,1:ndim)=ps(igrid)%special_values(3:3+ndim-1)+2.d0
288 call mpi_barrier(icomm,ierrmpi)
290 call mpi_allreduce(pearr,pearr_recv,numxt,mpi_integer,&
291 mpi_max,icomm,ierrmpi)
292 call mpi_allreduce(gdarr,gdarr_recv,numxt,mpi_integer,&
293 mpi_max,icomm,ierrmpi)
294 call mpi_allreduce(tcoff,tcoff_recv,numxt,mpi_double_precision,&
295 mpi_max,icomm,ierrmpi)
296 call mpi_allreduce(bdir,bdir_recv,numxt*ndim,mpi_double_precision,&
297 mpi_max,icomm,ierrmpi)
299 call mpi_allreduce(tcmax,tcmax_recv,numxt,mpi_double_precision,&
300 mpi_max,icomm,ierrmpi)
306 if(.not. mask) tcmax=tcmax_recv
307 end subroutine block_estable
309 subroutine block_trace_mfl(mask,Tcoff,Tcoff_line,Tcmax,Bdir,peArr,gdArr,xF,numR,xpe,xgd)
310 integer :: i,j,k,k^D,ix_next^D
311 logical :: mask,flag,first
312 double precision :: Tcoff(numxT^D),Tcoff_line(numFL)
313 double precision :: Tcmax(numxT^D),Tcmax_line(numFL)
314 double precision :: xF(numFL,numLP,ndim)
315 integer :: ix_mod(ndim,2),numR(numFL)
316 double precision :: alfa_mod(ndim,2)
317 double precision :: nowpoint(ndim),nowgridc(ndim)
318 double precision :: Bdir(numxT^D,ndim)
319 double precision :: init_dir,now_dir1(ndim),now_dir2(ndim)
320 integer :: peArr(numxT^D),xpe(numFL,numLP,2**ndim)
321 integer :: gdArr(numxT^D),xgd(numFL,numLP,2**ndim)
325 ^d&k^d=ceiling((xfi(i,^d)-xtmin(^d)-smalldouble)/dxt^d)\
326 tcoff_line(i)=tcoff(k^d)
327 if(.not. mask) tcmax_line(i)=tcmax(k^d)
332 nowpoint(:)=xf(i,j,:)
333 nowgridc(:)=xt(ix_next^d,:)
336 call rk_bdir(nowgridc,nowpoint,ix_next^d,now_dir1,bdir,&
337 ix_mod,first,init_dir)
339 call rk_bdir(nowgridc,nowpoint,ix_next^d,now_dir1,bdir,&
343 xgd(i,j,1)=gdarr(ix_mod(1,1),ix_mod(2,1))
344 xgd(i,j,2)=gdarr(ix_mod(1,2),ix_mod(2,1))
345 xgd(i,j,3)=gdarr(ix_mod(1,1),ix_mod(2,2))
346 xgd(i,j,4)=gdarr(ix_mod(1,2),ix_mod(2,2))
347 xpe(i,j,1)=pearr(ix_mod(1,1),ix_mod(2,1))
348 xpe(i,j,2)=pearr(ix_mod(1,2),ix_mod(2,1))
349 xpe(i,j,3)=pearr(ix_mod(1,1),ix_mod(2,2))
350 xpe(i,j,4)=pearr(ix_mod(1,2),ix_mod(2,2))
353 xgd(i,j,1)=gdarr(ix_mod(1,1),ix_mod(2,1),ix_mod(3,1))
354 xgd(i,j,2)=gdarr(ix_mod(1,2),ix_mod(2,1),ix_mod(3,1))
355 xgd(i,j,3)=gdarr(ix_mod(1,1),ix_mod(2,2),ix_mod(3,1))
356 xgd(i,j,4)=gdarr(ix_mod(1,2),ix_mod(2,2),ix_mod(3,1))
357 xgd(i,j,5)=gdarr(ix_mod(1,1),ix_mod(2,1),ix_mod(3,2))
358 xgd(i,j,6)=gdarr(ix_mod(1,2),ix_mod(2,1),ix_mod(3,2))
359 xgd(i,j,7)=gdarr(ix_mod(1,1),ix_mod(2,2),ix_mod(3,2))
360 xgd(i,j,8)=gdarr(ix_mod(1,2),ix_mod(2,2),ix_mod(3,2))
361 xpe(i,j,1)=pearr(ix_mod(1,1),ix_mod(2,1),ix_mod(3,1))
362 xpe(i,j,2)=pearr(ix_mod(1,2),ix_mod(2,1),ix_mod(3,1))
363 xpe(i,j,3)=pearr(ix_mod(1,1),ix_mod(2,2),ix_mod(3,1))
364 xpe(i,j,4)=pearr(ix_mod(1,2),ix_mod(2,2),ix_mod(3,1))
365 xpe(i,j,5)=pearr(ix_mod(1,1),ix_mod(2,1),ix_mod(3,2))
366 xpe(i,j,6)=pearr(ix_mod(1,2),ix_mod(2,1),ix_mod(3,2))
367 xpe(i,j,7)=pearr(ix_mod(1,1),ix_mod(2,2),ix_mod(3,2))
368 xpe(i,j,8)=pearr(ix_mod(1,2),ix_mod(2,2),ix_mod(3,2))
370 nowpoint(:)=nowpoint(:)+init_dir*now_dir1*dl
371 {
if(nowpoint(^d) .gt. xtmax(^d) .or. nowpoint(^d) .lt. xtmin(^d))
then
374 if(mask .and. nowpoint(ndim) .gt. phys_trac_mask)
then
379 ^d&ix_next^d=ceiling((nowpoint(^d)-xtmin(^d)-smalldouble)/dxt^d)\
380 nowgridc(:)=xt(ix_next^d,:)
381 call rk_bdir(nowgridc,nowpoint,ix_next^d,now_dir2,bdir,&
383 xf(i,j+1,:)=xf(i,j,:)+init_dir*dl*half*(now_dir1+now_dir2)
384 {
if(xf(i,j+1,^d) .gt. xtmax(^d) .or. xf(i,j+1,^d) .lt. xtmin(^d))
then
387 if(mask .and. xf(i,j+1,ndim) .gt. phys_trac_mask)
then
391 ^d&ix_next^d=ceiling((xf(i,j+1,^d)-xtmin(^d)-smalldouble)/dxt^d)\
393 tcoff_line(i)=max(tcoff_line(i),tcoff(ix_next^d))
394 if(.not.mask) tcmax_line(i)=max(tcmax_line(i),tcmax(ix_next^d))
400 if(tcoff_line(i) .gt. tmax*0.2d0)
then
401 tcoff_line(i)=tmax*0.2d0
404 if(tcoff_line(i) .gt. tcmax_line(i)*0.2d0)
then
405 tcoff_line(i)=tcmax_line(i)*0.2d0
409 end subroutine block_trace_mfl
411 subroutine rk_bdir(nowgridc,nowpoint,ix_next^D,now_dir,Bdir,ix_mod,first,init_dir)
412 double precision :: nowpoint(ndim),nowgridc(ndim)
413 integer :: ix_mod(ndim,2)
414 double precision :: alfa_mod(ndim,2)
415 integer :: ix_next^D,k^D
416 double precision :: now_dir(ndim)
417 double precision :: Bdir(numxT^D,ndim)
419 double precision,
optional :: init_dir
421 {
if(nowpoint(^d) .gt. xtmin(^d)+half*dxt^d .and. nowpoint(^d) .lt. xtmax(^d)-half*dxt^d)
then
422 if(nowpoint(^d) .le. nowgridc(^d))
then
423 ix_mod(^d,1)=ix_next^d-1
424 ix_mod(^d,2)=ix_next^d
425 alfa_mod(^d,1)=abs(nowgridc(^d)-nowpoint(^d))/dxt^d
426 alfa_mod(^d,2)=one-alfa_mod(^d,1)
428 ix_mod(^d,1)=ix_next^d
429 ix_mod(^d,2)=ix_next^d+1
430 alfa_mod(^d,2)=abs(nowgridc(^d)-nowpoint(^d))/dxt^d
431 alfa_mod(^d,1)=one-alfa_mod(^d,2)
434 ix_mod(^d,:)=ix_next^d
441 now_dir=now_dir + bdir(ix_mod(1,k1),ix_mod(2,k2),:)*alfa_mod(1,k1)*alfa_mod(2,k2)
449 now_dir=now_dir + bdir(ix_mod(1,k1),ix_mod(2,k2),ix_mod(3,k3),:)&
450 *alfa_mod(1,k1)*alfa_mod(2,k2)*alfa_mod(3,k3)
455 if(
present(init_dir))
then
456 init_dir=sign(one,now_dir(ndim))
458 end subroutine rk_bdir
460 subroutine block_interp_grid(mask,xF,numR,xpe,xgd,Tcoff_line)
462 double precision :: xF(numFL,numLP,ndim)
463 integer :: numR(numFL)
464 integer :: xpe(numFL,numLP,2**ndim)
465 integer :: xgd(numFL,numLP,2**ndim)
466 double precision :: Tcoff_line(numFL)
467 double precision :: weightIndex,weight,ds
468 integer :: i,j,k,igrid,iigrid,ixO^L,ixc^L,ixc^D
469 double precision :: dxMax^D,dxb^D
478 if(mype .eq. xpe(i,j,k))
then
480 if(igrid .le. igrids(igridstail))
then
481 ^d&dxb^d=rnode(rpdx^d_,igrid)\
482 ^d&ixcmin^d=floor((xf(i,j,^d)-dxmax^d-ps(igrid)%x(ixomin^dd,^d))/dxb^d)+ixomin^d\
483 ^d&ixcmax^d=floor((xf(i,j,^d)+dxmax^d-ps(igrid)%x(ixomin^dd,^d))/dxb^d)+ixomin^d\
484 {
if (ixcmin^d<ixomin^d) ixcmin^d=ixomin^d\}
485 {
if (ixcmax^d>ixomax^d) ixcmax^d=ixomax^d\}
486 {
do ixc^d=ixcmin^d,ixcmax^d\}
488 {ds=ds+(xf(i,j,^d)-ps(igrid)%x(ixc^dd,^d))**2\}
490 if(ds .le. 0.099d0*dl)
then
491 weight=(1/(0.099d0*dl))**weightindex
493 weight=(1/ds)**weightindex
495 ps(igrid)%wextra(ixc^d,tweight_)=ps(igrid)%wextra(ixc^d,tweight_)+weight
496 ps(igrid)%wextra(ixc^d,tcoff_)=ps(igrid)%wextra(ixc^d,tcoff_)+weight*tcoff_line(i)
499 call mpistop(
"we need to check here 366Line in mod_trac.t")
506 do iigrid=1,igridstail; igrid=igrids(iigrid);
507 where (ps(igrid)%wextra(ixo^s,tweight_)>0.d0)
508 ps(igrid)%wextra(ixo^s,tcoff_)=ps(igrid)%wextra(ixo^s,tcoff_)/ps(igrid)%wextra(ixo^s,tweight_)
510 ps(igrid)%wextra(ixo^s,tcoff_)=0.2d0*tmax
513 end subroutine block_interp_grid
528 subroutine init_trac_tcoff()
529 integer :: ixI^L,ixO^L,igrid,iigrid
534 do iigrid=1,igridstail; igrid=igrids(iigrid);
535 ps(igrid)%wextra(ixi^s,tcoff_)=0.d0
536 ps(igrid)%wextra(ixi^s,tweight_)=0.d0
539 end subroutine init_trac_tcoff
541 subroutine update_pegrid()
550 call traverse_gridtable()
552 end subroutine update_pegrid
554 subroutine traverse_gridtable()
557 double precision :: dxb^D,xb^L
558 integer :: iigrid,igrid,j
559 logical,
allocatable :: trac_pe_recv(:)
560 double precision :: hcmax_bt
562 allocate(trac_pe_recv(
npe))
566 do iigrid=1,igridstail; igrid=igrids(iigrid);
570 ngrid_trac=ngrid_trac+1
571 trac_grid(ngrid_trac)=igrid
572 if (xbmin^nd<hcmax_bt)
then
573 ngrid_ground=ngrid_ground+1
574 ground_grid(ngrid_ground)=igrid
579 call mpi_allreduce(trac_pe,trac_pe_recv,
npe,mpi_logical,mpi_lor,
icomm,
ierrmpi)
582 deallocate(trac_pe_recv)
584 end subroutine traverse_gridtable
587 integer :: ixI^L,ixO^L,igrid,iigrid,j
595 call mhd_get_pthermal(ps(igrid)%w,ps(igrid)%x,ixi^l,ixi^l,ps(igrid)%wextra(ixi^s,tcoff_))
597 if(has_equi_rho0)
then
598 ps(igrid)%wextra(ixi^s,tcoff_)=ps(igrid)%wextra(ixi^s,tcoff_)/&
599 (ps(igrid)%w(ixi^s,rho_) + ps(igrid)%equi_vars(ixi^s,equi_rho0_,0))
601 ps(igrid)%wextra(ixi^s,tcoff_)=ps(igrid)%wextra(ixi^s,tcoff_)/ps(igrid)%w(ixi^s,rho_)
607 subroutine get_btracing_dir(ipel,igridl,forwardl)
608 integer :: ipel(numFL,numLP),igridl(numFL,numLP)
609 logical :: forwardl(numFL)
611 integer :: igrid,ixO^L,iFL,j,ix^D,idir,ixb^D,ixbb^D
612 double precision :: xb^L,dxb^D,xd^D,factor,Bh
613 integer :: numL(ndim),ixmin(ndim),ixmax(ndim),ix(ndim)
614 logical :: forwardRC(numFL)
625 ^d&dxb^d=rnode(rpdx^d_,igrid);
626 ^d&xbmin^d=rnode(rpxmin^d_,igrid);
627 ^d&xbmax^d=rnode(rpxmax^d_,igrid);
628 ^d&ixmin(^d)=floor((xbmin^d-xprobmin^d)/(mhd_trac_finegrid*dl))+1;
629 ^d&ixmax(^d)=floor((xbmax^d-xprobmin^d)/(mhd_trac_finegrid*dl));
630 ^d&numl(^d)=floor((xprobmax^d-xprobmin^d)/(mhd_trac_finegrid*dl));
635 {
do ix^db=ixmin(^db),ixmax(^db)\}
639 ifl=ifl+(ix(idir)-(ndim-1-idir))*(numl(idir))**(ndim-1-idir)
644 ^d&ixb^d=floor((xfi(ifl,^d)-ps(igrid)%x(ixomin^dd,^d))/dxb^d)+ixomin^d;
645 ^d&xd^d=(xfi(ifl,^d)-ps(igrid)%x(ixb^dd,^d))/dxb^d;
648 factor={abs(1-ix^d-xd^d)*}
650 bh=bh+factor*(ps(igrid)%w(ixb^d+ixbb^d,mag(^nd))+ps(igrid)%B0(ixb^d+ixbb^d,^nd,0))
652 bh=bh+factor*ps(igrid)%w(ixb^d+ixbb^d,mag(^nd))
658 forwardl(ifl)=.false.
663 call mpi_allreduce(forwardl,forwardrc,numfl,mpi_logical,&
664 mpi_land,icomm,ierrmpi)
667 end subroutine get_btracing_dir
669 subroutine get_tcoff_line(xFL,numR,TcoffFL,ipeFL,igridFL,forwardFL,mask)
672 double precision :: xFL(numFL,numLP,ndim)
673 integer :: numR(numFL)
674 double precision :: TcoffFL(numFL),TmaxFL(numFL)
675 integer :: ipeFL(numFL,numLP),igridFL(numFL,numLP)
676 logical :: forwardFL(numFL)
677 logical,
intent(in) :: mask
679 integer :: nwP,nwL,iFL,iLP
680 double precision :: wPm(numFL,numLP,2),wLm(numFL,1+2)
681 character(len=std_len) :: ftype,tcondi
687 call trace_field_multi(xfl,wpm,wlm,dl,numfl,numlp,nwp,nwl,forwardfl,ftype,tcondi)
689 numr(ifl)=int(wlm(ifl,1))
690 tcofffl(ifl)=wlm(ifl,2)
691 tmaxfl(ifl)=wlm(ifl,3)
693 if(tcofffl(ifl)>0.2d0*tmax) tcofffl(ifl)=0.2d0*tmax
695 tmaxfl(ifl)=wlm(ifl,3)
696 if(tcofffl(ifl)>0.2d0*tmaxfl(ifl)) tcofffl(ifl)=0.2d0*tmaxfl(ifl)
699 if(tcofffl(ifl)<t_bott) tcofffl(ifl)=t_bott
703 if (numr(ifl)>0)
then
705 ipefl(ifl,ilp)=int(wpm(ifl,ilp,1))
706 igridfl(ifl,ilp)=int(wpm(ifl,ilp,2))
712 end subroutine get_tcoff_line
715 double precision :: xF(numFL,numLP,ndim)
716 integer :: numR(numFL),ipel(numFL,numLP),igridl(numFL,numLP)
717 double precision :: Tlcoff(numFL)
719 integer :: iFL,iLP,ixO^L,ixI^L,ixc^L,ixb^L,ixc^D
720 integer :: igrid,j,ipmin,ipmax,igrid_nb
721 double precision :: dxb^D,dxMax^D,xb^L,Tcnow
722 double precision :: xFnow(ndim)
723 integer :: weightIndex,idn^D,ixmax^ND
724 double precision :: ds,weight
736 do while (ilp<=numr(ifl))
739 do while (ipel(ifl,ipmin)/=mype .and. ipmin<=numr(ifl))
742 igrid=igridl(ifl,ipmin)
744 do while (ipel(ifl,ipmax)==mype .and. igridl(ifl,ipmax+1)==igrid .and. ipmax<numr(ifl))
749 ^d&dxb^d=rnode(rpdx^d_,igrid);
753 xfnow(:)=xf(ifl,ilp,:)
754 ^d&ixbmin^d=floor((xfnow(^d)-dxmax^d-ps(igrid)%x(ixomin^dd,^d))/dxb^d)+ixomin^d;
755 ^d&ixbmax^d=floor((xfnow(^d)+dxmax^d-ps(igrid)%x(ixomin^dd,^d))/dxb^d)+ixomin^d;
758 {ixcmin^d=max(ixbmin^d,ixomin^d)\}
759 {ixcmax^d=min(ixbmax^d,ixomax^d)\}
760 xbmin^nd=rnode(rpxmin^nd_,igrid)
761 xbmax^nd=rnode(rpxmax^nd_,igrid)
762 ixmax^nd=floor((phys_trac_mask-xbmin^nd)/dxb^nd)+ixomin^nd
763 if (xbmax^nd>phys_trac_mask) ixcmax^nd=min(ixmax^nd,ixcmax^nd)
764 {
do ixc^d=ixcmin^d,ixcmax^d\}
766 {ds=ds+(xfnow(^d)-ps(igrid)%x(ixc^dd,^d))**2\}
768 if(ds<1.0d-2*dxb1)
then
769 weight=(1/(1.0d-2*dxb1))**weightindex
771 weight=(1/ds)**weightindex
773 ps(igrid)%wextra(ixc^d,tweight_)=ps(igrid)%wextra(ixc^d,tweight_)+weight
774 ps(igrid)%wextra(ixc^d,tcoff_)=ps(igrid)%wextra(ixc^d,tcoff_)+weight*tcnow
779 if (ixbmin^d<ixomin^d)
then
782 if (neighbor(2,idn^dd,igrid)==mype .and. neighbor_type(idn^dd,igrid)==neighbor_sibling)
then
783 igrid_nb=neighbor(1,idn^dd,igrid)
784 ixcmin^dd=max(ixbmin^dd,ixomin^dd);
785 ixcmax^dd=min(ixbmax^dd,ixomax^dd);
786 ixcmin^d=ixomax^d+(ixbmin^d-ixomin^d)
788 xbmin^nd=rnode(rpxmin^nd_,igrid_nb)
789 xbmax^nd=rnode(rpxmax^nd_,igrid_nb)
790 ixmax^nd=floor((phys_trac_mask-xbmin^nd)/dxb^nd)+ixomin^nd
791 if (xbmax^nd>phys_trac_mask) ixcmax^nd=min(ixmax^nd,ixcmax^nd)
793 {
do ixc^dd=ixcmin^dd,ixcmax^dd;}
795 {ds=ds+(xfnow(^dd)-ps(igrid_nb)%x({ixc^dd},^dd))**2;}
797 if(ds<1.0d-2*dxb1)
then
798 weight=(1/(1.0d-2*dxb1))**weightindex
800 weight=(1/ds)**weightindex
802 ps(igrid_nb)%wextra(ixc^dd,tweight_)=ps(igrid_nb)%wextra(ixc^dd,tweight_)+weight
803 ps(igrid_nb)%wextra(ixc^dd,tcoff_)=ps(igrid_nb)%wextra(ixc^dd,tcoff_)+weight*tcnow
808 if (ixbmax^d>ixomin^d)
then
811 if (neighbor(2,idn^dd,igrid)==mype .and. neighbor_type(idn^dd,igrid)==neighbor_sibling)
then
812 igrid_nb=neighbor(1,idn^dd,igrid)
813 xbmin^nd=rnode(rpxmin^nd_,igrid_nb)
814 if (xbmin^nd<phys_trac_mask)
then
815 ixcmin^dd=max(ixbmin^dd,ixomin^dd);
816 ixcmax^dd=min(ixbmax^dd,ixomax^dd);
818 ixcmax^d=ixomin^d+(ixbmax^d-ixomax^d)
819 xbmax^nd=rnode(rpxmax^nd_,igrid_nb)
820 ixmax^nd=floor((phys_trac_mask-xbmin^nd)/dxb^nd)+ixomin^nd
821 if (xbmax^nd>phys_trac_mask) ixcmax^nd=min(ixmax^nd,ixcmax^nd)
823 {
do ixc^dd=ixcmin^dd,ixcmax^dd;}
825 {ds=ds+(xfnow(^dd)-ps(igrid_nb)%x({ixc^dd},^dd))**2;}
827 if(ds<1.0d-2*dxb1)
then
828 weight=(1/(1.0d-2*dxb1))**weightindex
830 weight=(1/ds)**weightindex
832 ps(igrid_nb)%wextra(ixc^dd,tweight_)=ps(igrid_nb)%wextra(ixc^dd,tweight_)+weight
833 ps(igrid_nb)%wextra(ixc^dd,tcoff_)=ps(igrid_nb)%wextra(ixc^dd,tcoff_)+weight*tcnow
848 where(ps(igrid)%wextra(ixo^s,tweight_)>0.d0)
849 ps(igrid)%wextra(ixo^s,tcoff_)=ps(igrid)%wextra(ixo^s,tcoff_)/ps(igrid)%wextra(ixo^s,tweight_)
851 ps(igrid)%wextra(ixo^s,tcoff_)=t_bott
858 subroutine trac_after_setdt(tco,trac_alfa,T_peak, T_bott_in)
859 double precision,
intent(in) :: trac_alfa,tco,T_peak, T_bott_in
862 select case(phys_trac_type)
868 call trac_simple(tco,trac_alfa,t_peak)
875 call tracl(.false.,t_peak)
878 call tracb(.false.,t_peak)
881 call tracl(.true.,t_peak)
884 call tracb(.true.,t_peak)
886 call mpistop(
"undefined TRAC method type")
889 end subroutine trac_after_setdt
898 if(
mype .eq. 0)
write(*,*)
'Using TRACL(ine) global method'
899 if(
mype .eq. 0)
write(*,*)
'By default, magnetic field lines are traced every 4 grid cells'
900 call init_trac_line(.false.)
903 if(
mype .eq. 0)
write(*,*)
'Using TRACB(lock) global method'
904 if(
mype .eq. 0)
write(*,*)
'Currently, only valid in Cartesian uniform settings'
905 if(
mype .eq. 0)
write(*,*)
'By default, magnetic field lines are traced every 4 grid cells'
906 call init_trac_block(.false.)
909 if(
mype .eq. 0)
write(*,*)
'Using TRACL(ine) method with a mask'
910 if(
mype .eq. 0)
write(*,*)
'By default, magnetic field lines are traced every 4 grid cells'
911 call init_trac_line(.true.)
914 if(
mype .eq. 0)
write(*,*)
'Using TRACB(lock) method with a mask'
915 if(
mype .eq. 0)
write(*,*)
'Currently, only valid in Cartesian uniform settings'
916 if(
mype .eq. 0)
write(*,*)
'By default, magnetic field lines are traced every 4 grid cells'
917 call init_trac_block(.true.)
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer domain_nx
number of cells for each dimension in level-one mesh
double precision phys_trac_mask
integer, parameter rpxmin
integer icomm
The MPI communicator.
integer mype
The rank of the current MPI task.
integer ierrmpi
A global MPI error return code.
integer npe
The number of MPI tasks.
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
logical phys_trac
Use TRAC (Johnston 2019 ApJL, 873, L22) for MHD or 1D HD.
integer refine_max_level
Maximal number of AMR levels.
integer max_blocks
The maximum number of grid blocks in a processor.
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_trac_after_setdt), pointer phys_trac_after_setdt
subroutine interp_tcoff(xF, ipel, igridl, numR, Tlcoff)
subroutine, public initialize_trac_after_settree
subroutine trace_field_multi(xfm, wPm, wLm, dL, numL, numP, nwP, nwL, forwardm, ftype, tcondi)