16 integer,
public,
protected ::
rho_
17 integer,
public,
protected ::
d_
20 integer,
allocatable,
public,
protected ::
mom(:)
23 integer,
allocatable,
public,
protected ::
tracer(:)
26 integer,
public,
protected ::
e_
28 integer,
public,
protected ::
p_
31 integer,
public,
protected ::
lfac_
34 integer,
public,
protected ::
xi_
57 double precision,
public ::
tolernr = 1.0d-9
58 double precision,
public ::
dmaxvel = 1.0d-7
77 subroutine srhd_read_params(files)
79 character(len=*),
intent(in) :: files(:)
87 open(
unitpar, file=trim(files(n)), status=
"old")
88 read(
unitpar, srhd_list,
end=111)
92 end subroutine srhd_read_params
97 integer,
intent(in) :: fh
98 integer,
parameter :: n_par = 1
99 double precision :: values(n_par)
100 character(len=name_len) :: names(n_par)
101 integer,
dimension(MPI_STATUS_SIZE) :: st
104 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
108 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
109 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
121 physics_type =
"srhd"
123 phys_total_energy = .true.
127 phys_internal_e = .false.
128 phys_partial_ionization=.false.
134 allocate(start_indices(number_species),stop_indices(number_species))
143 mom(:) = var_set_momentum(
ndir)
146 e_ = var_set_energy()
150 phys_req_diagonal = .false.
158 phys_req_diagonal = .true.
165 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
170 xi_ = var_set_auxvar(
'xi',
'xi')
171 lfac_= var_set_auxvar(
'lfac',
'lfac')
177 stop_indices(1)=nwflux
180 if (.not.
allocated(flux_type))
then
181 allocate(flux_type(
ndir, nw))
182 flux_type = flux_default
183 else if (any(shape(flux_type) /= [
ndir, nw]))
then
184 call mpistop(
"phys_check error: flux_type has wrong shape")
188 allocate(iw_vector(nvector))
189 iw_vector(1) =
mom(1) - 1
217 phys_req_diagonal = .true.
226 call mpistop (
"Error: srhd_gamma <= 0 or srhd_gamma == 1")
237 write(*,*)
'------------------------------------------------------------'
238 write(*,*)
'Using EOS set via srhd_eos=',
srhd_eos
239 write(*,*)
'Maximal lorentz factor (via dmaxvel) is=',
lfacmax
243 write(*,*)
'------------------------------------------------------------'
250 double precision :: mp,kB
263 call mpistop(
"Abort: must set positive values for unit length and numberdensity")
278 logical,
intent(in) :: primitive
279 integer,
intent(in) :: ixi^
l, ixo^
l
280 double precision,
intent(in) :: w(ixi^s, nw)
281 logical,
intent(inout) :: flag(ixi^s,1:nw)
291 where(w(ixo^s,
e_) <
small_e) flag(ixo^s,
e_) = .true.
299 integer,
intent(in) :: ixI^L, ixO^L
300 double precision,
intent(in) :: w(ixI^S, nw)
301 logical,
intent(inout) :: flag(ixI^S,1:nw)
306 where(w(ixo^s,
lfac_) < one) flag(ixo^s,
lfac_) = .true.
308 if(any(flag(ixo^s,
xi_)))
then
309 write(*,*)
'auxiliary xi too low: abort'
310 call mpistop(
'auxiliary check failed')
312 if(any(flag(ixo^s,
lfac_)))
then
313 write(*,*)
'auxiliary lfac too low: abort'
314 call mpistop(
'auxiliary check failed')
323 integer,
intent(in) :: ixi^
l, ixo^
l
324 double precision,
intent(inout) :: w(ixi^s, nw)
325 double precision,
dimension(ixO^S) :: rho,rhoh,pth
328 rho(ixo^s) = sum(w(ixo^s,
mom(:))**2, dim=
ndim+1)
329 w(ixo^s,
lfac_) = dsqrt(1.0d0+rho(ixo^s))
331 rho(ixo^s)=w(ixo^s,
rho_)
332 pth(ixo^s)=w(ixo^s,
p_)
337 w(ixo^s,
xi_) = w(ixo^s,
lfac_)**2.0d0*rhoh(ixo^s)
347 integer,
intent(in) :: ixi^
l,ixo^
l
348 double precision,
intent(inout) :: w(ixi^s, nw)
349 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
351 integer :: ix^
d,ierror,idir
352 integer :: flag_error(ixo^s)
353 double precision :: ssqr
356 {
do ix^db=ixomin^db,ixomax^db\}
360 ssqr= ssqr+w(ix^
d,
mom(idir))**2
363 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
364 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
365 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
371 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
372 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
373 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
379 w(ix^
d,
d_),ssqr,w(ix^
d,
e_),ierror)
380 flag_error(ix^
d) = ierror
383 {
do ix^db=ixomin^db,ixomax^db\}
387 ssqr= ssqr+w(ix^
d,
mom(idir))**2
390 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
391 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
392 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
398 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
399 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
400 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
406 w(ix^
d,
d_),ssqr,w(ix^
d,
e_),ierror)
407 flag_error(ix^
d) = ierror
412 if(any(flag_error(ixo^s)/=0))
then
413 print *,flag_error(ixo^s)
414 call mpistop(
'Problem when getting auxiliaries')
424 integer,
intent(in) :: ixi^
l, ixo^
l
425 double precision,
intent(inout) :: w(ixi^s, nw)
426 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
428 double precision,
dimension(ixO^S) :: rhoh,rho,pth
432 rhoh(ixo^s) = sum(w(ixo^s,
mom(:))**2, dim=
ndim+1)
433 w(ixo^s,
lfac_) = dsqrt(1.0d0+rhoh(ixo^s))
435 rho(ixo^s)=w(ixo^s,
rho_)
436 pth(ixo^s)=w(ixo^s,
p_)
441 rhoh(ixo^s)= rhoh(ixo^s)*w(ixo^s,
lfac_)
443 w(ixo^s,
xi_) = w(ixo^s,
lfac_)*rhoh(ixo^s)
446 w(ixo^s,
d_)=w(ixo^s,
lfac_)*rho(ixo^s)
450 w(ixo^s,
mom(idir)) = rhoh(ixo^s)*w(ixo^s,
mom(idir))
454 w(ixo^s,
e_) = w(ixo^s,
xi_)-pth(ixo^s)-w(ixo^s,
d_)
465 integer,
intent(in) :: ixi^
l, ixo^
l
466 double precision,
intent(inout) :: w(ixi^s, nw)
467 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
469 double precision,
dimension(ixO^S) :: rho,rhoh,e
470 double precision,
dimension(ixI^S) :: pth
471 character(len=30) :: subname_loc
477 rho(ixo^s) = w(ixo^s,
d_)/w(ixo^s,
lfac_)
481 rhoh(ixo^s) = w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
484 w(ixo^s,
rho_)=rho(ixo^s)
487 w(ixo^s,
mom(idir)) = w(ixo^s,
lfac_)*w(ixo^s,
mom(idir))&
490 w(ixo^s,
p_)=pth(ixo^s)
494 /(rho(ixo^s)*w(ixo^s,
lfac_))
502 integer,
intent(in) :: ixI^L, ixO^L
503 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
504 double precision,
intent(out) :: v(ixI^S,1:ndir)
509 v(ixo^s,idir) = w(ixo^s,
mom(idir))/w(ixo^s,
xi_)
519 integer,
intent(in) :: ixI^L, ixO^L
520 double precision,
intent(in) :: w(ixI^S,nw),rhoh(ixO^S)
521 double precision,
intent(in) :: x(ixI^S,1:ndim)
522 double precision,
intent(out) :: csound2(ixO^S)
524 double precision :: rho(ixO^S)
536 integer,
intent(in) :: ixi^
l, ixo^
l
537 double precision,
intent(inout) :: w(ixi^s,nw)
538 double precision,
intent(in) :: x(ixi^s,1:
ndim)
539 double precision,
intent(out) :: csound2(ixo^s)
541 double precision :: rho(ixo^s),rhoh(ixo^s)
546 rho = w(ixo^s,
d_)/w(ixo^s,
lfac_)
547 rhoh = w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
558 integer,
intent(in) :: ixi^
l, ixo^
l
559 double precision,
intent(in) :: w(ixi^s, nw)
560 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
561 double precision,
intent(out) :: pth(ixi^s)
564 double precision :: rho(ixo^s),rhoh(ixo^s),e(ixo^s)
567 rho = w(ixo^s,
d_)/w(ixo^s,
lfac_)
568 rhoh = w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
575 subroutine srhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
578 integer,
intent(in) :: ixI^L, ixO^L
579 double precision,
intent(in) :: qdt,dtfactor
580 double precision,
intent(in) :: wCT(ixI^S, 1:nw),wCTprim(ixI^S,1:nw), x(ixI^S, 1:ndim)
581 double precision,
intent(inout) :: w(ixI^S, 1:nw)
582 logical,
intent(in) :: qsourcesplit
583 logical,
intent(inout) :: active
591 integer,
intent(in) :: ixI^L, ixO^L
592 double precision,
intent(in) :: dx^D, x(ixI^S, 1:^ND)
593 double precision,
intent(in) :: w(ixI^S, 1:nw)
594 double precision,
intent(inout) :: dtnew
605 integer,
intent(in) :: ixI^L, ixO^L, idim
606 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S, 1:ndim)
607 double precision,
intent(inout) :: cmax(ixI^S)
609 double precision,
dimension(ixO^S) :: csound2,tmp1,tmp2,v2
610 double precision,
dimension(ixI^S) :: vidim, cmin
612 logical :: flag(ixI^S,1:nw)
617 tmp1(ixo^s)=w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
618 v2(ixo^s)=1.0d0-1.0d0/w(ixo^s,
lfac_)**2
620 vidim(ixo^s) = w(ixo^s,
mom(idim))/w(ixo^s,
xi_)
621 tmp2(ixo^s)=vidim(ixo^s)**2.0d0
622 tmp1(ixo^s)=1.0d0-v2(ixo^s)*csound2(ixo^s) &
623 -tmp2(ixo^s)*(1.0d0-csound2(ixo^s))
624 tmp2(ixo^s)=dsqrt(csound2(ixo^s)*(one-v2(ixo^s))*tmp1(ixo^s))
625 tmp1(ixo^s)=vidim(ixo^s)*(one-csound2(ixo^s))
626 cmax(ixo^s)=(tmp1(ixo^s)+tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
627 cmin(ixo^s)=(tmp1(ixo^s)-tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
629 cmin(ixo^s) = max(cmin(ixo^s), - 1.0d0)
630 cmin(ixo^s) = min(cmin(ixo^s), 1.0d0)
631 cmax(ixo^s) = max(cmax(ixo^s), - 1.0d0)
632 cmax(ixo^s) = min(cmax(ixo^s), 1.0d0)
634 cmax(ixo^s) = max(dabs(cmax(ixo^s)),dabs(cmin(ixo^s)))
641 integer,
intent(in) :: ixI^L, ixO^L
642 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
643 double precision,
intent(inout) :: a2max(ndim)
644 double precision :: a2(ixI^S,ndim,nw)
645 integer :: gxO^L,hxO^L,jxO^L,kxO^L,i
650 hxo^l=ixo^l-
kr(i,^
d);
651 gxo^l=hxo^l-
kr(i,^
d);
652 jxo^l=ixo^l+
kr(i,^
d);
653 kxo^l=jxo^l+
kr(i,^
d);
654 a2(ixo^s,i,1:nwflux)=dabs(-w(kxo^s,1:nwflux)+16.d0*w(jxo^s,1:nwflux)&
655 -30.d0*w(ixo^s,1:nwflux)+16.d0*w(hxo^s,1:nwflux)-w(gxo^s,1:nwflux))
656 a2max(i)=maxval(a2(ixo^s,i,1:nwflux))/12.d0/
dxlevel(i)**2
664 integer,
intent(in) :: ixI^L, ixO^L
665 double precision,
intent(in) :: vidim(ixI^S)
666 double precision,
intent(in),
dimension(ixO^S) :: csound2
667 double precision,
intent(in) :: v2(ixI^S)
668 double precision,
intent(out) :: cmax(ixI^S)
669 double precision,
intent(out) :: cmin(ixI^S)
671 double precision,
dimension(ixI^S):: tmp1,tmp2
673 tmp2(ixo^s)=vidim(ixo^s)**2.0d0
674 tmp1(ixo^s)=1.0d0-v2(ixo^s)*csound2(ixo^s) &
675 -tmp2(ixo^s)*(1.0d0-csound2(ixo^s))
676 tmp2(ixo^s)=dsqrt(csound2(ixo^s)*(one-v2(ixo^s))*tmp1(ixo^s))
677 tmp1(ixo^s)=vidim(ixo^s)*(one-csound2(ixo^s))
678 cmax(ixo^s)=(tmp1(ixo^s)+tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
680 cmax(ixo^s) = max(cmax(ixo^s), - 1.0d0)
681 cmax(ixo^s) = min(cmax(ixo^s), 1.0d0)
682 cmin(ixo^s)=(tmp1(ixo^s)-tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
684 cmin(ixo^s) = max(cmin(ixo^s), - 1.0d0)
685 cmin(ixo^s) = min(cmin(ixo^s), 1.0d0)
691 subroutine srhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
695 integer,
intent(in) :: ixI^L, ixO^L, idim
697 double precision,
intent(in) :: wLC(ixI^S, nw), wRC(ixI^S, nw)
699 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
700 double precision,
intent(in) :: x(ixI^S, 1:ndim)
701 double precision,
intent(inout) :: cmax(ixI^S,1:number_species)
702 double precision,
intent(inout),
optional :: cmin(ixI^S,1:number_species)
703 double precision,
intent(in) :: Hspeed(ixI^S,1:number_species)
705 double precision :: wmean(ixI^S,nw)
706 double precision,
dimension(ixO^S) :: csound2,tmp1,tmp2,tmp3
707 double precision,
dimension(ixI^S) :: vidim,cmaxL,cmaxR,cminL,cminR,v2
709 logical :: flag(ixI^S,1:nw)
716 tmp2=wlp(ixo^s,
xi_)/wlp(ixo^s,
lfac_)**2.0d0
719 vidim(ixo^s) = wlp(ixo^s,
mom(idim))/wlp(ixo^s,
lfac_)
720 v2(ixo^s) = 1.0d0-1.0d0/wlp(ixo^s,
lfac_)**2
726 tmp2=wrp(ixo^s,
xi_)/wrp(ixo^s,
lfac_)**2.0d0
729 vidim(ixo^s) = wrp(ixo^s,
mom(idim))/wrp(ixo^s,
lfac_)
730 v2(ixo^s) = 1.0d0-1.0d0/wrp(ixo^s,
lfac_)**2
733 if(
present(cmin))
then
735 cmax(ixo^s,1)=max(cmaxl(ixo^s),cmaxr(ixo^s))
736 cmin(ixo^s,1)=min(cminl(ixo^s),cminr(ixo^s))
739 cmaxl(ixo^s)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
740 cmaxr(ixo^s)=max(cmaxr(ixo^s),dabs(cminr(ixo^s)))
741 cmax(ixo^s,1)=max(cmaxl(ixo^s),cmaxr(ixo^s))
749 tmp1=wmean(ixo^s,
xi_)/wmean(ixo^s,
lfac_)**2.0d0
751 vidim(ixo^s) = wmean(ixo^s,
mom(idim))/wmean(ixo^s,
xi_)
752 v2(ixo^s)=1.0d0-1.0d0/wmean(ixo^s,
lfac_)**2
754 if(
present(cmin))
then
755 cmax(ixo^s,1)=cmaxl(ixo^s)
756 cmin(ixo^s,1)=cminl(ixo^s)
758 cmax(ixo^s,1)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
766 tmp1=wmean(ixo^s,
rho_)
767 tmp2=wmean(ixo^s,
xi_)/wmean(ixo^s,
lfac_)**2.0d0
770 vidim(ixo^s) = wmean(ixo^s,
mom(idim))/wmean(ixo^s,
lfac_)
771 v2(ixo^s) = 1.0d0-1.0d0/wmean(ixo^s,
lfac_)**2
773 if(
present(cmin))
then
774 cmax(ixo^s,1)=cmaxl(ixo^s)
775 cmin(ixo^s,1)=cminl(ixo^s)
777 cmax(ixo^s,1)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
786 integer,
intent(in) :: ixI^L, ixO^L, idim
788 double precision,
intent(in) :: wC(ixI^S,nw)
790 double precision,
intent(in) :: wP(ixI^S,nw)
791 double precision,
intent(in) :: x(ixI^S,1:ndim)
792 double precision,
intent(out) :: f(ixI^S,nwflux)
794 double precision :: pth(ixI^S)
795 double precision :: v(ixI^S,1:ndir)
798 pth(ixo^s)=wp(ixo^s,
p_)
800 v(ixo^s,idir) = wp(ixo^s,
mom(idir))/wp(ixo^s,
lfac_)
804 f(ixo^s,
d_)=v(ixo^s,idim)*wc(ixo^s,
rho_)
814 f(ixo^s,
mom(idir))= v(ixo^s,idim)*wc(ixo^s,
mom(idir))
816 f(ixo^s,
mom(idim))=pth(ixo^s)+f(ixo^s,
mom(idim))
820 f(ixo^s,
e_)=v(ixo^s,idim)*(wc(ixo^s,
e_) + pth(ixo^s))
829 integer,
intent(in) :: ixI^L, ixO^L
830 double precision,
intent(in) :: qdt, dtfactor, x(ixI^S, 1:ndim)
831 double precision,
intent(inout) :: wCT(ixI^S, 1:nw), w(ixI^S, 1:nw)
833 double precision :: pth(ixI^S), source(ixI^S), v(ixI^S,1:ndir)
834 integer :: idir, h1x^L{^NOONED, h2x^L}
835 integer :: mr_,mphi_,vr_,vphi_,vtheta_
836 double precision :: exp_factor(ixI^S), del_exp_factor(ixI^S), exp_factor_primitive(ixI^S)
847 source(ixo^s) =
source(ixo^s)*del_exp_factor(ixo^s)/exp_factor(ixo^s)
860 source(ixo^s) =
source(ixo^s) + wct(ixo^s, mphi_)*v(ixo^s,vphi_)
861 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
862 source(ixo^s) = -wct(ixo^s, mphi_) * v(ixo^s,vr_)
863 w(ixo^s, mphi_) = w(ixo^s, mphi_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
865 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
870 h1x^l=ixo^l-
kr(1,^
d); {^nooned h2x^l=ixo^l-
kr(2,^
d);}
875 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
876 *(
block%surfaceC(ixo^s, 1) -
block%surfaceC(h1x^s, 1)) &
877 /
block%dvolume(ixo^s)
884 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s, 1)
889 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
890 * (
block%surfaceC(ixo^s, 2) -
block%surfaceC(h2x^s, 2)) &
891 /
block%dvolume(ixo^s)
893 source(ixo^s) =
source(ixo^s) + (wct(ixo^s,
mom(3))*v(ixo^s,ndir)) / dtan(x(ixo^s, 2))
896 w(ixo^s,
mom(2)) = w(ixo^s,
mom(2)) + qdt *
source(ixo^s) / x(ixo^s, 1)
901 source(ixo^s) = -(wct(ixo^s,
mom(3)) * v(ixo^s, vr_)) &
902 - (wct(ixo^s,
mom(3)) * v(ixo^s, vtheta_)) / dtan(x(ixo^s, 2))
903 w(ixo^s,
mom(3)) = w(ixo^s,
mom(3)) + qdt *
source(ixo^s) / x(ixo^s, 1)
914 logical,
intent(in) :: primitive
915 integer,
intent(in) :: ixI^L,ixO^L
916 double precision,
intent(inout) :: w(ixI^S,1:nw)
917 double precision,
intent(in) :: x(ixI^S,1:ndim)
918 character(len=*),
intent(in) :: subname
921 logical :: flag(ixI^S,1:nw),flagall(ixI^S)
929 flagall(ixo^s)=(flag(ixo^s,
rho_).or.flag(ixo^s,
e_))
931 where(flagall(ixo^s))
943 where(flagall(ixo^s)) w(ixo^s,
e_) =
small_e
963 if(.not.primitive)
then
965 write(*,*)
"handle_small_values default: note reporting conservatives!"
981 integer,
intent(in) :: ixi^l,ixo^l
982 double precision,
intent(in) :: w(ixi^s, 1:nw)
983 logical,
intent(in) :: varconserve
984 double precision,
intent(out) :: geff(ixi^s)
986 double precision,
dimension(ixO^S) :: pth,rho,e_th,e
989 if (varconserve)
then
990 pth(ixo^s)=w(ixo^s,
xi_)-w(ixo^s,
e_)-w(ixo^s,
d_)
991 rho(ixo^s)=w(ixo^s,
d_)/w(ixo^s,
lfac_)
993 e = e_th+dsqrt(e_th**2+rho**2)
995 (one-(rho(ixo^s)/e(ixo^s))**2)
999 e = e_th+dsqrt(e_th**2+w(ixo^s,
rho_)**2)
1001 (one-(w(ixo^s,
rho_)/e(ixo^s))**2)
1014 double precision :: LsmallE,Lsmallp,Lsmallrho
1021 call mpistop(
"must set finite values small-density/pressure for small value treatments")
1031 gamma_1*lsmallrho*(lsmallrho/lsmalle))
1045 integer,
intent(in) :: ixo^
l
1046 double precision,
intent(in) :: rho(ixo^s),p(ixo^s)
1047 double precision,
intent(out) :: rhoh(ixo^s)
1049 double precision,
dimension(ixO^S) :: e_th,e
1054 e = e_th+dsqrt(e_th**2+rho**2)
1063 {
do ix^db= ixo^lim^db\}
1065 write(*,*)
"local pressure and density",p(ix^
d),rho(ix^
d)
1066 write(*,*)
"Error: small value of enthalpy rho*h=",rhoh(ix^
d),&
1067 " encountered when call srhd_get_enthalpy_eos"
1068 call mpistop(
'enthalpy below small_xi: stop (may need to turn on fixes)')
1074 {
do ix^db= ixo^lim^db\}
1087 integer,
intent(in) :: ixI^L, ixO^L
1088 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S)
1089 double precision,
intent(out) :: p(ixI^S)
1090 double precision,
intent(out) :: E(ixO^S)
1094 e = (rhoh+dsqrt(rhoh**2+(
srhd_gamma**2-one)*rho**2)) &
1096 p(ixo^s) = half*
gamma_1* (e-rho*(rho/e))
1102 {
do ix^db= ixo^lim^db\}
1104 write(*,*)
"local enthalpy rho*h and density rho",rhoh(ix^d),rho(ix^d)
1105 if(
srhd_eos)
write(*,*)
'E, rho^2/E, difference', &
1106 e(ix^d),rho(ix^d)**2/e(ix^d),e(ix^d)-rho(ix^d)**2/e(ix^d)
1107 write(*,*)
"Error: small value of gas pressure",p(ix^d),&
1108 " encountered when call srhd_get_pressure_eos"
1109 call mpistop(
'pressure below small_pressure: stop (may need to turn on fixes)')
1115 {
do ix^db= ixo^lim^db\}
1129 integer,
intent(in) :: ixI^L, ixO^L
1130 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S)
1131 double precision,
intent(out) :: csound2(ixO^S)
1133 double precision :: p(ixI^S)
1134 double precision :: E(ixO^S)
1140 +
gamma_1*(rho(ixo^s)/e(ixo^s))**2))&
1141 /(2.0d0*rhoh(ixo^s))
1143 csound2(ixo^s)=
srhd_gamma*p(ixo^s)/rhoh(ixo^s)
1147 {
do ix^db= ixo^lim^db\}
1148 if(csound2(ix^d)>=1.0d0.or.csound2(ix^d)<=0.0d0)
then
1149 write(*,*)
"sound speed error with p - rho - rhoh",p(ix^d),rhoh(ix^d),rho(ix^d)
1150 if(
srhd_eos)
write(*,*)
'and E', e(ix^d)
1151 write(*,*)
"Error: value of csound2",csound2(ix^d),&
1152 " encountered when call srhd_get_csound2_eos"
1153 call mpistop(
'sound speed stop (may need to turn on fixes)')
1159 {
do ix^db= ixo^lim^db\}
1160 if(csound2(ix^d)>=1.0d0)
then
1161 csound2(ix^d)=1.0d0-1.0d0/
lfacmax**2
1163 if(csound2(ix^d)<=0.0d0)
then
1175 integer,
intent(in) :: ixO^L
1176 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S),p(ixO^S)
1177 double precision,
intent(out) :: csound2(ixO^S)
1179 double precision :: E(ixO^S)
1193 {
do ix^db= ixo^lim^db\}
1194 if(csound2(ix^d)>=1.0d0.or.csound2(ix^d)<=0.0d0)
then
1195 write(*,*)
"sound speed error with p - rho - rhoh",p(ix^d),rhoh(ix^d),rho(ix^d)
1196 if(
srhd_eos)
write(*,*)
'and E', e(ix^d)
1197 write(*,*)
"Error: value of csound2",csound2(ix^d),&
1198 " encountered when call srhd_get_csound2_prim_eos"
1199 call mpistop(
'sound speed stop (may need to turn on fixes)')
1205 {
do ix^db= ixo^lim^db\}
1206 if(csound2(ix^d)>=1.0d0)
then
1207 csound2(ix^d)=1.0d0-1.0d0/
lfacmax**2
1209 if(csound2(ix^d)<=0.0d0)
then
1221 double precision,
intent(in) :: myd, myssqr, mytau
1222 double precision,
intent(inout) :: lfac, xi
1223 integer,
intent(inout) :: ierror
1226 double precision:: f,df,lfacl
1230 d = myd;
ssqr = myssqr;
tau = mytau;
1237 if (ierror == 0 .and. dabs(f/df)<
absaccnr)
then
1245 write(*,*)
'entering con2prim_eos with xi=',xi
1254 call con2primhydro_eos(lfac,xi,
d,
ssqr,
tau,ierror)
1259 double precision,
intent(in) :: xi,d,ssqr,tau
1260 double precision,
intent(out) :: f,df,mylfac
1261 integer,
intent(inout) :: ierror
1264 double precision :: dlfac
1265 double precision :: vsqr,p,dpdxi
1271 mylfac = one/dsqrt(one-vsqr)
1272 dlfac = -mylfac**3*ssqr/(xi**3)
1274 call funcpressure_eos(xi,mylfac,d,dlfac,p,dpdxi)
1288 subroutine con2primhydro_eos(lfac,xi,d,sqrs,tau,ierror)
1289 double precision,
intent(out) :: xi,lfac
1290 double precision,
intent(in) :: d,sqrs,tau
1291 integer,
intent(inout) :: ierror
1294 integer :: ni,niiter,nit,n2it,ni3
1295 double precision :: pcurrent,pnew
1296 double precision :: er,er1,ff,df,dp,v2
1297 double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
1298 double precision :: s2overcubeG2rh
1299 double precision :: xicurrent,h,dhdp
1300 double precision :: oldff1,oldff2,Nff
1301 double precision :: pleft,pright
1316 pmin=dsqrt(sqrs)/(one-
dmaxvel)-tau-d
1317 plabs=max(
minp,pmin)
1336 pcurrent=half*(pcurrent+pprev)
1344 xicurrent=tau+d+pcurrent
1356 v2=sqrs/xicurrent**2
1358 if(lfac2inv>zero)
then
1359 lfac=one/dsqrt(lfac2inv)
1371 s2overcubeg2rh=sqrs/(xicurrent**3)
1373 call funcenthalpy_eos(pcurrent,lfac2inv,d,sqrs,xicurrent,&
1374 s2overcubeg2rh,h,dhdp)
1376 ff=-xicurrent*lfac2inv + h
1377 df=- two*sqrs/xicurrent**2 + dhdp - lfac2inv
1379 if (ff*df==zero)
then
1389 if (ff*df>zero)
then
1392 pnew=max(pnew,plabs)
1396 pnew=min(pnew,prabs)
1402 er=two*dabs(dp)/(pnew+pcurrent)
1408 if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >=
maxitnr-
maxitnr/20).and.&
1409 ff * oldff1 < zero .and. dabs(ff)>
absaccnr)
then
1412 if(n2it<=3) pcurrent=half*(pnew+pcurrent)
1416 pcurrent=half*(pleft+pright)
1419 xicurrent=tau+d+pcurrent
1420 v2=sqrs/xicurrent**2
1423 if(lfac2inv>zero)
then
1424 lfac=one/dsqrt(lfac2inv)
1432 call bisection_enthalpy_eos(pnew,lfac2inv,d,xicurrent,h)
1433 nff=-xicurrent*lfac2inv + h
1436 if(ff * nff < zero)
then
1442 pcurrent=half*(pleft+pright)
1446 if(2.0d0*dabs(pleft-pright)/(pleft+pright)<
absaccnr &
1480 if(pcurrent<
minp)
then
1487 v2=sqrs/xicurrent**2
1489 if(lfac2inv>zero)
then
1490 lfac=one/dsqrt(lfac2inv)
1496 end subroutine con2primhydro_eos
1500 subroutine funcpressure_eos(xicurrent,lfac,d,dlfacdxi,p,dpdxi)
1502 double precision,
intent(in) :: xicurrent,lfac,d,dlfacdxi
1503 double precision,
intent(out) :: p,dpdxi
1505 double precision :: rho,h,E,dhdxi,rhotoE
1506 double precision :: dpdchi,dEdxi
1509 h=xicurrent/(lfac**2)
1511 e = (h+dsqrt(h**2+(
srhd_gamma**2-one)*rho**2)) &
1515 p = half*
gamma_1*(e-rho*rhotoe)
1517 dhdxi = one/(lfac**2)-2.0d0*xicurrent/(lfac**2)*dlfacdxi/lfac
1519 dedxi=(dhdxi+(h*dhdxi-(
srhd_gamma**2-one)*rho**2*dlfacdxi/lfac)&
1524 dpdxi=half*
gamma_1*(2.0d0*rho*rhotoe*dlfacdxi/lfac+&
1525 (one+rhotoe**2)*dedxi)
1527 end subroutine funcpressure_eos
1531 subroutine funcenthalpy_eos(pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p,h,dhdp)
1533 double precision,
intent(in) :: pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p
1534 double precision,
intent(out):: h,dhdp
1537 double precision:: rho,E_th,E,dE_thdp,dEdp
1539 rho=d*dsqrt(lfac2inv)
1541 e = (e_th + dsqrt(e_th**2+rho**2))
1547 dedp = de_thdp * (one+e_th/dsqrt(e_th**2+rho**2))&
1548 + d**2*dv2d2p/dsqrt(e_th**2+rho**2)
1551 gamma_1*(rho*(rho/e))*(-2.0d0*dv2d2p/lfac2inv+dedp/e))
1552 end subroutine funcenthalpy_eos
1556 subroutine bisection_enthalpy_eos(pcurrent,lfac2inv,d,xicurrent,h)
1558 double precision,
intent(in) :: pcurrent,lfac2inv,d,xicurrent
1559 double precision,
intent(out):: h
1562 double precision:: rho,E_th,E
1564 rho=d*dsqrt(lfac2inv)
1566 e = (e_th + dsqrt(e_th**2+rho**2))
1571 end subroutine bisection_enthalpy_eos
1574 subroutine con2prim(lfac,xi,myd,myssqr,mytau,ierror)
1577 double precision,
intent(in) :: myd, myssqr, mytau
1578 double precision,
intent(inout) :: lfac, xi
1579 integer,
intent(inout) :: ierror
1582 double precision:: f,df,lfacl
1586 d = myd;
ssqr = myssqr;
tau = mytau;
1593 if (ierror == 0 .and. dabs(f/df)<
absaccnr)
then
1601 write(*,*)
'entering con2prim with xi=',xi
1610 call con2primhydro(lfac,xi,
d,
ssqr,
tau,ierror)
1612 end subroutine con2prim
1614 subroutine funcd(xi,f,df,mylfac,d,ssqr,tau,ierror)
1615 double precision,
intent(in) :: xi,d,ssqr,tau
1616 double precision,
intent(out) :: f,df,mylfac
1617 integer,
intent(inout) :: ierror
1620 double precision :: dlfac
1621 double precision :: vsqr,p,dpdxi
1627 mylfac = one/dsqrt(one-vsqr)
1628 dlfac = -mylfac**3*ssqr/(xi**3)
1630 call funcpressure(xi,mylfac,d,dlfac,p,dpdxi)
1641 end subroutine funcd
1644 subroutine con2primhydro(lfac,xi,d,sqrs,tau,ierror)
1645 double precision,
intent(out) :: xi,lfac
1646 double precision,
intent(in) :: d,sqrs,tau
1647 integer,
intent(inout) :: ierror
1650 integer :: ni,niiter,nit,n2it,ni3
1651 double precision :: pcurrent,pnew
1652 double precision :: er,er1,ff,df,dp,v2
1653 double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
1654 double precision :: s2overcubeG2rh
1655 double precision :: xicurrent,h,dhdp
1656 double precision :: oldff1,oldff2,Nff
1657 double precision :: pleft,pright
1672 pmin=dsqrt(sqrs)/(one-
dmaxvel)-tau-d
1673 plabs=max(
minp,pmin)
1692 pcurrent=half*(pcurrent+pprev)
1700 xicurrent=tau+d+pcurrent
1712 v2=sqrs/xicurrent**2
1714 if(lfac2inv>zero)
then
1715 lfac=one/dsqrt(lfac2inv)
1727 s2overcubeg2rh=sqrs/(xicurrent**3)
1729 call funcenthalpy(pcurrent,lfac2inv,d,sqrs,xicurrent,&
1730 s2overcubeg2rh,h,dhdp)
1732 ff=-xicurrent*lfac2inv + h
1733 df=- two*sqrs/xicurrent**2 + dhdp - lfac2inv
1735 if (ff*df==zero)
then
1745 if (ff*df>zero)
then
1748 pnew=max(pnew,plabs)
1752 pnew=min(pnew,prabs)
1758 er=two*dabs(dp)/(pnew+pcurrent)
1764 if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >=
maxitnr-
maxitnr/20).and.&
1765 ff * oldff1 < zero .and. dabs(ff)>
absaccnr)
then
1768 if(n2it<=3) pcurrent=half*(pnew+pcurrent)
1772 pcurrent=half*(pleft+pright)
1775 xicurrent=tau+d+pcurrent
1776 v2=sqrs/xicurrent**2
1779 if(lfac2inv>zero)
then
1780 lfac=one/dsqrt(lfac2inv)
1788 call bisection_enthalpy(pnew,lfac2inv,d,xicurrent,h)
1789 nff=-xicurrent*lfac2inv + h
1792 if(ff * nff < zero)
then
1798 pcurrent=half*(pleft+pright)
1802 if(2.0d0*dabs(pleft-pright)/(pleft+pright)<
absaccnr &
1836 if(pcurrent<
minp)
then
1843 v2=sqrs/xicurrent**2
1845 if(lfac2inv>zero)
then
1846 lfac=one/dsqrt(lfac2inv)
1852 end subroutine con2primhydro
1856 subroutine funcpressure(xicurrent,lfac,d,dlfacdxi,p,dpdxi)
1858 double precision,
intent(in) :: xicurrent,lfac,d,dlfacdxi
1859 double precision,
intent(out) :: p,dpdxi
1861 double precision :: rho,h,E,dhdxi,rhotoE
1862 double precision :: dpdchi,dEdxi
1865 h=xicurrent/(lfac**2)
1870 dpdxi = dpdchi * one/lfac**2
1872 if (dlfacdxi /= 0.0d0) &
1873 dpdxi = dpdxi + dpdchi * ((d*lfac-2.0d0*xicurrent)/lfac**3) * dlfacdxi
1875 end subroutine funcpressure
1879 subroutine funcenthalpy(pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p,h,dhdp)
1881 double precision,
intent(in) :: pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p
1882 double precision,
intent(out):: h,dhdp
1885 double precision:: rho,E_th,E,dE_thdp,dEdp
1887 rho=d*dsqrt(lfac2inv)
1890 end subroutine funcenthalpy
1894 subroutine bisection_enthalpy(pcurrent,lfac2inv,d,xicurrent,h)
1896 double precision,
intent(in) :: pcurrent,lfac2inv,d,xicurrent
1897 double precision,
intent(out):: h
1900 double precision:: rho,E_th,E
1902 rho=d*dsqrt(lfac2inv)
1906 end subroutine bisection_enthalpy
Calculate w(iw)=w(iw)+qdt*SOURCE[wCT,qtC,x] within ixO for all indices iw=iwmin......
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
Module with geometry-related routines (e.g., divergence, curl)
integer, parameter spherical
integer, parameter cylindrical
integer, parameter cartesian_expansion
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
double precision small_pressure
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
integer, parameter unitpar
file handle for IO
double precision unit_mass
Physical scaling factor for mass.
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision unit_numberdensity
Physical scaling factor for number density.
double precision unit_pressure
Physical scaling factor for pressure.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision unit_length
Physical scaling factor for length.
logical use_particles
Use particles module or not.
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
integer ndir
Number of spatial dimensions (components) for vector variables.
double precision unit_velocity
Physical scaling factor for velocity.
double precision unit_temperature
Physical scaling factor for temperature.
logical si_unit
Use SI units (.true.) or use cgs units (.false.)
logical phys_trac
Use TRAC (Johnston 2019 ApJL, 873, L22) for MHD or 1D HD.
double precision small_density
integer r_
Indices for cylindrical coordinates FOR TESTS, negative value when not used:
integer boundspeed
bound (left/min and right.max) speed of Riemann fan
double precision, dimension(ndim) dxlevel
logical check_small_values
check and optionally fix unphysical small values (density, gas pressure)
Module containing all the particle routines.
subroutine particles_init()
Initialize particle data and parameters.
This module defines the procedures of a physics module. It contains function pointers for the various...
Module for handling problematic values in simulations, such as negative pressures.
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
subroutine, public small_values_average(ixIL, ixOL, w, x, w_flag, windex)
subroutine, public small_values_error(wprim, x, ixIL, ixOL, w_flag, subname)
character(len=20), public small_values_method
How to handle small values.
Special Relativistic Hydrodynamics (with EOS) physics module.
subroutine srhd_add_source(qdt, dtfactor, ixIL, ixOL, wCT, wCTprim, w, x, qsourcesplit, active)
dummy addsource subroutine
subroutine srhd_get_flux(wC, wP, x, ixIL, ixOL, idim, f)
Calculate fluxes within ixO^L.
logical, public, protected srhd_force_diagonal
Allows overruling default corner filling (for debug mode, otherwise corner primitives fail)
subroutine srhd_physical_units
double precision, public tolernr
subroutine srhd_get_cmax_loc(ixIL, ixOL, vidim, csound2, v2, cmax, cmin)
local version for recycling code when computing cmax-cmin
integer, public, protected srhd_n_tracer
Number of tracer species.
double precision, public inv_gamma_1
subroutine srhd_write_info(fh)
Write this module's parameters to a snapshot.
subroutine srhd_get_cmax(w, x, ixIL, ixOL, idim, cmax)
Calculate cmax_idim within ixO^L used especially for setdt CFL limit.
integer, dimension(:), allocatable, public, protected tracer
Indices of the tracers.
subroutine, public srhd_get_auxiliary(ixIL, ixOL, w, x)
Compute auxiliary variables lfac and xi from a conservative state using srhd_con2prim to calculate en...
subroutine, public srhd_get_pthermal(w, x, ixIL, ixOL, pth)
Calculate thermal pressure p within ixO^L must follow after update conservative with auxiliaries.
double precision, public absaccnr
double precision, public small_e
The smallest allowed energy.
integer, public, protected lfac_
Index of the Lorentz factor.
subroutine funcd_eos(xi, f, df, mylfac, d, ssqr, tau, ierror)
double precision, public gamma_to_gamma_1
subroutine funcd(xi, f, df, mylfac, d, ssqr, tau, ierror)
subroutine srhd_get_csound2_eos(ixIL, ixOL, rho, rhoh, csound2)
Calculate the square of the thermal sound speed csound2 within ixO^L. available rho - rho*h.
subroutine, public srhd_get_auxiliary_prim(ixIL, ixOL, w)
Set auxiliary variables lfac and xi from a primitive state only used when handle_small_values average...
integer, public maxitnr
parameters for NR in con2prim
subroutine, public srhd_phys_init()
Initialize the module.
double precision, public gamma_1
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
subroutine, public srhd_get_csound2(w, x, ixIL, ixOL, csound2)
Calculate the square of the thermal sound speed csound2 within ixO^L. here computed from conservative...
double precision, public small_xi
The smallest allowed inertia.
subroutine, public srhd_to_conserved(ixIL, ixOL, w, x)
Transform primitive variables into conservative ones.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
subroutine srhd_get_csound2_rhoh(w, x, ixIL, ixOL, rhoh, csound2)
Calculate the square of the thermal sound speed csound2 within ixO^L. here computed from conservative...
subroutine srhd_get_v(w, x, ixIL, ixOL, v)
Calculate v vector from conservatives.
subroutine, public srhd_get_enthalpy_eos(ixOL, rho, p, rhoh)
Compute the enthalpy rho*h from rho and pressure p.
double precision, public minp
subroutine, public srhd_to_primitive(ixIL, ixOL, w, x)
Transform conservative variables into primitive ones.
logical, public srhd_eos
Whether synge eos is used.
double precision, public lfacmax
integer, public, protected d_
subroutine srhd_handle_small_values(primitive, w, x, ixIL, ixOL, subname)
handles bootstrapping
subroutine srhd_get_dt(w, ixIL, ixOL, dtnew, dxD, x)
dummy get_dt subroutine
subroutine srhd_get_smallvalues_eos
Compute the small value limits.
subroutine srhd_add_source_geom(qdt, dtfactor, ixIL, ixOL, wCT, w, x)
Add geometrical source terms to w.
subroutine srhd_get_pressure_eos(ixIL, ixOL, rho, rhoh, p, E)
Calculate thermal pressure p from density rho and enthalpy rho*h will provide p (and E if srhd_eos)
subroutine, public srhd_check_params
integer, public, protected p_
Index of the gas pressure should equal e_.
subroutine con2prim_eos(lfac, xi, myd, myssqr, mytau, ierror)
con2prim: (D,S**2,tau) --> compute auxiliaries lfac and xi
subroutine srhd_get_csound2_prim_eos(ixOL, rho, rhoh, p, csound2)
Calculate the square of the thermal sound speed csound2 within ixO^L. available rho - rho*h - p.
subroutine srhd_get_cbounds(wLC, wRC, wLp, wRp, x, ixIL, ixOL, idim, Hspeed, cmax, cmin)
Estimating bounds for the minimum and maximum signal velocities here we will not use Hspeed at all (o...
logical, public, protected srhd_particles
Whether particles module is added.
double precision, public smalltau
double precision, public dmaxvel
integer, public, protected e_
Index of the energy density.
subroutine srhd_check_w_aux(ixIL, ixOL, w, flag)
Returns logical argument flag T where auxiliary values are not ok.
double precision, public minrho
subroutine, public srhd_check_w(primitive, ixIL, ixOL, w, flag)
Returns logical argument flag T where values are not ok.
subroutine srhd_get_a2max(w, x, ixIL, ixOL, a2max)
double precision, public smallxi
integer, public, protected xi_
Index of the inertia.
double precision, public srhd_gamma
The adiabatic index and derived values.
integer, public, protected rho_
Index of the density (in the w array)
subroutine, public srhd_get_geff_eos(w, ixIL, ixOL, varconserve, Geff)
calculate effective gamma
Module with all the methods that users can customize in AMRVAC.
procedure(set_surface), pointer usr_set_surface
integer nwflux
Number of flux variables.