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 :: wc(ixI^S,nw)
610 double precision,
dimension(ixO^S) :: csound2,tmp1,tmp2,v2
611 double precision,
dimension(ixI^S) :: vidim, cmin
613 logical :: flag(ixI^S,1:nw)
621 tmp1(ixo^s)=wc(ixo^s,
xi_)/wc(ixo^s,
lfac_)**2.0d0
622 v2(ixo^s)=1.0d0-1.0d0/wc(ixo^s,
lfac_)**2
624 vidim(ixo^s) = wc(ixo^s,
mom(idim))/wc(ixo^s,
xi_)
625 tmp2(ixo^s)=vidim(ixo^s)**2.0d0
626 tmp1(ixo^s)=1.0d0-v2(ixo^s)*csound2(ixo^s) &
627 -tmp2(ixo^s)*(1.0d0-csound2(ixo^s))
628 tmp2(ixo^s)=dsqrt(csound2(ixo^s)*(one-v2(ixo^s))*tmp1(ixo^s))
629 tmp1(ixo^s)=vidim(ixo^s)*(one-csound2(ixo^s))
630 cmax(ixo^s)=(tmp1(ixo^s)+tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
631 cmin(ixo^s)=(tmp1(ixo^s)-tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
633 cmin(ixo^s) = max(cmin(ixo^s), - 1.0d0)
634 cmin(ixo^s) = min(cmin(ixo^s), 1.0d0)
635 cmax(ixo^s) = max(cmax(ixo^s), - 1.0d0)
636 cmax(ixo^s) = min(cmax(ixo^s), 1.0d0)
638 cmax(ixo^s) = max(dabs(cmax(ixo^s)),dabs(cmin(ixo^s)))
645 integer,
intent(in) :: ixI^L, ixO^L
646 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
647 double precision,
intent(inout) :: a2max(ndim)
648 double precision :: a2(ixI^S,ndim,nw)
649 integer :: gxO^L,hxO^L,jxO^L,kxO^L,i
654 hxo^l=ixo^l-
kr(i,^
d);
655 gxo^l=hxo^l-
kr(i,^
d);
656 jxo^l=ixo^l+
kr(i,^
d);
657 kxo^l=jxo^l+
kr(i,^
d);
658 a2(ixo^s,i,1:nwflux)=dabs(-w(kxo^s,1:nwflux)+16.d0*w(jxo^s,1:nwflux)&
659 -30.d0*w(ixo^s,1:nwflux)+16.d0*w(hxo^s,1:nwflux)-w(gxo^s,1:nwflux))
660 a2max(i)=maxval(a2(ixo^s,i,1:nwflux))/12.d0/
dxlevel(i)**2
668 integer,
intent(in) :: ixI^L, ixO^L
669 double precision,
intent(in) :: vidim(ixI^S)
670 double precision,
intent(in),
dimension(ixO^S) :: csound2
671 double precision,
intent(in) :: v2(ixI^S)
672 double precision,
intent(out) :: cmax(ixI^S)
673 double precision,
intent(out) :: cmin(ixI^S)
675 double precision,
dimension(ixI^S):: tmp1,tmp2
677 tmp2(ixo^s)=vidim(ixo^s)**2.0d0
678 tmp1(ixo^s)=1.0d0-v2(ixo^s)*csound2(ixo^s) &
679 -tmp2(ixo^s)*(1.0d0-csound2(ixo^s))
680 tmp2(ixo^s)=dsqrt(csound2(ixo^s)*(one-v2(ixo^s))*tmp1(ixo^s))
681 tmp1(ixo^s)=vidim(ixo^s)*(one-csound2(ixo^s))
682 cmax(ixo^s)=(tmp1(ixo^s)+tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
684 cmax(ixo^s) = max(cmax(ixo^s), - 1.0d0)
685 cmax(ixo^s) = min(cmax(ixo^s), 1.0d0)
686 cmin(ixo^s)=(tmp1(ixo^s)-tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
688 cmin(ixo^s) = max(cmin(ixo^s), - 1.0d0)
689 cmin(ixo^s) = min(cmin(ixo^s), 1.0d0)
695 subroutine srhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
699 integer,
intent(in) :: ixI^L, ixO^L, idim
701 double precision,
intent(in) :: wLC(ixI^S, nw), wRC(ixI^S, nw)
703 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
704 double precision,
intent(in) :: x(ixI^S, 1:ndim)
705 double precision,
intent(inout) :: cmax(ixI^S,1:number_species)
706 double precision,
intent(inout),
optional :: cmin(ixI^S,1:number_species)
707 double precision,
intent(in) :: Hspeed(ixI^S,1:number_species)
709 double precision :: wmean(ixI^S,nw)
710 double precision,
dimension(ixO^S) :: csound2,tmp1,tmp2,tmp3
711 double precision,
dimension(ixI^S) :: vidim,cmaxL,cmaxR,cminL,cminR,v2
713 logical :: flag(ixI^S,1:nw)
720 tmp2=wlp(ixo^s,
xi_)/wlp(ixo^s,
lfac_)**2.0d0
723 vidim(ixo^s) = wlp(ixo^s,
mom(idim))/wlp(ixo^s,
lfac_)
724 v2(ixo^s) = 1.0d0-1.0d0/wlp(ixo^s,
lfac_)**2
730 tmp2=wrp(ixo^s,
xi_)/wrp(ixo^s,
lfac_)**2.0d0
733 vidim(ixo^s) = wrp(ixo^s,
mom(idim))/wrp(ixo^s,
lfac_)
734 v2(ixo^s) = 1.0d0-1.0d0/wrp(ixo^s,
lfac_)**2
737 if(
present(cmin))
then
739 cmax(ixo^s,1)=max(cmaxl(ixo^s),cmaxr(ixo^s))
740 cmin(ixo^s,1)=min(cminl(ixo^s),cminr(ixo^s))
743 cmaxl(ixo^s)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
744 cmaxr(ixo^s)=max(cmaxr(ixo^s),dabs(cminr(ixo^s)))
745 cmax(ixo^s,1)=max(cmaxl(ixo^s),cmaxr(ixo^s))
753 tmp1=wmean(ixo^s,
xi_)/wmean(ixo^s,
lfac_)**2.0d0
755 vidim(ixo^s) = wmean(ixo^s,
mom(idim))/wmean(ixo^s,
xi_)
756 v2(ixo^s)=1.0d0-1.0d0/wmean(ixo^s,
lfac_)**2
758 if(
present(cmin))
then
759 cmax(ixo^s,1)=cmaxl(ixo^s)
760 cmin(ixo^s,1)=cminl(ixo^s)
762 cmax(ixo^s,1)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
770 tmp1=wmean(ixo^s,
rho_)
771 tmp2=wmean(ixo^s,
xi_)/wmean(ixo^s,
lfac_)**2.0d0
774 vidim(ixo^s) = wmean(ixo^s,
mom(idim))/wmean(ixo^s,
lfac_)
775 v2(ixo^s) = 1.0d0-1.0d0/wmean(ixo^s,
lfac_)**2
777 if(
present(cmin))
then
778 cmax(ixo^s,1)=cmaxl(ixo^s)
779 cmin(ixo^s,1)=cminl(ixo^s)
781 cmax(ixo^s,1)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
790 integer,
intent(in) :: ixI^L, ixO^L, idim
792 double precision,
intent(in) :: wC(ixI^S,nw)
794 double precision,
intent(in) :: wP(ixI^S,nw)
795 double precision,
intent(in) :: x(ixI^S,1:ndim)
796 double precision,
intent(out) :: f(ixI^S,nwflux)
798 double precision :: pth(ixI^S)
799 double precision :: v(ixI^S,1:ndir)
802 pth(ixo^s)=wp(ixo^s,
p_)
804 v(ixo^s,idir) = wp(ixo^s,
mom(idir))/wp(ixo^s,
lfac_)
808 f(ixo^s,
d_)=v(ixo^s,idim)*wc(ixo^s,
rho_)
818 f(ixo^s,
mom(idir))= v(ixo^s,idim)*wc(ixo^s,
mom(idir))
820 f(ixo^s,
mom(idim))=pth(ixo^s)+f(ixo^s,
mom(idim))
824 f(ixo^s,
e_)=v(ixo^s,idim)*(wc(ixo^s,
e_) + pth(ixo^s))
833 integer,
intent(in) :: ixI^L, ixO^L
834 double precision,
intent(in) :: qdt, dtfactor, x(ixI^S, 1:ndim)
835 double precision,
intent(inout) :: wCT(ixI^S, 1:nw), wprim(ixI^S, 1:nw), w(ixI^S, 1:nw)
837 double precision :: pth(ixI^S), source(ixI^S), v(ixI^S,1:ndir)
838 integer :: idir, h1x^L{^NOONED, h2x^L}
840 double precision :: exp_factor(ixI^S), del_exp_factor(ixI^S), exp_factor_primitive(ixI^S)
851 source(ixo^s) =
source(ixo^s)*del_exp_factor(ixo^s)/exp_factor(ixo^s)
862 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
863 source(ixo^s) = -wct(ixo^s, mphi_) * wprim(ixo^s,
mom(
r_))
864 w(ixo^s, mphi_) = w(ixo^s, mphi_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
866 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
871 h1x^l=ixo^l-
kr(1,^
d); {^nooned h2x^l=ixo^l-
kr(2,^
d);}
876 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
877 *(
block%surfaceC(ixo^s, 1) -
block%surfaceC(h1x^s, 1)) &
878 /
block%dvolume(ixo^s)
884 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s, 1)
888 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
889 * (
block%surfaceC(ixo^s, 2) -
block%surfaceC(h2x^s, 2)) &
890 /
block%dvolume(ixo^s)
892 source(ixo^s) =
source(ixo^s) + (wct(ixo^s,
mom(3))*v(ixo^s,ndir)) / dtan(x(ixo^s, 2))
895 w(ixo^s,
mom(2)) = w(ixo^s,
mom(2)) + qdt *
source(ixo^s) / x(ixo^s, 1)
899 source(ixo^s) = -(wct(ixo^s,
mom(3)) * wprim(ixo^s,
mom(1))) &
900 - (wct(ixo^s,
mom(3)) * wprim(ixo^s,
mom(2))) / dtan(x(ixo^s, 2))
901 w(ixo^s,
mom(3)) = w(ixo^s,
mom(3)) + qdt *
source(ixo^s) / x(ixo^s, 1)
912 logical,
intent(in) :: primitive
913 integer,
intent(in) :: ixI^L,ixO^L
914 double precision,
intent(inout) :: w(ixI^S,1:nw)
915 double precision,
intent(in) :: x(ixI^S,1:ndim)
916 character(len=*),
intent(in) :: subname
919 logical :: flag(ixI^S,1:nw),flagall(ixI^S)
927 flagall(ixo^s)=(flag(ixo^s,
rho_).or.flag(ixo^s,
e_))
929 where(flagall(ixo^s))
941 where(flagall(ixo^s)) w(ixo^s,
e_) =
small_e
961 if(.not.primitive)
then
963 write(*,*)
"handle_small_values default: note reporting conservatives!"
979 integer,
intent(in) :: ixi^l,ixo^l
980 double precision,
intent(in) :: w(ixi^s, 1:nw)
981 logical,
intent(in) :: varconserve
982 double precision,
intent(out) :: geff(ixi^s)
984 double precision,
dimension(ixO^S) :: pth,rho,e_th,e
987 if (varconserve)
then
988 pth(ixo^s)=w(ixo^s,
xi_)-w(ixo^s,
e_)-w(ixo^s,
d_)
989 rho(ixo^s)=w(ixo^s,
d_)/w(ixo^s,
lfac_)
991 e = e_th+dsqrt(e_th**2+rho**2)
993 (one-(rho(ixo^s)/e(ixo^s))**2)
997 e = e_th+dsqrt(e_th**2+w(ixo^s,
rho_)**2)
999 (one-(w(ixo^s,
rho_)/e(ixo^s))**2)
1012 double precision :: LsmallE,Lsmallp,Lsmallrho
1019 call mpistop(
"must set finite values small-density/pressure for small value treatments")
1029 gamma_1*lsmallrho*(lsmallrho/lsmalle))
1043 integer,
intent(in) :: ixo^
l
1044 double precision,
intent(in) :: rho(ixo^s),p(ixo^s)
1045 double precision,
intent(out) :: rhoh(ixo^s)
1047 double precision,
dimension(ixO^S) :: e_th,e
1052 e = e_th+dsqrt(e_th**2+rho**2)
1061 {
do ix^db= ixo^lim^db\}
1063 write(*,*)
"local pressure and density",p(ix^
d),rho(ix^
d)
1064 write(*,*)
"Error: small value of enthalpy rho*h=",rhoh(ix^
d),&
1065 " encountered when call srhd_get_enthalpy_eos"
1066 call mpistop(
'enthalpy below small_xi: stop (may need to turn on fixes)')
1072 {
do ix^db= ixo^lim^db\}
1085 integer,
intent(in) :: ixI^L, ixO^L
1086 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S)
1087 double precision,
intent(out) :: p(ixI^S)
1088 double precision,
intent(out) :: E(ixO^S)
1092 e = (rhoh+dsqrt(rhoh**2+(
srhd_gamma**2-one)*rho**2)) &
1094 p(ixo^s) = half*
gamma_1* (e-rho*(rho/e))
1100 {
do ix^db= ixo^lim^db\}
1102 write(*,*)
"local enthalpy rho*h and density rho",rhoh(ix^d),rho(ix^d)
1103 if(
srhd_eos)
write(*,*)
'E, rho^2/E, difference', &
1104 e(ix^d),rho(ix^d)**2/e(ix^d),e(ix^d)-rho(ix^d)**2/e(ix^d)
1105 write(*,*)
"Error: small value of gas pressure",p(ix^d),&
1106 " encountered when call srhd_get_pressure_eos"
1107 call mpistop(
'pressure below small_pressure: stop (may need to turn on fixes)')
1113 {
do ix^db= ixo^lim^db\}
1127 integer,
intent(in) :: ixI^L, ixO^L
1128 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S)
1129 double precision,
intent(out) :: csound2(ixO^S)
1131 double precision :: p(ixI^S)
1132 double precision :: E(ixO^S)
1138 +
gamma_1*(rho(ixo^s)/e(ixo^s))**2))&
1139 /(2.0d0*rhoh(ixo^s))
1141 csound2(ixo^s)=
srhd_gamma*p(ixo^s)/rhoh(ixo^s)
1145 {
do ix^db= ixo^lim^db\}
1146 if(csound2(ix^d)>=1.0d0.or.csound2(ix^d)<=0.0d0)
then
1147 write(*,*)
"sound speed error with p - rho - rhoh",p(ix^d),rhoh(ix^d),rho(ix^d)
1148 if(
srhd_eos)
write(*,*)
'and E', e(ix^d)
1149 write(*,*)
"Error: value of csound2",csound2(ix^d),&
1150 " encountered when call srhd_get_csound2_eos"
1151 call mpistop(
'sound speed stop (may need to turn on fixes)')
1157 {
do ix^db= ixo^lim^db\}
1158 if(csound2(ix^d)>=1.0d0)
then
1159 csound2(ix^d)=1.0d0-1.0d0/
lfacmax**2
1161 if(csound2(ix^d)<=0.0d0)
then
1173 integer,
intent(in) :: ixO^L
1174 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S),p(ixO^S)
1175 double precision,
intent(out) :: csound2(ixO^S)
1177 double precision :: E(ixO^S)
1191 {
do ix^db= ixo^lim^db\}
1192 if(csound2(ix^d)>=1.0d0.or.csound2(ix^d)<=0.0d0)
then
1193 write(*,*)
"sound speed error with p - rho - rhoh",p(ix^d),rhoh(ix^d),rho(ix^d)
1194 if(
srhd_eos)
write(*,*)
'and E', e(ix^d)
1195 write(*,*)
"Error: value of csound2",csound2(ix^d),&
1196 " encountered when call srhd_get_csound2_prim_eos"
1197 call mpistop(
'sound speed stop (may need to turn on fixes)')
1203 {
do ix^db= ixo^lim^db\}
1204 if(csound2(ix^d)>=1.0d0)
then
1205 csound2(ix^d)=1.0d0-1.0d0/
lfacmax**2
1207 if(csound2(ix^d)<=0.0d0)
then
1219 double precision,
intent(in) :: myd, myssqr, mytau
1220 double precision,
intent(inout) :: lfac, xi
1221 integer,
intent(inout) :: ierror
1224 double precision:: f,df,lfacl
1228 d = myd;
ssqr = myssqr;
tau = mytau;
1235 if (ierror == 0 .and. dabs(f/df)<
absaccnr)
then
1243 write(*,*)
'entering con2prim_eos with xi=',xi
1252 call con2primhydro_eos(lfac,xi,
d,
ssqr,
tau,ierror)
1257 double precision,
intent(in) :: xi,d,ssqr,tau
1258 double precision,
intent(out) :: f,df,mylfac
1259 integer,
intent(inout) :: ierror
1262 double precision :: dlfac
1263 double precision :: vsqr,p,dpdxi
1269 mylfac = one/dsqrt(one-vsqr)
1270 dlfac = -mylfac**3*ssqr/(xi**3)
1272 call funcpressure_eos(xi,mylfac,d,dlfac,p,dpdxi)
1286 subroutine con2primhydro_eos(lfac,xi,d,sqrs,tau,ierror)
1287 double precision,
intent(out) :: xi,lfac
1288 double precision,
intent(in) :: d,sqrs,tau
1289 integer,
intent(inout) :: ierror
1292 integer :: ni,niiter,nit,n2it,ni3
1293 double precision :: pcurrent,pnew
1294 double precision :: er,er1,ff,df,dp,v2
1295 double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
1296 double precision :: s2overcubeG2rh
1297 double precision :: xicurrent,h,dhdp
1298 double precision :: oldff1,oldff2,Nff
1299 double precision :: pleft,pright
1314 pmin=dsqrt(sqrs)/(one-
dmaxvel)-tau-d
1315 plabs=max(
minp,pmin)
1334 pcurrent=half*(pcurrent+pprev)
1342 xicurrent=tau+d+pcurrent
1354 v2=sqrs/xicurrent**2
1356 if(lfac2inv>zero)
then
1357 lfac=one/dsqrt(lfac2inv)
1369 s2overcubeg2rh=sqrs/(xicurrent**3)
1371 call funcenthalpy_eos(pcurrent,lfac2inv,d,sqrs,xicurrent,&
1372 s2overcubeg2rh,h,dhdp)
1374 ff=-xicurrent*lfac2inv + h
1375 df=- two*sqrs/xicurrent**2 + dhdp - lfac2inv
1377 if (ff*df==zero)
then
1387 if (ff*df>zero)
then
1390 pnew=max(pnew,plabs)
1394 pnew=min(pnew,prabs)
1400 er=two*dabs(dp)/(pnew+pcurrent)
1406 if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >=
maxitnr-
maxitnr/20).and.&
1407 ff * oldff1 < zero .and. dabs(ff)>
absaccnr)
then
1410 if(n2it<=3) pcurrent=half*(pnew+pcurrent)
1414 pcurrent=half*(pleft+pright)
1417 xicurrent=tau+d+pcurrent
1418 v2=sqrs/xicurrent**2
1421 if(lfac2inv>zero)
then
1422 lfac=one/dsqrt(lfac2inv)
1430 call bisection_enthalpy_eos(pnew,lfac2inv,d,xicurrent,h)
1431 nff=-xicurrent*lfac2inv + h
1434 if(ff * nff < zero)
then
1440 pcurrent=half*(pleft+pright)
1444 if(2.0d0*dabs(pleft-pright)/(pleft+pright)<
absaccnr &
1478 if(pcurrent<
minp)
then
1485 v2=sqrs/xicurrent**2
1487 if(lfac2inv>zero)
then
1488 lfac=one/dsqrt(lfac2inv)
1494 end subroutine con2primhydro_eos
1498 subroutine funcpressure_eos(xicurrent,lfac,d,dlfacdxi,p,dpdxi)
1500 double precision,
intent(in) :: xicurrent,lfac,d,dlfacdxi
1501 double precision,
intent(out) :: p,dpdxi
1503 double precision :: rho,h,E,dhdxi,rhotoE
1504 double precision :: dpdchi,dEdxi
1507 h=xicurrent/(lfac**2)
1509 e = (h+dsqrt(h**2+(
srhd_gamma**2-one)*rho**2)) &
1513 p = half*
gamma_1*(e-rho*rhotoe)
1515 dhdxi = one/(lfac**2)-2.0d0*xicurrent/(lfac**2)*dlfacdxi/lfac
1517 dedxi=(dhdxi+(h*dhdxi-(
srhd_gamma**2-one)*rho**2*dlfacdxi/lfac)&
1522 dpdxi=half*
gamma_1*(2.0d0*rho*rhotoe*dlfacdxi/lfac+&
1523 (one+rhotoe**2)*dedxi)
1525 end subroutine funcpressure_eos
1529 subroutine funcenthalpy_eos(pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p,h,dhdp)
1531 double precision,
intent(in) :: pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p
1532 double precision,
intent(out):: h,dhdp
1535 double precision:: rho,E_th,E,dE_thdp,dEdp
1537 rho=d*dsqrt(lfac2inv)
1539 e = (e_th + dsqrt(e_th**2+rho**2))
1545 dedp = de_thdp * (one+e_th/dsqrt(e_th**2+rho**2))&
1546 + d**2*dv2d2p/dsqrt(e_th**2+rho**2)
1549 gamma_1*(rho*(rho/e))*(-2.0d0*dv2d2p/lfac2inv+dedp/e))
1550 end subroutine funcenthalpy_eos
1554 subroutine bisection_enthalpy_eos(pcurrent,lfac2inv,d,xicurrent,h)
1556 double precision,
intent(in) :: pcurrent,lfac2inv,d,xicurrent
1557 double precision,
intent(out):: h
1560 double precision:: rho,E_th,E
1562 rho=d*dsqrt(lfac2inv)
1564 e = (e_th + dsqrt(e_th**2+rho**2))
1569 end subroutine bisection_enthalpy_eos
1572 subroutine con2prim(lfac,xi,myd,myssqr,mytau,ierror)
1575 double precision,
intent(in) :: myd, myssqr, mytau
1576 double precision,
intent(inout) :: lfac, xi
1577 integer,
intent(inout) :: ierror
1580 double precision:: f,df,lfacl
1584 d = myd;
ssqr = myssqr;
tau = mytau;
1591 if (ierror == 0 .and. dabs(f/df)<
absaccnr)
then
1599 write(*,*)
'entering con2prim with xi=',xi
1608 call con2primhydro(lfac,xi,
d,
ssqr,
tau,ierror)
1610 end subroutine con2prim
1612 subroutine funcd(xi,f,df,mylfac,d,ssqr,tau,ierror)
1613 double precision,
intent(in) :: xi,d,ssqr,tau
1614 double precision,
intent(out) :: f,df,mylfac
1615 integer,
intent(inout) :: ierror
1618 double precision :: dlfac
1619 double precision :: vsqr,p,dpdxi
1625 mylfac = one/dsqrt(one-vsqr)
1626 dlfac = -mylfac**3*ssqr/(xi**3)
1628 call funcpressure(xi,mylfac,d,dlfac,p,dpdxi)
1639 end subroutine funcd
1642 subroutine con2primhydro(lfac,xi,d,sqrs,tau,ierror)
1643 double precision,
intent(out) :: xi,lfac
1644 double precision,
intent(in) :: d,sqrs,tau
1645 integer,
intent(inout) :: ierror
1648 integer :: ni,niiter,nit,n2it,ni3
1649 double precision :: pcurrent,pnew
1650 double precision :: er,er1,ff,df,dp,v2
1651 double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
1652 double precision :: s2overcubeG2rh
1653 double precision :: xicurrent,h,dhdp
1654 double precision :: oldff1,oldff2,Nff
1655 double precision :: pleft,pright
1670 pmin=dsqrt(sqrs)/(one-
dmaxvel)-tau-d
1671 plabs=max(
minp,pmin)
1690 pcurrent=half*(pcurrent+pprev)
1698 xicurrent=tau+d+pcurrent
1710 v2=sqrs/xicurrent**2
1712 if(lfac2inv>zero)
then
1713 lfac=one/dsqrt(lfac2inv)
1725 s2overcubeg2rh=sqrs/(xicurrent**3)
1727 call funcenthalpy(pcurrent,lfac2inv,d,sqrs,xicurrent,&
1728 s2overcubeg2rh,h,dhdp)
1730 ff=-xicurrent*lfac2inv + h
1731 df=- two*sqrs/xicurrent**2 + dhdp - lfac2inv
1733 if (ff*df==zero)
then
1743 if (ff*df>zero)
then
1746 pnew=max(pnew,plabs)
1750 pnew=min(pnew,prabs)
1756 er=two*dabs(dp)/(pnew+pcurrent)
1762 if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >=
maxitnr-
maxitnr/20).and.&
1763 ff * oldff1 < zero .and. dabs(ff)>
absaccnr)
then
1766 if(n2it<=3) pcurrent=half*(pnew+pcurrent)
1770 pcurrent=half*(pleft+pright)
1773 xicurrent=tau+d+pcurrent
1774 v2=sqrs/xicurrent**2
1777 if(lfac2inv>zero)
then
1778 lfac=one/dsqrt(lfac2inv)
1786 call bisection_enthalpy(pnew,lfac2inv,d,xicurrent,h)
1787 nff=-xicurrent*lfac2inv + h
1790 if(ff * nff < zero)
then
1796 pcurrent=half*(pleft+pright)
1800 if(2.0d0*dabs(pleft-pright)/(pleft+pright)<
absaccnr &
1834 if(pcurrent<
minp)
then
1841 v2=sqrs/xicurrent**2
1843 if(lfac2inv>zero)
then
1844 lfac=one/dsqrt(lfac2inv)
1850 end subroutine con2primhydro
1854 subroutine funcpressure(xicurrent,lfac,d,dlfacdxi,p,dpdxi)
1856 double precision,
intent(in) :: xicurrent,lfac,d,dlfacdxi
1857 double precision,
intent(out) :: p,dpdxi
1859 double precision :: rho,h,E,dhdxi,rhotoE
1860 double precision :: dpdchi,dEdxi
1863 h=xicurrent/(lfac**2)
1868 dpdxi = dpdchi * one/lfac**2
1870 if (dlfacdxi /= 0.0d0) &
1871 dpdxi = dpdxi + dpdchi * ((d*lfac-2.0d0*xicurrent)/lfac**3) * dlfacdxi
1873 end subroutine funcpressure
1877 subroutine funcenthalpy(pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p,h,dhdp)
1879 double precision,
intent(in) :: pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p
1880 double precision,
intent(out):: h,dhdp
1883 double precision:: rho,E_th,E,dE_thdp,dEdp
1885 rho=d*dsqrt(lfac2inv)
1888 end subroutine funcenthalpy
1892 subroutine bisection_enthalpy(pcurrent,lfac2inv,d,xicurrent,h)
1894 double precision,
intent(in) :: pcurrent,lfac2inv,d,xicurrent
1895 double precision,
intent(out):: h
1898 double precision:: rho,E_th,E
1900 rho=d*dsqrt(lfac2inv)
1904 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.
double precision, 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 for MHD or 1D HD.
logical fix_small_values
fix small values with average or replace methods
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
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
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_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
subroutine srhd_add_source_geom(qdt, dtfactor, ixIL, ixOL, wCT, wprim, w, x)
Add geometrical source terms to w.
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.