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
143 logical :: compactres = .false.
161 logical,
protected :: radio_acoustic_filter = .false.
162 integer,
protected :: size_ra_filter = 1
166 logical :: dt_c = .false.
176 logical :: total_energy = .true.
180 logical :: gravity_energy
182 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
184 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
186 character(len=std_len) :: typedivbdiff =
'all'
226 subroutine rmhd_read_params(files)
229 character(len=*),
intent(in) :: files(:)
247 do n = 1,
size(files)
248 open(
unitpar, file=trim(files(n)), status=
"old")
249 read(
unitpar, rmhd_list,
end=111)
253 end subroutine rmhd_read_params
256 subroutine rmhd_write_info(fh)
258 integer,
intent(in) :: fh
260 integer,
parameter :: n_par = 1
261 double precision :: values(n_par)
262 integer,
dimension(MPI_STATUS_SIZE) :: st
263 character(len=name_len) :: names(n_par)
265 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
269 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
270 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
271 end subroutine rmhd_write_info
297 if(
mype==0)
write(*,*)
'WARNING: set rmhd_partial_ionization=F when eq_state_units=F'
303 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
306 physics_type =
"rmhd"
321 phys_total_energy=total_energy
323 gravity_energy=.true.
325 gravity_energy=.false.
331 if(
mype==0)
write(*,*)
'WARNING: reset rmhd_trac_type=1 for 1D simulation'
336 if(
mype==0)
write(*,*)
'WARNING: set rmhd_trac_mask==bigdouble for global TRAC method'
345 type_divb = divb_none
348 type_divb = divb_multigrid
350 mg%operator_type = mg_laplacian
357 case (
'powel',
'powell')
358 type_divb = divb_powel
360 type_divb = divb_janhunen
362 type_divb = divb_linde
363 case (
'lindejanhunen')
364 type_divb = divb_lindejanhunen
366 type_divb = divb_lindepowel
370 type_divb = divb_lindeglm
375 call mpistop(
'Unknown divB fix')
378 allocate(start_indices(number_species),stop_indices(number_species))
385 mom(:) = var_set_momentum(
ndir)
391 e_ = var_set_energy()
400 mag(:) = var_set_bfield(
ndir)
404 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
410 r_e = var_set_radiation_energy()
423 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
428 te_ = var_set_auxvar(
'Te',
'Te')
437 stop_indices(1)=nwflux
467 allocate(iw_vector(nvector))
468 iw_vector(1) = mom(1) - 1
469 iw_vector(2) = mag(1) - 1
472 if (.not.
allocated(flux_type))
then
473 allocate(flux_type(
ndir, nwflux))
474 flux_type = flux_default
475 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
476 call mpistop(
"phys_check error: flux_type has wrong shape")
479 if(nwflux>mag(
ndir))
then
481 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
486 flux_type(:,
psi_)=flux_special
488 flux_type(idir,mag(idir))=flux_special
492 flux_type(idir,mag(idir))=flux_tvdlf
498 phys_get_dt => rmhd_get_dt
499 phys_get_cmax => rmhd_get_cmax_origin
500 phys_get_tcutoff => rmhd_get_tcutoff
501 phys_get_h_speed => rmhd_get_h_speed
503 phys_get_cbounds => rmhd_get_cbounds_split_rho
505 phys_get_cbounds => rmhd_get_cbounds
508 phys_to_primitive => rmhd_to_primitive_split_rho
510 phys_to_conserved => rmhd_to_conserved_split_rho
513 phys_to_primitive => rmhd_to_primitive_origin
515 phys_to_conserved => rmhd_to_conserved_origin
519 phys_get_flux => rmhd_get_flux_split
521 phys_get_flux => rmhd_get_flux
525 phys_add_source_geom => rmhd_add_source_geom_split
527 phys_add_source_geom => rmhd_add_source_geom
529 phys_add_source => rmhd_add_source
530 phys_check_params => rmhd_check_params
531 phys_write_info => rmhd_write_info
533 phys_handle_small_values => rmhd_handle_small_values_origin
534 rmhd_handle_small_values => rmhd_handle_small_values_origin
535 phys_check_w => rmhd_check_w_origin
540 phys_get_pthermal => rmhd_get_pthermal_origin
544 phys_set_equi_vars => set_equi_vars_grid
547 if(type_divb==divb_glm)
then
548 phys_modify_wlr => rmhd_modify_wlr
553 rmhd_get_rfactor=>rfactor_from_temperature_ionization
554 phys_update_temperature => rmhd_update_temperature
558 rmhd_get_rfactor=>rfactor_from_constant_ionization
575 transverse_ghost_cells = 1
576 phys_get_ct_velocity => rmhd_get_ct_velocity_average
577 phys_update_faces => rmhd_update_faces_average
579 transverse_ghost_cells = 1
580 phys_get_ct_velocity => rmhd_get_ct_velocity_contact
581 phys_update_faces => rmhd_update_faces_contact
583 transverse_ghost_cells = 2
584 phys_get_ct_velocity => rmhd_get_ct_velocity_hll
585 phys_update_faces => rmhd_update_faces_hll
587 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
590 phys_modify_wlr => rmhd_modify_wlr
592 phys_boundary_adjust => rmhd_boundary_adjust
601 call rmhd_physical_units()
610 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%subtract_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%subtract_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
1107 end subroutine rmhd_physical_units
1109 subroutine rmhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1111 logical,
intent(in) :: primitive
1112 integer,
intent(in) :: ixi^
l, ixo^
l
1113 double precision,
intent(in) :: w(ixi^s,nw)
1114 logical,
intent(inout) :: flag(ixi^s,1:nw)
1115 double precision :: tmp
1119 {
do ix^db=ixomin^db,ixomax^db\}
1133 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1137 if(tmp<small_e) flag(ix^
d,
e_) = .true.
1142 end subroutine rmhd_check_w_origin
1145 subroutine rmhd_to_conserved_origin(ixI^L,ixO^L,w,x)
1147 integer,
intent(in) :: ixi^
l, ixo^
l
1148 double precision,
intent(inout) :: w(ixi^s, nw)
1149 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1152 {
do ix^db=ixomin^db,ixomax^db\}
1154 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1156 +(^
c&w(ix^
d,
b^
c_)**2+))
1160 end subroutine rmhd_to_conserved_origin
1163 subroutine rmhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
1165 integer,
intent(in) :: ixi^
l, ixo^
l
1166 double precision,
intent(inout) :: w(ixi^s, nw)
1167 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1168 double precision :: rho
1171 {
do ix^db=ixomin^db,ixomax^db\}
1174 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1175 +half*((^
c&w(ix^
d,
m^
c_)**2+)*rho&
1176 +(^
c&w(ix^
d,
b^
c_)**2+))
1180 end subroutine rmhd_to_conserved_split_rho
1183 subroutine rmhd_to_primitive_origin(ixI^L,ixO^L,w,x)
1185 integer,
intent(in) :: ixi^
l, ixo^
l
1186 double precision,
intent(inout) :: w(ixi^s, nw)
1187 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1188 double precision :: inv_rho
1193 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_origin')
1196 {
do ix^db=ixomin^db,ixomax^db\}
1197 inv_rho = 1.d0/w(ix^
d,
rho_)
1201 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1203 +(^
c&w(ix^
d,
b^
c_)**2+)))
1205 end subroutine rmhd_to_primitive_origin
1208 subroutine rmhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
1210 integer,
intent(in) :: ixi^
l, ixo^
l
1211 double precision,
intent(inout) :: w(ixi^s, nw)
1212 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1213 double precision :: inv_rho
1218 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_split_rho')
1221 {
do ix^db=ixomin^db,ixomax^db\}
1226 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1228 (^
c&w(ix^
d,
m^
c_)**2+)+(^
c&w(ix^
d,
b^
c_)**2+)))
1230 end subroutine rmhd_to_primitive_split_rho
1235 integer,
intent(in) :: ixi^
l, ixo^
l
1236 double precision,
intent(inout) :: w(ixi^s, nw)
1237 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1242 {
do ix^db=ixomin^db,ixomax^db\}
1245 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1247 +(^
c&w(ix^
d,
b^
c_)**2+))
1250 {
do ix^db=ixomin^db,ixomax^db\}
1252 w(ix^d,
e_)=w(ix^d,
e_)&
1253 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1254 +(^
c&w(ix^d,
b^
c_)**2+))
1262 integer,
intent(in) :: ixi^
l, ixo^
l
1263 double precision,
intent(inout) :: w(ixi^s, nw)
1264 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1269 {
do ix^db=ixomin^db,ixomax^db\}
1272 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1274 +(^
c&w(ix^
d,
b^
c_)**2+))
1277 {
do ix^db=ixomin^db,ixomax^db\}
1279 w(ix^d,
e_)=w(ix^d,
e_)&
1280 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1281 +(^
c&w(ix^d,
b^
c_)**2+))
1285 if(fix_small_values)
then
1286 call rmhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'rmhd_e_to_ei')
1290 subroutine rmhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
1293 logical,
intent(in) :: primitive
1294 integer,
intent(in) :: ixi^
l,ixo^
l
1295 double precision,
intent(inout) :: w(ixi^s,1:nw)
1296 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1297 character(len=*),
intent(in) :: subname
1298 double precision :: rho
1299 integer :: idir, ix^
d
1300 logical :: flag(ixi^s,1:nw)
1302 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
1306 {
do ix^db=ixomin^db,ixomax^db\}
1316 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
1328 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))&
1332 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))
1339 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
1341 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
1344 {
do ix^db=iximin^db,iximax^db\}
1350 w(ix^d,
e_)=w(ix^d,
e_)&
1351 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1353 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
1355 {
do ix^db=iximin^db,iximax^db\}
1361 w(ix^d,
e_)=w(ix^d,
e_)&
1362 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1365 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
1367 if(.not.primitive)
then
1370 {
do ix^db=iximin^db,iximax^db\}
1376 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
1377 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
1378 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+)))
1381 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
1384 end subroutine rmhd_handle_small_values_origin
1389 integer,
intent(in) :: ixi^
l, ixo^
l
1390 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
1391 double precision,
intent(out) :: v(ixi^s,
ndir)
1392 double precision :: rho(ixi^s)
1396 rho(ixo^s)=1.d0/rho(ixo^s)
1399 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
1404 subroutine rmhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
1406 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1407 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1408 double precision,
intent(inout) :: cmax(ixi^s)
1409 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1413 {
do ix^db=ixomin^db,ixomax^db \}
1424 cfast2=b2*inv_rho+cmax(ix^
d)
1425 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
1426 if(avmincs2<zero) avmincs2=zero
1427 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1428 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
1431 {
do ix^db=ixomin^db,ixomax^db \}
1441 b2=(^
c&w(ix^d,
b^
c_)**2+)
1442 cfast2=b2*inv_rho+cmax(ix^d)
1443 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1444 if(avmincs2<zero) avmincs2=zero
1445 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1446 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
1449 end subroutine rmhd_get_cmax_origin
1452 subroutine rmhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
1455 integer,
intent(in) :: ixi^
l,ixo^
l
1456 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1457 double precision,
intent(out) :: tco_local,tmax_local
1459 double precision,
intent(inout) :: w(ixi^s,1:nw)
1460 double precision,
parameter :: trac_delta=0.25d0
1461 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s)
1462 double precision,
dimension(ixI^S,1:ndir) :: bunitvec
1463 double precision,
dimension(ixI^S,1:ndim) :: gradt
1464 double precision :: bdir(
ndim)
1465 double precision :: ltrc,ltrp,altr(ixi^s)
1466 integer :: idims,jxo^
l,hxo^
l,ixa^
d,ixb^
d,ix^
d
1467 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
1468 logical :: lrlt(ixi^s)
1471 call rmhd_get_temperature_from_te(w,x,ixi^
l,ixi^
l,te)
1473 call rmhd_get_rfactor(w,x,ixi^
l,ixi^
l,te)
1474 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
1477 tmax_local=maxval(te(ixo^s))
1487 lts(ixo^s)=0.5d0*abs(te(jxo^s)-te(hxo^s))/te(ixo^s)
1489 where(lts(ixo^s) > trac_delta)
1492 if(any(lrlt(ixo^s)))
then
1493 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
1504 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
1505 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1506 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
1507 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
1509 call mpistop(
"rmhd_trac_type not allowed for 1D simulation")
1521 gradt(ixo^s,idims)=tmp1(ixo^s)
1525 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))+
block%B0(ixo^s,:,0)
1527 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))
1533 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
1536 if(sum(bdir(:)**2) .gt. zero)
then
1537 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
1539 block%special_values(3:ndim+2)=bdir(1:ndim)
1541 tmp1(ixo^s)=dsqrt(sum(bunitvec(ixo^s,:)**2,dim=ndim+1))
1542 where(tmp1(ixo^s)/=0.d0)
1543 tmp1(ixo^s)=1.d0/tmp1(ixo^s)
1545 tmp1(ixo^s)=bigdouble
1549 bunitvec(ixo^s,idims)=bunitvec(ixo^s,idims)*tmp1(ixo^s)
1552 lts(ixo^s)=abs(sum(gradt(ixo^s,1:ndim)*bunitvec(ixo^s,1:ndim),dim=ndim+1))/te(ixo^s)
1554 if(slab_uniform)
then
1555 lts(ixo^s)=minval(dxlevel)*lts(ixo^s)
1557 lts(ixo^s)=minval(block%ds(ixo^s,:),dim=ndim+1)*lts(ixo^s)
1560 where(lts(ixo^s) > trac_delta)
1563 if(any(lrlt(ixo^s)))
then
1564 block%special_values(1)=maxval(te(ixo^s), mask=lrlt(ixo^s))
1566 block%special_values(1)=zero
1568 block%special_values(2)=tmax_local
1587 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1588 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1589 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1592 {
do ix^db=ixpmin^db,ixpmax^db\}
1594 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))+block%B0(ix^d,^
c,0)\
1596 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))\
1598 tmp1(ix^d)=1.d0/(dsqrt(^
c&bunitvec(ix^d,^
c)**2+)+smalldouble)
1600 ^d&bunitvec({ix^d},^d)=bunitvec({ix^d},^d)*tmp1({ix^d})\
1602 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec({ix^d},^d)+)/te(ix^d)
1604 if(slab_uniform)
then
1605 lts(ix^d)=min(^d&dxlevel(^d))*lts(ix^d)
1607 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
1609 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
1614 hxo^l=ixp^l-kr(idims,^d);
1615 jxo^l=ixp^l+kr(idims,^d);
1617 altr(ixp^s)=0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1619 altr(ixp^s)=altr(ixp^s)+0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1622 block%wextra(ixp^s,
tcoff_)=te(ixp^s)*altr(ixp^s)**0.4d0
1626 call mpistop(
"unknown rmhd_trac_type")
1629 end subroutine rmhd_get_tcutoff
1632 subroutine rmhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
1635 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1636 double precision,
intent(in) :: wprim(ixi^s, nw)
1637 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1638 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
1640 double precision :: csound(ixi^s,
ndim)
1641 double precision,
allocatable :: tmp(:^
d&)
1642 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
1646 allocate(tmp(ixa^s))
1648 call rmhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
1649 csound(ixa^s,id)=tmp(ixa^s)
1652 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
1653 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
1654 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
1655 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))
1659 ixamax^
d=ixcmax^
d+
kr(id,^
d);
1660 ixamin^
d=ixcmin^
d+
kr(id,^
d);
1661 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)))
1662 ixamax^
d=ixcmax^
d-
kr(id,^
d);
1663 ixamin^
d=ixcmin^
d-
kr(id,^
d);
1664 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)))
1669 ixamax^
d=jxcmax^
d+
kr(id,^
d);
1670 ixamin^
d=jxcmin^
d+
kr(id,^
d);
1671 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)))
1672 ixamax^
d=jxcmax^
d-
kr(id,^
d);
1673 ixamin^
d=jxcmin^
d-
kr(id,^
d);
1674 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)))
1678 end subroutine rmhd_get_h_speed
1681 subroutine rmhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1683 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1684 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1685 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1686 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1687 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1688 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1689 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1691 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1692 double precision :: umean, dmean, tmp1, tmp2, tmp3
1699 call rmhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1700 call rmhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1701 if(
present(cmin))
then
1702 {
do ix^db=ixomin^db,ixomax^db\}
1703 tmp1=sqrt(wlp(ix^
d,
rho_))
1704 tmp2=sqrt(wrp(ix^
d,
rho_))
1705 tmp3=1.d0/(tmp1+tmp2)
1706 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1707 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1708 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1709 cmin(ix^
d,1)=umean-dmean
1710 cmax(ix^
d,1)=umean+dmean
1712 if(h_correction)
then
1713 {
do ix^db=ixomin^db,ixomax^db\}
1714 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1715 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1719 {
do ix^db=ixomin^db,ixomax^db\}
1720 tmp1=sqrt(wlp(ix^d,
rho_))
1721 tmp2=sqrt(wrp(ix^d,
rho_))
1722 tmp3=1.d0/(tmp1+tmp2)
1723 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1724 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1725 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1726 cmax(ix^d,1)=abs(umean)+dmean
1730 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1731 call rmhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
1732 if(
present(cmin))
then
1733 {
do ix^db=ixomin^db,ixomax^db\}
1734 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1735 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1737 if(h_correction)
then
1738 {
do ix^db=ixomin^db,ixomax^db\}
1739 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1740 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1744 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1748 call rmhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
1749 call rmhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
1750 if(
present(cmin))
then
1751 {
do ix^db=ixomin^db,ixomax^db\}
1752 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1753 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1754 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1756 if(h_correction)
then
1757 {
do ix^db=ixomin^db,ixomax^db\}
1758 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1759 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1763 {
do ix^db=ixomin^db,ixomax^db\}
1764 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1765 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1769 end subroutine rmhd_get_cbounds
1772 subroutine rmhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1774 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1775 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1776 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1777 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1778 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1779 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1780 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1781 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1782 double precision :: umean, dmean, tmp1, tmp2, tmp3
1789 call rmhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1790 call rmhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1791 if(
present(cmin))
then
1792 {
do ix^db=ixomin^db,ixomax^db\}
1795 tmp3=1.d0/(tmp1+tmp2)
1796 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1797 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1798 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1799 cmin(ix^
d,1)=umean-dmean
1800 cmax(ix^
d,1)=umean+dmean
1802 if(h_correction)
then
1803 {
do ix^db=ixomin^db,ixomax^db\}
1804 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1805 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1809 {
do ix^db=ixomin^db,ixomax^db\}
1812 tmp3=1.d0/(tmp1+tmp2)
1813 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1814 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1815 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1816 cmax(ix^d,1)=abs(umean)+dmean
1820 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1821 call rmhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
1822 if(
present(cmin))
then
1823 {
do ix^db=ixomin^db,ixomax^db\}
1824 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1825 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1827 if(h_correction)
then
1828 {
do ix^db=ixomin^db,ixomax^db\}
1829 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1830 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1834 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1838 call rmhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
1839 call rmhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
1840 if(
present(cmin))
then
1841 {
do ix^db=ixomin^db,ixomax^db\}
1842 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1843 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1844 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1846 if(h_correction)
then
1847 {
do ix^db=ixomin^db,ixomax^db\}
1848 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1849 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1853 {
do ix^db=ixomin^db,ixomax^db\}
1854 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1855 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1859 end subroutine rmhd_get_cbounds_split_rho
1862 subroutine rmhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1865 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1866 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1867 double precision,
intent(in) :: cmax(ixi^s)
1868 double precision,
intent(in),
optional :: cmin(ixi^s)
1869 type(ct_velocity),
intent(inout):: vcts
1871 end subroutine rmhd_get_ct_velocity_average
1873 subroutine rmhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1876 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1877 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1878 double precision,
intent(in) :: cmax(ixi^s)
1879 double precision,
intent(in),
optional :: cmin(ixi^s)
1880 type(ct_velocity),
intent(inout):: vcts
1883 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
1885 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
1887 end subroutine rmhd_get_ct_velocity_contact
1889 subroutine rmhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1892 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1893 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1894 double precision,
intent(in) :: cmax(ixi^s)
1895 double precision,
intent(in),
optional :: cmin(ixi^s)
1896 type(ct_velocity),
intent(inout):: vcts
1898 integer :: idime,idimn
1900 if(.not.
allocated(vcts%vbarC))
then
1901 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
1902 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
1905 if(
present(cmin))
then
1906 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
1907 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1909 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1910 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
1913 idimn=mod(idim,
ndir)+1
1914 idime=mod(idim+1,
ndir)+1
1916 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
1917 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
1918 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
1919 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1920 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1922 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
1923 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
1924 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
1925 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1926 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1928 end subroutine rmhd_get_ct_velocity_hll
1931 subroutine rmhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
1933 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1934 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1935 double precision,
intent(out):: csound(ixo^s)
1936 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
1937 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1938 double precision :: prad_max(ixo^s)
1943 if(radio_acoustic_filter)
then
1944 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
1948 {
do ix^db=ixomin^db,ixomax^db \}
1949 inv_rho=1.d0/w(ix^
d,
rho_)
1950 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1952 csound(ix^
d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
1957 cfast2=b2*inv_rho+csound(ix^
d)
1958 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
1960 if(avmincs2<zero) avmincs2=zero
1961 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1964 {
do ix^db=ixomin^db,ixomax^db \}
1965 inv_rho=1.d0/w(ix^d,
rho_)
1966 prad_max(ix^d)=maxval(prad_tensor(ix^d,:,:))
1968 csound(ix^d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+prad_max(ix^d))*inv_rho
1972 b2=(^
c&w(ix^d,
b^
c_)**2+)
1973 cfast2=b2*inv_rho+csound(ix^d)
1974 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1975 if(avmincs2<zero) avmincs2=zero
1976 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1979 end subroutine rmhd_get_csound_prim
1982 subroutine rmhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
1984 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1985 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1986 double precision,
intent(out):: csound(ixo^s)
1987 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1988 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1989 double precision :: prad_max(ixo^s)
1994 if (radio_acoustic_filter)
then
1995 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2000 {
do ix^db=ixomin^db,ixomax^db \}
2003 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2008 cfast2=b2*inv_rho+csound(ix^
d)
2009 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
2011 if(avmincs2<zero) avmincs2=zero
2012 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2015 {
do ix^db=ixomin^db,ixomax^db \}
2018 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
2020 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
2022 b2=(^
c&w(ix^d,
b^
c_)**2+)
2023 cfast2=b2*inv_rho+csound(ix^d)
2024 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2025 if(avmincs2<zero) avmincs2=zero
2026 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2029 end subroutine rmhd_get_csound_prim_split
2032 subroutine rmhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
2036 integer,
intent(in) :: ixi^
l, ixo^
l
2037 double precision,
intent(in) :: w(ixi^s,nw)
2038 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2039 double precision,
intent(out):: pth(ixi^s)
2043 {
do ix^db=ixomin^db,ixomax^db\}
2048 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)&
2049 +(^
c&w(ix^
d,
b^
c_)**2+)))
2054 if(check_small_values.and..not.fix_small_values)
then
2055 {
do ix^db=ixomin^db,ixomax^db\}
2056 if(pth(ix^d)<small_pressure)
then
2057 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
2058 " encountered when call rmhd_get_pthermal"
2059 write(*,*)
"Iteration: ", it,
" Time: ", global_time
2060 write(*,*)
"Location: ", x(ix^d,:)
2061 write(*,*)
"Cell number: ", ix^d
2063 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
2066 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
2067 write(*,*)
"Saving status at the previous time step"
2072 end subroutine rmhd_get_pthermal_origin
2075 subroutine rmhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
2077 integer,
intent(in) :: ixi^
l, ixo^
l
2078 double precision,
intent(in) :: w(ixi^s, 1:nw)
2079 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2080 double precision,
intent(out):: res(ixi^s)
2081 res(ixo^s) = w(ixo^s,
te_)
2082 end subroutine rmhd_get_temperature_from_te
2085 subroutine rmhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
2087 integer,
intent(in) :: ixi^
l, ixo^
l
2088 double precision,
intent(in) :: w(ixi^s, 1:nw)
2089 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2090 double precision,
intent(out):: res(ixi^s)
2091 double precision :: r(ixi^s)
2093 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2094 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
2095 end subroutine rmhd_get_temperature_from_eint
2098 subroutine rmhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
2100 integer,
intent(in) :: ixi^
l, ixo^
l
2101 double precision,
intent(in) :: w(ixi^s, 1:nw)
2102 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2103 double precision,
intent(out):: res(ixi^s)
2104 double precision :: r(ixi^s)
2106 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2108 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
2109 end subroutine rmhd_get_temperature_from_etot
2111 subroutine rmhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
2113 integer,
intent(in) :: ixi^
l, ixo^
l
2114 double precision,
intent(in) :: w(ixi^s, 1:nw)
2115 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2116 double precision,
intent(out):: res(ixi^s)
2117 double precision :: r(ixi^s)
2119 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2122 end subroutine rmhd_get_temperature_from_etot_with_equi
2124 subroutine rmhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
2126 integer,
intent(in) :: ixi^
l, ixo^
l
2127 double precision,
intent(in) :: w(ixi^s, 1:nw)
2128 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2129 double precision,
intent(out):: res(ixi^s)
2130 double precision :: r(ixi^s)
2132 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2135 end subroutine rmhd_get_temperature_from_eint_with_equi
2137 subroutine rmhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
2139 integer,
intent(in) :: ixi^
l, ixo^
l
2140 double precision,
intent(in) :: w(ixi^s, 1:nw)
2141 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2142 double precision,
intent(out):: res(ixi^s)
2143 double precision :: r(ixi^s)
2145 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2147 end subroutine rmhd_get_temperature_equi
2149 subroutine rmhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
2151 integer,
intent(in) :: ixi^
l, ixo^
l
2152 double precision,
intent(in) :: w(ixi^s, 1:nw)
2153 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2154 double precision,
intent(out):: res(ixi^s)
2156 end subroutine rmhd_get_rho_equi
2158 subroutine rmhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
2160 integer,
intent(in) :: ixi^
l, ixo^
l
2161 double precision,
intent(in) :: w(ixi^s, 1:nw)
2162 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2163 double precision,
intent(out):: res(ixi^s)
2165 end subroutine rmhd_get_pe_equi
2168 subroutine rmhd_get_p_total(w,x,ixI^L,ixO^L,p)
2170 integer,
intent(in) :: ixi^
l, ixo^
l
2171 double precision,
intent(in) :: w(ixi^s,nw)
2172 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2173 double precision,
intent(out) :: p(ixi^s)
2176 p(ixo^s) = p(ixo^s) + 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
2177 end subroutine rmhd_get_p_total
2184 integer,
intent(in) :: ixi^
l, ixo^
l, nth
2185 double precision,
intent(in) :: w(ixi^s, 1:nw)
2186 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2187 double precision,
intent(out):: prad(ixo^s, 1:
ndim, 1:
ndim)
2195 call mpistop(
'Radiation formalism unknown')
2202 integer,
intent(in) :: ixi^
l, ixo^
l
2203 double precision,
intent(in) :: w(ixi^s, 1:nw)
2204 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2205 double precision :: pth(ixi^s)
2206 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2207 double precision :: prad_max(ixo^s)
2208 double precision,
intent(out) :: pth_plus_prad(ixi^s)
2213 {
do ix^
d = ixomin^
d,ixomax^
d\}
2214 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2217 if (radio_acoustic_filter)
then
2218 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2220 pth_plus_prad(ixo^s) = pth(ixo^s) + prad_max(ixo^s)
2224 subroutine rmhd_radio_acoustic_filter(x, ixI^L, ixO^L, prad_max)
2226 integer,
intent(in) :: ixi^
l, ixo^
l
2227 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2228 double precision,
intent(inout) :: prad_max(ixo^s)
2229 double precision :: tmp_prad(ixi^s)
2230 integer :: ix^
d, filter, idim
2232 if (size_ra_filter .lt. 1)
call mpistop(
"ra filter of size < 1 makes no sense")
2233 if (size_ra_filter .gt.
nghostcells)
call mpistop(
"ra filter of size < nghostcells makes no sense")
2235 tmp_prad(ixi^s) = zero
2236 tmp_prad(ixo^s) = prad_max(ixo^s)
2237 do filter = 1,size_ra_filter
2240 {
do ix^
d = ixomin^
d,ixomax^
d\}
2241 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d+filter*
kr(idim,^
d)))
2242 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d-filter*
kr(idim,^
d)))
2246 end subroutine rmhd_radio_acoustic_filter
2251 integer,
intent(in) :: ixi^
l, ixo^
l
2252 double precision,
intent(in) :: w(ixi^s, 1:nw)
2253 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2254 double precision :: pth(ixi^s)
2255 double precision,
intent(out):: tgas(ixi^s)
2258 tgas(ixi^s) = pth(ixi^s)/w(ixi^s,
rho_)
2266 integer,
intent(in) :: ixi^
l, ixo^
l
2267 double precision,
intent(in) :: w(ixi^s, 1:nw)
2268 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2269 double precision,
intent(out):: trad(ixi^s)
2276 subroutine rmhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
2280 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2282 double precision,
intent(in) :: wc(ixi^s,nw)
2284 double precision,
intent(in) :: w(ixi^s,nw)
2285 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2286 double precision,
intent(out) :: f(ixi^s,nwflux)
2287 double precision :: vhall(ixi^s,1:
ndir)
2288 double precision :: ptotal
2291 {
do ix^db=ixomin^db,ixomax^db\}
2296 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2298 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2301 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2302 -w(ix^
d,mag(idim))*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2307 {
do ix^db=ixomin^db,ixomax^db\}
2308 f(ix^d,mag(idim))=w(ix^d,
psi_)
2310 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
2314 {
do ix^db=ixomin^db,ixomax^db\}
2315 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2322 {
do ix^db=ixomin^db,ixomax^db\}
2327 {
do ix^db=ixomin^db,ixomax^db\}
2328 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^
c&w({ix^d},
b^
c_)**2+)+smalldouble)
2332 end subroutine rmhd_get_flux
2335 subroutine rmhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
2338 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2340 double precision,
intent(in) :: wc(ixi^s,nw)
2342 double precision,
intent(in) :: w(ixi^s,nw)
2343 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2344 double precision,
intent(out) :: f(ixi^s,nwflux)
2345 double precision :: vhall(ixi^s,1:
ndir)
2346 double precision :: ptotal, btotal(ixo^s,1:
ndir)
2349 {
do ix^db=ixomin^db,ixomax^db\}
2357 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2366 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
2370 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
2371 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2373 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
2377 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2380 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
2384 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2385 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2389 {
do ix^db=ixomin^db,ixomax^db\}
2390 f(ix^d,mag(idim))=w(ix^d,
psi_)
2392 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
2396 {
do ix^db=ixomin^db,ixomax^db\}
2397 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2404 {
do ix^db=ixomin^db,ixomax^db\}
2409 {
do ix^db=ixomin^db,ixomax^db\}
2410 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
2414 end subroutine rmhd_get_flux_split
2418 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
2421 integer,
intent(in) :: ixi^
l, ixo^
l
2422 double precision,
dimension(:^D&,:),
intent(inout) :: ff
2423 double precision,
intent(out) :: src(ixi^s)
2425 double precision :: ffc(ixi^s,1:
ndim)
2426 double precision :: dxinv(
ndim)
2427 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
2433 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
2435 ixbmin^
d=ixcmin^
d+ix^
d;
2436 ixbmax^
d=ixcmax^
d+ix^
d;
2439 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
2441 ff(ixi^s,1:ndim)=0.d0
2443 ixb^l=ixo^l-kr(idims,^d);
2444 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
2446 if({ ix^d==0 .and. ^d==idims | .or.})
then
2447 ixbmin^d=ixcmin^d-ix^d;
2448 ixbmax^d=ixcmax^d-ix^d;
2449 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
2452 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
2455 if(slab_uniform)
then
2457 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
2458 ixb^l=ixo^l-kr(idims,^d);
2459 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2463 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
2464 ixb^l=ixo^l-kr(idims,^d);
2465 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2467 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
2469 end subroutine get_flux_on_cell_face
2472 subroutine rmhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2478 integer,
intent(in) :: ixi^
l, ixo^
l
2479 double precision,
intent(in) :: qdt,dtfactor
2480 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2481 double precision,
intent(inout) :: w(ixi^s,1:nw)
2482 logical,
intent(in) :: qsourcesplit
2483 logical,
intent(inout) :: active
2489 if (.not. qsourcesplit)
then
2492 call add_pe0_divv(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2495 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
2500 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2505 call add_source_res2(qdt,ixi^
l,ixo^
l,wct,w,x)
2509 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
2515 select case (type_divb)
2520 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2523 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2526 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2527 case (divb_janhunen)
2529 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2530 case (divb_lindejanhunen)
2532 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2533 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2534 case (divb_lindepowel)
2536 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2537 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2538 case (divb_lindeglm)
2540 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2541 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2542 case (divb_multigrid)
2547 call mpistop(
'Unknown divB fix')
2557 w,x,gravity_energy,qsourcesplit,active)
2563 call rmhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x,qsourcesplit,active)
2566 if(.not.qsourcesplit)
then
2568 call rmhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
2571 end subroutine rmhd_add_source
2573 subroutine rmhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2579 integer,
intent(in) :: ixi^
l, ixo^
l
2580 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
2581 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw)
2582 double precision,
intent(inout) :: w(ixi^s,1:nw)
2583 logical,
intent(in) :: qsourcesplit
2584 logical,
intent(inout) :: active
2585 double precision :: cmax(ixi^s)
2592 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2597 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2603 call mpistop(
'Radiation formalism unknown')
2605 end subroutine rmhd_add_radiation_source
2607 subroutine add_pe0_divv(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2610 integer,
intent(in) :: ixi^
l, ixo^
l
2611 double precision,
intent(in) :: qdt,dtfactor
2612 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2613 double precision,
intent(inout) :: w(ixi^s,1:nw)
2614 double precision :: divv(ixi^s)
2630 end subroutine add_pe0_divv
2632 subroutine get_tau(ixI^L,ixO^L,w,Te,tau,sigT5)
2634 integer,
intent(in) :: ixi^
l, ixo^
l
2635 double precision,
dimension(ixI^S,1:nw),
intent(in) :: w
2636 double precision,
dimension(ixI^S),
intent(in) :: te
2637 double precision,
dimension(ixI^S),
intent(out) :: tau,sigt5
2638 double precision :: dxmin,taumin
2639 double precision,
dimension(ixI^S) :: sigt7,eint
2647 sigt7(ixo^s)=sigt5(ixo^s)*
block%wextra(ixo^s,
tcoff_)
2650 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2654 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2657 tau(ixo^s)=max(taumin*
dt,sigt7(ixo^s)/eint(ixo^s)/
cmax_global**2)
2658 end subroutine get_tau
2660 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
2662 integer,
intent(in) :: ixi^
l,ixo^
l
2663 double precision,
intent(in) :: qdt
2664 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
2665 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
2666 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
2667 double precision :: invdx
2668 double precision,
dimension(ixI^S) :: te,tau,sigt,htc_qsrc,tface,r
2669 double precision,
dimension(ixI^S) :: htc_esrc,bsum,bunit
2670 double precision,
dimension(ixI^S,1:ndim) :: btot
2672 integer :: hxc^
l,hxo^
l,ixc^
l,jxc^
l,jxo^
l,kxc^
l
2674 call rmhd_get_rfactor(wctprim,x,ixi^
l,ixi^
l,r)
2677 te(ixi^s)=wctprim(ixi^s,
p_)/(r(ixi^s)*w(ixi^s,
rho_))
2678 call get_tau(ixi^
l,ixo^
l,wctprim,te,tau,sigt)
2682 btot(ixo^s,idims)=wct(ixo^s,mag(idims))+
block%B0(ixo^s,idims,0)
2684 btot(ixo^s,idims)=wct(ixo^s,mag(idims))
2687 bsum(ixo^s)=sqrt(sum(btot(ixo^s,:)**2,dim=
ndim+1))+smalldouble
2691 ixcmin^
d=ixomin^
d-
kr(idims,^
d);ixcmax^
d=ixomax^
d;
2692 jxc^
l=ixc^
l+
kr(idims,^
d);
2693 kxc^
l=jxc^
l+
kr(idims,^
d);
2694 hxc^
l=ixc^
l-
kr(idims,^
d);
2695 hxo^
l=ixo^
l-
kr(idims,^
d);
2696 tface(ixc^s)=(7.d0*(te(ixc^s)+te(jxc^s))-(te(hxc^s)+te(kxc^s)))/12.d0
2697 bunit(ixo^s)=btot(ixo^s,idims)/bsum(ixo^s)
2698 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*bunit(ixo^s)*(tface(ixo^s)-tface(hxo^s))*invdx
2700 htc_qsrc(ixo^s)=(htc_qsrc(ixo^s)+wct(ixo^s,
q_))/tau(ixo^s)
2701 w(ixo^s,
q_)=w(ixo^s,
q_)-qdt*htc_qsrc(ixo^s)
2702 end subroutine add_hypertc_source
2705 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
2707 integer,
intent(in) :: ixi^
l, ixo^
l
2708 double precision,
intent(in) :: w(ixi^s,1:nw)
2709 double precision,
intent(inout) :: jxb(ixi^s,3)
2710 double precision :: a(ixi^s,3),
b(ixi^s,3)
2712 double precision :: current(ixi^s,7-2*
ndir:3)
2713 integer :: idir, idirmin
2718 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
2722 b(ixo^s, idir) = w(ixo^s,mag(idir))
2729 a(ixo^s,idir)=current(ixo^s,idir)
2732 end subroutine get_lorentz_force
2736 subroutine rmhd_gamma2_alfven(ixI^L, ixO^L, w, gamma_A2)
2738 integer,
intent(in) :: ixi^
l, ixo^
l
2739 double precision,
intent(in) :: w(ixi^s, nw)
2740 double precision,
intent(out) :: gamma_a2(ixo^s)
2741 double precision :: rho(ixi^s)
2747 rho(ixo^s) = w(ixo^s,
rho_)
2750 gamma_a2(ixo^s) = 1.0d0/(1.0d0+
rmhd_mag_en_all(w, ixi^
l, ixo^
l)/rho(ixo^s)*inv_squared_c)
2751 end subroutine rmhd_gamma2_alfven
2755 function rmhd_gamma_alfven(w, ixI^L, ixO^L)
result(gamma_A)
2757 integer,
intent(in) :: ixi^
l, ixo^
l
2758 double precision,
intent(in) :: w(ixi^s, nw)
2759 double precision :: gamma_a(ixo^s)
2761 call rmhd_gamma2_alfven(ixi^
l, ixo^
l, w, gamma_a)
2762 gamma_a = sqrt(gamma_a)
2763 end function rmhd_gamma_alfven
2767 integer,
intent(in) :: ixi^
l, ixo^
l
2768 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
2769 double precision,
intent(out) :: rho(ixi^s)
2774 rho(ixo^s) = w(ixo^s,
rho_)
2779 subroutine rmhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
2782 integer,
intent(in) :: ixi^
l,ixo^
l, ie
2783 double precision,
intent(inout) :: w(ixi^s,1:nw)
2784 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2785 character(len=*),
intent(in) :: subname
2786 double precision :: rho(ixi^s)
2788 logical :: flag(ixi^s,1:nw)
2792 where(w(ixo^s,ie)+
block%equi_vars(ixo^s,
equi_pe0_,0)*inv_gamma_1<small_e)&
2793 flag(ixo^s,ie)=.true.
2795 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
2797 if(any(flag(ixo^s,ie)))
then
2801 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e - &
2804 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
2810 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
2813 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
2818 end subroutine rmhd_handle_small_ei
2820 subroutine rmhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
2824 integer,
intent(in) :: ixi^
l, ixo^
l
2825 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2826 double precision,
intent(inout) :: w(ixi^s,1:nw)
2828 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
2836 end subroutine rmhd_update_temperature
2839 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2841 integer,
intent(in) :: ixi^
l, ixo^
l
2842 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2843 double precision,
intent(inout) :: w(ixi^s,1:nw)
2844 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
2855 a(ixo^s,idir)=
block%J0(ixo^s,idir)
2860 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2863 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2868 if(total_energy)
then
2871 b(ixo^s,:)=wct(ixo^s,mag(:))
2880 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2883 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2887 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
2890 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
2891 end subroutine add_source_b0split
2897 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
2901 integer,
intent(in) :: ixi^
l, ixo^
l
2902 double precision,
intent(in) :: qdt
2903 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2904 double precision,
intent(inout) :: w(ixi^s,1:nw)
2905 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim,jxo^
l,hxo^
l,ix
2906 integer :: lxo^
l, kxo^
l
2907 double precision :: tmp(ixi^s),tmp2(ixi^s)
2909 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
2910 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
2914 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2915 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
2920 gradeta(ixo^s,1:
ndim)=zero
2926 gradeta(ixo^s,idim)=tmp(ixo^s)
2932 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
2937 tmp2(ixi^s)=bf(ixi^s,idir)
2939 lxo^
l=ixo^
l+2*
kr(idim,^
d);
2940 jxo^
l=ixo^
l+
kr(idim,^
d);
2941 hxo^
l=ixo^
l-
kr(idim,^
d);
2942 kxo^
l=ixo^
l-2*
kr(idim,^
d);
2943 tmp(ixo^s)=tmp(ixo^s)+&
2944 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
2948 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
2951 do jdir=1,
ndim;
do kdir=idirmin,3
2952 if (
lvc(idir,jdir,kdir)/=0)
then
2953 if (
lvc(idir,jdir,kdir)==1)
then
2954 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
2956 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
2962 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
2963 if(total_energy)
then
2964 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
2969 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
2971 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
2972 end subroutine add_source_res1
2976 subroutine add_source_res2(qdt,ixI^L,ixO^L,wCT,w,x)
2980 integer,
intent(in) :: ixi^
l, ixo^
l
2981 double precision,
intent(in) :: qdt
2982 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2983 double precision,
intent(inout) :: w(ixi^s,1:nw)
2985 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
2986 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
2987 integer :: ixa^
l,idir,idirmin,idirmin1
2990 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2991 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
2999 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
rmhd_eta
3004 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
3012 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
3015 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
3019 tmp(ixo^s)=qdt*
rmhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
3021 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
3023 if(total_energy)
then
3026 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
3027 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
3030 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
3033 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res2')
3034 end subroutine add_source_res2
3038 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
3041 integer,
intent(in) :: ixi^
l, ixo^
l
3042 double precision,
intent(in) :: qdt
3043 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3044 double precision,
intent(inout) :: w(ixi^s,1:nw)
3046 double precision :: current(ixi^s,7-2*
ndir:3)
3047 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
3048 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
3051 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3052 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
3054 tmpvec(ixa^s,1:
ndir)=zero
3056 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
3059 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3061 tmpvec(ixa^s,1:
ndir)=zero
3062 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
3065 tmpvec2(ixa^s,1:
ndir)=zero
3066 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3068 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
3070 if(total_energy)
then
3073 tmpvec2(ixa^s,1:
ndir)=zero
3074 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
3075 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
3076 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
3077 end do;
end do;
end do
3079 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
3080 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
3082 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
3083 end subroutine add_source_hyperres
3085 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
3091 integer,
intent(in) :: ixi^
l, ixo^
l
3092 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3093 double precision,
intent(inout) :: w(ixi^s,1:nw)
3094 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
3113 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
3116 if(total_energy)
then
3125 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
3132 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
3135 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
3136 end subroutine add_source_glm
3139 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
3141 integer,
intent(in) :: ixi^
l, ixo^
l
3142 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3143 double precision,
intent(inout) :: w(ixi^s,1:nw)
3144 double precision :: divb(ixi^s), ba(1:
ndir)
3145 integer :: idir, ix^
d
3150 {
do ix^db=ixomin^db,ixomax^db\}
3155 if (total_energy)
then
3161 {
do ix^db=ixomin^db,ixomax^db\}
3163 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
3165 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
3166 if (total_energy)
then
3168 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
3172 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
3173 end subroutine add_source_powel
3175 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
3179 integer,
intent(in) :: ixi^
l, ixo^
l
3180 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3181 double precision,
intent(inout) :: w(ixi^s,1:nw)
3182 double precision :: divb(ixi^s)
3183 integer :: idir, ix^
d
3187 {
do ix^db=ixomin^db,ixomax^db\}
3191 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
3192 end subroutine add_source_janhunen
3194 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
3198 integer,
intent(in) :: ixi^
l, ixo^
l
3199 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3200 double precision,
intent(inout) :: w(ixi^s,1:nw)
3201 double precision :: divb(ixi^s),graddivb(ixi^s)
3202 integer :: idim, idir, ixp^
l, i^
d, iside
3203 logical,
dimension(-1:1^D&) :: leveljump
3210 if(i^
d==0|.and.) cycle
3211 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
3212 leveljump(i^
d)=.true.
3214 leveljump(i^
d)=.false.
3222 i^dd=kr(^dd,^d)*(2*iside-3);
3223 if (leveljump(i^dd))
then
3225 ixpmin^d=ixomin^d-i^d
3227 ixpmax^d=ixomax^d-i^d
3237 select case(typegrad)
3239 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
3241 call gradientl(divb,ixi^l,ixp^l,idim,graddivb)
3244 if (slab_uniform)
then
3245 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
3247 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
3248 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
3250 w(ixp^s,mag(idim))=w(ixp^s,mag(idim))+graddivb(ixp^s)
3252 if (typedivbdiff==
'all' .and. total_energy)
then
3254 w(ixp^s,
e_)=w(ixp^s,
e_)+wct(ixp^s,mag(idim))*graddivb(ixp^s)
3257 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
3258 end subroutine add_source_linde
3263 integer,
intent(in) :: ixi^
l, ixo^
l
3264 double precision,
intent(in) :: w(ixi^s,1:nw)
3265 double precision :: divb(ixi^s), dsurface(ixi^s)
3266 double precision :: invb(ixo^s)
3267 integer :: ixa^
l,idims
3269 call get_divb(w,ixi^
l,ixo^
l,divb)
3271 where(invb(ixo^s)/=0.d0)
3272 invb(ixo^s)=1.d0/invb(ixo^s)
3275 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
3277 ixamin^
d=ixomin^
d-1;
3278 ixamax^
d=ixomax^
d-1;
3279 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
3281 ixa^
l=ixo^
l-
kr(idims,^
d);
3282 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
3284 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
3285 block%dvolume(ixo^s)/dsurface(ixo^s)
3294 integer,
intent(in) :: ixo^
l, ixi^
l
3295 double precision,
intent(in) :: w(ixi^s,1:nw)
3296 integer,
intent(out) :: idirmin
3298 double precision :: current(ixi^s,7-2*
ndir:3)
3299 integer :: idir, idirmin0
3303 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
3304 block%J0(ixo^s,idirmin0:3)
3308 subroutine rmhd_get_dt(w,ixI^L,ixO^L,dtnew,dx^D,x)
3316 integer,
intent(in) :: ixi^
l, ixo^
l
3317 double precision,
intent(inout) :: dtnew
3318 double precision,
intent(in) ::
dx^
d
3319 double precision,
intent(in) :: w(ixi^s,1:nw)
3320 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3321 double precision :: dxarr(
ndim)
3322 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
3323 integer :: idirmin,idim
3327 if (.not. dt_c)
then
3338 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
3341 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
3359 call mpistop(
'Radiation formalism unknown')
3375 end subroutine rmhd_get_dt
3378 subroutine rmhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
3381 integer,
intent(in) :: ixi^
l, ixo^
l
3382 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
3383 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3384 double precision :: tmp,tmp1,invr,cot
3386 integer :: mr_,mphi_
3387 integer :: br_,bphi_
3390 br_=mag(1); bphi_=mag(1)-1+
phi_
3393 {
do ix^db=ixomin^db,ixomax^db\}
3396 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
3401 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
3406 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
3407 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
3408 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
3409 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
3410 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
3412 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
3413 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
3414 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
3417 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
3422 {
do ix^db=ixomin^db,ixomax^db\}
3424 if(local_timestep)
then
3425 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
3430 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
3436 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
3439 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
3440 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
3444 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
3450 cot=1.d0/tan(x(ix^d,2))
3454 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3455 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
3457 if(.not.stagger_grid)
then
3458 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3460 tmp=tmp+wprim(ix^d,
psi_)*cot
3462 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3467 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3468 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
3469 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
3471 if(.not.stagger_grid)
then
3472 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3474 tmp=tmp+wprim(ix^d,
psi_)*cot
3476 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3479 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
3480 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
3481 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
3482 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
3483 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
3485 if(.not.stagger_grid)
then
3486 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
3487 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
3488 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
3489 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
3490 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
3495 end subroutine rmhd_add_source_geom
3498 subroutine rmhd_add_source_geom_split(qdt,dtfactor, ixI^L,ixO^L,wCT,wprim,w,x)
3501 integer,
intent(in) :: ixi^
l, ixo^
l
3502 double precision,
intent(in) :: qdt, dtfactor, x(ixi^s,1:
ndim)
3503 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3504 double precision :: tmp(ixi^s),tmp1(ixi^s),tmp2(ixi^s),invrho(ixo^s),invr(ixo^s)
3505 integer :: iw,idir, h1x^
l{^nooned, h2x^
l}
3506 integer :: mr_,mphi_
3507 integer :: br_,bphi_
3510 br_=mag(1); bphi_=mag(1)-1+
phi_
3514 invrho(ixo^s) = 1d0/wct(ixo^s,
rho_)
3518 invr(ixo^s) =
block%dt(ixo^s) * dtfactor/x(ixo^s,1)
3520 invr(ixo^s) = qdt/x(ixo^s,1)
3525 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp)
3527 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*(tmp(ixo^s)-&
3528 wct(ixo^s,bphi_)**2+wct(ixo^s,mphi_)**2*invrho(ixo^s))
3529 w(ixo^s,mphi_)=w(ixo^s,mphi_)+qdt*invr(ixo^s)*(&
3530 -wct(ixo^s,mphi_)*wct(ixo^s,mr_)*invrho(ixo^s) &
3531 +wct(ixo^s,bphi_)*wct(ixo^s,br_))
3533 w(ixo^s,bphi_)=w(ixo^s,bphi_)+invr(ixo^s)*&
3534 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
3535 -wct(ixo^s,br_)*wct(ixo^s,mphi_)) &
3539 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*tmp(ixo^s)
3541 if(
rmhd_glm) w(ixo^s,br_)=w(ixo^s,br_)+wct(ixo^s,
psi_)*invr(ixo^s)
3543 h1x^
l=ixo^
l-
kr(1,^
d); {^nooned h2x^
l=ixo^
l-
kr(2,^
d);}
3544 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp1)
3545 tmp(ixo^s)=tmp1(ixo^s)
3547 tmp2(ixo^s)=sum(
block%B0(ixo^s,:,0)*wct(ixo^s,mag(:)),dim=
ndim+1)
3548 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3551 tmp(ixo^s)=tmp(ixo^s)*x(ixo^s,1) &
3552 *(
block%surfaceC(ixo^s,1)-
block%surfaceC(h1x^s,1))/
block%dvolume(ixo^s)
3555 tmp(ixo^s)=tmp(ixo^s)+wct(ixo^s,
mom(idir))**2*invrho(ixo^s)-wct(ixo^s,mag(idir))**2
3556 if(
b0field) tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,idir,0)*wct(ixo^s,mag(idir))
3559 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+tmp(ixo^s)*invr(ixo^s)
3562 w(ixo^s,mag(1))=w(ixo^s,mag(1))+invr(ixo^s)*2.0d0*wct(ixo^s,
psi_)
3566 tmp(ixo^s)=tmp1(ixo^s)
3568 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3571 tmp1(ixo^s) =
block%dt(ixo^s) * tmp(ixo^s)
3573 tmp1(ixo^s) = qdt * tmp(ixo^s)
3576 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp1(ixo^s) &
3577 *(
block%surfaceC(ixo^s,2)-
block%surfaceC(h2x^s,2)) &
3578 /
block%dvolume(ixo^s)
3579 tmp(ixo^s)=-(wct(ixo^s,
mom(1))*wct(ixo^s,
mom(2))*invrho(ixo^s) &
3580 -wct(ixo^s,mag(1))*wct(ixo^s,mag(2)))
3582 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(2)) &
3583 +wct(ixo^s,mag(1))*
block%B0(ixo^s,2,0)
3586 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(3))**2*invrho(ixo^s) &
3587 -wct(ixo^s,mag(3))**2)*dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3589 tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,3,0)*wct(ixo^s,mag(3))&
3590 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3593 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp(ixo^s)*invr(ixo^s)
3596 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(2)) &
3597 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(1)))*invrho(ixo^s)
3599 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,2,0) &
3600 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,1,0))*invrho(ixo^s)
3603 tmp(ixo^s)=tmp(ixo^s) &
3604 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
3606 w(ixo^s,mag(2))=w(ixo^s,mag(2))+tmp(ixo^s)*invr(ixo^s)
3611 tmp(ixo^s)=-(wct(ixo^s,
mom(3))*wct(ixo^s,
mom(1))*invrho(ixo^s) &
3612 -wct(ixo^s,mag(3))*wct(ixo^s,mag(1))) {^nooned &
3613 -(wct(ixo^s,
mom(2))*wct(ixo^s,
mom(3))*invrho(ixo^s) &
3614 -wct(ixo^s,mag(2))*wct(ixo^s,mag(3))) &
3615 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3617 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(3)) &
3618 +wct(ixo^s,mag(1))*
block%B0(ixo^s,3,0) {^nooned &
3619 +(
block%B0(ixo^s,2,0)*wct(ixo^s,mag(3)) &
3620 +wct(ixo^s,mag(2))*
block%B0(ixo^s,3,0)) &
3621 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3623 w(ixo^s,
mom(3))=w(ixo^s,
mom(3))+tmp(ixo^s)*invr(ixo^s)
3626 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(3)) &
3627 -wct(ixo^s,
mom(3))*wct(ixo^s,mag(1)))*invrho(ixo^s) {^nooned &
3628 -(wct(ixo^s,
mom(3))*wct(ixo^s,mag(2)) &
3629 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(3)))*dcos(x(ixo^s,2)) &
3630 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3632 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,3,0) &
3633 -wct(ixo^s,
mom(3))*
block%B0(ixo^s,1,0))*invrho(ixo^s){^nooned &
3634 -(wct(ixo^s,
mom(3))*
block%B0(ixo^s,2,0) &
3635 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,3,0))*dcos(x(ixo^s,2)) &
3636 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3638 w(ixo^s,mag(3))=w(ixo^s,mag(3))+tmp(ixo^s)*invr(ixo^s)
3642 end subroutine rmhd_add_source_geom_split
3647 integer,
intent(in) :: ixi^
l, ixo^
l
3648 double precision,
intent(in) :: w(ixi^s, nw)
3649 double precision :: mge(ixo^s)
3652 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
3654 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
3658 subroutine rmhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
3661 integer,
intent(in) :: ixi^
l, ixo^
l, idir
3662 double precision,
intent(in) :: qt
3663 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
3664 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
3666 double precision :: db(ixo^s), dpsi(ixo^s)
3670 {
do ix^db=ixomin^db,ixomax^db\}
3671 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3672 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3673 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3674 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3683 {
do ix^db=ixomin^db,ixomax^db\}
3684 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
3685 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
3686 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
3687 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
3688 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3690 if(total_energy)
then
3691 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
3692 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
3694 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3696 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3699 if(total_energy)
then
3700 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
3701 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
3705 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
3706 end subroutine rmhd_modify_wlr
3708 subroutine rmhd_boundary_adjust(igrid,psb)
3710 integer,
intent(in) :: igrid
3712 integer :: ib, idims, iside, ixo^
l, i^
d
3721 i^
d=
kr(^
d,idims)*(2*iside-3);
3722 if (neighbor_type(i^
d,igrid)/=1) cycle
3723 ib=(idims-1)*2+iside
3741 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
3745 end subroutine rmhd_boundary_adjust
3747 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
3749 integer,
intent(in) :: ixg^
l,ixo^
l,ib
3750 double precision,
intent(inout) :: w(ixg^s,1:nw)
3751 double precision,
intent(in) :: x(ixg^s,1:
ndim)
3752 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
3753 integer :: ix^
d,ixf^
l
3766 do ix1=ixfmax1,ixfmin1,-1
3767 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
3768 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3769 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3772 do ix1=ixfmax1,ixfmin1,-1
3773 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
3774 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
3775 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3776 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3777 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3778 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3779 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3793 do ix1=ixfmax1,ixfmin1,-1
3794 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3795 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3796 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3797 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3798 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3799 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3802 do ix1=ixfmax1,ixfmin1,-1
3803 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3804 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3805 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3806 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3807 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3808 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3809 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3810 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3811 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3812 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3813 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3814 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3815 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3816 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3817 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3818 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3819 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3820 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3834 do ix1=ixfmin1,ixfmax1
3835 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
3836 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3837 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3840 do ix1=ixfmin1,ixfmax1
3841 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
3842 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
3843 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3844 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3845 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3846 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3847 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3861 do ix1=ixfmin1,ixfmax1
3862 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3863 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3864 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3865 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3866 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3867 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3870 do ix1=ixfmin1,ixfmax1
3871 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3872 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3873 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3874 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3875 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3876 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3877 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3878 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3879 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3880 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3881 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3882 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3883 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3884 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3885 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3886 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3887 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3888 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3902 do ix2=ixfmax2,ixfmin2,-1
3903 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
3904 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3905 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3908 do ix2=ixfmax2,ixfmin2,-1
3909 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
3910 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
3911 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3912 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3913 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3914 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3915 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3929 do ix2=ixfmax2,ixfmin2,-1
3930 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3931 ix2+1,ixfmin3:ixfmax3,mag(2)) &
3932 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
3933 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
3934 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
3935 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
3938 do ix2=ixfmax2,ixfmin2,-1
3939 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
3940 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
3941 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
3942 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
3943 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
3944 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3945 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
3946 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
3947 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3948 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
3949 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
3950 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
3951 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
3952 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
3953 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3954 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
3955 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
3956 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
3970 do ix2=ixfmin2,ixfmax2
3971 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
3972 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3973 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3976 do ix2=ixfmin2,ixfmax2
3977 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
3978 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
3979 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3980 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3981 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3982 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3983 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3997 do ix2=ixfmin2,ixfmax2
3998 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3999 ix2-1,ixfmin3:ixfmax3,mag(2)) &
4000 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
4001 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
4002 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
4003 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
4006 do ix2=ixfmin2,ixfmax2
4007 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
4008 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
4009 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
4010 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
4011 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
4012 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4013 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
4014 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
4015 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4016 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
4017 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
4018 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
4019 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
4020 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
4021 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
4022 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
4023 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
4024 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4041 do ix3=ixfmax3,ixfmin3,-1
4042 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
4043 ixfmin2:ixfmax2,ix3+1,mag(3)) &
4044 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4045 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4046 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4047 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4050 do ix3=ixfmax3,ixfmin3,-1
4051 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
4052 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
4053 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4054 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
4055 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4056 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4057 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4058 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4059 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4060 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4061 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4062 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4063 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4064 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4065 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4066 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4067 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
4068 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4083 do ix3=ixfmin3,ixfmax3
4084 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
4085 ixfmin2:ixfmax2,ix3-1,mag(3)) &
4086 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4087 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4088 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4089 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4092 do ix3=ixfmin3,ixfmax3
4093 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
4094 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
4095 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4096 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
4097 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4098 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4099 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4100 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4101 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4102 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4103 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4104 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4105 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4106 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4107 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4108 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4109 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
4110 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4116 call mpistop(
"Special boundary is not defined for this region")
4118 end subroutine fixdivb_boundary
4126 double precision,
intent(in) :: qdt
4127 double precision,
intent(in) :: qt
4128 logical,
intent(inout) :: active
4130 integer,
parameter :: max_its = 50
4131 double precision :: residual_it(max_its), max_divb
4132 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
4133 double precision :: res
4134 double precision,
parameter :: max_residual = 1
d-3
4135 double precision,
parameter :: residual_reduction = 1
d-10
4136 integer :: iigrid, igrid
4137 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
4140 mg%operator_type = mg_laplacian
4147 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4148 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4151 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
4152 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4154 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4155 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4158 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4159 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4163 write(*,*)
"rmhd_clean_divb_multigrid warning: unknown boundary type"
4164 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4165 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4172 do iigrid = 1, igridstail
4173 igrid = igrids(iigrid);
4176 lvl =
mg%boxes(id)%lvl
4177 nc =
mg%box_size_lvl(lvl)
4183 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
4185 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
4186 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
4191 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
4194 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
4195 if (
mype == 0) print *,
"iteration vs residual"
4198 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
4199 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
4200 if (residual_it(n) < residual_reduction * max_divb)
exit
4202 if (
mype == 0 .and. n > max_its)
then
4203 print *,
"divb_multigrid warning: not fully converged"
4204 print *,
"current amplitude of divb: ", residual_it(max_its)
4205 print *,
"multigrid smallest grid: ", &
4206 mg%domain_size_lvl(:,
mg%lowest_lvl)
4207 print *,
"note: smallest grid ideally has <= 8 cells"
4208 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
4209 print *,
"note: dx/dy/dz should be similar"
4213 call mg_fas_vcycle(
mg, max_res=res)
4214 if (res < max_residual)
exit
4216 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
4220 do iigrid = 1, igridstail
4221 igrid = igrids(iigrid);
4228 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
4231 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
4233 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
4235 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
4248 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
4249 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
4251 if(total_energy)
then
4253 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
4256 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
4264 subroutine rmhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4268 integer,
intent(in) :: ixi^
l, ixo^
l
4269 double precision,
intent(in) :: qt,qdt
4271 double precision,
intent(in) :: wp(ixi^s,1:nw)
4272 type(state) :: sct, s
4273 type(ct_velocity) :: vcts
4274 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4275 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4277 double precision :: circ(ixi^s,1:
ndim)
4279 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4280 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
4281 integer :: idim1,idim2,idir,iwdim1,iwdim2
4283 associate(bfaces=>s%ws,x=>s%x)
4290 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4294 i1kr^
d=
kr(idim1,^
d);
4297 i2kr^
d=
kr(idim2,^
d);
4300 if (
lvc(idim1,idim2,idir)==1)
then
4302 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4304 {
do ix^db=ixcmin^db,ixcmax^db\}
4305 fe(ix^
d,idir)=quarter*&
4306 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
4307 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
4309 if(
rmhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
4311 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
4319 if(
associated(usr_set_electric_field)) &
4320 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4322 circ(ixi^s,1:ndim)=zero
4327 ixcmin^d=ixomin^d-kr(idim1,^d);
4329 ixa^l=ixc^l-kr(idim2,^d);
4332 if(lvc(idim1,idim2,idir)==1)
then
4334 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4337 else if(lvc(idim1,idim2,idir)==-1)
then
4339 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4345 {
do ix^db=ixcmin^db,ixcmax^db\}
4347 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4349 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4356 end subroutine rmhd_update_faces_average
4359 subroutine rmhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4364 integer,
intent(in) :: ixi^
l, ixo^
l
4365 double precision,
intent(in) :: qt, qdt
4367 double precision,
intent(in) :: wp(ixi^s,1:nw)
4368 type(state) :: sct, s
4369 type(ct_velocity) :: vcts
4370 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4371 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4373 double precision :: circ(ixi^s,1:
ndim)
4375 double precision :: ecc(ixi^s,
sdim:3)
4376 double precision :: ein(ixi^s,
sdim:3)
4378 double precision :: el(ixi^s),er(ixi^s)
4380 double precision :: elc,erc
4382 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4384 double precision :: jce(ixi^s,
sdim:3)
4386 double precision :: xs(ixgs^t,1:
ndim)
4387 double precision :: gradi(ixgs^t)
4388 integer :: ixc^
l,ixa^
l
4389 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
4391 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
4394 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4397 {
do ix^db=iximin^db,iximax^db\}
4400 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_)
4401 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_)
4402 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_)
4405 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
4412 {
do ix^db=iximin^db,iximax^db\}
4415 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
4416 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
4417 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4420 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4434 i1kr^d=kr(idim1,^d);
4437 i2kr^d=kr(idim2,^d);
4440 if (lvc(idim1,idim2,idir)==1)
then
4442 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4445 {
do ix^db=ixcmin^db,ixcmax^db\}
4446 fe(ix^d,idir)=quarter*&
4447 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
4448 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
4453 ixamax^d=ixcmax^d+i1kr^d;
4454 {
do ix^db=ixamin^db,ixamax^db\}
4455 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
4456 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
4459 do ix^db=ixcmin^db,ixcmax^db\}
4460 if(vnorm(ix^d,idim1)>0.d0)
then
4462 else if(vnorm(ix^d,idim1)<0.d0)
then
4463 elc=el({ix^d+i1kr^d})
4465 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
4467 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
4469 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
4470 erc=er({ix^d+i1kr^d})
4472 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
4474 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4479 ixamax^d=ixcmax^d+i2kr^d;
4480 {
do ix^db=ixamin^db,ixamax^db\}
4481 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
4482 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
4485 do ix^db=ixcmin^db,ixcmax^db\}
4486 if(vnorm(ix^d,idim2)>0.d0)
then
4488 else if(vnorm(ix^d,idim2)<0.d0)
then
4489 elc=el({ix^d+i2kr^d})
4491 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
4493 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
4495 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
4496 erc=er({ix^d+i2kr^d})
4498 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
4500 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4504 if(
rmhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
4506 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
4520 if (lvc(idim1,idim2,idir)==0) cycle
4522 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4523 ixamax^d=ixcmax^d-kr(idir,^d)+1;
4526 xs(ixa^s,:)=x(ixa^s,:)
4527 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
4528 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
4529 if (lvc(idim1,idim2,idir)==1)
then
4530 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4532 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4539 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4541 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
4545 {
do ix^db=ixomin^db,ixomax^db\}
4546 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4547 +ein(ix1,ix2-1,ix3-1,idir))
4548 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4549 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4551 else if(idir==2)
then
4552 {
do ix^db=ixomin^db,ixomax^db\}
4553 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4554 +ein(ix1-1,ix2,ix3-1,idir))
4555 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4556 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4559 {
do ix^db=ixomin^db,ixomax^db\}
4560 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
4561 +ein(ix1-1,ix2-1,ix3,idir))
4562 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4563 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4569 {
do ix^db=ixomin^db,ixomax^db\}
4570 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
4571 +ein(ix1-1,ix2-1,idir))
4572 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4573 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4578 block%w(ixo^s,nw)=block%w(ixo^s,nw)+jce(ixo^s,idir)
4584 if(
associated(usr_set_electric_field)) &
4585 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4587 circ(ixi^s,1:ndim)=zero
4592 ixcmin^d=ixomin^d-kr(idim1,^d);
4594 ixa^l=ixc^l-kr(idim2,^d);
4597 if(lvc(idim1,idim2,idir)==1)
then
4599 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4602 else if(lvc(idim1,idim2,idir)==-1)
then
4604 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4610 {
do ix^db=ixcmin^db,ixcmax^db\}
4612 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4614 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4621 end subroutine rmhd_update_faces_contact
4624 subroutine rmhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4629 integer,
intent(in) :: ixi^
l, ixo^
l
4630 double precision,
intent(in) :: qt, qdt
4632 double precision,
intent(in) :: wp(ixi^s,1:nw)
4633 type(state) :: sct, s
4634 type(ct_velocity) :: vcts
4635 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4636 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4638 double precision :: vtill(ixi^s,2)
4639 double precision :: vtilr(ixi^s,2)
4640 double precision :: bfacetot(ixi^s,
ndim)
4641 double precision :: btill(ixi^s,
ndim)
4642 double precision :: btilr(ixi^s,
ndim)
4643 double precision :: cp(ixi^s,2)
4644 double precision :: cm(ixi^s,2)
4645 double precision :: circ(ixi^s,1:
ndim)
4647 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4648 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
4649 integer :: idim1,idim2,idir,ix^
d
4651 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
4652 cbarmax=>vcts%cbarmax)
4665 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4678 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
4682 idim2=mod(idir+1,3)+1
4684 jxc^
l=ixc^
l+
kr(idim1,^
d);
4685 ixcp^
l=ixc^
l+
kr(idim2,^
d);
4689 vtill(ixi^s,2),vtilr(ixi^s,2))
4692 vtill(ixi^s,1),vtilr(ixi^s,1))
4698 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
4699 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
4701 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
4702 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
4705 btill(ixi^s,idim1),btilr(ixi^s,idim1))
4708 btill(ixi^s,idim2),btilr(ixi^s,idim2))
4712 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
4713 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
4715 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
4716 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
4720 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
4721 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
4722 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
4723 /(cp(ixc^s,1)+cm(ixc^s,1)) &
4724 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
4725 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
4726 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
4727 /(cp(ixc^s,2)+cm(ixc^s,2))
4730 if(
rmhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
4731 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
4745 circ(ixi^s,1:
ndim)=zero
4750 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
4754 if(
lvc(idim1,idim2,idir)/=0)
then
4755 hxc^
l=ixc^
l-
kr(idim2,^
d);
4757 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4758 +
lvc(idim1,idim2,idir)&
4764 {
do ix^db=ixcmin^db,ixcmax^db\}
4766 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
4768 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
4774 end subroutine rmhd_update_faces_hll
4777 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
4782 integer,
intent(in) :: ixi^
l, ixo^
l
4784 double precision,
intent(in) :: wp(ixi^s,1:nw)
4785 type(state),
intent(in) :: sct, s
4787 double precision :: jce(ixi^s,
sdim:3)
4790 double precision :: jcc(ixi^s,7-2*
ndir:3)
4792 double precision :: xs(ixgs^t,1:
ndim)
4794 double precision :: eta(ixi^s)
4795 double precision :: gradi(ixgs^t)
4796 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
4798 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
4804 if (
lvc(idim1,idim2,idir)==0) cycle
4806 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4807 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
4810 xs(ixb^s,:)=x(ixb^s,:)
4811 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
4812 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
4813 if (
lvc(idim1,idim2,idir)==1)
then
4814 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4816 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4831 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4832 jcc(ixc^s,idir)=0.d0
4834 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4835 ixamin^
d=ixcmin^
d+ix^
d;
4836 ixamax^
d=ixcmax^
d+ix^
d;
4837 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
4839 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
4840 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
4845 end subroutine get_resistive_electric_field
4851 integer,
intent(in) :: ixo^
l
4860 do ix^db=ixomin^db,ixomax^db\}
4862 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4863 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
4864 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4865 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
4866 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
4867 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
4870 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4871 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
4872 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4873 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
4913 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
4914 double precision,
intent(inout) :: ws(ixis^s,1:nws)
4915 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4916 double precision :: adummy(ixis^s,1:3)
4921 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
4924 integer,
intent(in) :: ixi^
l, ixo^
l
4925 double precision,
intent(in) :: w(ixi^s,1:nw)
4926 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4927 double precision,
intent(out):: rfactor(ixi^s)
4928 double precision :: iz_h(ixo^s),iz_he(ixo^s)
4932 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)
4933 end subroutine rfactor_from_temperature_ionization
4935 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
4937 integer,
intent(in) :: ixi^
l, ixo^
l
4938 double precision,
intent(in) :: w(ixi^s,1:nw)
4939 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4940 double precision,
intent(out):: rfactor(ixi^s)
4943 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, wctprim, x, ixil, ixol, primitives_filled)
Calculates cell-centered diffusion coefficient to be used in multigrid.
subroutine, public add_afld_rad_force(qdt, ixil, ixol, wct, wctprim, 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_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
get dt limit for radiation force: NOTE: only uniform cartesian here!
subroutine, public afld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
subroutine, public afld_init(he_abundance, afld_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
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_init(phys_gamma)
Initialize the module.
subroutine cak_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
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 with updates by RK (16/03/2026) Module for including flux limited diffusion (FLD)-appro...
subroutine, public fld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor NOTE: w is primitive on entry.
subroutine, public fld_get_diffcoef_central(w, wct, wctprim, x, ixil, ixol, primitives_filled)
Calculates cell-centered diffusion coefficient to be used in multigrid.
subroutine, public add_fld_rad_force(qdt, ixil, ixol, wct, wctprim, 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_init(he_abundance, r_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
get dt limit for radiation force: NOTE: only uniform cartesian here!
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
spatial steps for all dimensions at all levels
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(wprim, ixil, ixol, dtnew, dxd, x)
subroutine gravity_init()
Initialize the module.
subroutine gravity_add_source(qdt, ixil, ixol, wct, wctprim, w, x, energy, 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.
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 which can be used for multiple source terms in the governing equatio...
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 explicit timestep for the TC (mhd implementation) Note: for multi-D MHD (1D MHD will use HD f...
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_init(phys_wider_stencil)
Initialize the module.
subroutine viscosity_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
procedure(sub_add_source), pointer, public viscosity_add_source
The data structure that contains information about a tree node/grid block.