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
183 if (.not.
allocated(flux_type))
then
184 allocate(flux_type(
ndir, nw))
185 flux_type = flux_default
186 else if (any(shape(flux_type) /= [
ndir, nw]))
then
187 call mpistop(
"phys_check error: flux_type has wrong shape")
191 allocate(iw_vector(nvector))
192 iw_vector(1) =
mom(1) - 1
220 phys_req_diagonal = .true.
229 call mpistop (
"Error: srhd_gamma <= 0 or srhd_gamma == 1")
240 write(*,*)
'------------------------------------------------------------'
241 write(*,*)
'Using EOS set via srhd_eos=',
srhd_eos
242 write(*,*)
'Maximal lorentz factor (via dmaxvel) is=',
lfacmax
246 write(*,*)
'------------------------------------------------------------'
253 double precision :: mp,kB
266 call mpistop(
"Abort: must set positive values for unit length and numberdensity")
281 logical,
intent(in) :: primitive
282 integer,
intent(in) :: ixi^
l, ixo^
l
283 double precision,
intent(in) :: w(ixi^s, nw)
284 logical,
intent(inout) :: flag(ixi^s,1:nw)
294 where(w(ixo^s,
e_) <
small_e) flag(ixo^s,
e_) = .true.
302 integer,
intent(in) :: ixI^L, ixO^L
303 double precision,
intent(in) :: w(ixI^S, nw)
304 logical,
intent(inout) :: flag(ixI^S,1:nw)
309 where(w(ixo^s,
lfac_) < one) flag(ixo^s,
lfac_) = .true.
311 if(any(flag(ixo^s,
xi_)))
then
312 write(*,*)
'auxiliary xi too low: abort'
313 call mpistop(
'auxiliary check failed')
315 if(any(flag(ixo^s,
lfac_)))
then
316 write(*,*)
'auxiliary lfac too low: abort'
317 call mpistop(
'auxiliary check failed')
326 integer,
intent(in) :: ixi^
l, ixo^
l
327 double precision,
intent(inout) :: w(ixi^s, nw)
328 double precision,
dimension(ixO^S) :: rho,rhoh,pth
331 rho(ixo^s) = sum(w(ixo^s,
mom(:))**2, dim=
ndim+1)
332 w(ixo^s,
lfac_) = dsqrt(1.0d0+rho(ixo^s))
334 rho(ixo^s)=w(ixo^s,
rho_)
335 pth(ixo^s)=w(ixo^s,
p_)
340 w(ixo^s,
xi_) = w(ixo^s,
lfac_)**2.0d0*rhoh(ixo^s)
350 integer,
intent(in) :: ixi^
l,ixo^
l
351 double precision,
intent(inout) :: w(ixi^s, nw)
352 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
354 integer :: ix^
d,ierror,idir
355 integer :: flag_error(ixo^s)
356 double precision :: ssqr
359 {
do ix^db=ixomin^db,ixomax^db\}
363 ssqr= ssqr+w(ix^
d,
mom(idir))**2
366 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
367 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
368 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
374 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
375 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
376 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
382 w(ix^
d,
d_),ssqr,w(ix^
d,
e_),ierror)
383 flag_error(ix^
d) = ierror
386 {
do ix^db=ixomin^db,ixomax^db\}
390 ssqr= ssqr+w(ix^
d,
mom(idir))**2
393 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
394 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
395 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
401 print *,
'entering con2prim with', w(ix^
d,
lfac_),w(ix^
d,
xi_), &
402 w(ix^
d,
d_),ssqr,w(ix^
d,
e_)
403 print *,
'in position',ix^
d,x(ix^
d,1:
ndim)
409 w(ix^
d,
d_),ssqr,w(ix^
d,
e_),ierror)
410 flag_error(ix^
d) = ierror
415 if(any(flag_error(ixo^s)/=0))
then
416 print *,flag_error(ixo^s)
417 call mpistop(
'Problem when getting auxiliaries')
427 integer,
intent(in) :: ixi^
l, ixo^
l
428 double precision,
intent(inout) :: w(ixi^s, nw)
429 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
431 double precision,
dimension(ixO^S) :: rhoh,rho,pth
435 rhoh(ixo^s) = sum(w(ixo^s,
mom(:))**2, dim=
ndim+1)
436 w(ixo^s,
lfac_) = dsqrt(1.0d0+rhoh(ixo^s))
438 rho(ixo^s)=w(ixo^s,
rho_)
439 pth(ixo^s)=w(ixo^s,
p_)
444 rhoh(ixo^s)= rhoh(ixo^s)*w(ixo^s,
lfac_)
446 w(ixo^s,
xi_) = w(ixo^s,
lfac_)*rhoh(ixo^s)
449 w(ixo^s,
d_)=w(ixo^s,
lfac_)*rho(ixo^s)
453 w(ixo^s,
mom(idir)) = rhoh(ixo^s)*w(ixo^s,
mom(idir))
457 w(ixo^s,
e_) = w(ixo^s,
xi_)-pth(ixo^s)-w(ixo^s,
d_)
468 integer,
intent(in) :: ixi^
l, ixo^
l
469 double precision,
intent(inout) :: w(ixi^s, nw)
470 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
472 double precision,
dimension(ixO^S) :: rho,rhoh,e
473 double precision,
dimension(ixI^S) :: pth
474 character(len=30) :: subname_loc
480 rho(ixo^s) = w(ixo^s,
d_)/w(ixo^s,
lfac_)
484 rhoh(ixo^s) = w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
487 w(ixo^s,
rho_)=rho(ixo^s)
490 w(ixo^s,
mom(idir)) = w(ixo^s,
lfac_)*w(ixo^s,
mom(idir))&
493 w(ixo^s,
p_)=pth(ixo^s)
497 /(rho(ixo^s)*w(ixo^s,
lfac_))
505 integer,
intent(in) :: ixI^L, ixO^L
506 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
507 double precision,
intent(out) :: v(ixI^S,1:ndir)
512 v(ixo^s,idir) = w(ixo^s,
mom(idir))/w(ixo^s,
xi_)
522 integer,
intent(in) :: ixI^L, ixO^L
523 double precision,
intent(in) :: w(ixI^S,nw),rhoh(ixO^S)
524 double precision,
intent(in) :: x(ixI^S,1:ndim)
525 double precision,
intent(out) :: csound2(ixO^S)
527 double precision :: rho(ixO^S)
539 integer,
intent(in) :: ixi^
l, ixo^
l
540 double precision,
intent(inout) :: w(ixi^s,nw)
541 double precision,
intent(in) :: x(ixi^s,1:
ndim)
542 double precision,
intent(out) :: csound2(ixo^s)
544 double precision :: rho(ixo^s),rhoh(ixo^s)
549 rho = w(ixo^s,
d_)/w(ixo^s,
lfac_)
550 rhoh = w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
561 integer,
intent(in) :: ixi^
l, ixo^
l
562 double precision,
intent(in) :: w(ixi^s, nw)
563 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
564 double precision,
intent(out) :: pth(ixi^s)
567 double precision :: rho(ixo^s),rhoh(ixo^s),e(ixo^s)
570 rho = w(ixo^s,
d_)/w(ixo^s,
lfac_)
571 rhoh = w(ixo^s,
xi_)/w(ixo^s,
lfac_)**2.0d0
578 subroutine srhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
581 integer,
intent(in) :: ixI^L, ixO^L
582 double precision,
intent(in) :: qdt,dtfactor
583 double precision,
intent(in) :: wCT(ixI^S, 1:nw),wCTprim(ixI^S,1:nw), x(ixI^S, 1:ndim)
584 double precision,
intent(inout) :: w(ixI^S, 1:nw)
585 logical,
intent(in) :: qsourcesplit
586 logical,
intent(inout) :: active
594 integer,
intent(in) :: ixI^L, ixO^L
595 double precision,
intent(in) :: dx^D, x(ixI^S, 1:^ND)
596 double precision,
intent(in) :: w(ixI^S, 1:nw)
597 double precision,
intent(inout) :: dtnew
608 integer,
intent(in) :: ixI^L, ixO^L, idim
609 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S, 1:ndim)
610 double precision,
intent(inout) :: cmax(ixI^S)
612 double precision :: wc(ixI^S,nw)
613 double precision,
dimension(ixO^S) :: csound2,tmp1,tmp2,v2
614 double precision,
dimension(ixI^S) :: vidim, cmin
616 logical :: flag(ixI^S,1:nw)
624 tmp1(ixo^s)=wc(ixo^s,
xi_)/wc(ixo^s,
lfac_)**2.0d0
625 v2(ixo^s)=1.0d0-1.0d0/wc(ixo^s,
lfac_)**2
627 vidim(ixo^s) = wc(ixo^s,
mom(idim))/wc(ixo^s,
xi_)
628 tmp2(ixo^s)=vidim(ixo^s)**2.0d0
629 tmp1(ixo^s)=1.0d0-v2(ixo^s)*csound2(ixo^s) &
630 -tmp2(ixo^s)*(1.0d0-csound2(ixo^s))
631 tmp2(ixo^s)=dsqrt(csound2(ixo^s)*(one-v2(ixo^s))*tmp1(ixo^s))
632 tmp1(ixo^s)=vidim(ixo^s)*(one-csound2(ixo^s))
633 cmax(ixo^s)=(tmp1(ixo^s)+tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
634 cmin(ixo^s)=(tmp1(ixo^s)-tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
636 cmin(ixo^s) = max(cmin(ixo^s), - 1.0d0)
637 cmin(ixo^s) = min(cmin(ixo^s), 1.0d0)
638 cmax(ixo^s) = max(cmax(ixo^s), - 1.0d0)
639 cmax(ixo^s) = min(cmax(ixo^s), 1.0d0)
641 cmax(ixo^s) = max(dabs(cmax(ixo^s)),dabs(cmin(ixo^s)))
648 integer,
intent(in) :: ixI^L, ixO^L
649 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
650 double precision,
intent(inout) :: a2max(ndim)
651 double precision :: a2(ixI^S,ndim,nw)
652 integer :: gxO^L,hxO^L,jxO^L,kxO^L,i
657 hxo^l=ixo^l-
kr(i,^
d);
658 gxo^l=hxo^l-
kr(i,^
d);
659 jxo^l=ixo^l+
kr(i,^
d);
660 kxo^l=jxo^l+
kr(i,^
d);
661 a2(ixo^s,i,1:nwflux)=dabs(-w(kxo^s,1:nwflux)+16.d0*w(jxo^s,1:nwflux)&
662 -30.d0*w(ixo^s,1:nwflux)+16.d0*w(hxo^s,1:nwflux)-w(gxo^s,1:nwflux))
663 a2max(i)=maxval(a2(ixo^s,i,1:nwflux))/12.d0/
dxlevel(i)**2
671 integer,
intent(in) :: ixI^L, ixO^L
672 double precision,
intent(in) :: vidim(ixI^S)
673 double precision,
intent(in),
dimension(ixO^S) :: csound2
674 double precision,
intent(in) :: v2(ixI^S)
675 double precision,
intent(out) :: cmax(ixI^S)
676 double precision,
intent(out) :: cmin(ixI^S)
678 double precision,
dimension(ixI^S):: tmp1,tmp2
680 tmp2(ixo^s)=vidim(ixo^s)**2.0d0
681 tmp1(ixo^s)=1.0d0-v2(ixo^s)*csound2(ixo^s) &
682 -tmp2(ixo^s)*(1.0d0-csound2(ixo^s))
683 tmp2(ixo^s)=dsqrt(csound2(ixo^s)*(one-v2(ixo^s))*tmp1(ixo^s))
684 tmp1(ixo^s)=vidim(ixo^s)*(one-csound2(ixo^s))
685 cmax(ixo^s)=(tmp1(ixo^s)+tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
687 cmax(ixo^s) = max(cmax(ixo^s), - 1.0d0)
688 cmax(ixo^s) = min(cmax(ixo^s), 1.0d0)
689 cmin(ixo^s)=(tmp1(ixo^s)-tmp2(ixo^s))/(one-v2(ixo^s)*csound2(ixo^s))
691 cmin(ixo^s) = max(cmin(ixo^s), - 1.0d0)
692 cmin(ixo^s) = min(cmin(ixo^s), 1.0d0)
698 subroutine srhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
702 integer,
intent(in) :: ixI^L, ixO^L, idim
704 double precision,
intent(in) :: wLC(ixI^S, nw), wRC(ixI^S, nw)
706 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
707 double precision,
intent(in) :: x(ixI^S, 1:ndim)
708 double precision,
intent(inout) :: cmax(ixI^S,1:number_species)
709 double precision,
intent(inout),
optional :: cmin(ixI^S,1:number_species)
710 double precision,
intent(in) :: Hspeed(ixI^S,1:number_species)
712 double precision :: wmean(ixI^S,nw)
713 double precision,
dimension(ixO^S) :: csound2,tmp1,tmp2,tmp3
714 double precision,
dimension(ixI^S) :: vidim,cmaxL,cmaxR,cminL,cminR,v2
716 logical :: flag(ixI^S,1:nw)
723 tmp2=wlp(ixo^s,
xi_)/wlp(ixo^s,
lfac_)**2.0d0
726 vidim(ixo^s) = wlp(ixo^s,
mom(idim))/wlp(ixo^s,
lfac_)
727 v2(ixo^s) = 1.0d0-1.0d0/wlp(ixo^s,
lfac_)**2
733 tmp2=wrp(ixo^s,
xi_)/wrp(ixo^s,
lfac_)**2.0d0
736 vidim(ixo^s) = wrp(ixo^s,
mom(idim))/wrp(ixo^s,
lfac_)
737 v2(ixo^s) = 1.0d0-1.0d0/wrp(ixo^s,
lfac_)**2
740 if(
present(cmin))
then
742 cmax(ixo^s,1)=max(cmaxl(ixo^s),cmaxr(ixo^s))
743 cmin(ixo^s,1)=min(cminl(ixo^s),cminr(ixo^s))
746 cmaxl(ixo^s)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
747 cmaxr(ixo^s)=max(cmaxr(ixo^s),dabs(cminr(ixo^s)))
748 cmax(ixo^s,1)=max(cmaxl(ixo^s),cmaxr(ixo^s))
756 tmp1=wmean(ixo^s,
xi_)/wmean(ixo^s,
lfac_)**2.0d0
758 vidim(ixo^s) = wmean(ixo^s,
mom(idim))/wmean(ixo^s,
xi_)
759 v2(ixo^s)=1.0d0-1.0d0/wmean(ixo^s,
lfac_)**2
761 if(
present(cmin))
then
762 cmax(ixo^s,1)=cmaxl(ixo^s)
763 cmin(ixo^s,1)=cminl(ixo^s)
765 cmax(ixo^s,1)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
773 tmp1=wmean(ixo^s,
rho_)
774 tmp2=wmean(ixo^s,
xi_)/wmean(ixo^s,
lfac_)**2.0d0
777 vidim(ixo^s) = wmean(ixo^s,
mom(idim))/wmean(ixo^s,
lfac_)
778 v2(ixo^s) = 1.0d0-1.0d0/wmean(ixo^s,
lfac_)**2
780 if(
present(cmin))
then
781 cmax(ixo^s,1)=cmaxl(ixo^s)
782 cmin(ixo^s,1)=cminl(ixo^s)
784 cmax(ixo^s,1)=max(cmaxl(ixo^s),dabs(cminl(ixo^s)))
793 integer,
intent(in) :: ixI^L, ixO^L, idim
795 double precision,
intent(in) :: wC(ixI^S,nw)
797 double precision,
intent(in) :: wP(ixI^S,nw)
798 double precision,
intent(in) :: x(ixI^S,1:ndim)
799 double precision,
intent(out) :: f(ixI^S,nwflux)
801 double precision :: pth(ixI^S)
802 double precision :: v(ixI^S,1:ndir)
805 pth(ixo^s)=wp(ixo^s,
p_)
807 v(ixo^s,idir) = wp(ixo^s,
mom(idir))/wp(ixo^s,
lfac_)
811 f(ixo^s,
d_)=v(ixo^s,idim)*wc(ixo^s,
rho_)
821 f(ixo^s,
mom(idir))= v(ixo^s,idim)*wc(ixo^s,
mom(idir))
823 f(ixo^s,
mom(idim))=pth(ixo^s)+f(ixo^s,
mom(idim))
827 f(ixo^s,
e_)=v(ixo^s,idim)*(wc(ixo^s,
e_) + pth(ixo^s))
836 integer,
intent(in) :: ixI^L, ixO^L
837 double precision,
intent(in) :: qdt, dtfactor, x(ixI^S, 1:ndim)
838 double precision,
intent(inout) :: wCT(ixI^S, 1:nw), wprim(ixI^S, 1:nw), w(ixI^S, 1:nw)
840 double precision :: pth(ixI^S), source(ixI^S), v(ixI^S,1:ndir)
841 integer :: idir, h1x^L{^NOONED, h2x^L}
843 double precision :: exp_factor(ixI^S), del_exp_factor(ixI^S), exp_factor_primitive(ixI^S)
854 source(ixo^s) =
source(ixo^s)*del_exp_factor(ixo^s)/exp_factor(ixo^s)
865 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
866 source(ixo^s) = -wct(ixo^s, mphi_) * wprim(ixo^s,
mom(
r_))
867 w(ixo^s, mphi_) = w(ixo^s, mphi_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
869 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
874 h1x^l=ixo^l-
kr(1,^
d); {^nooned h2x^l=ixo^l-
kr(2,^
d);}
879 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
880 *(
block%surfaceC(ixo^s, 1) -
block%surfaceC(h1x^s, 1)) &
881 /
block%dvolume(ixo^s)
887 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s, 1)
891 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
892 * (
block%surfaceC(ixo^s, 2) -
block%surfaceC(h2x^s, 2)) &
893 /
block%dvolume(ixo^s)
895 source(ixo^s) =
source(ixo^s) + (wct(ixo^s,
mom(3))*v(ixo^s,ndir)) / dtan(x(ixo^s, 2))
898 w(ixo^s,
mom(2)) = w(ixo^s,
mom(2)) + qdt *
source(ixo^s) / x(ixo^s, 1)
902 source(ixo^s) = -(wct(ixo^s,
mom(3)) * wprim(ixo^s,
mom(1))) &
903 - (wct(ixo^s,
mom(3)) * wprim(ixo^s,
mom(2))) / dtan(x(ixo^s, 2))
904 w(ixo^s,
mom(3)) = w(ixo^s,
mom(3)) + qdt *
source(ixo^s) / x(ixo^s, 1)
915 logical,
intent(in) :: primitive
916 integer,
intent(in) :: ixI^L,ixO^L
917 double precision,
intent(inout) :: w(ixI^S,1:nw)
918 double precision,
intent(in) :: x(ixI^S,1:ndim)
919 character(len=*),
intent(in) :: subname
922 logical :: flag(ixI^S,1:nw),flagall(ixI^S)
930 flagall(ixo^s)=(flag(ixo^s,
rho_).or.flag(ixo^s,
e_))
932 where(flagall(ixo^s))
944 where(flagall(ixo^s)) w(ixo^s,
e_) =
small_e
964 if(.not.primitive)
then
966 write(*,*)
"handle_small_values default: note reporting conservatives!"
982 integer,
intent(in) :: ixi^l,ixo^l
983 double precision,
intent(in) :: w(ixi^s, 1:nw)
984 logical,
intent(in) :: varconserve
985 double precision,
intent(out) :: geff(ixi^s)
987 double precision,
dimension(ixO^S) :: pth,rho,e_th,e
990 if (varconserve)
then
991 pth(ixo^s)=w(ixo^s,
xi_)-w(ixo^s,
e_)-w(ixo^s,
d_)
992 rho(ixo^s)=w(ixo^s,
d_)/w(ixo^s,
lfac_)
994 e = e_th+dsqrt(e_th**2+rho**2)
996 (one-(rho(ixo^s)/e(ixo^s))**2)
1000 e = e_th+dsqrt(e_th**2+w(ixo^s,
rho_)**2)
1002 (one-(w(ixo^s,
rho_)/e(ixo^s))**2)
1015 double precision :: LsmallE,Lsmallp,Lsmallrho
1022 call mpistop(
"must set finite values small-density/pressure for small value treatments")
1032 gamma_1*lsmallrho*(lsmallrho/lsmalle))
1046 integer,
intent(in) :: ixo^
l
1047 double precision,
intent(in) :: rho(ixo^s),p(ixo^s)
1048 double precision,
intent(out) :: rhoh(ixo^s)
1050 double precision,
dimension(ixO^S) :: e_th,e
1055 e = e_th+dsqrt(e_th**2+rho**2)
1064 {
do ix^db= ixo^lim^db\}
1066 write(*,*)
"local pressure and density",p(ix^
d),rho(ix^
d)
1067 write(*,*)
"Error: small value of enthalpy rho*h=",rhoh(ix^
d),&
1068 " encountered when call srhd_get_enthalpy_eos"
1069 call mpistop(
'enthalpy below small_xi: stop (may need to turn on fixes)')
1075 {
do ix^db= ixo^lim^db\}
1088 integer,
intent(in) :: ixI^L, ixO^L
1089 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S)
1090 double precision,
intent(out) :: p(ixI^S)
1091 double precision,
intent(out) :: E(ixO^S)
1095 e = (rhoh+dsqrt(rhoh**2+(
srhd_gamma**2-one)*rho**2)) &
1097 p(ixo^s) = half*
gamma_1* (e-rho*(rho/e))
1103 {
do ix^db= ixo^lim^db\}
1105 write(*,*)
"local enthalpy rho*h and density rho",rhoh(ix^d),rho(ix^d)
1106 if(
srhd_eos)
write(*,*)
'E, rho^2/E, difference', &
1107 e(ix^d),rho(ix^d)**2/e(ix^d),e(ix^d)-rho(ix^d)**2/e(ix^d)
1108 write(*,*)
"Error: small value of gas pressure",p(ix^d),&
1109 " encountered when call srhd_get_pressure_eos"
1110 call mpistop(
'pressure below small_pressure: stop (may need to turn on fixes)')
1116 {
do ix^db= ixo^lim^db\}
1130 integer,
intent(in) :: ixI^L, ixO^L
1131 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S)
1132 double precision,
intent(out) :: csound2(ixO^S)
1134 double precision :: p(ixI^S)
1135 double precision :: E(ixO^S)
1141 +
gamma_1*(rho(ixo^s)/e(ixo^s))**2))&
1142 /(2.0d0*rhoh(ixo^s))
1144 csound2(ixo^s)=
srhd_gamma*p(ixo^s)/rhoh(ixo^s)
1148 {
do ix^db= ixo^lim^db\}
1149 if(csound2(ix^d)>=1.0d0.or.csound2(ix^d)<=0.0d0)
then
1150 write(*,*)
"sound speed error with p - rho - rhoh",p(ix^d),rhoh(ix^d),rho(ix^d)
1151 if(
srhd_eos)
write(*,*)
'and E', e(ix^d)
1152 write(*,*)
"Error: value of csound2",csound2(ix^d),&
1153 " encountered when call srhd_get_csound2_eos"
1154 call mpistop(
'sound speed stop (may need to turn on fixes)')
1160 {
do ix^db= ixo^lim^db\}
1161 if(csound2(ix^d)>=1.0d0)
then
1162 csound2(ix^d)=1.0d0-1.0d0/
lfacmax**2
1164 if(csound2(ix^d)<=0.0d0)
then
1176 integer,
intent(in) :: ixO^L
1177 double precision,
intent(in) :: rho(ixO^S),rhoh(ixO^S),p(ixO^S)
1178 double precision,
intent(out) :: csound2(ixO^S)
1180 double precision :: E(ixO^S)
1194 {
do ix^db= ixo^lim^db\}
1195 if(csound2(ix^d)>=1.0d0.or.csound2(ix^d)<=0.0d0)
then
1196 write(*,*)
"sound speed error with p - rho - rhoh",p(ix^d),rhoh(ix^d),rho(ix^d)
1197 if(
srhd_eos)
write(*,*)
'and E', e(ix^d)
1198 write(*,*)
"Error: value of csound2",csound2(ix^d),&
1199 " encountered when call srhd_get_csound2_prim_eos"
1200 call mpistop(
'sound speed stop (may need to turn on fixes)')
1206 {
do ix^db= ixo^lim^db\}
1207 if(csound2(ix^d)>=1.0d0)
then
1208 csound2(ix^d)=1.0d0-1.0d0/
lfacmax**2
1210 if(csound2(ix^d)<=0.0d0)
then
1222 double precision,
intent(in) :: myd, myssqr, mytau
1223 double precision,
intent(inout) :: lfac, xi
1224 integer,
intent(inout) :: ierror
1227 double precision:: f,df,lfacl
1231 d = myd;
ssqr = myssqr;
tau = mytau;
1238 if (ierror == 0 .and. dabs(f/df)<
absaccnr)
then
1246 write(*,*)
'entering con2prim_eos with xi=',xi
1255 call con2primhydro_eos(lfac,xi,
d,
ssqr,
tau,ierror)
1260 double precision,
intent(in) :: xi,d,ssqr,tau
1261 double precision,
intent(out) :: f,df,mylfac
1262 integer,
intent(inout) :: ierror
1265 double precision :: dlfac
1266 double precision :: vsqr,p,dpdxi
1272 mylfac = one/dsqrt(one-vsqr)
1273 dlfac = -mylfac**3*ssqr/(xi**3)
1275 call funcpressure_eos(xi,mylfac,d,dlfac,p,dpdxi)
1289 subroutine con2primhydro_eos(lfac,xi,d,sqrs,tau,ierror)
1290 double precision,
intent(out) :: xi,lfac
1291 double precision,
intent(in) :: d,sqrs,tau
1292 integer,
intent(inout) :: ierror
1295 integer :: ni,niiter,nit,n2it,ni3
1296 double precision :: pcurrent,pnew
1297 double precision :: er,er1,ff,df,dp,v2
1298 double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
1299 double precision :: s2overcubeG2rh
1300 double precision :: xicurrent,h,dhdp
1301 double precision :: oldff1,oldff2,Nff
1302 double precision :: pleft,pright
1317 pmin=dsqrt(sqrs)/(one-
dmaxvel)-tau-d
1318 plabs=max(
minp,pmin)
1337 pcurrent=half*(pcurrent+pprev)
1345 xicurrent=tau+d+pcurrent
1357 v2=sqrs/xicurrent**2
1359 if(lfac2inv>zero)
then
1360 lfac=one/dsqrt(lfac2inv)
1372 s2overcubeg2rh=sqrs/(xicurrent**3)
1374 call funcenthalpy_eos(pcurrent,lfac2inv,d,sqrs,xicurrent,&
1375 s2overcubeg2rh,h,dhdp)
1377 ff=-xicurrent*lfac2inv + h
1378 df=- two*sqrs/xicurrent**2 + dhdp - lfac2inv
1380 if (ff*df==zero)
then
1390 if (ff*df>zero)
then
1393 pnew=max(pnew,plabs)
1397 pnew=min(pnew,prabs)
1403 er=two*dabs(dp)/(pnew+pcurrent)
1409 if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >=
maxitnr-
maxitnr/20).and.&
1410 ff * oldff1 < zero .and. dabs(ff)>
absaccnr)
then
1413 if(n2it<=3) pcurrent=half*(pnew+pcurrent)
1417 pcurrent=half*(pleft+pright)
1420 xicurrent=tau+d+pcurrent
1421 v2=sqrs/xicurrent**2
1424 if(lfac2inv>zero)
then
1425 lfac=one/dsqrt(lfac2inv)
1433 call bisection_enthalpy_eos(pnew,lfac2inv,d,xicurrent,h)
1434 nff=-xicurrent*lfac2inv + h
1437 if(ff * nff < zero)
then
1443 pcurrent=half*(pleft+pright)
1447 if(2.0d0*dabs(pleft-pright)/(pleft+pright)<
absaccnr &
1481 if(pcurrent<
minp)
then
1488 v2=sqrs/xicurrent**2
1490 if(lfac2inv>zero)
then
1491 lfac=one/dsqrt(lfac2inv)
1497 end subroutine con2primhydro_eos
1501 subroutine funcpressure_eos(xicurrent,lfac,d,dlfacdxi,p,dpdxi)
1503 double precision,
intent(in) :: xicurrent,lfac,d,dlfacdxi
1504 double precision,
intent(out) :: p,dpdxi
1506 double precision :: rho,h,E,dhdxi,rhotoE
1507 double precision :: dpdchi,dEdxi
1510 h=xicurrent/(lfac**2)
1512 e = (h+dsqrt(h**2+(
srhd_gamma**2-one)*rho**2)) &
1516 p = half*
gamma_1*(e-rho*rhotoe)
1518 dhdxi = one/(lfac**2)-2.0d0*xicurrent/(lfac**2)*dlfacdxi/lfac
1520 dedxi=(dhdxi+(h*dhdxi-(
srhd_gamma**2-one)*rho**2*dlfacdxi/lfac)&
1525 dpdxi=half*
gamma_1*(2.0d0*rho*rhotoe*dlfacdxi/lfac+&
1526 (one+rhotoe**2)*dedxi)
1528 end subroutine funcpressure_eos
1532 subroutine funcenthalpy_eos(pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p,h,dhdp)
1534 double precision,
intent(in) :: pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p
1535 double precision,
intent(out):: h,dhdp
1538 double precision:: rho,E_th,E,dE_thdp,dEdp
1540 rho=d*dsqrt(lfac2inv)
1542 e = (e_th + dsqrt(e_th**2+rho**2))
1548 dedp = de_thdp * (one+e_th/dsqrt(e_th**2+rho**2))&
1549 + d**2*dv2d2p/dsqrt(e_th**2+rho**2)
1552 gamma_1*(rho*(rho/e))*(-2.0d0*dv2d2p/lfac2inv+dedp/e))
1553 end subroutine funcenthalpy_eos
1557 subroutine bisection_enthalpy_eos(pcurrent,lfac2inv,d,xicurrent,h)
1559 double precision,
intent(in) :: pcurrent,lfac2inv,d,xicurrent
1560 double precision,
intent(out):: h
1563 double precision:: rho,E_th,E
1565 rho=d*dsqrt(lfac2inv)
1567 e = (e_th + dsqrt(e_th**2+rho**2))
1572 end subroutine bisection_enthalpy_eos
1575 subroutine con2prim(lfac,xi,myd,myssqr,mytau,ierror)
1578 double precision,
intent(in) :: myd, myssqr, mytau
1579 double precision,
intent(inout) :: lfac, xi
1580 integer,
intent(inout) :: ierror
1583 double precision:: f,df,lfacl
1587 d = myd;
ssqr = myssqr;
tau = mytau;
1594 if (ierror == 0 .and. dabs(f/df)<
absaccnr)
then
1602 write(*,*)
'entering con2prim with xi=',xi
1611 call con2primhydro(lfac,xi,
d,
ssqr,
tau,ierror)
1613 end subroutine con2prim
1615 subroutine funcd(xi,f,df,mylfac,d,ssqr,tau,ierror)
1616 double precision,
intent(in) :: xi,d,ssqr,tau
1617 double precision,
intent(out) :: f,df,mylfac
1618 integer,
intent(inout) :: ierror
1621 double precision :: dlfac
1622 double precision :: vsqr,p,dpdxi
1628 mylfac = one/dsqrt(one-vsqr)
1629 dlfac = -mylfac**3*ssqr/(xi**3)
1631 call funcpressure(xi,mylfac,d,dlfac,p,dpdxi)
1642 end subroutine funcd
1645 subroutine con2primhydro(lfac,xi,d,sqrs,tau,ierror)
1646 double precision,
intent(out) :: xi,lfac
1647 double precision,
intent(in) :: d,sqrs,tau
1648 integer,
intent(inout) :: ierror
1651 integer :: ni,niiter,nit,n2it,ni3
1652 double precision :: pcurrent,pnew
1653 double precision :: er,er1,ff,df,dp,v2
1654 double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
1655 double precision :: s2overcubeG2rh
1656 double precision :: xicurrent,h,dhdp
1657 double precision :: oldff1,oldff2,Nff
1658 double precision :: pleft,pright
1673 pmin=dsqrt(sqrs)/(one-
dmaxvel)-tau-d
1674 plabs=max(
minp,pmin)
1693 pcurrent=half*(pcurrent+pprev)
1701 xicurrent=tau+d+pcurrent
1713 v2=sqrs/xicurrent**2
1715 if(lfac2inv>zero)
then
1716 lfac=one/dsqrt(lfac2inv)
1728 s2overcubeg2rh=sqrs/(xicurrent**3)
1730 call funcenthalpy(pcurrent,lfac2inv,d,sqrs,xicurrent,&
1731 s2overcubeg2rh,h,dhdp)
1733 ff=-xicurrent*lfac2inv + h
1734 df=- two*sqrs/xicurrent**2 + dhdp - lfac2inv
1736 if (ff*df==zero)
then
1746 if (ff*df>zero)
then
1749 pnew=max(pnew,plabs)
1753 pnew=min(pnew,prabs)
1759 er=two*dabs(dp)/(pnew+pcurrent)
1765 if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >=
maxitnr-
maxitnr/20).and.&
1766 ff * oldff1 < zero .and. dabs(ff)>
absaccnr)
then
1769 if(n2it<=3) pcurrent=half*(pnew+pcurrent)
1773 pcurrent=half*(pleft+pright)
1776 xicurrent=tau+d+pcurrent
1777 v2=sqrs/xicurrent**2
1780 if(lfac2inv>zero)
then
1781 lfac=one/dsqrt(lfac2inv)
1789 call bisection_enthalpy(pnew,lfac2inv,d,xicurrent,h)
1790 nff=-xicurrent*lfac2inv + h
1793 if(ff * nff < zero)
then
1799 pcurrent=half*(pleft+pright)
1803 if(2.0d0*dabs(pleft-pright)/(pleft+pright)<
absaccnr &
1837 if(pcurrent<
minp)
then
1844 v2=sqrs/xicurrent**2
1846 if(lfac2inv>zero)
then
1847 lfac=one/dsqrt(lfac2inv)
1853 end subroutine con2primhydro
1857 subroutine funcpressure(xicurrent,lfac,d,dlfacdxi,p,dpdxi)
1859 double precision,
intent(in) :: xicurrent,lfac,d,dlfacdxi
1860 double precision,
intent(out) :: p,dpdxi
1862 double precision :: rho,h,E,dhdxi,rhotoE
1863 double precision :: dpdchi,dEdxi
1866 h=xicurrent/(lfac**2)
1871 dpdxi = dpdchi * one/lfac**2
1873 if (dlfacdxi /= 0.0d0) &
1874 dpdxi = dpdxi + dpdchi * ((d*lfac-2.0d0*xicurrent)/lfac**3) * dlfacdxi
1876 end subroutine funcpressure
1880 subroutine funcenthalpy(pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p,h,dhdp)
1882 double precision,
intent(in) :: pcurrent,lfac2inv,d,sqrs,xicurrent,dv2d2p
1883 double precision,
intent(out):: h,dhdp
1886 double precision:: rho,E_th,E,dE_thdp,dEdp
1888 rho=d*dsqrt(lfac2inv)
1891 end subroutine funcenthalpy
1895 subroutine bisection_enthalpy(pcurrent,lfac2inv,d,xicurrent,h)
1897 double precision,
intent(in) :: pcurrent,lfac2inv,d,xicurrent
1898 double precision,
intent(out):: h
1901 double precision:: rho,E_th,E
1903 rho=d*dsqrt(lfac2inv)
1907 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.