19 double precision,
public ::
afld_mu = 0.6d0
72 double precision,
private,
protected :: afld_gamma
98 character(len=*),
intent(in) :: files(:)
107 do n = 1,
size(files)
108 open(
unitpar, file=trim(files(n)), status=
"old")
109 read(
unitpar, fld_list,
end=111)
121 subroutine afld_init(He_abundance, rhd_radiation_diffusion, afld_gamma)
128 double precision,
intent(in) :: he_abundance, afld_gamma
129 logical,
intent(in) :: rhd_radiation_diffusion
130 double precision :: sigma_thomson
133 character(len=1) :: ind_1
134 character(len=1) :: ind_2
135 character(len=2) :: cmp_f
136 character(len=5) :: cmp_e
139 call mpistop(
"Anisotropic in 1D... really?")
165 if (rhd_radiation_diffusion)
then
174 mg%operator_type = mg_ahelmholtz
181 write(ind_1,
'(I1)') idir
187 afld_mu = (1.+4*he_abundance)/(2.+3.*he_abundance)
203 energy,qsourcesplit,active)
209 integer,
intent(in) :: ixi^
l, ixo^
l
210 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
211 double precision,
intent(in) :: wct(ixi^s,1:nw)
212 double precision,
intent(inout) :: w(ixi^s,1:nw)
213 logical,
intent(in) :: energy,qsourcesplit
214 logical,
intent(inout) :: active
216 double precision :: radiation_forcect(ixo^s,1:
ndim)
217 double precision :: kappact(ixo^s,1:
ndim)
218 double precision :: rad_fluxct(ixo^s,1:
ndim)
220 double precision :: div_v(ixi^s,1:
ndim,1:
ndim)
221 double precision :: edd(ixo^s,1:
ndim,1:
ndim)
222 double precision :: nabla_vp(ixo^s)
223 double precision :: vel(ixi^s), grad_v(ixi^s), grad0_v(ixo^s)
224 double precision :: grad_e(ixo^s)
226 integer :: idir, jdir
228 double precision :: fld_r(ixo^s,1:
ndim), lambda(ixo^s,1:
ndim)
240 radiation_forcect(ixo^s,idir) = kappact(ixo^s,idir)*rad_fluxct(ixo^s,idir)/(
const_c/
unit_velocity)
246 w(ixo^s,iw_mom(idir)) = w(ixo^s,iw_mom(idir)) &
247 + qdt * wct(ixo^s,iw_rho)*radiation_forcect(ixo^s,idir)
253 w(ixo^s,iw_e) = w(ixo^s,iw_e) &
254 + qdt * wct(ixo^s,iw_mom(idir))*radiation_forcect(ixo^s,idir)
265 vel(ixi^s) = wct(ixi^s,iw_mom(jdir))/wct(ixi^s,iw_rho)
268 div_v(ixo^s,idir,jdir) = grad_v(ixo^s)
280 nabla_vp(ixo^s) = div_v(ixo^s,1,1)*edd(ixo^s,1,1) &
285 nabla_vp(ixo^s) = div_v(ixo^s,1,1)*edd(ixo^s,1,1) &
286 + div_v(ixo^s,1,2)*edd(ixo^s,1,2) &
287 + div_v(ixo^s,2,1)*edd(ixo^s,2,1) &
288 + div_v(ixo^s,2,2)*edd(ixo^s,2,2)
292 nabla_vp(ixo^s) = div_v(ixo^s,1,1)*edd(ixo^s,1,1) &
293 + div_v(ixo^s,1,2)*edd(ixo^s,1,2) &
294 + div_v(ixo^s,1,3)*edd(ixo^s,1,3) &
295 + div_v(ixo^s,2,1)*edd(ixo^s,2,1) &
296 + div_v(ixo^s,2,2)*edd(ixo^s,2,2) &
297 + div_v(ixo^s,2,3)*edd(ixo^s,2,3) &
298 + div_v(ixo^s,3,1)*edd(ixo^s,3,1) &
299 + div_v(ixo^s,3,2)*edd(ixo^s,3,2) &
300 + div_v(ixo^s,3,3)*edd(ixo^s,3,3)
303 w(ixo^s,iw_r_e) = w(ixo^s,iw_r_e) &
304 - qdt * nabla_vp(ixo^s)*wct(ixo^s,iw_r_e)
315 integer,
intent(in) :: ixi^
l, ixo^
l
316 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim), w(ixi^s,1:nw)
317 double precision,
intent(inout) :: dtnew
319 double precision :: radiation_force(ixo^s,1:
ndim)
320 double precision :: rad_flux(ixo^s,1:
ndim)
321 double precision :: kappa(ixo^s,1:
ndim)
322 double precision :: dxinv(1:
ndim), max_grad
325 ^
d&dxinv(^
d)=one/
dx^
d;
331 radiation_force(ixo^s,idim) = w(ixo^s,iw_rho)*kappa(ixo^s,idim)*rad_flux(ixo^s,idim)/(const_c/
unit_velocity)
332 max_grad = maxval(abs(radiation_force(ixo^s,idim)))
333 max_grad = max(max_grad, epsilon(1.0d0))
334 dtnew = min(dtnew,
courantpar / sqrt(max_grad * dxinv(idim)))
342 energy,qsourcesplit,active)
349 integer,
intent(in) :: ixi^
l, ixo^
l
350 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
351 double precision,
intent(in) :: wct(ixi^s,1:nw)
352 double precision,
intent(inout) :: w(ixi^s,1:nw)
353 logical,
intent(in) :: energy,qsourcesplit
354 logical,
intent(inout) :: active
373 integer,
intent(in) :: ixi^
l, ixo^
l
374 double precision,
intent(in) :: w(ixi^s, 1:nw)
375 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
376 double precision,
intent(out) :: fld_kappa(ixo^s,1:
ndim)
377 double precision :: temp(ixi^s), pth(ixi^s), a2(ixo^s)
378 double precision :: rho0,temp0,n,sigma_b
379 double precision :: akram, bkram
380 double precision :: vth(ixo^s), gradv(ixi^s), eta(ixo^s), t(ixo^s)
382 integer :: i,j,ix^
d, idim
400 fld_kappa(ixo^s,idim) =
fld_kappa0/
unit_opacity*(one + n*dexp(-one/sigma_b*(dlog(w(ixo^s,iw_rho)/rho0))**two))
402 call phys_get_pthermal(w,x,ixi^
l,ixo^
l,temp)
403 temp(ixo^s)=temp(ixo^s)/w(ixo^s,iw_rho)
410 call phys_get_pthermal(w,x,ixi^
l,ixo^
l,pth)
413 akram = 13.1351597305
414 bkram = -4.5182188206
417 * (1.d0+10.d0**akram*w(ixo^s,iw_rho)*
unit_density*(a2(ixo^s)/1.d12)**bkram)
419 {
do ix^
d=ixomin^
d,ixomax^
d\ }
431 {
do ix^
d=ixomin^
d,ixomax^
d\ }
440 call mpistop(
"special opacity not defined")
445 call mpistop(
"Doesn't know opacity law")
461 integer,
intent(in) :: ixi^
l, ixo^
l
462 double precision,
intent(in) :: w(ixi^s, 1:nw)
463 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
464 double precision,
intent(out) :: fld_r(ixo^s,1:
ndim), fld_lambda(ixo^s,1:
ndim)
465 double precision :: kappa(ixo^s,1:
ndim)
466 double precision :: normgrad2(ixo^s)
467 double precision :: grad_r_e(ixi^s), grad_r_eo(ixo^s)
468 double precision :: rad_e(ixi^s)
469 integer :: idir, ix^
d
471 double precision :: tmp_l(ixi^s), filtered_l(ixi^s)
472 integer :: filter, idim
476 fld_lambda(ixo^s,1:
ndim) = 1.d0/3.d0
477 fld_r(ixo^s,1:
ndim) = zero
482 rad_e(ixi^s) = w(ixi^s, iw_r_e)
488 normgrad2(ixo^s) = grad_r_eo(ixo^s)**2
495 fld_r(ixo^s,idir) = dsqrt(normgrad2(ixo^s))/(kappa(ixo^s,idir)*w(ixo^s,iw_rho)*w(ixo^s,iw_r_e))
498 fld_lambda(ixo^s,idir) = one/fld_r(ixo^s,idir)
506 normgrad2(ixo^s) = 0.d0
508 rad_e(ixi^s) = w(ixi^s, iw_r_e)
514 normgrad2(ixo^s) = grad_r_eo(ixo^s)**2
520 fld_r(ixo^s,idir) = dsqrt(normgrad2(ixo^s))/(kappa(ixo^s,idir)*w(ixo^s,iw_rho)*w(ixo^s,iw_r_e))
524 fld_lambda(ixo^s,idir) = (2.d0+fld_r(ixo^s,idir))/(6.d0+3*fld_r(ixo^s,idir)+fld_r(ixo^s,idir)**2.d0)
531 normgrad2(ixo^s) = 0.d0
533 rad_e(ixi^s) = w(ixi^s, iw_r_e)
539 normgrad2(ixo^s) = grad_r_eo(ixo^s)**2
546 fld_r(ixo^s,idir) = dsqrt(normgrad2(ixo^s))/(kappa(ixo^s,idir)*w(ixo^s,iw_rho)*w(ixo^s,iw_r_e))
550 {
do ix^
d=ixomin^
d,ixomax^
d\ }
551 if (fld_r(ix^
d,idir) .lt. 3.d0/2.d0)
then
552 fld_lambda(ix^
d,idir) = 2.d0/(3.d0 + dsqrt(9.d0 + 12.d0*fld_r(ix^
d,idir)**2.d0))
554 fld_lambda(ix^
d,idir) = 1.d0/(1.d0 + fld_r(ix^
d,idir) + dsqrt(1.d0 + 2.d0*fld_r(ix^
d,idir)))
562 call mpistop(
"special fluxlimiter not defined")
566 call mpistop(
'Fluxlimiter unknown')
576 tmp_l(ixo^s) = fld_lambda(ixo^s, idir)
577 filtered_l(ixo^s) = zero
582 filtered_l(ix^
d) = filtered_l(ix^
d) &
583 + tmp_l(ix^
d+filter*
kr(idim,^
d)) &
584 + tmp_l(ix^
d-filter*
kr(idim,^
d))
595 fld_lambda(ixo^s,idir) = tmp_l(ixo^s)
606 integer,
intent(in) :: ixi^
l, ixo^
l
607 double precision,
intent(in) :: w(ixi^s, 1:nw)
608 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
609 double precision,
intent(out) :: rad_flux(ixo^s, 1:
ndim)
611 double precision :: grad_r_e(ixi^s), grad_r_eo(ixo^s)
612 double precision :: rad_e(ixi^s)
613 double precision :: kappa(ixo^s,1:
ndim), lambda(ixo^s,1:
ndim), fld_r(ixo^s,1:
ndim)
614 integer :: ix^
d, idir
616 rad_e(ixi^s) = w(ixi^s, iw_r_e)
625 rad_flux(ixo^s, idir) = -(const_c/
unit_velocity)*lambda(ixo^s,idir)/(kappa(ixo^s,idir)*w(ixo^s,iw_rho))*grad_r_eo(ixo^s)
639 integer,
intent(in) :: ixI^L, ixO^L
640 double precision,
intent(in) :: w(ixI^S, 1:nw)
641 double precision,
intent(in) :: x(ixI^S, 1:ndim)
642 double precision,
intent(out) :: eddington_tensor(ixO^S,1:ndim,1:ndim)
643 double precision :: tnsr2(ixO^S,1:ndim,1:ndim)
644 double precision :: normgrad2(ixO^S), f(ixO^S,1:ndim)
645 double precision :: grad_r_e(ixI^S, 1:ndim), rad_e(ixI^S)
646 double precision :: grad_r_eO(ixO^S, 1:ndim)
647 double precision :: lambda(ixO^S,1:ndim), fld_R(ixO^S,1:ndim)
648 integer :: i,j, idir,jdir
654 normgrad2(ixo^s) = zero
656 rad_e(ixi^s) = w(ixi^s, iw_r_e)
659 normgrad2(ixo^s) = normgrad2(ixo^s) + grad_r_eo(ixo^s,idir)**2
666 f(ixo^s,idir) = lambda(ixo^s,idir) + lambda(ixo^s,idir)**two * fld_r(ixo^s,idir)**two
667 f(ixo^s,idir) = one/two*(one-f(ixo^s,idir)) + one/two*(3.d0*f(ixo^s,idir) - one)
673 eddington_tensor(ixo^s,1,1) = f(ixo^s,1)
678 eddington_tensor(ixo^s,idir,idir) = half*(one-f(ixo^s,idir))
683 if (idir .ne. jdir) eddington_tensor(ixo^s,idir,jdir) = zero
684 tnsr2(ixo^s,idir,jdir) = half*(3.d0*f(ixo^s,idir) - 1)&
685 *grad_r_eo(ixo^s,idir)*grad_r_eo(ixo^s,jdir)/normgrad2(ixo^s)
699 where ((tnsr2(ixo^s,idir,jdir) .eq. tnsr2(ixo^s,idir,jdir)) &
700 .and. (normgrad2(ixo^s) .gt. smalldouble))
701 eddington_tensor(ixo^s,idir,jdir) = eddington_tensor(ixo^s,idir,jdir) + tnsr2(ixo^s,idir,jdir)
714 integer,
intent(in) :: ixi^
l, ixo^
l
715 double precision,
intent(in) :: w(ixi^s, 1:nw)
716 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
717 double precision :: eddington_tensor(ixo^s,1:
ndim,1:
ndim)
718 double precision,
intent(out):: rad_pressure(ixo^s,1:
ndim,1:
ndim)
726 rad_pressure(ixo^s,i,j) = eddington_tensor(ixo^s,i,j)* w(ixo^s,iw_r_e)
1074 type(state),
target :: psa(max_blocks)
1075 type(state),
target :: psb(max_blocks)
1076 double precision,
intent(in) :: qdt
1077 double precision,
intent(in) :: qtC
1078 double precision,
intent(in) :: dtfactor
1081 double precision :: res, max_residual, lambda
1082 integer,
parameter :: max_its = 50
1084 integer :: iw_to,iw_from
1085 integer :: iigrid, igrid, id
1086 integer :: nc, lvl, i
1088 real(dp) :: fac, facD
1096 if (qdt <
dtmin)
then
1098 print *,
'skipping implicit solve: dt too small!'
1106 mg%operator_type = mg_ahelmholtz
1107 mg%smoother_type = mg_smoother_gsrb
1108 call mg_set_methods(
mg)
1110 if (.not.
mg%is_allocated)
call mpistop(
"multigrid tree not allocated yet")
1113 lambda = 1.d0/(dtfactor *
dt_diff)
1114 call ahelmholtz_set_lambda(lambda)
1126 call mg_restrict(
mg, mg_iveps)
1127 call mg_fill_ghost_cells(
mg, mg_iveps)
1136 call mg_restrict(
mg, mg_iveps1)
1137 call mg_fill_ghost_cells(
mg, mg_iveps1)
1139 call mg_restrict(
mg, mg_iveps2)
1140 call mg_fill_ghost_cells(
mg, mg_iveps2)
1154 call mg_fas_fmg(
mg, .true., max_res=res)
1157 if (res < max_residual)
exit
1158 call mg_fas_vcycle(
mg, max_res=res)
1161 if (res .le. 0.d0)
then
1163 if (
mg%my_rank == 0) &
1164 write(*,*)
it,
' resiudal zero ', res
1167 if (
mg%my_rank == 0)
then
1169 error stop
"Diffusion residual to zero"
1173 if (n == max_its + 1)
then
1175 if (
mg%my_rank == 0) &
1176 write(*,*)
it,
' resiudal high ', res
1179 if (
mg%my_rank == 0)
then
1180 print *,
"Did you specify boundary conditions correctly?"
1181 print *,
"Or is the variation in diffusion too large?"
1183 print *,
mg%bc(1, mg_iphi)%bc_value,
mg%bc(2, mg_iphi)%bc_value
1185 error stop
"diffusion_solve: no convergence"
1206 type(state),
target :: psa(max_blocks)
1207 double precision,
intent(in) :: qtC
1209 integer :: iigrid, igrid, level
1216 do iigrid=1,igridstail; igrid=igrids(iigrid);
1231 integer,
intent(in) :: ixI^L, ixO^L
1232 double precision,
intent(inout) :: w(ixI^S, 1:nw)
1234 double precision :: gradE(ixO^S),divF(ixO^S)
1235 double precision :: divF_h(ixO^S),divF_j(ixO^S)
1236 double precision :: diff_term(ixO^S)
1238 integer :: idir, jxO^L, hxO^L
1244 hxo^l=ixo^l-
kr(idir,^
d);
1245 jxo^l=ixo^l+
kr(idir,^
d);
1249 divf(ixo^s) = divf(ixo^s) + 2.d0*(divf_h(ixo^s) + divf_j(ixo^s))/
dxlevel(idir)**2
1252 w(ixo^s,iw_r_e) = divf(ixo^s)
1263 integer,
intent(in) :: ixI^L, ixO^L
1264 double precision,
intent(inout) :: w(ixI^S, 1:nw)
1265 double precision,
intent(in) :: wCT(ixI^S, 1:nw)
1266 double precision,
intent(in) :: x(ixI^S, 1:ndim)
1268 double precision :: kappa(ixO^S,1:ndim), lambda(ixO^S,1:ndim), fld_R(ixO^S,1:ndim)
1270 double precision :: max_D(ixI^S), grad_r_e(ixI^S), rad_e(ixI^S)
1271 integer :: idir,i,j, ix^D, idim
1284 w(ixo^s,
i_diff_mg(idim)) = (const_c/
unit_velocity)*lambda(ixo^s,idim)/(kappa(ixo^s,idim)*wct(ixo^s,iw_rho))
1286 where (w(ixo^s,
i_diff_mg(idim)) .lt. 0.d0)
1305 type(state),
target :: psa(max_blocks)
1308 integer :: iigrid, igrid, level
1313 do iigrid=1,igridstail; igrid=igrids(iigrid);
1327 integer,
intent(in) :: ixI^L, ixO^L, idim
1328 double precision,
intent(inout) :: w(ixI^S, 1:nw)
1330 double precision :: tmp_D(ixI^S), filtered_D(ixI^S)
1331 integer :: ix^D, filter, idir
1337 filtered_d(ixo^s) = zero
1342 filtered_d(ix^d) = filtered_d(ix^d) &
1343 + tmp_d(ix^d+filter*
kr(idir,^d)) &
1344 + tmp_d(ix^d-filter*
kr(idir,^d))
1373 integer,
intent(in) :: ixI^L, ixO^L
1374 double precision,
intent(in) :: x(ixI^S,1:ndim)
1375 double precision,
intent(in) :: wCT(ixI^S,1:nw)
1376 double precision,
intent(inout) :: w(ixI^S,1:nw)
1378 double precision :: a1(ixO^S), a2(ixO^S)
1379 double precision :: c0(ixO^S), c1(ixO^S)
1380 double precision :: e_gas(ixO^S), E_rad(ixO^S)
1381 double precision :: kappa(ixO^S)
1382 double precision :: sigma_b
1393 e_gas(ixo^s) = wct(ixo^s,iw_e) - half*sum(wct(ixo^s, iw_mom(:))**2, dim=ndim+1)/wct(ixo^s, iw_rho)
1398 {
do ix^d=ixomin^d,ixomax^d\ }
1402 e_rad(ixo^s) = wct(ixo^s,iw_r_e)
1407 call mpistop(
"apoint qdot opacity")
1414 a1(ixo^s) = const_rad_a*(
afld_mu*const_mp/const_kb*(afld_gamma-1))**4/(wct(ixo^s,iw_rho)*
unit_density)**4 &
1416 a2(ixo^s) = e_gas(ixo^s) + e_rad(ixo^s)
1418 c0(ixo^s) = a2(ixo^s)/a1(ixo^s)
1419 c1(ixo^s) = 1.d0/a1(ixo^s)
1422 a1(ixo^s) = 4*kappa(ixo^s)*sigma_b*(afld_gamma-one)**4/wct(ixo^s,iw_rho)**3*
dt
1425 c0(ixo^s) = ((one + a2(ixo^s))*e_gas(ixo^s) + a2(ixo^s)*e_rad(ixo^s))/a1(ixo^s)
1426 c1(ixo^s) = (one + a2(ixo^s))/a1(ixo^s)
1432 {
do ix^d=ixomin^d,ixomax^d\ }
1437 call newton_method(e_gas(ix^d), e_rad(ix^d), c0(ix^d), c1(ix^d))
1439 call halley_method(e_gas(ix^d), e_rad(ix^d), c0(ix^d), c1(ix^d))
1441 call halley_method(e_gas(ix^d), e_rad(ix^d), c0(ix^d), c1(ix^d))
1443 call mpistop(
'root-method not known')
1448 e_rad(ixo^s) = a2(ixo^s) - e_gas(ixo^s)
1451 e_rad(ixo^s) = (a1(ixo^s)*e_gas(ixo^s)**4.d0 + e_rad(ixo^s))/(one + a2(ixo^s))
1472 w(ixo^s,iw_e) = e_gas(ixo^s)
1477 w(ixo^s,iw_e) = w(ixo^s,iw_e) + half*sum(wct(ixo^s, iw_mom(:))**2, dim=ndim+1)/wct(ixo^s, iw_rho)
1484 w(ixo^s,iw_r_e) = e_rad(ixo^s)
1493 double precision,
intent(in) :: c0, c1
1494 double precision,
intent(in) :: E_rad
1495 double precision,
intent(inout) :: e_gas
1497 double precision :: bisect_a, bisect_b, bisect_c
1498 integer :: n, max_its
1504 bisect_b = 1.2d0*max(abs(c0/c1),abs(c0)**(1.d0/4.d0))
1508 do while (abs(bisect_b-bisect_a) .ge.
fld_bisect_tol*min(e_gas,e_rad))
1509 bisect_c = (bisect_a + bisect_b)/two
1512 if (n .gt. max_its)
then
1514 call mpistop(
'No convergece in bisection scheme')
1539 call mpistop(
"Problem with fld bisection method")
1547 print*,
"IGNORING GAS-RAD ENERGY EXCHANGE ", c0, c1
1562 2435 e_gas = (bisect_a + bisect_b)/two
1569 double precision,
intent(in) :: c0, c1
1570 double precision,
intent(in) :: E_rad
1571 double precision,
intent(inout) :: e_gas
1573 double precision :: xval, yval, der, deltax
1588 xval = xval + deltax
1590 if (ii .gt. 1d3)
then
1603 double precision,
intent(in) :: c0, c1
1604 double precision,
intent(in) :: E_rad
1605 double precision,
intent(inout) :: e_gas
1607 double precision :: xval, yval, der, dder, deltax
1623 deltax = -two*yval*der/(two*der**2 - yval*dder)
1624 xval = xval + deltax
1626 if (ii .gt. 1d3)
then
1640 double precision,
intent(in) :: e_gas
1641 double precision,
intent(in) :: c0, c1
1642 double precision :: val
1644 val = e_gas**4.d0 + c1*e_gas - c0
1651 double precision,
intent(in) :: e_gas
1652 double precision,
intent(in) :: c0, c1
1653 double precision :: der
1655 der = 4.d0*e_gas**3.d0 + c1
1662 double precision,
intent(in) :: e_gas
1663 double precision,
intent(in) :: c0, c1
1664 double precision :: dder
1666 dder = 4.d0*3.d0*e_gas**2.d0
1674 integer,
intent(in) :: ixI^L, ixO^L, idir
1675 integer,
intent(in) :: n
1677 double precision,
intent(in) :: q(ixI^S), x(ixI^S,1:ndim)
1678 double precision,
intent(out) :: gradq(ixO^S)
1679 integer :: jxO^L, hxO^L
1693 call mpistop(
"gradientO stencil too wide")
1694 elseif (n .eq. 1)
then
1695 hxo^l=ixo^l-
kr(idir,^
d);
1696 jxo^l=ixo^l+
kr(idir,^
d);
1697 gradq(ixo^s)=(q(jxo^s)-q(hxo^s))/(x(jxo^s,idir)-x(hxo^s,idir))
1698 elseif (n .eq. 2)
then
1701 hxo^l=ixo^l-
kr(idir,^
d);
1702 jxo^l=ixo^l+
kr(idir,^
d);
1703 gradq(ixo^s) = gradq(ixo^s) + 2.d0/3.d0*(q(jxo^s)-q(hxo^s))
1705 hxo^l=ixo^l-2*
kr(idir,^
d);
1706 jxo^l=ixo^l+2*
kr(idir,^
d);
1707 gradq(ixo^s) = gradq(ixo^s) - 1.d0/12.d0*(q(jxo^s)-q(hxo^s))
1709 gradq(ixo^s) = gradq(ixo^s)/
dxlevel(idir)
1710 elseif (n .eq. 3)
then
1713 hxo^l=ixo^l-
kr(idir,^
d);
1714 jxo^l=ixo^l+
kr(idir,^
d);
1715 gradq(ixo^s) = gradq(ixo^s) + 3.d0/4.d0*(q(jxo^s)-q(hxo^s))
1717 hxo^l=ixo^l-2*
kr(idir,^
d);
1718 jxo^l=ixo^l+2*
kr(idir,^
d);
1719 gradq(ixo^s) = gradq(ixo^s) - 3.d0/20.d0*(q(jxo^s)-q(hxo^s))
1721 hxo^l=ixo^l-3*
kr(idir,^
d);
1722 jxo^l=ixo^l+3*
kr(idir,^
d);
1723 gradq(ixo^s) = gradq(ixo^s) + 1.d0/60.d0*(q(jxo^s)-q(hxo^s))
1725 gradq(ixo^s) = gradq(ixo^s)/
dxlevel(idir)
1727 call mpistop(
"gradientO stencil unknown")
subroutine mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for including anisotropic flux limited diffusion (AFLD)-approximation in Radiation-hydrodynami...
logical lineforce_opacities
Use or dont use lineforce opacities.
subroutine afld_smooth_diffcoef(w, ixIL, ixOL, idim)
Use running average on Diffusion coefficient.
character(len=8) fld_interaction_method
Which method to find the root for the energy interaction polynomial.
subroutine, public afld_radforce_get_dt(w, ixIL, ixOL, dtnew, dxD, x)
subroutine, public afld_get_fluxlimiter(w, x, ixIL, ixOL, fld_lambda, fld_R)
Calculate fld flux limiter This subroutine calculates flux limiter lambda using the prescription stor...
subroutine, public get_afld_energy_interact(qdt, ixIL, ixOL, wCT, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
subroutine put_diffterm_onegrid(ixIL, ixOL, w)
inplace update of psa==>F_im(psa)
logical fld_eint_split
source split for energy interact and radforce:
subroutine bisection_method(e_gas, E_rad, c0, c1)
Find the root of the 4th degree polynomial using the bisection method.
subroutine, public afld_init(He_abundance, rhd_radiation_diffusion, afld_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine evaluate_e_rad_mg(qtC, psa)
inplace update of psa==>F_im(psa)
logical flux_lim_filter
Take a running average over the fluxlimiter.
integer, dimension(:), allocatable, public i_diff_mg
Index for Diffusion coeficients.
double precision, public fld_bisect_tol
Tolerance for bisection method for Energy sourceterms This is a percentage of the minimum of gas- and...
double precision, public fld_kappa0
Opacity per unit of unit_density.
double precision, public fld_diff_tol
Tolerance for adi method for radiative Energy diffusion.
character(len=16) fld_fluxlimiter
Diffusion limit lambda = 0.33.
subroutine afld_get_eddington(w, x, ixIL, ixOL, eddington_tensor)
Calculate Eddington-tensor Stores Eddington-tensor in w-array.
double precision function ddpolynomial_bisection(e_gas, c0, c1)
Evaluate second derivative of polynomial at argument e_gas.
subroutine energy_interaction(w, wCT, x, ixIL, ixOL)
This subroutine calculates the radiation heating, radiation cooling and photon tiring using an implic...
subroutine afld_get_diffcoef_central(w, wCT, x, ixIL, ixOL)
Calculates cell-centered diffusion coefficient to be used in multigrid.
logical fld_diff_testcase
Set Diffusion coefficient to unity.
logical diffcrash_resume
Resume run when multigrid returns error.
double precision function dpolynomial_bisection(e_gas, c0, c1)
Evaluate first derivative of polynomial at argument e_gas.
character(len=8), dimension(:), allocatable fld_opacity_law
Use constant Opacity?
subroutine update_diffcoeff(psa)
subroutine halley_method(e_gas, E_rad, c0, c1)
Find the root of the 4th degree polynomial using the Halley method.
double precision function polynomial_bisection(e_gas, c0, c1)
Evaluate polynomial at argument e_gas.
character(len=8) afld_diff_scheme
Which method to solve diffusion part.
subroutine gradiento(q, x, ixIL, ixOL, idir, gradq, n)
Calculate gradient of a scalar q within ixL in direction idir difference with gradient is gradq(ixO^S...
subroutine, public get_afld_rad_force(qdt, ixIL, ixOL, wCT, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
subroutine diffuse_e_rad_mg(dtfactor, qdt, qtC, psa, psb)
Calling all subroutines to perform the multigrid method Communicates rad_e and diff_coeff to multigri...
subroutine, public afld_get_radflux(w, x, ixIL, ixOL, rad_flux)
Calculate Radiation Flux stores radiation flux in w-array.
subroutine, public afld_get_opacity(w, x, ixIL, ixOL, fld_kappa)
Sets the opacity in the w-array by calling mod_opal_opacity.
double precision, public diff_crit
Number for splitting the diffusion module.
logical fld_radforce_split
subroutine, public afld_get_radpress(w, x, ixIL, ixOL, rad_pressure)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
logical diff_coef_filter
Take running average for Diffusion coefficient.
double precision, public afld_mu
mean particle mass
subroutine afld_params_read(files)
public methods these are called in mod_rhd_phys
integer, public i_test
Index for testvariable.
double precision dt_diff
running timestep for diffusion solver, initialised as zero
subroutine newton_method(e_gas, E_rad, c0, c1)
Find the root of the 4th degree polynomial using the Newton-Ralphson method.
Module for physical and numeric constants.
double precision, parameter const_c
Module with basic grid data structures.
Module with geometry-related routines (e.g., divergence, curl)
subroutine gradient(q, ixIL, ixOL, idir, gradq)
Calculate gradient of a scalar q within ixL in direction idir.
update ghost cells of all blocks including physical boundaries
subroutine getbc(time, qdt, psb, nwstart, nwbc, req_diag)
do update ghost cells of all blocks including physical boundaries
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision small_pressure
double precision unit_density
Physical scaling factor for density.
double precision unit_opacity
Physical scaling factor for Opacity.
integer, parameter unitpar
file handle for IO
double precision global_time
The global simulation time.
integer, dimension(3, 3) kr
Kronecker delta tensor.
integer it
Number of time steps taken.
double precision unit_pressure
Physical scaling factor for pressure.
integer, parameter ndim
Number of spatial dimensions for grid variables.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer mype
The rank of the current MPI task.
integer, dimension(:), allocatable, parameter d
double precision courantpar
The Courant (CFL) number used for the simulation.
double precision unit_velocity
Physical scaling factor for velocity.
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision unit_temperature
Physical scaling factor for temperature.
double precision, dimension(:,:), allocatable dx
integer nghostcells
Number of ghost cells surrounding a grid.
logical use_multigrid
Use multigrid (only available in 2D and 3D)
double precision dtmin
Stop the simulation when the time step becomes smaller than this value.
double precision, dimension(ndim) dxlevel
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
type(mg_t) mg
Data structure containing the multigrid tree.
subroutine mg_copy_to_tree(iw_from, iw_to, restrict, restrict_gc, factor, state_from)
Copy a variable to the multigrid tree, including a layer of ghost cells.
subroutine mg_copy_from_tree_gc(iw_from, iw_to, state_to)
Copy from multigrid tree with one layer of ghost cells. Corner ghost cells are not used/set.
This module reads in opacities from opal tables.
subroutine, public set_opal_opacity(rho, temp, kappa)
This subroutine calculates the opacity for a given temperature-density structure. The opacities are r...
subroutine, public init_opal(He_abundance, tablename)
This routine is called when the fld radiation module is initialised. Here, the tables for different H...
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_get_tgas), pointer phys_get_tgas
procedure(sub_evaluate_implicit), pointer phys_evaluate_implicit
logical phys_req_diagonal
Whether the physics routines require diagonal ghost cells, for example for computing a curl.
procedure(sub_get_pthermal), pointer phys_get_pthermal
procedure(sub_set_mg_bounds), pointer phys_set_mg_bounds
procedure(sub_implicit_update), pointer phys_implicit_update
Module with all the methods that users can customize in AMRVAC.
procedure(special_diffcoef), pointer usr_special_diffcoef
procedure(special_fluxlimiter), pointer usr_special_fluxlimiter
procedure(special_opacity_qdot), pointer usr_special_opacity_qdot
procedure(special_aniso_opacity), pointer usr_special_aniso_opacity
integer function var_set_extravar(name_cons, name_prim, ix)
Set extra variable in w, which is not advected and has no boundary conditions. This has to be done af...
The data structure that contains information about a tree node/grid block.