27 double precision,
protected :: small_e
29 double precision,
public,
protected ::
small_r_e = 0.d0
38 double precision :: divbdiff = 0.8d0
43 double precision,
public,
protected ::
h_ion_fr=1d0
46 double precision,
public,
protected ::
he_ion_fr=1d0
53 double precision,
public,
protected ::
rr=1d0
55 double precision :: gamma_1, inv_gamma_1
57 double precision :: inv_squared_c0, inv_squared_c
64 integer,
public,
protected ::
rho_
66 integer,
allocatable,
public,
protected ::
mom(:)
68 integer,
public,
protected :: ^
c&m^C_
70 integer,
public,
protected ::
e_
72 integer,
public,
protected ::
r_e
74 integer,
public,
protected :: ^
c&b^C_
76 integer,
public,
protected ::
p_
78 integer,
public,
protected ::
q_
80 integer,
public,
protected ::
psi_
82 integer,
public,
protected ::
te_
87 integer,
allocatable,
public,
protected ::
tracer(:)
95 integer,
parameter :: divb_none = 0
96 integer,
parameter :: divb_multigrid = -1
97 integer,
parameter :: divb_glm = 1
98 integer,
parameter :: divb_powel = 2
99 integer,
parameter :: divb_janhunen = 3
100 integer,
parameter :: divb_linde = 4
101 integer,
parameter :: divb_lindejanhunen = 5
102 integer,
parameter :: divb_lindepowel = 6
103 integer,
parameter :: divb_lindeglm = 7
104 integer,
parameter :: divb_ct = 8
145 logical :: compactres = .false.
163 logical,
protected :: radio_acoustic_filter = .false.
164 integer,
protected :: size_ra_filter = 1
168 logical :: dt_c = .false.
178 logical :: total_energy = .true.
182 logical :: gravity_energy
184 logical :: gravity_rhov = .false.
186 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
188 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
190 character(len=std_len) :: typedivbdiff =
'all'
230 subroutine rmhd_read_params(files)
233 character(len=*),
intent(in) :: files(:)
251 do n = 1,
size(files)
252 open(
unitpar, file=trim(files(n)), status=
"old")
253 read(
unitpar, rmhd_list,
end=111)
257 end subroutine rmhd_read_params
260 subroutine rmhd_write_info(fh)
262 integer,
intent(in) :: fh
264 integer,
parameter :: n_par = 1
265 double precision :: values(n_par)
266 integer,
dimension(MPI_STATUS_SIZE) :: st
267 character(len=name_len) :: names(n_par)
269 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
273 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
274 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
275 end subroutine rmhd_write_info
301 if(
mype==0)
write(*,*)
'WARNING: set rmhd_partial_ionization=F when eq_state_units=F'
307 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
310 physics_type =
"rmhd"
325 phys_total_energy=total_energy
327 gravity_energy=.true.
332 gravity_energy=.false.
338 if(
mype==0)
write(*,*)
'WARNING: reset rmhd_trac_type=1 for 1D simulation'
343 if(
mype==0)
write(*,*)
'WARNING: set rmhd_trac_mask==bigdouble for global TRAC method'
352 type_divb = divb_none
355 type_divb = divb_multigrid
357 mg%operator_type = mg_laplacian
364 case (
'powel',
'powell')
365 type_divb = divb_powel
367 type_divb = divb_janhunen
369 type_divb = divb_linde
370 case (
'lindejanhunen')
371 type_divb = divb_lindejanhunen
373 type_divb = divb_lindepowel
377 type_divb = divb_lindeglm
382 call mpistop(
'Unknown divB fix')
385 allocate(start_indices(number_species),stop_indices(number_species))
392 mom(:) = var_set_momentum(
ndir)
398 e_ = var_set_energy()
407 mag(:) = var_set_bfield(
ndir)
411 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
417 r_e = var_set_radiation_energy()
430 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
443 te_ = var_set_auxvar(
'Te',
'Te')
452 stop_indices(1)=nwflux
485 allocate(iw_vector(nvector))
486 iw_vector(1) = mom(1) - 1
487 iw_vector(2) = mag(1) - 1
490 if (.not.
allocated(flux_type))
then
491 allocate(flux_type(
ndir, nwflux))
492 flux_type = flux_default
493 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
494 call mpistop(
"phys_check error: flux_type has wrong shape")
497 if(nwflux>mag(
ndir))
then
499 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
504 flux_type(:,
psi_)=flux_special
506 flux_type(idir,mag(idir))=flux_special
510 flux_type(idir,mag(idir))=flux_tvdlf
516 phys_get_dt => rmhd_get_dt
517 phys_get_cmax => rmhd_get_cmax_origin
518 phys_get_a2max => rmhd_get_a2max
519 phys_get_tcutoff => rmhd_get_tcutoff
520 phys_get_h_speed => rmhd_get_h_speed
522 phys_get_cbounds => rmhd_get_cbounds_split_rho
524 phys_get_cbounds => rmhd_get_cbounds
527 phys_to_primitive => rmhd_to_primitive_split_rho
529 phys_to_conserved => rmhd_to_conserved_split_rho
532 phys_to_primitive => rmhd_to_primitive_origin
534 phys_to_conserved => rmhd_to_conserved_origin
538 phys_get_flux => rmhd_get_flux_split
540 phys_get_flux => rmhd_get_flux
544 phys_add_source_geom => rmhd_add_source_geom_split
546 phys_add_source_geom => rmhd_add_source_geom
548 phys_add_source => rmhd_add_source
549 phys_check_params => rmhd_check_params
550 phys_write_info => rmhd_write_info
552 phys_handle_small_values => rmhd_handle_small_values_origin
553 rmhd_handle_small_values => rmhd_handle_small_values_origin
554 phys_check_w => rmhd_check_w_origin
560 phys_get_pthermal => rmhd_get_pthermal_origin
564 phys_set_equi_vars => set_equi_vars_grid
567 if(type_divb==divb_glm)
then
568 phys_modify_wlr => rmhd_modify_wlr
573 rmhd_get_rfactor=>rfactor_from_temperature_ionization
574 phys_update_temperature => rmhd_update_temperature
578 rmhd_get_rfactor=>rfactor_from_constant_ionization
593 phys_get_ct_velocity => rmhd_get_ct_velocity
594 phys_update_faces => rmhd_update_faces
596 phys_modify_wlr => rmhd_modify_wlr
598 phys_boundary_adjust => rmhd_boundary_adjust
607 call rmhd_physical_units()
616 call mpistop(
'Radiation formalism unknown')
623 call mpistop(
"thermal conduction needs rmhd_energy=T")
626 call mpistop(
"hyperbolic thermal conduction needs rmhd_energy=T")
636 call add_sts_method(rmhd_get_tc_dt_rmhd,rmhd_sts_set_source_tc_rmhd,e_,1,e_,1,.false.)
638 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot_with_equi
640 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot
643 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint_with_equi
645 tc_fl%has_equi = .true.
646 tc_fl%get_temperature_equi => rmhd_get_temperature_equi
647 tc_fl%get_rho_equi => rmhd_get_rho_equi
649 tc_fl%has_equi = .false.
652 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint
664 te_fl_rmhd%get_var_Rfactor => rmhd_get_rfactor
666 phys_te_images => rmhd_te_images
679 if (particles_eta < zero) particles_eta =
rmhd_eta
680 if (particles_etah < zero) particles_eta =
rmhd_etah
682 write(*,*)
'*****Using particles: with rmhd_eta, rmhd_etah :',
rmhd_eta,
rmhd_etah
683 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
695 subroutine rmhd_te_images
700 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
702 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
704 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
706 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
709 call mpistop(
"Error in synthesize emission: Unknown convert_type")
711 end subroutine rmhd_te_images
717 subroutine rmhd_sts_set_source_tc_rmhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
721 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
722 double precision,
intent(in) :: x(ixi^s,1:
ndim)
723 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
724 double precision,
intent(in) :: my_dt
725 logical,
intent(in) :: fix_conserve_at_step
727 end subroutine rmhd_sts_set_source_tc_rmhd
729 function rmhd_get_tc_dt_rmhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
735 integer,
intent(in) :: ixi^
l, ixo^
l
736 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
737 double precision,
intent(in) :: w(ixi^s,1:nw)
738 double precision :: dtnew
741 end function rmhd_get_tc_dt_rmhd
743 subroutine rmhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
745 integer,
intent(in) :: ixi^
l,ixo^
l
746 double precision,
intent(inout) :: w(ixi^s,1:nw)
747 double precision,
intent(in) :: x(ixi^s,1:
ndim)
748 integer,
intent(in) :: step
749 character(len=140) :: error_msg
751 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
752 call rmhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
753 end subroutine rmhd_tc_handle_small_e
756 subroutine tc_params_read_rmhd(fl)
758 type(tc_fluid),
intent(inout) :: fl
759 double precision :: tc_k_para=0d0
760 double precision :: tc_k_perp=0d0
763 logical :: tc_perpendicular=.false.
764 logical :: tc_saturate=.false.
765 character(len=std_len) :: tc_slope_limiter=
"MC"
767 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp
771 read(
unitpar, tc_list,
end=111)
775 fl%tc_perpendicular = tc_perpendicular
776 fl%tc_saturate = tc_saturate
777 fl%tc_k_para = tc_k_para
778 fl%tc_k_perp = tc_k_perp
779 select case(tc_slope_limiter)
781 fl%tc_slope_limiter = 0
784 fl%tc_slope_limiter = 1
787 fl%tc_slope_limiter = 2
790 fl%tc_slope_limiter = 3
793 fl%tc_slope_limiter = 4
795 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod")
797 end subroutine tc_params_read_rmhd
801 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
804 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
805 double precision,
intent(in) :: x(ixi^s,1:
ndim)
806 double precision :: delx(ixi^s,1:
ndim)
807 double precision :: xc(ixi^s,1:
ndim),xshift^
d
808 integer :: idims, ixc^
l, hxo^
l, ix, idims2
814 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
818 hxo^
l=ixo^
l-
kr(idims,^
d);
824 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
827 xshift^
d=half*(one-
kr(^
d,idims));
834 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
838 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
840 end subroutine set_equi_vars_grid_faces
843 subroutine set_equi_vars_grid(igrid)
846 integer,
intent(in) :: igrid
852 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
853 end subroutine set_equi_vars_grid
856 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
858 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
859 double precision,
intent(in) :: w(ixi^s, 1:nw)
860 double precision,
intent(in) :: x(ixi^s,1:
ndim)
861 double precision :: wnew(ixo^s, 1:nwc)
868 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
874 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
878 wnew(ixo^s,
e_)=w(ixo^s,
e_)
882 if(
b0field .and. total_energy)
then
883 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
884 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
887 end function convert_vars_splitting
889 subroutine rmhd_check_params
897 if (
rmhd_gamma <= 0.0d0)
call mpistop (
"Error: rmhd_gamma <= 0")
898 if (
rmhd_adiab < 0.0d0)
call mpistop (
"Error: rmhd_adiab < 0")
902 call mpistop (
"Error: rmhd_gamma <= 0 or rmhd_gamma == 1")
903 inv_gamma_1=1.d0/gamma_1
910 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
915 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
922 end subroutine rmhd_check_params
936 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
937 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
940 mg%bc(ib, mg_iphi)%bc_type = mg_bc_dirichlet
941 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
945 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
946 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
954 call mpistop(
"divE_multigrid warning: unknown b.c. ")
959 subroutine rmhd_physical_units()
961 double precision :: mp,kb,miu0,c_lightspeed
962 double precision :: a,
b
1027 end subroutine rmhd_physical_units
1029 subroutine rmhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1031 logical,
intent(in) :: primitive
1032 integer,
intent(in) :: ixi^
l, ixo^
l
1033 double precision,
intent(in) :: w(ixi^s,nw)
1034 logical,
intent(inout) :: flag(ixi^s,1:nw)
1035 double precision :: tmp
1039 {
do ix^db=ixomin^db,ixomax^db\}
1053 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1057 if(tmp<small_e) flag(ix^
d,
e_) = .true.
1062 end subroutine rmhd_check_w_origin
1065 subroutine rmhd_to_conserved_origin(ixI^L,ixO^L,w,x)
1067 integer,
intent(in) :: ixi^
l, ixo^
l
1068 double precision,
intent(inout) :: w(ixi^s, nw)
1069 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1072 {
do ix^db=ixomin^db,ixomax^db\}
1074 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1076 +(^
c&w(ix^
d,
b^
c_)**2+))
1080 end subroutine rmhd_to_conserved_origin
1083 subroutine rmhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
1085 integer,
intent(in) :: ixi^
l, ixo^
l
1086 double precision,
intent(inout) :: w(ixi^s, nw)
1087 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1088 double precision :: rho
1091 {
do ix^db=ixomin^db,ixomax^db\}
1094 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1095 +half*((^
c&w(ix^
d,
m^
c_)**2+)*rho&
1096 +(^
c&w(ix^
d,
b^
c_)**2+))
1100 end subroutine rmhd_to_conserved_split_rho
1103 subroutine rmhd_to_primitive_origin(ixI^L,ixO^L,w,x)
1105 integer,
intent(in) :: ixi^
l, ixo^
l
1106 double precision,
intent(inout) :: w(ixi^s, nw)
1107 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1108 double precision :: inv_rho
1113 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_origin')
1116 {
do ix^db=ixomin^db,ixomax^db\}
1117 inv_rho = 1.d0/w(ix^
d,
rho_)
1121 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1123 +(^
c&w(ix^
d,
b^
c_)**2+)))
1125 end subroutine rmhd_to_primitive_origin
1128 subroutine rmhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
1130 integer,
intent(in) :: ixi^
l, ixo^
l
1131 double precision,
intent(inout) :: w(ixi^s, nw)
1132 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1133 double precision :: inv_rho
1138 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_split_rho')
1141 {
do ix^db=ixomin^db,ixomax^db\}
1146 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1148 (^
c&w(ix^
d,
m^
c_)**2+)+(^
c&w(ix^
d,
b^
c_)**2+)))
1150 end subroutine rmhd_to_primitive_split_rho
1155 integer,
intent(in) :: ixi^
l, ixo^
l
1156 double precision,
intent(inout) :: w(ixi^s, nw)
1157 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1162 {
do ix^db=ixomin^db,ixomax^db\}
1165 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1167 +(^
c&w(ix^
d,
b^
c_)**2+))
1170 {
do ix^db=ixomin^db,ixomax^db\}
1172 w(ix^d,
e_)=w(ix^d,
e_)&
1173 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1174 +(^
c&w(ix^d,
b^
c_)**2+))
1182 integer,
intent(in) :: ixi^
l, ixo^
l
1183 double precision,
intent(inout) :: w(ixi^s, nw)
1184 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1189 {
do ix^db=ixomin^db,ixomax^db\}
1192 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1194 +(^
c&w(ix^
d,
b^
c_)**2+))
1197 {
do ix^db=ixomin^db,ixomax^db\}
1199 w(ix^d,
e_)=w(ix^d,
e_)&
1200 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1201 +(^
c&w(ix^d,
b^
c_)**2+))
1205 if(fix_small_values)
then
1206 call rmhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'rmhd_e_to_ei')
1210 subroutine rmhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
1213 logical,
intent(in) :: primitive
1214 integer,
intent(in) :: ixi^
l,ixo^
l
1215 double precision,
intent(inout) :: w(ixi^s,1:nw)
1216 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1217 character(len=*),
intent(in) :: subname
1218 double precision :: rho
1219 integer :: idir, ix^
d
1220 logical :: flag(ixi^s,1:nw)
1222 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
1226 {
do ix^db=ixomin^db,ixomax^db\}
1236 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
1248 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))&
1252 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))
1259 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
1261 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
1264 {
do ix^db=iximin^db,iximax^db\}
1270 w(ix^d,
e_)=w(ix^d,
e_)&
1271 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1273 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
1275 {
do ix^db=iximin^db,iximax^db\}
1281 w(ix^d,
e_)=w(ix^d,
e_)&
1282 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1285 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
1287 if(.not.primitive)
then
1290 {
do ix^db=iximin^db,iximax^db\}
1296 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
1297 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
1298 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+)))
1301 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
1304 end subroutine rmhd_handle_small_values_origin
1309 integer,
intent(in) :: ixi^
l, ixo^
l
1310 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
1311 double precision,
intent(out) :: v(ixi^s,
ndir)
1312 double precision :: rho(ixi^s)
1316 rho(ixo^s)=1.d0/rho(ixo^s)
1319 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
1324 subroutine rmhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
1326 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1327 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1328 double precision,
intent(inout) :: cmax(ixi^s)
1329 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1333 {
do ix^db=ixomin^db,ixomax^db \}
1344 cfast2=b2*inv_rho+cmax(ix^
d)
1345 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
1346 if(avmincs2<zero) avmincs2=zero
1347 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1348 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
1351 {
do ix^db=ixomin^db,ixomax^db \}
1361 b2=(^
c&w(ix^d,
b^
c_)**2+)
1362 cfast2=b2*inv_rho+cmax(ix^d)
1363 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1364 if(avmincs2<zero) avmincs2=zero
1365 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1366 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
1369 end subroutine rmhd_get_cmax_origin
1371 subroutine rmhd_get_a2max(w,x,ixI^L,ixO^L,a2max)
1373 integer,
intent(in) :: ixi^
l, ixo^
l
1374 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1375 double precision,
intent(inout) :: a2max(
ndim)
1376 double precision :: a2(ixi^s,
ndim,nw)
1377 integer :: gxo^
l,hxo^
l,jxo^
l,kxo^
l,i,j
1382 hxo^
l=ixo^
l-
kr(i,^
d);
1383 gxo^
l=hxo^
l-
kr(i,^
d);
1384 jxo^
l=ixo^
l+
kr(i,^
d);
1385 kxo^
l=jxo^
l+
kr(i,^
d);
1386 a2(ixo^s,i,1:nw)=abs(-w(kxo^s,1:nw)+16.d0*w(jxo^s,1:nw)&
1387 -30.d0*w(ixo^s,1:nw)+16.d0*w(hxo^s,1:nw)-w(gxo^s,1:nw))
1388 a2max(i)=maxval(a2(ixo^s,i,1:nw))/12.d0/
dxlevel(i)**2
1390 end subroutine rmhd_get_a2max
1393 subroutine rmhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
1396 integer,
intent(in) :: ixi^
l,ixo^
l
1397 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1398 double precision,
intent(out) :: tco_local,tmax_local
1400 double precision,
intent(inout) :: w(ixi^s,1:nw)
1401 double precision,
parameter :: trac_delta=0.25d0
1402 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s)
1403 double precision,
dimension(ixI^S,1:ndir) :: bunitvec
1404 double precision,
dimension(ixI^S,1:ndim) :: gradt
1405 double precision :: bdir(
ndim)
1406 double precision :: ltrc,ltrp,altr(ixi^s)
1407 integer :: idims,jxo^
l,hxo^
l,ixa^
d,ixb^
d,ix^
d
1408 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
1409 logical :: lrlt(ixi^s)
1412 call rmhd_get_temperature_from_te(w,x,ixi^
l,ixi^
l,te)
1414 call rmhd_get_rfactor(w,x,ixi^
l,ixi^
l,te)
1415 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
1418 tmax_local=maxval(te(ixo^s))
1428 lts(ixo^s)=0.5d0*abs(te(jxo^s)-te(hxo^s))/te(ixo^s)
1430 where(lts(ixo^s) > trac_delta)
1433 if(any(lrlt(ixo^s)))
then
1434 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
1445 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
1446 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1447 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
1448 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
1450 call mpistop(
"rmhd_trac_type not allowed for 1D simulation")
1462 gradt(ixo^s,idims)=tmp1(ixo^s)
1466 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))+
block%B0(ixo^s,:,0)
1468 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))
1474 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
1477 if(sum(bdir(:)**2) .gt. zero)
then
1478 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
1480 block%special_values(3:ndim+2)=bdir(1:ndim)
1482 tmp1(ixo^s)=dsqrt(sum(bunitvec(ixo^s,:)**2,dim=ndim+1))
1483 where(tmp1(ixo^s)/=0.d0)
1484 tmp1(ixo^s)=1.d0/tmp1(ixo^s)
1486 tmp1(ixo^s)=bigdouble
1490 bunitvec(ixo^s,idims)=bunitvec(ixo^s,idims)*tmp1(ixo^s)
1493 lts(ixo^s)=abs(sum(gradt(ixo^s,1:ndim)*bunitvec(ixo^s,1:ndim),dim=ndim+1))/te(ixo^s)
1495 if(slab_uniform)
then
1496 lts(ixo^s)=minval(dxlevel)*lts(ixo^s)
1498 lts(ixo^s)=minval(block%ds(ixo^s,:),dim=ndim+1)*lts(ixo^s)
1501 where(lts(ixo^s) > trac_delta)
1504 if(any(lrlt(ixo^s)))
then
1505 block%special_values(1)=maxval(te(ixo^s), mask=lrlt(ixo^s))
1507 block%special_values(1)=zero
1509 block%special_values(2)=tmax_local
1528 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1529 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1530 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1533 {
do ix^db=ixpmin^db,ixpmax^db\}
1535 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))+block%B0(ix^d,^
c,0)\
1537 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))\
1539 tmp1(ix^d)=1.d0/(dsqrt(^
c&bunitvec(ix^d,^
c)**2+)+smalldouble)
1541 ^d&bunitvec({ix^d},^d)=bunitvec({ix^d},^d)*tmp1({ix^d})\
1543 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec({ix^d},^d)+)/te(ix^d)
1545 if(slab_uniform)
then
1546 lts(ix^d)=min(^d&dxlevel(^d))*lts(ix^d)
1548 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
1550 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
1555 hxo^l=ixp^l-kr(idims,^d);
1556 jxo^l=ixp^l+kr(idims,^d);
1558 altr(ixp^s)=0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1560 altr(ixp^s)=altr(ixp^s)+0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1563 block%wextra(ixp^s,
tcoff_)=te(ixp^s)*altr(ixp^s)**0.4d0
1567 call mpistop(
"unknown rmhd_trac_type")
1570 end subroutine rmhd_get_tcutoff
1573 subroutine rmhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
1576 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1577 double precision,
intent(in) :: wprim(ixi^s, nw)
1578 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1579 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
1581 double precision :: csound(ixi^s,
ndim)
1582 double precision,
allocatable :: tmp(:^
d&)
1583 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
1587 allocate(tmp(ixa^s))
1589 call rmhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
1590 csound(ixa^s,id)=tmp(ixa^s)
1593 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
1594 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
1595 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
1596 hspeed(ixc^s,1)=0.5d0*abs(wprim(jxc^s,
mom(idim))+csound(jxc^s,idim)-wprim(ixc^s,
mom(idim))+csound(ixc^s,idim))
1600 ixamax^
d=ixcmax^
d+
kr(id,^
d);
1601 ixamin^
d=ixcmin^
d+
kr(id,^
d);
1602 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(ixa^s,
mom(id))+csound(ixa^s,id)-wprim(ixc^s,
mom(id))+csound(ixc^s,id)))
1603 ixamax^
d=ixcmax^
d-
kr(id,^
d);
1604 ixamin^
d=ixcmin^
d-
kr(id,^
d);
1605 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(ixc^s,
mom(id))+csound(ixc^s,id)-wprim(ixa^s,
mom(id))+csound(ixa^s,id)))
1610 ixamax^
d=jxcmax^
d+
kr(id,^
d);
1611 ixamin^
d=jxcmin^
d+
kr(id,^
d);
1612 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(ixa^s,
mom(id))+csound(ixa^s,id)-wprim(jxc^s,
mom(id))+csound(jxc^s,id)))
1613 ixamax^
d=jxcmax^
d-
kr(id,^
d);
1614 ixamin^
d=jxcmin^
d-
kr(id,^
d);
1615 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(jxc^s,
mom(id))+csound(jxc^s,id)-wprim(ixa^s,
mom(id))+csound(ixa^s,id)))
1619 end subroutine rmhd_get_h_speed
1622 subroutine rmhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1624 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1625 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1626 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1627 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1628 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1629 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1630 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1632 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1633 double precision :: umean, dmean, tmp1, tmp2, tmp3
1640 call rmhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1641 call rmhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1642 if(
present(cmin))
then
1643 {
do ix^db=ixomin^db,ixomax^db\}
1644 tmp1=sqrt(wlp(ix^
d,
rho_))
1645 tmp2=sqrt(wrp(ix^
d,
rho_))
1646 tmp3=1.d0/(tmp1+tmp2)
1647 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1648 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1649 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1650 cmin(ix^
d,1)=umean-dmean
1651 cmax(ix^
d,1)=umean+dmean
1653 if(h_correction)
then
1654 {
do ix^db=ixomin^db,ixomax^db\}
1655 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1656 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1660 {
do ix^db=ixomin^db,ixomax^db\}
1661 tmp1=sqrt(wlp(ix^d,
rho_))
1662 tmp2=sqrt(wrp(ix^d,
rho_))
1663 tmp3=1.d0/(tmp1+tmp2)
1664 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1665 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1666 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1667 cmax(ix^d,1)=abs(umean)+dmean
1671 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1672 call rmhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
1673 if(
present(cmin))
then
1674 {
do ix^db=ixomin^db,ixomax^db\}
1675 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1676 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1678 if(h_correction)
then
1679 {
do ix^db=ixomin^db,ixomax^db\}
1680 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1681 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1685 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1689 call rmhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
1690 call rmhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
1691 if(
present(cmin))
then
1692 {
do ix^db=ixomin^db,ixomax^db\}
1693 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1694 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1695 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1697 if(h_correction)
then
1698 {
do ix^db=ixomin^db,ixomax^db\}
1699 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1700 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1704 {
do ix^db=ixomin^db,ixomax^db\}
1705 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1706 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1710 end subroutine rmhd_get_cbounds
1713 subroutine rmhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1715 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1716 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1717 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1718 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1719 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1720 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1721 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1722 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1723 double precision :: umean, dmean, tmp1, tmp2, tmp3
1730 call rmhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1731 call rmhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1732 if(
present(cmin))
then
1733 {
do ix^db=ixomin^db,ixomax^db\}
1736 tmp3=1.d0/(tmp1+tmp2)
1737 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1738 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1739 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1740 cmin(ix^
d,1)=umean-dmean
1741 cmax(ix^
d,1)=umean+dmean
1743 if(h_correction)
then
1744 {
do ix^db=ixomin^db,ixomax^db\}
1745 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1746 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1750 {
do ix^db=ixomin^db,ixomax^db\}
1753 tmp3=1.d0/(tmp1+tmp2)
1754 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1755 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1756 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1757 cmax(ix^d,1)=abs(umean)+dmean
1761 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1762 call rmhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
1763 if(
present(cmin))
then
1764 {
do ix^db=ixomin^db,ixomax^db\}
1765 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1766 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1768 if(h_correction)
then
1769 {
do ix^db=ixomin^db,ixomax^db\}
1770 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1771 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1775 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1779 call rmhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
1780 call rmhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
1781 if(
present(cmin))
then
1782 {
do ix^db=ixomin^db,ixomax^db\}
1783 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1784 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1785 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1787 if(h_correction)
then
1788 {
do ix^db=ixomin^db,ixomax^db\}
1789 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1790 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1794 {
do ix^db=ixomin^db,ixomax^db\}
1795 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1796 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1800 end subroutine rmhd_get_cbounds_split_rho
1803 subroutine rmhd_get_ct_velocity(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1805 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1806 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1807 double precision,
intent(in) :: cmax(ixi^s)
1808 double precision,
intent(in),
optional :: cmin(ixi^s)
1809 type(ct_velocity),
intent(inout) :: vcts
1810 integer :: idime,idimn
1816 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
1818 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
1820 if(.not.
allocated(vcts%vbarC))
then
1821 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
1822 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
1825 if(
present(cmin))
then
1826 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
1827 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1829 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1830 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
1833 idimn=mod(idim,
ndir)+1
1834 idime=mod(idim+1,
ndir)+1
1836 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
1837 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
1838 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
1839 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1840 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1841 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
1842 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
1843 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
1844 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1845 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1847 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
1849 end subroutine rmhd_get_ct_velocity
1852 subroutine rmhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
1854 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1855 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1856 double precision,
intent(out):: csound(ixo^s)
1857 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
1858 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1859 double precision :: prad_max(ixo^s)
1864 if(radio_acoustic_filter)
then
1865 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
1869 {
do ix^db=ixomin^db,ixomax^db \}
1870 inv_rho=1.d0/w(ix^
d,
rho_)
1871 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1873 csound(ix^
d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
1878 cfast2=b2*inv_rho+csound(ix^
d)
1879 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
1881 if(avmincs2<zero) avmincs2=zero
1882 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1885 {
do ix^db=ixomin^db,ixomax^db \}
1886 inv_rho=1.d0/w(ix^d,
rho_)
1887 prad_max(ix^d)=maxval(prad_tensor(ix^d,:,:))
1889 csound(ix^d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+prad_max(ix^d))*inv_rho
1893 b2=(^
c&w(ix^d,
b^
c_)**2+)
1894 cfast2=b2*inv_rho+csound(ix^d)
1895 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1896 if(avmincs2<zero) avmincs2=zero
1897 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1900 end subroutine rmhd_get_csound_prim
1903 subroutine rmhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
1905 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1906 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1907 double precision,
intent(out):: csound(ixo^s)
1908 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1909 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1910 double precision :: prad_max(ixo^s)
1915 if (radio_acoustic_filter)
then
1916 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
1921 {
do ix^db=ixomin^db,ixomax^db \}
1924 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1929 cfast2=b2*inv_rho+csound(ix^
d)
1930 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
1932 if(avmincs2<zero) avmincs2=zero
1933 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1936 {
do ix^db=ixomin^db,ixomax^db \}
1939 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
1941 csound(ix^d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i)+prad_max(ix^d))*inv_rho
1943 b2=(^
c&w(ix^d,
b^
c_)**2+)
1944 cfast2=b2*inv_rho+csound(ix^d)
1945 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1946 if(avmincs2<zero) avmincs2=zero
1947 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1950 end subroutine rmhd_get_csound_prim_split
1953 subroutine rmhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
1957 integer,
intent(in) :: ixi^
l, ixo^
l
1958 double precision,
intent(in) :: w(ixi^s,nw)
1959 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1960 double precision,
intent(out):: pth(ixi^s)
1964 {
do ix^db=ixomin^db,ixomax^db\}
1969 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)&
1970 +(^
c&w(ix^
d,
b^
c_)**2+)))
1975 if(check_small_values.and..not.fix_small_values)
then
1976 {
do ix^db=ixomin^db,ixomax^db\}
1977 if(pth(ix^d)<small_pressure)
then
1978 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1979 " encountered when call rmhd_get_pthermal"
1980 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1981 write(*,*)
"Location: ", x(ix^d,:)
1982 write(*,*)
"Cell number: ", ix^d
1984 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1987 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1988 write(*,*)
"Saving status at the previous time step"
1993 end subroutine rmhd_get_pthermal_origin
1996 subroutine rmhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
1998 integer,
intent(in) :: ixi^
l, ixo^
l
1999 double precision,
intent(in) :: w(ixi^s, 1:nw)
2000 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2001 double precision,
intent(out):: res(ixi^s)
2002 res(ixo^s) = w(ixo^s,
te_)
2003 end subroutine rmhd_get_temperature_from_te
2006 subroutine rmhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
2008 integer,
intent(in) :: ixi^
l, ixo^
l
2009 double precision,
intent(in) :: w(ixi^s, 1:nw)
2010 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2011 double precision,
intent(out):: res(ixi^s)
2012 double precision :: r(ixi^s)
2014 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2015 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
2016 end subroutine rmhd_get_temperature_from_eint
2019 subroutine rmhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
2021 integer,
intent(in) :: ixi^
l, ixo^
l
2022 double precision,
intent(in) :: w(ixi^s, 1:nw)
2023 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2024 double precision,
intent(out):: res(ixi^s)
2025 double precision :: r(ixi^s)
2027 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2029 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
2030 end subroutine rmhd_get_temperature_from_etot
2032 subroutine rmhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
2034 integer,
intent(in) :: ixi^
l, ixo^
l
2035 double precision,
intent(in) :: w(ixi^s, 1:nw)
2036 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2037 double precision,
intent(out):: res(ixi^s)
2038 double precision :: r(ixi^s)
2040 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2043 end subroutine rmhd_get_temperature_from_etot_with_equi
2045 subroutine rmhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
2047 integer,
intent(in) :: ixi^
l, ixo^
l
2048 double precision,
intent(in) :: w(ixi^s, 1:nw)
2049 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2050 double precision,
intent(out):: res(ixi^s)
2051 double precision :: r(ixi^s)
2053 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2056 end subroutine rmhd_get_temperature_from_eint_with_equi
2058 subroutine rmhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
2060 integer,
intent(in) :: ixi^
l, ixo^
l
2061 double precision,
intent(in) :: w(ixi^s, 1:nw)
2062 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2063 double precision,
intent(out):: res(ixi^s)
2064 double precision :: r(ixi^s)
2066 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2068 end subroutine rmhd_get_temperature_equi
2070 subroutine rmhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
2072 integer,
intent(in) :: ixi^
l, ixo^
l
2073 double precision,
intent(in) :: w(ixi^s, 1:nw)
2074 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2075 double precision,
intent(out):: res(ixi^s)
2077 end subroutine rmhd_get_rho_equi
2079 subroutine rmhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
2081 integer,
intent(in) :: ixi^
l, ixo^
l
2082 double precision,
intent(in) :: w(ixi^s, 1:nw)
2083 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2084 double precision,
intent(out):: res(ixi^s)
2086 end subroutine rmhd_get_pe_equi
2089 subroutine rmhd_get_p_total(w,x,ixI^L,ixO^L,p)
2091 integer,
intent(in) :: ixi^
l, ixo^
l
2092 double precision,
intent(in) :: w(ixi^s,nw)
2093 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2094 double precision,
intent(out) :: p(ixi^s)
2097 p(ixo^s) = p(ixo^s) + 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
2098 end subroutine rmhd_get_p_total
2105 integer,
intent(in) :: ixi^
l, ixo^
l, nth
2106 double precision,
intent(in) :: w(ixi^s, 1:nw)
2107 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2108 double precision,
intent(out):: prad(ixo^s, 1:
ndim, 1:
ndim)
2116 call mpistop(
'Radiation formalism unknown')
2123 integer,
intent(in) :: ixi^
l, ixo^
l
2124 double precision,
intent(in) :: w(ixi^s, 1:nw)
2125 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2126 double precision :: pth(ixi^s)
2127 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2128 double precision :: prad_max(ixo^s)
2129 double precision,
intent(out) :: pth_plus_prad(ixi^s)
2134 {
do ix^
d = ixomin^
d,ixomax^
d\}
2135 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2138 if (radio_acoustic_filter)
then
2139 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2141 pth_plus_prad(ixo^s) = pth(ixo^s) + prad_max(ixo^s)
2145 subroutine rmhd_radio_acoustic_filter(x, ixI^L, ixO^L, prad_max)
2147 integer,
intent(in) :: ixi^
l, ixo^
l
2148 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2149 double precision,
intent(inout) :: prad_max(ixo^s)
2150 double precision :: tmp_prad(ixi^s)
2151 integer :: ix^
d, filter, idim
2153 if (size_ra_filter .lt. 1)
call mpistop(
"ra filter of size < 1 makes no sense")
2154 if (size_ra_filter .gt.
nghostcells)
call mpistop(
"ra filter of size < nghostcells makes no sense")
2156 tmp_prad(ixi^s) = zero
2157 tmp_prad(ixo^s) = prad_max(ixo^s)
2158 do filter = 1,size_ra_filter
2161 {
do ix^
d = ixomin^
d,ixomax^
d\}
2162 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d+filter*
kr(idim,^
d)))
2163 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d-filter*
kr(idim,^
d)))
2167 end subroutine rmhd_radio_acoustic_filter
2172 integer,
intent(in) :: ixi^
l, ixo^
l
2173 double precision,
intent(in) :: w(ixi^s, 1:nw)
2174 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2175 double precision :: pth(ixi^s)
2176 double precision,
intent(out):: tgas(ixi^s)
2179 tgas(ixi^s) = pth(ixi^s)/w(ixi^s,
rho_)
2187 integer,
intent(in) :: ixi^
l, ixo^
l
2188 double precision,
intent(in) :: w(ixi^s, 1:nw)
2189 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2190 double precision,
intent(out):: trad(ixi^s)
2197 subroutine rmhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
2201 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2203 double precision,
intent(in) :: wc(ixi^s,nw)
2205 double precision,
intent(in) :: w(ixi^s,nw)
2206 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2207 double precision,
intent(out) :: f(ixi^s,nwflux)
2208 double precision :: vhall(ixi^s,1:
ndir)
2209 double precision :: ptotal
2212 {
do ix^db=ixomin^db,ixomax^db\}
2217 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2219 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2222 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2223 -w(ix^
d,mag(idim))*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2228 {
do ix^db=ixomin^db,ixomax^db\}
2229 f(ix^d,mag(idim))=w(ix^d,
psi_)
2231 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
2235 {
do ix^db=ixomin^db,ixomax^db\}
2236 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2243 {
do ix^db=ixomin^db,ixomax^db\}
2248 {
do ix^db=ixomin^db,ixomax^db\}
2249 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^d&w({ix^d},
b^d_)**2+)+smalldouble)
2253 end subroutine rmhd_get_flux
2256 subroutine rmhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
2259 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2261 double precision,
intent(in) :: wc(ixi^s,nw)
2263 double precision,
intent(in) :: w(ixi^s,nw)
2264 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2265 double precision,
intent(out) :: f(ixi^s,nwflux)
2266 double precision :: vhall(ixi^s,1:
ndir)
2267 double precision :: ptotal, btotal(ixo^s,1:
ndir)
2270 {
do ix^db=ixomin^db,ixomax^db\}
2278 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2287 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
2291 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
2292 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2294 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
2298 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2301 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
2305 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2306 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2310 {
do ix^db=ixomin^db,ixomax^db\}
2311 f(ix^d,mag(idim))=w(ix^d,
psi_)
2313 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
2317 {
do ix^db=ixomin^db,ixomax^db\}
2318 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2325 {
do ix^db=ixomin^db,ixomax^db\}
2330 {
do ix^db=ixomin^db,ixomax^db\}
2331 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
2335 end subroutine rmhd_get_flux_split
2339 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
2342 integer,
intent(in) :: ixi^
l, ixo^
l
2343 double precision,
dimension(:^D&,:),
intent(inout) :: ff
2344 double precision,
intent(out) :: src(ixi^s)
2346 double precision :: ffc(ixi^s,1:
ndim)
2347 double precision :: dxinv(
ndim)
2348 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
2354 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
2356 ixbmin^
d=ixcmin^
d+ix^
d;
2357 ixbmax^
d=ixcmax^
d+ix^
d;
2360 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
2362 ff(ixi^s,1:ndim)=0.d0
2364 ixb^l=ixo^l-kr(idims,^d);
2365 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
2367 if({ ix^d==0 .and. ^d==idims | .or.})
then
2368 ixbmin^d=ixcmin^d-ix^d;
2369 ixbmax^d=ixcmax^d-ix^d;
2370 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
2373 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
2376 if(slab_uniform)
then
2378 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
2379 ixb^l=ixo^l-kr(idims,^d);
2380 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2384 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
2385 ixb^l=ixo^l-kr(idims,^d);
2386 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2388 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
2390 end subroutine get_flux_on_cell_face
2393 subroutine rmhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2399 integer,
intent(in) :: ixi^
l, ixo^
l
2400 double precision,
intent(in) :: qdt,dtfactor
2401 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2402 double precision,
intent(inout) :: w(ixi^s,1:nw)
2403 logical,
intent(in) :: qsourcesplit
2404 logical,
intent(inout) :: active
2410 if (.not. qsourcesplit)
then
2413 call add_pe0_divv(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2416 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
2421 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2426 call add_source_res2(qdt,ixi^
l,ixo^
l,wct,w,x)
2430 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
2436 select case (type_divb)
2441 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2444 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2447 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2448 case (divb_janhunen)
2450 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2451 case (divb_lindejanhunen)
2453 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2454 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2455 case (divb_lindepowel)
2457 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2458 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2459 case (divb_lindeglm)
2461 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2462 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2463 case (divb_multigrid)
2468 call mpistop(
'Unknown divB fix')
2478 w,x,gravity_energy,gravity_rhov,qsourcesplit,active)
2484 call rmhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,w,x,qsourcesplit,active)
2487 if(.not.qsourcesplit)
then
2489 call rmhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
2492 end subroutine rmhd_add_source
2494 subroutine rmhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,w,x,qsourcesplit,active)
2500 integer,
intent(in) :: ixi^
l, ixo^
l
2501 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
2502 double precision,
intent(in) :: wct(ixi^s,1:nw)
2503 double precision,
intent(inout) :: w(ixi^s,1:nw)
2504 logical,
intent(in) :: qsourcesplit
2505 logical,
intent(inout) :: active
2506 double precision :: cmax(ixi^s)
2513 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2518 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2524 call mpistop(
'Radiation formalism unknown')
2526 end subroutine rmhd_add_radiation_source
2528 subroutine add_pe0_divv(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2531 integer,
intent(in) :: ixi^
l, ixo^
l
2532 double precision,
intent(in) :: qdt,dtfactor
2533 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2534 double precision,
intent(inout) :: w(ixi^s,1:nw)
2535 double precision :: divv(ixi^s)
2551 end subroutine add_pe0_divv
2553 subroutine get_tau(ixI^L,ixO^L,w,Te,tau,sigT5)
2555 integer,
intent(in) :: ixi^
l, ixo^
l
2556 double precision,
dimension(ixI^S,1:nw),
intent(in) :: w
2557 double precision,
dimension(ixI^S),
intent(in) :: te
2558 double precision,
dimension(ixI^S),
intent(out) :: tau,sigt5
2559 double precision :: dxmin,taumin
2560 double precision,
dimension(ixI^S) :: sigt7,eint
2568 sigt7(ixo^s)=sigt5(ixo^s)*
block%wextra(ixo^s,
tcoff_)
2571 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2575 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2578 tau(ixo^s)=max(taumin*
dt,sigt7(ixo^s)/eint(ixo^s)/
cmax_global**2)
2579 end subroutine get_tau
2581 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
2583 integer,
intent(in) :: ixi^
l,ixo^
l
2584 double precision,
intent(in) :: qdt
2585 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
2586 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
2587 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
2588 double precision :: invdx
2589 double precision,
dimension(ixI^S) :: te,tau,sigt,htc_qsrc,tface,r
2590 double precision,
dimension(ixI^S) :: htc_esrc,bsum,bunit
2591 double precision,
dimension(ixI^S,1:ndim) :: btot
2593 integer :: hxc^
l,hxo^
l,ixc^
l,jxc^
l,jxo^
l,kxc^
l
2595 call rmhd_get_rfactor(wctprim,x,ixi^
l,ixi^
l,r)
2597 te(ixi^s)=wctprim(ixi^s,
p_)/(r(ixi^s)*w(ixi^s,
rho_))
2598 call get_tau(ixi^
l,ixo^
l,wctprim,te,tau,sigt)
2602 btot(ixo^s,idims)=wct(ixo^s,mag(idims))+
block%B0(ixo^s,idims,0)
2604 btot(ixo^s,idims)=wct(ixo^s,mag(idims))
2607 bsum(ixo^s)=sqrt(sum(btot(ixo^s,:)**2,dim=
ndim+1))+smalldouble
2611 ixcmin^
d=ixomin^
d-
kr(idims,^
d);ixcmax^
d=ixomax^
d;
2612 jxc^
l=ixc^
l+
kr(idims,^
d);
2613 kxc^
l=jxc^
l+
kr(idims,^
d);
2614 hxc^
l=ixc^
l-
kr(idims,^
d);
2615 hxo^
l=ixo^
l-
kr(idims,^
d);
2616 tface(ixc^s)=(7.d0*(te(ixc^s)+te(jxc^s))-(te(hxc^s)+te(kxc^s)))/12.d0
2617 bunit(ixo^s)=btot(ixo^s,idims)/bsum(ixo^s)
2618 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*bunit(ixo^s)*(tface(ixo^s)-tface(hxo^s))*invdx
2620 htc_qsrc(ixo^s)=(htc_qsrc(ixo^s)+wct(ixo^s,
q_))/tau(ixo^s)
2621 w(ixo^s,
q_)=w(ixo^s,
q_)-qdt*htc_qsrc(ixo^s)
2622 end subroutine add_hypertc_source
2625 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
2627 integer,
intent(in) :: ixi^
l, ixo^
l
2628 double precision,
intent(in) :: w(ixi^s,1:nw)
2629 double precision,
intent(inout) :: jxb(ixi^s,3)
2630 double precision :: a(ixi^s,3),
b(ixi^s,3)
2632 double precision :: current(ixi^s,7-2*
ndir:3)
2633 integer :: idir, idirmin
2638 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
2642 b(ixo^s, idir) = w(ixo^s,mag(idir))
2649 a(ixo^s,idir)=current(ixo^s,idir)
2652 end subroutine get_lorentz_force
2656 subroutine rmhd_gamma2_alfven(ixI^L, ixO^L, w, gamma_A2)
2658 integer,
intent(in) :: ixi^
l, ixo^
l
2659 double precision,
intent(in) :: w(ixi^s, nw)
2660 double precision,
intent(out) :: gamma_a2(ixo^s)
2661 double precision :: rho(ixi^s)
2667 rho(ixo^s) = w(ixo^s,
rho_)
2670 gamma_a2(ixo^s) = 1.0d0/(1.0d0+
rmhd_mag_en_all(w, ixi^
l, ixo^
l)/rho(ixo^s)*inv_squared_c)
2671 end subroutine rmhd_gamma2_alfven
2675 function rmhd_gamma_alfven(w, ixI^L, ixO^L)
result(gamma_A)
2677 integer,
intent(in) :: ixi^
l, ixo^
l
2678 double precision,
intent(in) :: w(ixi^s, nw)
2679 double precision :: gamma_a(ixo^s)
2681 call rmhd_gamma2_alfven(ixi^
l, ixo^
l, w, gamma_a)
2682 gamma_a = sqrt(gamma_a)
2683 end function rmhd_gamma_alfven
2687 integer,
intent(in) :: ixi^
l, ixo^
l
2688 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
2689 double precision,
intent(out) :: rho(ixi^s)
2694 rho(ixo^s) = w(ixo^s,
rho_)
2699 subroutine rmhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
2702 integer,
intent(in) :: ixi^
l,ixo^
l, ie
2703 double precision,
intent(inout) :: w(ixi^s,1:nw)
2704 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2705 character(len=*),
intent(in) :: subname
2706 double precision :: rho(ixi^s)
2708 logical :: flag(ixi^s,1:nw)
2712 where(w(ixo^s,ie)+
block%equi_vars(ixo^s,
equi_pe0_,0)*inv_gamma_1<small_e)&
2713 flag(ixo^s,ie)=.true.
2715 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
2717 if(any(flag(ixo^s,ie)))
then
2721 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e - &
2724 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
2730 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
2733 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
2738 end subroutine rmhd_handle_small_ei
2740 subroutine rmhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
2744 integer,
intent(in) :: ixi^
l, ixo^
l
2745 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2746 double precision,
intent(inout) :: w(ixi^s,1:nw)
2748 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
2756 end subroutine rmhd_update_temperature
2759 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2761 integer,
intent(in) :: ixi^
l, ixo^
l
2762 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2763 double precision,
intent(inout) :: w(ixi^s,1:nw)
2764 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
2775 a(ixo^s,idir)=
block%J0(ixo^s,idir)
2780 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2783 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2788 if(total_energy)
then
2791 b(ixo^s,:)=wct(ixo^s,mag(:))
2800 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2803 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2807 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
2810 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
2811 end subroutine add_source_b0split
2817 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
2821 integer,
intent(in) :: ixi^
l, ixo^
l
2822 double precision,
intent(in) :: qdt
2823 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2824 double precision,
intent(inout) :: w(ixi^s,1:nw)
2825 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim,jxo^
l,hxo^
l,ix
2826 integer :: lxo^
l, kxo^
l
2827 double precision :: tmp(ixi^s),tmp2(ixi^s)
2829 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
2830 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
2838 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2839 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
2844 gradeta(ixo^s,1:
ndim)=zero
2850 gradeta(ixo^s,idim)=tmp(ixo^s)
2856 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
2862 tmp2(ixi^s)=bf(ixi^s,idir)
2864 lxo^
l=ixo^
l+2*
kr(idim,^
d);
2865 jxo^
l=ixo^
l+
kr(idim,^
d);
2866 hxo^
l=ixo^
l-
kr(idim,^
d);
2867 kxo^
l=ixo^
l-2*
kr(idim,^
d);
2868 tmp(ixo^s)=tmp(ixo^s)+&
2869 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
2874 tmp2(ixi^s)=bf(ixi^s,idir)
2876 jxo^
l=ixo^
l+
kr(idim,^
d);
2877 hxo^
l=ixo^
l-
kr(idim,^
d);
2878 tmp(ixo^s)=tmp(ixo^s)+&
2879 (tmp2(jxo^s)-2.0d0*tmp2(ixo^s)+tmp2(hxo^s))/
dxlevel(idim)**2
2883 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
2886 do jdir=1,
ndim;
do kdir=idirmin,3
2887 if (
lvc(idir,jdir,kdir)/=0)
then
2888 if (
lvc(idir,jdir,kdir)==1)
then
2889 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
2891 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
2897 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
2898 if(total_energy)
then
2899 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
2904 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
2906 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
2907 end subroutine add_source_res1
2911 subroutine add_source_res2(qdt,ixI^L,ixO^L,wCT,w,x)
2915 integer,
intent(in) :: ixi^
l, ixo^
l
2916 double precision,
intent(in) :: qdt
2917 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2918 double precision,
intent(inout) :: w(ixi^s,1:nw)
2920 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
2921 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
2922 integer :: ixa^
l,idir,idirmin,idirmin1
2925 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2926 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
2934 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
rmhd_eta
2939 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
2947 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
2950 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
2954 tmp(ixo^s)=qdt*
rmhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
2956 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
2958 if(total_energy)
then
2961 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
2962 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
2965 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
2968 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res2')
2969 end subroutine add_source_res2
2973 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
2976 integer,
intent(in) :: ixi^
l, ixo^
l
2977 double precision,
intent(in) :: qdt
2978 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2979 double precision,
intent(inout) :: w(ixi^s,1:nw)
2981 double precision :: current(ixi^s,7-2*
ndir:3)
2982 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
2983 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
2986 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2987 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
2989 tmpvec(ixa^s,1:
ndir)=zero
2991 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
2994 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
2996 tmpvec(ixa^s,1:
ndir)=zero
2997 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
3000 tmpvec2(ixa^s,1:
ndir)=zero
3001 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3003 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
3005 if(total_energy)
then
3008 tmpvec2(ixa^s,1:
ndir)=zero
3009 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
3010 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
3011 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
3012 end do;
end do;
end do
3014 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
3015 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
3017 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
3018 end subroutine add_source_hyperres
3020 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
3026 integer,
intent(in) :: ixi^
l, ixo^
l
3027 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3028 double precision,
intent(inout) :: w(ixi^s,1:nw)
3029 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
3048 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
3051 if(total_energy)
then
3060 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
3067 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
3070 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
3071 end subroutine add_source_glm
3074 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
3076 integer,
intent(in) :: ixi^
l, ixo^
l
3077 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3078 double precision,
intent(inout) :: w(ixi^s,1:nw)
3079 double precision :: divb(ixi^s), ba(1:
ndir)
3080 integer :: idir, ix^
d
3085 {
do ix^db=ixomin^db,ixomax^db\}
3090 if (total_energy)
then
3096 {
do ix^db=ixomin^db,ixomax^db\}
3098 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
3100 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
3101 if (total_energy)
then
3103 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
3107 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
3108 end subroutine add_source_powel
3110 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
3114 integer,
intent(in) :: ixi^
l, ixo^
l
3115 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3116 double precision,
intent(inout) :: w(ixi^s,1:nw)
3117 double precision :: divb(ixi^s)
3118 integer :: idir, ix^
d
3122 {
do ix^db=ixomin^db,ixomax^db\}
3126 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
3127 end subroutine add_source_janhunen
3129 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
3133 integer,
intent(in) :: ixi^
l, ixo^
l
3134 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3135 double precision,
intent(inout) :: w(ixi^s,1:nw)
3136 double precision :: divb(ixi^s),graddivb(ixi^s)
3137 integer :: idim, idir, ixp^
l, i^
d, iside
3138 logical,
dimension(-1:1^D&) :: leveljump
3145 if(i^
d==0|.and.) cycle
3146 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
3147 leveljump(i^
d)=.true.
3149 leveljump(i^
d)=.false.
3157 i^dd=kr(^dd,^d)*(2*iside-3);
3158 if (leveljump(i^dd))
then
3160 ixpmin^d=ixomin^d-i^d
3162 ixpmax^d=ixomax^d-i^d
3172 select case(typegrad)
3174 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
3176 call gradientl(divb,ixi^l,ixp^l,idim,graddivb)
3179 if (slab_uniform)
then
3180 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
3182 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
3183 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
3185 w(ixp^s,mag(idim))=w(ixp^s,mag(idim))+graddivb(ixp^s)
3187 if (typedivbdiff==
'all' .and. total_energy)
then
3189 w(ixp^s,
e_)=w(ixp^s,
e_)+wct(ixp^s,mag(idim))*graddivb(ixp^s)
3192 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
3193 end subroutine add_source_linde
3198 integer,
intent(in) :: ixi^
l, ixo^
l
3199 double precision,
intent(in) :: w(ixi^s,1:nw)
3200 double precision :: divb(ixi^s), dsurface(ixi^s)
3201 double precision :: invb(ixo^s)
3202 integer :: ixa^
l,idims
3204 call get_divb(w,ixi^
l,ixo^
l,divb)
3206 where(invb(ixo^s)/=0.d0)
3207 invb(ixo^s)=1.d0/invb(ixo^s)
3210 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
3212 ixamin^
d=ixomin^
d-1;
3213 ixamax^
d=ixomax^
d-1;
3214 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
3216 ixa^
l=ixo^
l-
kr(idims,^
d);
3217 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
3219 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
3220 block%dvolume(ixo^s)/dsurface(ixo^s)
3229 integer,
intent(in) :: ixo^
l, ixi^
l
3230 double precision,
intent(in) :: w(ixi^s,1:nw)
3231 integer,
intent(out) :: idirmin
3233 double precision :: current(ixi^s,7-2*
ndir:3)
3234 integer :: idir, idirmin0
3238 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
3239 block%J0(ixo^s,idirmin0:3)
3243 subroutine rmhd_get_dt(w,ixI^L,ixO^L,dtnew,dx^D,x)
3251 integer,
intent(in) :: ixi^
l, ixo^
l
3252 double precision,
intent(inout) :: dtnew
3253 double precision,
intent(in) ::
dx^
d
3254 double precision,
intent(in) :: w(ixi^s,1:nw)
3255 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3256 double precision :: dxarr(
ndim)
3257 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
3258 integer :: idirmin,idim
3262 if (.not. dt_c)
then
3273 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
3276 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
3294 call mpistop(
'Radiation formalism unknown')
3310 end subroutine rmhd_get_dt
3313 subroutine rmhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
3316 integer,
intent(in) :: ixi^
l, ixo^
l
3317 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
3318 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3319 double precision :: tmp,tmp1,invr,cot
3321 integer :: mr_,mphi_
3322 integer :: br_,bphi_
3325 br_=mag(1); bphi_=mag(1)-1+
phi_
3328 {
do ix^db=ixomin^db,ixomax^db\}
3331 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
3336 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
3341 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
3342 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
3343 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
3344 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
3345 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
3347 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
3348 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
3349 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
3352 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
3357 {
do ix^db=ixomin^db,ixomax^db\}
3359 if(local_timestep)
then
3360 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
3365 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
3371 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
3374 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
3375 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
3379 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
3385 cot=1.d0/tan(x(ix^d,2))
3389 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3390 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
3392 if(.not.stagger_grid)
then
3393 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3395 tmp=tmp+wprim(ix^d,
psi_)*cot
3397 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3402 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3403 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
3404 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
3406 if(.not.stagger_grid)
then
3407 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3409 tmp=tmp+wprim(ix^d,
psi_)*cot
3411 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3414 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
3415 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
3416 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
3417 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
3418 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
3420 if(.not.stagger_grid)
then
3421 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
3422 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
3423 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
3424 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
3425 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
3430 end subroutine rmhd_add_source_geom
3433 subroutine rmhd_add_source_geom_split(qdt,dtfactor, ixI^L,ixO^L,wCT,wprim,w,x)
3436 integer,
intent(in) :: ixi^
l, ixo^
l
3437 double precision,
intent(in) :: qdt, dtfactor, x(ixi^s,1:
ndim)
3438 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3439 double precision :: tmp(ixi^s),tmp1(ixi^s),tmp2(ixi^s),invrho(ixo^s),invr(ixo^s)
3440 integer :: iw,idir, h1x^
l{^nooned, h2x^
l}
3441 integer :: mr_,mphi_
3442 integer :: br_,bphi_
3445 br_=mag(1); bphi_=mag(1)-1+
phi_
3449 invrho(ixo^s) = 1d0/wct(ixo^s,
rho_)
3453 invr(ixo^s) =
block%dt(ixo^s) * dtfactor/x(ixo^s,1)
3455 invr(ixo^s) = qdt/x(ixo^s,1)
3460 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp)
3462 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*(tmp(ixo^s)-&
3463 wct(ixo^s,bphi_)**2+wct(ixo^s,mphi_)**2*invrho(ixo^s))
3464 w(ixo^s,mphi_)=w(ixo^s,mphi_)+qdt*invr(ixo^s)*(&
3465 -wct(ixo^s,mphi_)*wct(ixo^s,mr_)*invrho(ixo^s) &
3466 +wct(ixo^s,bphi_)*wct(ixo^s,br_))
3468 w(ixo^s,bphi_)=w(ixo^s,bphi_)+invr(ixo^s)*&
3469 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
3470 -wct(ixo^s,br_)*wct(ixo^s,mphi_)) &
3474 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*tmp(ixo^s)
3476 if(
rmhd_glm) w(ixo^s,br_)=w(ixo^s,br_)+wct(ixo^s,
psi_)*invr(ixo^s)
3478 h1x^
l=ixo^
l-
kr(1,^
d); {^nooned h2x^
l=ixo^
l-
kr(2,^
d);}
3479 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp1)
3480 tmp(ixo^s)=tmp1(ixo^s)
3482 tmp2(ixo^s)=sum(
block%B0(ixo^s,:,0)*wct(ixo^s,mag(:)),dim=
ndim+1)
3483 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3486 tmp(ixo^s)=tmp(ixo^s)*x(ixo^s,1) &
3487 *(
block%surfaceC(ixo^s,1)-
block%surfaceC(h1x^s,1))/
block%dvolume(ixo^s)
3490 tmp(ixo^s)=tmp(ixo^s)+wct(ixo^s,
mom(idir))**2*invrho(ixo^s)-wct(ixo^s,mag(idir))**2
3491 if(
b0field) tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,idir,0)*wct(ixo^s,mag(idir))
3494 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+tmp(ixo^s)*invr(ixo^s)
3497 w(ixo^s,mag(1))=w(ixo^s,mag(1))+invr(ixo^s)*2.0d0*wct(ixo^s,
psi_)
3501 tmp(ixo^s)=tmp1(ixo^s)
3503 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3506 tmp1(ixo^s) =
block%dt(ixo^s) * tmp(ixo^s)
3508 tmp1(ixo^s) = qdt * tmp(ixo^s)
3511 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp1(ixo^s) &
3512 *(
block%surfaceC(ixo^s,2)-
block%surfaceC(h2x^s,2)) &
3513 /
block%dvolume(ixo^s)
3514 tmp(ixo^s)=-(wct(ixo^s,
mom(1))*wct(ixo^s,
mom(2))*invrho(ixo^s) &
3515 -wct(ixo^s,mag(1))*wct(ixo^s,mag(2)))
3517 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(2)) &
3518 +wct(ixo^s,mag(1))*
block%B0(ixo^s,2,0)
3521 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(3))**2*invrho(ixo^s) &
3522 -wct(ixo^s,mag(3))**2)*dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3524 tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,3,0)*wct(ixo^s,mag(3))&
3525 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3528 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp(ixo^s)*invr(ixo^s)
3531 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(2)) &
3532 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(1)))*invrho(ixo^s)
3534 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,2,0) &
3535 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,1,0))*invrho(ixo^s)
3538 tmp(ixo^s)=tmp(ixo^s) &
3539 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
3541 w(ixo^s,mag(2))=w(ixo^s,mag(2))+tmp(ixo^s)*invr(ixo^s)
3546 tmp(ixo^s)=-(wct(ixo^s,
mom(3))*wct(ixo^s,
mom(1))*invrho(ixo^s) &
3547 -wct(ixo^s,mag(3))*wct(ixo^s,mag(1))) {^nooned &
3548 -(wct(ixo^s,
mom(2))*wct(ixo^s,
mom(3))*invrho(ixo^s) &
3549 -wct(ixo^s,mag(2))*wct(ixo^s,mag(3))) &
3550 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3552 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(3)) &
3553 +wct(ixo^s,mag(1))*
block%B0(ixo^s,3,0) {^nooned &
3554 +(
block%B0(ixo^s,2,0)*wct(ixo^s,mag(3)) &
3555 +wct(ixo^s,mag(2))*
block%B0(ixo^s,3,0)) &
3556 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3558 w(ixo^s,
mom(3))=w(ixo^s,
mom(3))+tmp(ixo^s)*invr(ixo^s)
3561 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(3)) &
3562 -wct(ixo^s,
mom(3))*wct(ixo^s,mag(1)))*invrho(ixo^s) {^nooned &
3563 -(wct(ixo^s,
mom(3))*wct(ixo^s,mag(2)) &
3564 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(3)))*dcos(x(ixo^s,2)) &
3565 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3567 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,3,0) &
3568 -wct(ixo^s,
mom(3))*
block%B0(ixo^s,1,0))*invrho(ixo^s){^nooned &
3569 -(wct(ixo^s,
mom(3))*
block%B0(ixo^s,2,0) &
3570 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,3,0))*dcos(x(ixo^s,2)) &
3571 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3573 w(ixo^s,mag(3))=w(ixo^s,mag(3))+tmp(ixo^s)*invr(ixo^s)
3577 end subroutine rmhd_add_source_geom_split
3582 integer,
intent(in) :: ixi^
l, ixo^
l
3583 double precision,
intent(in) :: w(ixi^s, nw)
3584 double precision :: mge(ixo^s)
3587 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
3589 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
3593 subroutine rmhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
3596 integer,
intent(in) :: ixi^
l, ixo^
l, idir
3597 double precision,
intent(in) :: qt
3598 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
3599 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
3601 double precision :: db(ixo^s), dpsi(ixo^s)
3605 {
do ix^db=ixomin^db,ixomax^db\}
3606 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3607 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3608 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3609 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3618 {
do ix^db=ixomin^db,ixomax^db\}
3619 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
3620 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
3621 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
3622 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
3623 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3625 if(total_energy)
then
3626 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
3627 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
3629 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3631 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3634 if(total_energy)
then
3635 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
3636 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
3640 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
3641 end subroutine rmhd_modify_wlr
3643 subroutine rmhd_boundary_adjust(igrid,psb)
3645 integer,
intent(in) :: igrid
3647 integer :: ib, idims, iside, ixo^
l, i^
d
3656 i^
d=
kr(^
d,idims)*(2*iside-3);
3657 if (neighbor_type(i^
d,igrid)/=1) cycle
3658 ib=(idims-1)*2+iside
3676 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
3680 end subroutine rmhd_boundary_adjust
3682 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
3684 integer,
intent(in) :: ixg^
l,ixo^
l,ib
3685 double precision,
intent(inout) :: w(ixg^s,1:nw)
3686 double precision,
intent(in) :: x(ixg^s,1:
ndim)
3687 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
3688 integer :: ix^
d,ixf^
l
3701 do ix1=ixfmax1,ixfmin1,-1
3702 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
3703 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3704 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3707 do ix1=ixfmax1,ixfmin1,-1
3708 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
3709 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
3710 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3711 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3712 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3713 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3714 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3728 do ix1=ixfmax1,ixfmin1,-1
3729 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3730 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3731 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3732 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3733 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3734 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3737 do ix1=ixfmax1,ixfmin1,-1
3738 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3739 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3740 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3741 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3742 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3743 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3744 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3745 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3746 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3747 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3748 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3749 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3750 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3751 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3752 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3753 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3754 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3755 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3769 do ix1=ixfmin1,ixfmax1
3770 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
3771 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3772 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3775 do ix1=ixfmin1,ixfmax1
3776 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
3777 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
3778 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3779 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3780 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3781 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3782 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3796 do ix1=ixfmin1,ixfmax1
3797 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3798 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3799 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3800 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3801 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3802 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3805 do ix1=ixfmin1,ixfmax1
3806 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3807 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3808 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3809 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3810 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3811 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3812 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3813 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3814 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3815 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3816 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3817 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3818 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3819 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3820 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3821 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3822 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3823 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3837 do ix2=ixfmax2,ixfmin2,-1
3838 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
3839 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3840 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3843 do ix2=ixfmax2,ixfmin2,-1
3844 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
3845 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
3846 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3847 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3848 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3849 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3850 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3864 do ix2=ixfmax2,ixfmin2,-1
3865 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3866 ix2+1,ixfmin3:ixfmax3,mag(2)) &
3867 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
3868 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
3869 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
3870 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
3873 do ix2=ixfmax2,ixfmin2,-1
3874 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
3875 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
3876 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
3877 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
3878 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
3879 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3880 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
3881 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
3882 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3883 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
3884 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
3885 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
3886 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
3887 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
3888 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3889 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
3890 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
3891 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
3905 do ix2=ixfmin2,ixfmax2
3906 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
3907 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3908 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3911 do ix2=ixfmin2,ixfmax2
3912 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
3913 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
3914 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3915 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3916 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3917 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3918 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3932 do ix2=ixfmin2,ixfmax2
3933 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3934 ix2-1,ixfmin3:ixfmax3,mag(2)) &
3935 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
3936 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
3937 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
3938 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
3941 do ix2=ixfmin2,ixfmax2
3942 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
3943 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
3944 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
3945 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
3946 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
3947 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3948 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
3949 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
3950 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3951 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
3952 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
3953 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
3954 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
3955 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
3956 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3957 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
3958 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
3959 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
3976 do ix3=ixfmax3,ixfmin3,-1
3977 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
3978 ixfmin2:ixfmax2,ix3+1,mag(3)) &
3979 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
3980 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
3981 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
3982 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
3985 do ix3=ixfmax3,ixfmin3,-1
3986 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
3987 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
3988 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
3989 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
3990 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
3991 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
3992 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
3993 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
3994 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
3995 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
3996 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
3997 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
3998 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
3999 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4000 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4001 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4002 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
4003 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4018 do ix3=ixfmin3,ixfmax3
4019 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
4020 ixfmin2:ixfmax2,ix3-1,mag(3)) &
4021 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4022 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4023 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4024 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4027 do ix3=ixfmin3,ixfmax3
4028 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
4029 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
4030 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4031 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
4032 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4033 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4034 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4035 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4036 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4037 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4038 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4039 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4040 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4041 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4042 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4043 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4044 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
4045 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4051 call mpistop(
"Special boundary is not defined for this region")
4053 end subroutine fixdivb_boundary
4061 double precision,
intent(in) :: qdt
4062 double precision,
intent(in) :: qt
4063 logical,
intent(inout) :: active
4065 integer,
parameter :: max_its = 50
4066 double precision :: residual_it(max_its), max_divb
4067 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
4068 double precision :: res
4069 double precision,
parameter :: max_residual = 1
d-3
4070 double precision,
parameter :: residual_reduction = 1
d-10
4071 integer :: iigrid, igrid
4072 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
4075 mg%operator_type = mg_laplacian
4082 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4083 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4086 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
4087 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4089 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4090 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4093 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4094 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4098 write(*,*)
"rmhd_clean_divb_multigrid warning: unknown boundary type"
4099 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4100 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4107 do iigrid = 1, igridstail
4108 igrid = igrids(iigrid);
4111 lvl =
mg%boxes(id)%lvl
4112 nc =
mg%box_size_lvl(lvl)
4118 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
4120 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
4121 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
4126 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
4129 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
4130 if (
mype == 0) print *,
"iteration vs residual"
4133 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
4134 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
4135 if (residual_it(n) < residual_reduction * max_divb)
exit
4137 if (
mype == 0 .and. n > max_its)
then
4138 print *,
"divb_multigrid warning: not fully converged"
4139 print *,
"current amplitude of divb: ", residual_it(max_its)
4140 print *,
"multigrid smallest grid: ", &
4141 mg%domain_size_lvl(:,
mg%lowest_lvl)
4142 print *,
"note: smallest grid ideally has <= 8 cells"
4143 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
4144 print *,
"note: dx/dy/dz should be similar"
4148 call mg_fas_vcycle(
mg, max_res=res)
4149 if (res < max_residual)
exit
4151 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
4155 do iigrid = 1, igridstail
4156 igrid = igrids(iigrid);
4163 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
4166 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
4168 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
4170 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
4183 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
4184 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
4186 if(total_energy)
then
4188 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
4191 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
4198 subroutine rmhd_update_faces(ixI^L,ixO^L,qt,qdt,wprim,fC,fE,sCT,s,vcts)
4200 integer,
intent(in) :: ixi^
l, ixo^
l
4201 double precision,
intent(in) :: qt,qdt
4203 double precision,
intent(in) :: wprim(ixi^s,1:nw)
4204 type(state) :: sct, s
4205 type(ct_velocity) :: vcts
4206 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4207 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4211 call update_faces_average(ixi^
l,ixo^
l,qt,qdt,fc,fe,sct,s)
4213 call update_faces_contact(ixi^
l,ixo^
l,qt,qdt,wprim,fc,fe,sct,s,vcts)
4215 call update_faces_hll(ixi^
l,ixo^
l,qt,qdt,fe,sct,s,vcts)
4217 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
4219 end subroutine rmhd_update_faces
4222 subroutine update_faces_average(ixI^L,ixO^L,qt,qdt,fC,fE,sCT,s)
4225 integer,
intent(in) :: ixi^
l, ixo^
l
4226 double precision,
intent(in) :: qt, qdt
4227 type(state) :: sct, s
4228 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4229 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4230 double precision :: circ(ixi^s,1:
ndim)
4232 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4233 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
4234 integer :: idim1,idim2,idir,iwdim1,iwdim2
4236 associate(bfaces=>s%ws,x=>s%x)
4241 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,sct,s,e_resi)
4244 i1kr^
d=
kr(idim1,^
d);
4247 i2kr^
d=
kr(idim2,^
d);
4250 if (
lvc(idim1,idim2,idir)==1)
then
4252 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4254 {
do ix^db=ixcmin^db,ixcmax^db\}
4255 fe(ix^
d,idir)=quarter*&
4256 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
4257 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
4259 if(
rmhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
4261 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
4268 if(
associated(usr_set_electric_field)) &
4269 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4270 circ(ixi^s,1:ndim)=zero
4274 ixcmin^d=ixomin^d-kr(idim1,^d);
4276 ixa^l=ixc^l-kr(idim2,^d);
4279 if(lvc(idim1,idim2,idir)==1)
then
4281 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4284 else if(lvc(idim1,idim2,idir)==-1)
then
4286 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4293 where(s%surfaceC(ixc^s,idim1) > 1.0d-9*s%dvolume(ixc^s))
4294 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
4296 circ(ixc^s,idim1)=zero
4299 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
4302 end subroutine update_faces_average
4305 subroutine update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4309 integer,
intent(in) :: ixi^
l, ixo^
l
4310 double precision,
intent(in) :: qt, qdt
4312 double precision,
intent(in) :: wp(ixi^s,1:nw)
4313 type(state) :: sct, s
4314 type(ct_velocity) :: vcts
4315 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4316 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4317 double precision :: circ(ixi^s,1:
ndim)
4319 double precision :: ecc(ixi^s,
sdim:3)
4320 double precision :: ein(ixi^s,
sdim:3)
4322 double precision :: el(ixi^s),er(ixi^s)
4324 double precision :: elc,erc
4326 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4328 double precision :: jce(ixi^s,
sdim:3)
4330 double precision :: xs(ixgs^t,1:
ndim)
4331 double precision :: gradi(ixgs^t)
4332 integer :: ixc^
l,ixa^
l
4333 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
4335 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
4337 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,sct,s,e_resi)
4339 {
do ix^db=iximin^db,iximax^db\}
4342 ecc(ix^
d,1)=(wp(ix^
d,b2_)+
block%B0(ix^
d,2,0))*wp(ix^
d,m3_)-(wp(ix^
d,b3_)+
block%B0(ix^
d,3,0))*wp(ix^
d,m2_)
4343 ecc(ix^
d,2)=(wp(ix^
d,b3_)+
block%B0(ix^
d,3,0))*wp(ix^
d,m1_)-(wp(ix^
d,b1_)+
block%B0(ix^
d,1,0))*wp(ix^
d,m3_)
4344 ecc(ix^
d,3)=(wp(ix^
d,b1_)+
block%B0(ix^
d,1,0))*wp(ix^
d,m2_)-(wp(ix^
d,b2_)+
block%B0(ix^
d,2,0))*wp(ix^
d,m1_)
4347 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
4354 {
do ix^db=iximin^db,iximax^db\}
4357 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
4358 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
4359 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4362 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4376 i1kr^d=kr(idim1,^d);
4379 i2kr^d=kr(idim2,^d);
4382 if (lvc(idim1,idim2,idir)==1)
then
4384 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4387 {
do ix^db=ixcmin^db,ixcmax^db\}
4388 fe(ix^d,idir)=quarter*&
4389 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
4390 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
4395 ixamax^d=ixcmax^d+i1kr^d;
4396 {
do ix^db=ixamin^db,ixamax^db\}
4397 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
4398 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
4401 do ix^db=ixcmin^db,ixcmax^db\}
4402 if(vnorm(ix^d,idim1)>0.d0)
then
4404 else if(vnorm(ix^d,idim1)<0.d0)
then
4405 elc=el({ix^d+i1kr^d})
4407 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
4409 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
4411 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
4412 erc=er({ix^d+i1kr^d})
4414 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
4416 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4420 ixamax^d=ixcmax^d+i2kr^d;
4421 {
do ix^db=ixamin^db,ixamax^db\}
4422 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
4423 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
4426 do ix^db=ixcmin^db,ixcmax^db\}
4427 if(vnorm(ix^d,idim2)>0.d0)
then
4429 else if(vnorm(ix^d,idim2)<0.d0)
then
4430 elc=el({ix^d+i2kr^d})
4432 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
4434 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
4436 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
4437 erc=er({ix^d+i2kr^d})
4439 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
4441 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4445 if(
rmhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
4447 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
4460 if (lvc(idim1,idim2,idir)==0) cycle
4462 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4463 ixamax^d=ixcmax^d-kr(idir,^d)+1;
4466 xs(ixa^s,:)=x(ixa^s,:)
4467 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
4468 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
4469 if (lvc(idim1,idim2,idir)==1)
then
4470 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4472 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4479 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4481 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
4485 {
do ix^db=ixomin^db,ixomax^db\}
4486 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4487 +ein(ix1,ix2-1,ix3-1,idir))
4488 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4489 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4491 else if(idir==2)
then
4492 {
do ix^db=ixomin^db,ixomax^db\}
4493 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4494 +ein(ix1-1,ix2,ix3-1,idir))
4495 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4496 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4499 {
do ix^db=ixomin^db,ixomax^db\}
4500 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
4501 +ein(ix1-1,ix2-1,ix3,idir))
4502 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4503 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4509 {
do ix^db=ixomin^db,ixomax^db\}
4510 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
4511 +ein(ix1-1,ix2-1,idir))
4512 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4513 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4518 block%w(ixo^s,nw)=block%w(ixo^s,nw)+jce(ixo^s,idir)
4523 if(
associated(usr_set_electric_field)) &
4524 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4525 circ(ixi^s,1:ndim)=zero
4529 ixcmin^d=ixomin^d-kr(idim1,^d);
4531 ixa^l=ixc^l-kr(idim2,^d);
4534 if(lvc(idim1,idim2,idir)==1)
then
4536 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4539 else if(lvc(idim1,idim2,idir)==-1)
then
4541 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4548 where(s%surfaceC(ixc^s,idim1) > smalldouble)
4549 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
4551 circ(ixc^s,idim1)=zero
4554 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
4557 end subroutine update_faces_contact
4560 subroutine update_faces_hll(ixI^L,ixO^L,qt,qdt,fE,sCT,s,vcts)
4564 integer,
intent(in) :: ixi^
l, ixo^
l
4565 double precision,
intent(in) :: qt, qdt
4566 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4567 type(state) :: sct, s
4568 type(ct_velocity) :: vcts
4569 double precision :: vtill(ixi^s,2)
4570 double precision :: vtilr(ixi^s,2)
4571 double precision :: bfacetot(ixi^s,
ndim)
4572 double precision :: btill(ixi^s,
ndim)
4573 double precision :: btilr(ixi^s,
ndim)
4574 double precision :: cp(ixi^s,2)
4575 double precision :: cm(ixi^s,2)
4576 double precision :: circ(ixi^s,1:
ndim)
4578 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4579 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
4580 integer :: idim1,idim2,idir
4582 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
4583 cbarmax=>vcts%cbarmax)
4595 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,sct,s,e_resi)
4607 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
4610 idim2=mod(idir+1,3)+1
4611 jxc^
l=ixc^
l+
kr(idim1,^
d);
4612 ixcp^
l=ixc^
l+
kr(idim2,^
d);
4615 vtill(ixi^s,2),vtilr(ixi^s,2))
4617 vtill(ixi^s,1),vtilr(ixi^s,1))
4622 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
4623 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
4625 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
4626 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
4629 btill(ixi^s,idim1),btilr(ixi^s,idim1))
4631 btill(ixi^s,idim2),btilr(ixi^s,idim2))
4633 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
4634 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
4635 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
4636 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
4638 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
4639 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
4640 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
4641 /(cp(ixc^s,1)+cm(ixc^s,1)) &
4642 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
4643 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
4644 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
4645 /(cp(ixc^s,2)+cm(ixc^s,2))
4647 if(
rmhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
4648 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
4658 circ(ixi^s,1:
ndim)=zero
4662 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
4666 if(
lvc(idim1,idim2,idir)/=0)
then
4667 hxc^
l=ixc^
l-
kr(idim2,^
d);
4669 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4670 +
lvc(idim1,idim2,idir)&
4677 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
4678 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
4680 circ(ixc^s,idim1)=zero
4683 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
4686 end subroutine update_faces_hll
4689 subroutine get_resistive_electric_field(ixI^L,ixO^L,sCT,s,jce)
4693 integer,
intent(in) :: ixi^
l, ixo^
l
4694 type(state),
intent(in) :: sct, s
4696 double precision :: jce(ixi^s,
sdim:3)
4698 double precision :: jcc(ixi^s,7-2*
ndir:3)
4700 double precision :: xs(ixgs^t,1:
ndim)
4702 double precision :: eta(ixi^s)
4703 double precision :: gradi(ixgs^t)
4704 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
4706 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
4712 if (
lvc(idim1,idim2,idir)==0) cycle
4714 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4715 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
4718 xs(ixb^s,:)=x(ixb^s,:)
4719 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
4720 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
4721 if (
lvc(idim1,idim2,idir)==1)
then
4722 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4724 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4739 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4740 jcc(ixc^s,idir)=0.d0
4742 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4743 ixamin^
d=ixcmin^
d+ix^
d;
4744 ixamax^
d=ixcmax^
d+ix^
d;
4745 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
4747 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
4748 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
4752 end subroutine get_resistive_electric_field
4758 integer,
intent(in) :: ixo^
l
4767 do ix^db=ixomin^db,ixomax^db\}
4769 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4770 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
4771 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4772 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
4773 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
4774 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
4777 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4778 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
4779 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4780 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
4820 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
4821 double precision,
intent(inout) :: ws(ixis^s,1:nws)
4822 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4823 double precision :: adummy(ixis^s,1:3)
4828 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
4831 integer,
intent(in) :: ixi^
l, ixo^
l
4832 double precision,
intent(in) :: w(ixi^s,1:nw)
4833 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4834 double precision,
intent(out):: rfactor(ixi^s)
4835 double precision :: iz_h(ixo^s),iz_he(ixo^s)
4839 rfactor(ixo^s)=(1.d0+iz_h(ixo^s)+0.1d0*(1.d0+iz_he(ixo^s)*(1.d0+iz_he(ixo^s))))/(2.d0+3.d0*
he_abundance)
4840 end subroutine rfactor_from_temperature_ionization
4842 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
4844 integer,
intent(in) :: ixi^
l, ixo^
l
4845 double precision,
intent(in) :: w(ixi^s,1:nw)
4846 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4847 double precision,
intent(out):: rfactor(ixi^s)
4850 end subroutine rfactor_from_constant_ionization
Module for including anisotropic flux limited diffusion (AFLD)-approximation in Radiation-hydrodynami...
subroutine afld_get_diffcoef_central(w, wct, x, ixil, ixol)
Calculates cell-centered diffusion coefficient to be used in multigrid.
subroutine, public get_afld_rad_force(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
subroutine, public afld_init(he_abundance, rhd_radiation_diffusion, afld_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine, public afld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
subroutine, public afld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
subroutine, public get_afld_energy_interact(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine cak_get_dt(w, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine cak_init(phys_gamma)
Initialize the module.
subroutine cak_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter const_rad_a
subroutine reconstruct(ixil, ixcl, idir, q, ql, qr)
Reconstruct scalar q within ixO^L to 1/2 dx in direction idir Return both left and right reconstructe...
subroutine b_from_vector_potentiala(ixisl, ixil, ixol, ws, x, a)
calculate magnetic field from vector potential A at cell edges
subroutine add_convert_method(phys_convert_vars, nwc, dataset_names, file_suffix)
Module for flux conservation near refinement boundaries.
Nicolas Moens Module for including flux limited diffusion (FLD)-approximation in Radiation-hydrodynam...
subroutine, public get_fld_rad_force(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
subroutine, public fld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
subroutine, public fld_init(he_abundance, radiation_diffusion, energy_interact, r_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine fld_get_diffcoef_central(w, wct, x, ixil, ixol)
Calculates cell-centered diffusion coefficient to be used in multigrid.
character(len=8) fld_diff_scheme
Which method to solve diffusion part.
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
Module with basic grid data structures.
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
subroutine, public get_divb(w, ixil, ixol, divb, nth_in)
Calculate div B within ixO.
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
Module with geometry-related routines (e.g., divergence, curl)
subroutine divvector(qvec, ixil, ixol, divq, nth_in)
integer, parameter spherical
integer, parameter cylindrical
subroutine curlvector(qvec, ixil, ixol, curlvec, idirmin, idirmin0, ndir0, fourthorder)
Calculate curl of a vector qvec within ixL Options to employ standard second order CD evaluations use...
subroutine gradient(q, ixil, ixol, idir, gradq, nth_in)
subroutine gradientf(q, x, ixil, ixol, idir, gradq, nth_in, pm_in)
subroutine gradientl(q, ixil, ixol, idir, gradq)
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 dtdiffpar
For resistive MHD, the time step is also limited by the diffusion time: .
character(len=std_len) typegrad
double precision unit_charge
Physical scaling factor for charge.
integer, parameter bc_noinflow
double precision small_pressure
integer ixghi
Upper index of grid block arrays.
pure subroutine cross_product(ixil, ixol, a, b, axb)
Cross product of two vectors.
integer, dimension(3, 3, 3) lvc
Levi-Civita tensor.
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
double precision unit_opacity
Physical scaling factor for Opacity.
integer, parameter unitpar
file handle for IO
integer, parameter bc_asymm
double precision unit_mass
Physical scaling factor for mass.
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision phys_trac_mask
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
double precision unit_numberdensity
Physical scaling factor for number density.
character(len=std_len) convert_type
Which format to use when converting.
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 stagger_grid
True for using stagger grid.
double precision cmax_global
global fastest wave speed needed in fd scheme and glm method
logical use_particles
Use particles module or not.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer icomm
The MPI communicator.
double precision bdip
amplitude of background dipolar, quadrupolar, octupolar, user's field
integer b0i
background magnetic field location indicator
integer mype
The rank of the current MPI task.
double precision, dimension(:), allocatable, parameter d
logical local_timestep
each cell has its own timestep or not
double precision dt
global time step
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ixm
the mesh range of a physical block without ghost cells
integer ierrmpi
A global MPI error return code.
logical autoconvert
If true, already convert to output format during the run.
logical slab
Cartesian geometry or not.
integer, parameter bc_periodic
integer, parameter bc_special
boundary condition types
double precision unit_magneticfield
Physical scaling factor for magnetic field.
double precision unit_velocity
Physical scaling factor for velocity.
double precision c_norm
Normalised speed of light.
logical b0field
split magnetic field as background B0 field
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision unit_temperature
Physical scaling factor for temperature.
double precision unit_radflux
Physical scaling factor for radiation flux.
integer, parameter bc_cont
logical si_unit
Use SI units (.true.) or use cgs units (.false.)
double precision, dimension(:,:), allocatable dx
integer nghostcells
Number of ghost cells surrounding a grid.
integer, parameter sdim
starting dimension for electric field
integer, parameter bc_symm
logical phys_trac
Use TRAC for MHD or 1D HD.
logical need_global_cmax
need global maximal wave speed
logical convert
If true and restart_from_file is given, convert snapshots to other file formats.
logical fix_small_values
fix small values with average or replace methods
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
logical use_multigrid
Use multigrid (only available in 2D and 3D)
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
double precision small_density
integer max_blocks
The maximum number of grid blocks in a processor.
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
integer phys_trac_finegrid
integer, parameter unitconvert
integer number_equi_vars
number of equilibrium set variables, besides the mag field
integer, parameter ixglo
Lower index of grid block arrays (always 1)
Module for including gravity in (magneto)hydrodynamics simulations.
subroutine gravity_get_dt(w, ixil, ixol, dtnew, dxd, x)
subroutine gravity_init()
Initialize the module.
subroutine gravity_add_source(qdt, ixil, ixol, wct, wctprim, w, x, energy, rhov, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
module ionization degree - get ionization degree for given temperature
subroutine ionization_degree_from_temperature(ixil, ixol, te, iz_h, iz_he)
subroutine ionization_degree_init()
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
type(mg_t) mg
Data structure containing the multigrid tree.
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...
Radiation-magneto-hydrodynamics module.
subroutine, public get_current(w, ixil, ixol, idirmin, current)
Calculate idirmin and the idirmin:3 components of the common current array make sure that dxlevel(^D)...
integer, public, protected rmhd_trac_type
Which TRAC method is used.
character(len=8), public rmhd_pressure
In the case of no rmhd_energy, how to compute pressure.
subroutine, public rmhd_phys_init()
logical, public, protected rmhd_thermal_conduction
Whether thermal conduction is used.
double precision, public rmhd_gamma
The adiabatic index.
character(len=8), public rmhd_radiation_formalism
Formalism to treat radiation.
logical, public divbwave
Add divB wave in Roe solver.
integer, public, protected rmhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
double precision, public, protected h_ion_fr
Ionization fraction of H H_ion_fr = H+/(H+ + H)
integer, dimension(2 *^nd), public, protected boundary_divbfix_skip
To skip * layer of ghost cells during divB=0 fix for boundary.
logical, public, protected rmhd_hyperbolic_thermal_conduction
Whether thermal conduction is used.
double precision, public, protected rr
logical, public rmhd_equi_thermal
double precision, public rmhd_etah
Hall resistivity.
logical, public, protected rmhd_radiation_diffusion
Treat radiation energy diffusion.
subroutine, public rmhd_face_to_center(ixol, s)
calculate cell-center values from face-center values
procedure(sub_get_pthermal), pointer, public rmhd_get_pthermal
integer, public, protected psi_
Indices of the GLM psi.
type(tc_fluid), allocatable, public tc_fl
type of fluid for thermal conduction
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
subroutine, public b_from_vector_potential(ixisl, ixil, ixol, ws, x)
calculate magnetic field from vector potential
logical, public, protected rmhd_cak_force
Whether CAK radiation line force is activated.
logical, public, protected rmhd_radiation_force
Treat radiation fld_Rad_force.
logical, public, protected rmhd_glm
Whether GLM-MHD is used to control div B.
double precision, public, protected small_r_e
The smallest allowed radiation energy.
double precision, public rmhd_eta_hyper
The MHD hyper-resistivity.
logical, public clean_initial_divb
clean initial divB
integer, public, protected rmhd_n_tracer
Number of tracer species.
logical, public, protected rmhd_particles
Whether particles module is added.
integer, public, protected b
double precision, public kbmpmua4
kb/(m_p mu)* 1/a_rad**4,
integer, public, protected m
subroutine, public rmhd_get_trad(w, x, ixil, ixol, trad)
Calculates radiation temperature.
integer, public equi_rho0_
equi vars indices in the stateequi_vars array
double precision, public rmhd_adiab
The adiabatic constant.
subroutine, public rmhd_get_pthermal_plus_pradiation(w, x, ixil, ixol, pth_plus_prad)
Calculates the sum of the gas pressure and the max Prad tensor element.
integer, public, protected q_
Index of the heat flux q.
integer, public, protected tweight_
logical, public has_equi_rho0
whether split off equilibrium density
double precision, public rmhd_eta
The MHD resistivity.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
subroutine, public get_normalized_divb(w, ixil, ixol, divb)
get dimensionless div B = |divB| * volume / area / |B|
integer, public, protected rho_
Index of the density (in the w array)
integer, public, protected c_
double precision function, dimension(ixo^s), public rmhd_mag_en_all(w, ixil, ixol)
Compute 2 times total magnetic energy.
type(te_fluid), allocatable, public te_fl_rmhd
type of fluid for thermal emission synthesis
logical, public, protected rmhd_gravity
Whether gravity is added.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
logical, public, protected rmhd_glm_extended
Whether extended GLM-MHD is used with additional sources.
logical, public, protected rmhd_viscosity
Whether viscosity is added.
logical, public, protected rmhd_partial_ionization
Whether plasma is partially ionized.
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
integer, public, protected e_
Index of the energy density (-1 if not present)
logical, public, protected rmhd_radiation_advection
Treat radiation advection.
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
subroutine, public rmhd_get_rho(w, x, ixil, ixol, rho)
integer, dimension(:), allocatable, public, protected tracer
Indices of the tracers.
logical, public, protected rmhd_energy_interact
Treat radiation-gas energy interaction.
subroutine, public rmhd_get_tgas(w, x, ixil, ixol, tgas)
Calculates gas temperature.
character(len=std_len), public, protected type_ct
Method type of constrained transport.
procedure(sub_convert), pointer, public rmhd_to_conserved
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
logical, public partial_energy
Whether an internal or hydrodynamic energy equation is used.
procedure(sub_convert), pointer, public rmhd_to_primitive
logical, public, protected rmhd_dump_full_vars
whether dump full variables (when splitting is used) in a separate dat file
logical, public, protected rmhd_trac
Whether TRAC method is used.
subroutine, public rmhd_clean_divb_multigrid(qdt, qt, active)
subroutine, public rmhd_set_mg_bounds
Set the boundaries for the diffusion of E.
subroutine, public rmhd_get_v(w, x, ixil, ixol, v)
Calculate v vector.
double precision, public hypertc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
logical, public has_equi_pe0
whether split off equilibrium thermal pressure
subroutine, public rmhd_get_pradiation(w, x, ixil, ixol, prad, nth)
Calculate radiation pressure within ixO^L.
integer, public, protected te_
Indices of temperature.
logical, public, protected source_split_divb
Whether divB cleaning sources are added splitting from fluid solver.
integer, public, protected r_e
Index of the radiation energy.
procedure(sub_get_pthermal), pointer, public rmhd_get_temperature
character(len=std_len), public, protected typedivbfix
Method type to clean divergence of B.
logical, public, protected b0field_forcefree
B0 field is force-free.
double precision, public rmhd_glm_alpha
GLM-MHD parameter: ratio of the diffusive and advective time scales for div b taking values within [0...
integer, public, protected rmhd_divb_nth
Whether divB is computed with a fourth order approximation.
subroutine, public rmhd_ei_to_e(ixil, ixol, w, x)
Transform internal energy to total energy.
integer, public equi_pe0_
double precision, public, protected he_ion_fr
Ionization fraction of He He_ion_fr = (He2+ + He+)/(He2+ + He+ + He)
logical, public, protected rmhd_energy
Whether an energy equation is used.
logical, dimension(2 *^nd), public, protected boundary_divbfix
To control divB=0 fix for boundary.
double precision, public, protected rmhd_trac_mask
Height of the mask used in the TRAC method.
logical, public, protected eq_state_units
subroutine, public rmhd_e_to_ei(ixil, ixol, w, x)
Transform total energy to internal energy.
logical, public, protected rmhd_4th_order
MHD fourth order.
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method 1) in amrvac.par in sts_list set the following parameters which have...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
double precision function, public get_tc_dt_mhd(w, ixil, ixol, dxd, x, fl)
Get the explicut timestep for the TC (mhd implementation)
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine, public tc_get_mhd_params(fl, read_mhd_params)
Init TC coefficients: MHD case.
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_equi_vars), pointer usr_set_equi_vars
procedure(special_mg_bc), pointer usr_special_mg_bc
procedure(set_electric_field), pointer usr_set_electric_field
The module add viscous source terms and check time step.
subroutine viscosity_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
subroutine viscosity_init(phys_wider_stencil)
Initialize the module.
subroutine viscosity_get_dt(w, ixil, ixol, dtnew, dxd, x)
The data structure that contains information about a tree node/grid block.