22 double precision,
public ::
afld_mu = 0.6d0
76 double precision,
private,
protected :: afld_gamma
102 character(len=*),
intent(in) :: files(:)
111 do n = 1,
size(files)
112 open(
unitpar, file=trim(files(n)), status=
"old")
113 read(
unitpar, fld_list,
end=111)
125 subroutine afld_init(He_abundance, rhd_radiation_diffusion, afld_gamma)
132 double precision,
intent(in) :: he_abundance, afld_gamma
133 logical,
intent(in) :: rhd_radiation_diffusion
134 double precision :: sigma_thomson
137 character(len=1) :: ind_1
138 character(len=1) :: ind_2
139 character(len=2) :: cmp_f
140 character(len=5) :: cmp_e
143 call mpistop(
"Anisotropic in 1D... really?")
169 if (rhd_radiation_diffusion)
then
178 mg%operator_type = mg_ahelmholtz
185 write(ind_1,
'(I1)') idir
191 afld_mu = (1.+4*he_abundance)/(2.+3.*he_abundance)
207 energy,qsourcesplit,active)
213 integer,
intent(in) :: ixi^
l, ixo^
l
214 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
215 double precision,
intent(in) :: wct(ixi^s,1:nw)
216 double precision,
intent(inout) :: w(ixi^s,1:nw)
217 logical,
intent(in) :: energy,qsourcesplit
218 logical,
intent(inout) :: active
220 double precision :: radiation_forcect(ixo^s,1:
ndim)
221 double precision :: kappact(ixo^s,1:
ndim)
222 double precision :: rad_fluxct(ixo^s,1:
ndim)
224 double precision :: div_v(ixi^s,1:
ndim,1:
ndim)
225 double precision :: edd(ixo^s,1:
ndim,1:
ndim)
226 double precision :: nabla_vp(ixo^s)
227 double precision :: vel(ixi^s), grad_v(ixi^s), grad0_v(ixo^s)
228 double precision :: grad_e(ixo^s)
230 integer :: idir, jdir
232 double precision :: fld_r(ixo^s,1:
ndim), lambda(ixo^s,1:
ndim)
244 radiation_forcect(ixo^s,idir) = kappact(ixo^s,idir)*rad_fluxct(ixo^s,idir)/(
const_c/
unit_velocity)
250 w(ixo^s,iw_mom(idir)) = w(ixo^s,iw_mom(idir)) &
251 + qdt * wct(ixo^s,iw_rho)*radiation_forcect(ixo^s,idir)
257 w(ixo^s,iw_e) = w(ixo^s,iw_e) &
258 + qdt * wct(ixo^s,iw_mom(idir))*radiation_forcect(ixo^s,idir)
269 vel(ixi^s) = wct(ixi^s,iw_mom(jdir))/wct(ixi^s,iw_rho)
272 div_v(ixo^s,idir,jdir) = grad_v(ixo^s)
284 nabla_vp(ixo^s) = div_v(ixo^s,1,1)*edd(ixo^s,1,1) &
289 nabla_vp(ixo^s) = div_v(ixo^s,1,1)*edd(ixo^s,1,1) &
290 + div_v(ixo^s,1,2)*edd(ixo^s,1,2) &
291 + div_v(ixo^s,2,1)*edd(ixo^s,2,1) &
292 + div_v(ixo^s,2,2)*edd(ixo^s,2,2)
296 nabla_vp(ixo^s) = div_v(ixo^s,1,1)*edd(ixo^s,1,1) &
297 + div_v(ixo^s,1,2)*edd(ixo^s,1,2) &
298 + div_v(ixo^s,1,3)*edd(ixo^s,1,3) &
299 + div_v(ixo^s,2,1)*edd(ixo^s,2,1) &
300 + div_v(ixo^s,2,2)*edd(ixo^s,2,2) &
301 + div_v(ixo^s,2,3)*edd(ixo^s,2,3) &
302 + div_v(ixo^s,3,1)*edd(ixo^s,3,1) &
303 + div_v(ixo^s,3,2)*edd(ixo^s,3,2) &
304 + div_v(ixo^s,3,3)*edd(ixo^s,3,3)
307 w(ixo^s,iw_r_e) = w(ixo^s,iw_r_e) &
308 - qdt * nabla_vp(ixo^s)*wct(ixo^s,iw_r_e)
319 integer,
intent(in) :: ixi^
l, ixo^
l
320 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim), w(ixi^s,1:nw)
321 double precision,
intent(inout) :: dtnew
323 double precision :: radiation_force(ixo^s,1:
ndim)
324 double precision :: rad_flux(ixo^s,1:
ndim)
325 double precision :: kappa(ixo^s,1:
ndim)
326 double precision :: dxinv(1:
ndim), max_grad
329 ^
d&dxinv(^
d)=one/
dx^
d;
335 radiation_force(ixo^s,idim) = w(ixo^s,iw_rho)*kappa(ixo^s,idim)*rad_flux(ixo^s,idim)/(const_c/
unit_velocity)
336 max_grad = maxval(abs(radiation_force(ixo^s,idim)))
337 max_grad = max(max_grad, epsilon(1.0d0))
338 dtnew = min(dtnew,
courantpar / sqrt(max_grad * dxinv(idim)))
346 energy,qsourcesplit,active)
353 integer,
intent(in) :: ixi^
l, ixo^
l
354 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
355 double precision,
intent(in) :: wct(ixi^s,1:nw)
356 double precision,
intent(inout) :: w(ixi^s,1:nw)
357 logical,
intent(in) :: energy,qsourcesplit
358 logical,
intent(inout) :: active
377 integer,
intent(in) :: ixi^
l, ixo^
l
378 double precision,
intent(in) :: w(ixi^s, 1:nw)
379 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
380 double precision,
intent(out) :: fld_kappa(ixo^s,1:
ndim)
381 double precision :: temp(ixi^s), pth(ixi^s), a2(ixo^s)
382 double precision :: rho0,temp0,n,sigma_b
383 double precision :: akram, bkram
384 double precision :: vth(ixo^s), gradv(ixi^s), eta(ixo^s), t(ixo^s)
386 integer :: i,j,ix^
d, idim
404 fld_kappa(ixo^s,idim) =
fld_kappa0/
unit_opacity*(one + n*dexp(-one/sigma_b*(dlog(w(ixo^s,iw_rho)/rho0))**two))
406 call phys_get_pthermal(w,x,ixi^
l,ixo^
l,temp)
407 temp(ixo^s)=temp(ixo^s)/w(ixo^s,iw_rho)
414 call phys_get_pthermal(w,x,ixi^
l,ixo^
l,pth)
417 akram = 13.1351597305
418 bkram = -4.5182188206
421 * (1.d0+10.d0**akram*w(ixo^s,iw_rho)*
unit_density*(a2(ixo^s)/1.d12)**bkram)
423 {
do ix^
d=ixomin^
d,ixomax^
d\ }
435 {
do ix^
d=ixomin^
d,ixomax^
d\ }
444 call mpistop(
"special opacity not defined")
449 call mpistop(
"Doesn't know opacity law")
465 integer,
intent(in) :: ixi^
l, ixo^
l
466 double precision,
intent(in) :: w(ixi^s, 1:nw)
467 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
468 double precision,
intent(out) :: fld_r(ixo^s,1:
ndim), fld_lambda(ixo^s,1:
ndim)
469 double precision :: kappa(ixo^s,1:
ndim)
470 double precision :: normgrad2(ixo^s)
471 double precision :: grad_r_e(ixi^s), grad_r_eo(ixo^s)
472 double precision :: rad_e(ixi^s)
473 integer :: idir, ix^
d
475 double precision :: tmp_l(ixi^s), filtered_l(ixi^s)
476 integer :: filter, idim
480 fld_lambda(ixo^s,1:
ndim) = 1.d0/3.d0
481 fld_r(ixo^s,1:
ndim) = zero
486 rad_e(ixi^s) = w(ixi^s, iw_r_e)
492 normgrad2(ixo^s) = grad_r_eo(ixo^s)**2
499 fld_r(ixo^s,idir) = dsqrt(normgrad2(ixo^s))/(kappa(ixo^s,idir)*w(ixo^s,iw_rho)*w(ixo^s,iw_r_e))
502 fld_lambda(ixo^s,idir) = one/fld_r(ixo^s,idir)
510 normgrad2(ixo^s) = 0.d0
512 rad_e(ixi^s) = w(ixi^s, iw_r_e)
518 normgrad2(ixo^s) = grad_r_eo(ixo^s)**2
524 fld_r(ixo^s,idir) = dsqrt(normgrad2(ixo^s))/(kappa(ixo^s,idir)*w(ixo^s,iw_rho)*w(ixo^s,iw_r_e))
528 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)
535 normgrad2(ixo^s) = 0.d0
537 rad_e(ixi^s) = w(ixi^s, iw_r_e)
543 normgrad2(ixo^s) = grad_r_eo(ixo^s)**2
550 fld_r(ixo^s,idir) = dsqrt(normgrad2(ixo^s))/(kappa(ixo^s,idir)*w(ixo^s,iw_rho)*w(ixo^s,iw_r_e))
554 {
do ix^
d=ixomin^
d,ixomax^
d\ }
555 if (fld_r(ix^
d,idir) .lt. 3.d0/2.d0)
then
556 fld_lambda(ix^
d,idir) = 2.d0/(3.d0 + dsqrt(9.d0 + 12.d0*fld_r(ix^
d,idir)**2.d0))
558 fld_lambda(ix^
d,idir) = 1.d0/(1.d0 + fld_r(ix^
d,idir) + dsqrt(1.d0 + 2.d0*fld_r(ix^
d,idir)))
566 call mpistop(
"special fluxlimiter not defined")
570 call mpistop(
'Fluxlimiter unknown')
575 if (
size_l_filter .lt. 1)
call mpistop(
"D filter of size < 1 makes no sense")
580 tmp_l(ixo^s) = fld_lambda(ixo^s, idir)
581 filtered_l(ixo^s) = zero
586 filtered_l(ix^
d) = filtered_l(ix^
d) &
587 + tmp_l(ix^
d+filter*
kr(idim,^
d)) &
588 + tmp_l(ix^
d-filter*
kr(idim,^
d))
599 fld_lambda(ixo^s,idir) = tmp_l(ixo^s)
610 integer,
intent(in) :: ixi^
l, ixo^
l
611 double precision,
intent(in) :: w(ixi^s, 1:nw)
612 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
613 double precision,
intent(out) :: rad_flux(ixo^s, 1:
ndim)
615 double precision :: grad_r_e(ixi^s), grad_r_eo(ixo^s)
616 double precision :: rad_e(ixi^s)
617 double precision :: kappa(ixo^s,1:
ndim), lambda(ixo^s,1:
ndim), fld_r(ixo^s,1:
ndim)
618 integer :: ix^
d, idir
620 rad_e(ixi^s) = w(ixi^s, iw_r_e)
629 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)
643 integer,
intent(in) :: ixI^L, ixO^L
644 double precision,
intent(in) :: w(ixI^S, 1:nw)
645 double precision,
intent(in) :: x(ixI^S, 1:ndim)
646 double precision,
intent(out) :: eddington_tensor(ixO^S,1:ndim,1:ndim)
647 double precision :: tnsr2(ixO^S,1:ndim,1:ndim)
648 double precision :: normgrad2(ixO^S), f(ixO^S,1:ndim)
649 double precision :: grad_r_e(ixI^S, 1:ndim), rad_e(ixI^S)
650 double precision :: grad_r_eO(ixO^S, 1:ndim)
651 double precision :: lambda(ixO^S,1:ndim), fld_R(ixO^S,1:ndim)
652 integer :: i,j, idir,jdir
658 normgrad2(ixo^s) = zero
660 rad_e(ixi^s) = w(ixi^s, iw_r_e)
663 normgrad2(ixo^s) = normgrad2(ixo^s) + grad_r_eo(ixo^s,idir)**2
670 f(ixo^s,idir) = lambda(ixo^s,idir) + lambda(ixo^s,idir)**two * fld_r(ixo^s,idir)**two
671 f(ixo^s,idir) = one/two*(one-f(ixo^s,idir)) + one/two*(3.d0*f(ixo^s,idir) - one)
677 eddington_tensor(ixo^s,1,1) = f(ixo^s,1)
682 eddington_tensor(ixo^s,idir,idir) = half*(one-f(ixo^s,idir))
687 if (idir .ne. jdir) eddington_tensor(ixo^s,idir,jdir) = zero
688 tnsr2(ixo^s,idir,jdir) = half*(3.d0*f(ixo^s,idir) - 1)&
689 *grad_r_eo(ixo^s,idir)*grad_r_eo(ixo^s,jdir)/normgrad2(ixo^s)
703 where ((tnsr2(ixo^s,idir,jdir) .eq. tnsr2(ixo^s,idir,jdir)) &
704 .and. (normgrad2(ixo^s) .gt. smalldouble))
705 eddington_tensor(ixo^s,idir,jdir) = eddington_tensor(ixo^s,idir,jdir) + tnsr2(ixo^s,idir,jdir)
718 integer,
intent(in) :: ixi^
l, ixo^
l
719 double precision,
intent(in) :: w(ixi^s, 1:nw)
720 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
721 double precision :: eddington_tensor(ixo^s,1:
ndim,1:
ndim)
722 double precision,
intent(out):: rad_pressure(ixo^s,1:
ndim,1:
ndim)
730 rad_pressure(ixo^s,i,j) = eddington_tensor(ixo^s,i,j)* w(ixo^s,iw_r_e)
1078 type(state),
target :: psa(max_blocks)
1079 type(state),
target :: psb(max_blocks)
1080 double precision,
intent(in) :: qdt
1081 double precision,
intent(in) :: qtC
1082 double precision,
intent(in) :: dtfactor
1085 double precision :: res, max_residual, lambda
1086 integer,
parameter :: max_its = 50
1088 integer :: iw_to,iw_from
1089 integer :: iigrid, igrid, id
1090 integer :: nc, lvl, i
1092 real(dp) :: fac, facD
1100 if (qdt <
dtmin)
then
1102 print *,
'skipping implicit solve: dt too small!'
1110 mg%operator_type = mg_ahelmholtz
1111 mg%smoother_type = mg_smoother_gsrb
1112 call mg_set_methods(
mg)
1114 if (.not.
mg%is_allocated)
call mpistop(
"multigrid tree not allocated yet")
1117 lambda = 1.d0/(dtfactor *
dt_diff)
1118 call ahelmholtz_set_lambda(lambda)
1130 call mg_restrict(
mg, mg_iveps)
1131 call mg_fill_ghost_cells(
mg, mg_iveps)
1140 call mg_restrict(
mg, mg_iveps1)
1141 call mg_fill_ghost_cells(
mg, mg_iveps1)
1143 call mg_restrict(
mg, mg_iveps2)
1144 call mg_fill_ghost_cells(
mg, mg_iveps2)
1158 call mg_fas_fmg(
mg, .true., max_res=res)
1161 if (res < max_residual)
exit
1162 call mg_fas_vcycle(
mg, max_res=res)
1165 if (res .le. 0.d0)
then
1167 if (
mg%my_rank == 0) &
1168 write(*,*)
it,
' resiudal zero ', res
1171 if (
mg%my_rank == 0)
then
1173 error stop
"Diffusion residual to zero"
1177 if (n == max_its + 1)
then
1179 if (
mg%my_rank == 0) &
1180 write(*,*)
it,
' resiudal high ', res
1183 if (
mg%my_rank == 0)
then
1184 print *,
"Did you specify boundary conditions correctly?"
1185 print *,
"Or is the variation in diffusion too large?"
1187 print *,
mg%bc(1, mg_iphi)%bc_value,
mg%bc(2, mg_iphi)%bc_value
1189 error stop
"diffusion_solve: no convergence"
1210 type(state),
target :: psa(max_blocks)
1211 double precision,
intent(in) :: qtC
1213 integer :: iigrid, igrid, level
1220 do iigrid=1,igridstail; igrid=igrids(iigrid);
1235 integer,
intent(in) :: ixI^L, ixO^L
1236 double precision,
intent(inout) :: w(ixI^S, 1:nw)
1238 double precision :: gradE(ixO^S),divF(ixO^S)
1239 double precision :: divF_h(ixO^S),divF_j(ixO^S)
1240 double precision :: diff_term(ixO^S)
1242 integer :: idir, jxO^L, hxO^L
1248 hxo^l=ixo^l-
kr(idir,^
d);
1249 jxo^l=ixo^l+
kr(idir,^
d);
1253 divf(ixo^s) = divf(ixo^s) + 2.d0*(divf_h(ixo^s) + divf_j(ixo^s))/
dxlevel(idir)**2
1256 w(ixo^s,iw_r_e) = divf(ixo^s)
1267 integer,
intent(in) :: ixI^L, ixO^L
1268 double precision,
intent(inout) :: w(ixI^S, 1:nw)
1269 double precision,
intent(in) :: wCT(ixI^S, 1:nw)
1270 double precision,
intent(in) :: x(ixI^S, 1:ndim)
1272 double precision :: kappa(ixO^S,1:ndim), lambda(ixO^S,1:ndim), fld_R(ixO^S,1:ndim)
1274 double precision :: max_D(ixI^S), grad_r_e(ixI^S), rad_e(ixI^S)
1275 integer :: idir,i,j, ix^D, idim
1288 w(ixo^s,
i_diff_mg(idim)) = (const_c/
unit_velocity)*lambda(ixo^s,idim)/(kappa(ixo^s,idim)*wct(ixo^s,iw_rho))
1290 where (w(ixo^s,
i_diff_mg(idim)) .lt. 0.d0)
1309 type(state),
target :: psa(max_blocks)
1312 integer :: iigrid, igrid, level
1317 do iigrid=1,igridstail; igrid=igrids(iigrid);
1331 integer,
intent(in) :: ixI^L, ixO^L, idim
1332 double precision,
intent(inout) :: w(ixI^S, 1:nw)
1334 double precision :: tmp_D(ixI^S), filtered_D(ixI^S)
1335 integer :: ix^D, filter, idir
1337 if (
size_d_filter .lt. 1)
call mpistop(
"D filter of size < 1 makes no sense")
1341 filtered_d(ixo^s) = zero
1346 filtered_d(ix^d) = filtered_d(ix^d) &
1347 + tmp_d(ix^d+filter*
kr(idir,^d)) &
1348 + tmp_d(ix^d-filter*
kr(idir,^d))
1377 integer,
intent(in) :: ixI^L, ixO^L
1378 double precision,
intent(in) :: x(ixI^S,1:ndim)
1379 double precision,
intent(in) :: wCT(ixI^S,1:nw)
1380 double precision,
intent(inout) :: w(ixI^S,1:nw)
1382 double precision :: a1(ixO^S), a2(ixO^S)
1383 double precision :: c0(ixO^S), c1(ixO^S)
1384 double precision :: e_gas(ixO^S), E_rad(ixO^S)
1385 double precision :: kappa(ixO^S)
1386 double precision :: sigma_b
1397 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)
1402 {
do ix^d=ixomin^d,ixomax^d\ }
1406 e_rad(ixo^s) = wct(ixo^s,iw_r_e)
1411 call mpistop(
"apoint qdot opacity")
1418 a1(ixo^s) = const_rad_a*(
afld_mu*const_mp/const_kb*(afld_gamma-1))**4/(wct(ixo^s,iw_rho)*
unit_density)**4 &
1420 a2(ixo^s) = e_gas(ixo^s) + e_rad(ixo^s)
1422 c0(ixo^s) = a2(ixo^s)/a1(ixo^s)
1423 c1(ixo^s) = 1.d0/a1(ixo^s)
1426 a1(ixo^s) = 4*kappa(ixo^s)*sigma_b*(afld_gamma-one)**4/wct(ixo^s,iw_rho)**3*
dt
1429 c0(ixo^s) = ((one + a2(ixo^s))*e_gas(ixo^s) + a2(ixo^s)*e_rad(ixo^s))/a1(ixo^s)
1430 c1(ixo^s) = (one + a2(ixo^s))/a1(ixo^s)
1436 {
do ix^d=ixomin^d,ixomax^d\ }
1441 call newton_method(e_gas(ix^d), e_rad(ix^d), c0(ix^d), c1(ix^d))
1443 call halley_method(e_gas(ix^d), e_rad(ix^d), c0(ix^d), c1(ix^d))
1445 call halley_method(e_gas(ix^d), e_rad(ix^d), c0(ix^d), c1(ix^d))
1447 call mpistop(
'root-method not known')
1452 e_rad(ixo^s) = a2(ixo^s) - e_gas(ixo^s)
1455 e_rad(ixo^s) = (a1(ixo^s)*e_gas(ixo^s)**4.d0 + e_rad(ixo^s))/(one + a2(ixo^s))
1476 w(ixo^s,iw_e) = e_gas(ixo^s)
1481 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)
1488 w(ixo^s,iw_r_e) = e_rad(ixo^s)
1497 double precision,
intent(in) :: c0, c1
1498 double precision,
intent(in) :: E_rad
1499 double precision,
intent(inout) :: e_gas
1501 double precision :: bisect_a, bisect_b, bisect_c
1502 integer :: n, max_its
1508 bisect_b = 1.2d0*max(abs(c0/c1),abs(c0)**(1.d0/4.d0))
1512 do while (abs(bisect_b-bisect_a) .ge.
fld_bisect_tol*min(e_gas,e_rad))
1513 bisect_c = (bisect_a + bisect_b)/two
1516 if (n .gt. max_its)
then
1518 call mpistop(
'No convergece in bisection scheme')
1543 call mpistop(
"Problem with fld bisection method")
1551 print*,
"IGNORING GAS-RAD ENERGY EXCHANGE ", c0, c1
1566 2435 e_gas = (bisect_a + bisect_b)/two
1573 double precision,
intent(in) :: c0, c1
1574 double precision,
intent(in) :: E_rad
1575 double precision,
intent(inout) :: e_gas
1577 double precision :: xval, yval, der, deltax
1592 xval = xval + deltax
1594 if (ii .gt. 1d3)
then
1607 double precision,
intent(in) :: c0, c1
1608 double precision,
intent(in) :: E_rad
1609 double precision,
intent(inout) :: e_gas
1611 double precision :: xval, yval, der, dder, deltax
1627 deltax = -two*yval*der/(two*der**2 - yval*dder)
1628 xval = xval + deltax
1630 if (ii .gt. 1d3)
then
1644 double precision,
intent(in) :: e_gas
1645 double precision,
intent(in) :: c0, c1
1646 double precision :: val
1648 val = e_gas**4.d0 + c1*e_gas - c0
1655 double precision,
intent(in) :: e_gas
1656 double precision,
intent(in) :: c0, c1
1657 double precision :: der
1659 der = 4.d0*e_gas**3.d0 + c1
1666 double precision,
intent(in) :: e_gas
1667 double precision,
intent(in) :: c0, c1
1668 double precision :: dder
1670 dder = 4.d0*3.d0*e_gas**2.d0
1678 integer,
intent(in) :: ixI^L, ixO^L, idir
1679 integer,
intent(in) :: n
1681 double precision,
intent(in) :: q(ixI^S), x(ixI^S,1:ndim)
1682 double precision,
intent(out) :: gradq(ixO^S)
1683 integer :: jxO^L, hxO^L
1697 call mpistop(
"gradientO stencil too wide")
1698 elseif (n .eq. 1)
then
1699 hxo^l=ixo^l-
kr(idir,^
d);
1700 jxo^l=ixo^l+
kr(idir,^
d);
1701 gradq(ixo^s)=(q(jxo^s)-q(hxo^s))/(x(jxo^s,idir)-x(hxo^s,idir))
1702 elseif (n .eq. 2)
then
1705 hxo^l=ixo^l-
kr(idir,^
d);
1706 jxo^l=ixo^l+
kr(idir,^
d);
1707 gradq(ixo^s) = gradq(ixo^s) + 2.d0/3.d0*(q(jxo^s)-q(hxo^s))
1709 hxo^l=ixo^l-2*
kr(idir,^
d);
1710 jxo^l=ixo^l+2*
kr(idir,^
d);
1711 gradq(ixo^s) = gradq(ixo^s) - 1.d0/12.d0*(q(jxo^s)-q(hxo^s))
1713 gradq(ixo^s) = gradq(ixo^s)/
dxlevel(idir)
1714 elseif (n .eq. 3)
then
1717 hxo^l=ixo^l-
kr(idir,^
d);
1718 jxo^l=ixo^l+
kr(idir,^
d);
1719 gradq(ixo^s) = gradq(ixo^s) + 3.d0/4.d0*(q(jxo^s)-q(hxo^s))
1721 hxo^l=ixo^l-2*
kr(idir,^
d);
1722 jxo^l=ixo^l+2*
kr(idir,^
d);
1723 gradq(ixo^s) = gradq(ixo^s) - 3.d0/20.d0*(q(jxo^s)-q(hxo^s))
1725 hxo^l=ixo^l-3*
kr(idir,^
d);
1726 jxo^l=ixo^l+3*
kr(idir,^
d);
1727 gradq(ixo^s) = gradq(ixo^s) + 1.d0/60.d0*(q(jxo^s)-q(hxo^s))
1729 gradq(ixo^s) = gradq(ixo^s)/
dxlevel(idir)
1731 call mpistop(
"gradientO stencil unknown")
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=50) fld_opal_table
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.
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
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 Rosseland-mean opacities from OPAL tables. Table opacity values are given in bas...
subroutine, public init_opal_table(tablename)
This subroutine is called when the FLD radiation module is initialised. The OPAL tables for different...
subroutine, public set_opal_opacity(rho, temp, kappa)
This subroutine calculates the opacity for a given temperature-density structure. Opacities are read ...
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.