27 double precision,
protected :: small_e
29 double precision,
public,
protected ::
small_r_e = 0.d0
38 double precision :: divbdiff = 0.8d0
43 double precision,
public,
protected ::
h_ion_fr=1d0
46 double precision,
public,
protected ::
he_ion_fr=1d0
53 double precision,
public,
protected ::
rr=1d0
55 double precision :: gamma_1, inv_gamma_1
57 double precision :: inv_squared_c0, inv_squared_c
64 integer,
public,
protected ::
rho_
66 integer,
allocatable,
public,
protected ::
mom(:)
68 integer,
public,
protected :: ^
c&m^C_
70 integer,
public,
protected ::
e_
72 integer,
public,
protected ::
r_e
74 integer,
public,
protected :: ^
c&b^C_
76 integer,
public,
protected ::
p_
78 integer,
public,
protected ::
q_
80 integer,
public,
protected ::
psi_
82 integer,
public,
protected ::
te_
87 integer,
allocatable,
public,
protected ::
tracer(:)
95 integer,
parameter :: divb_none = 0
96 integer,
parameter :: divb_multigrid = -1
97 integer,
parameter :: divb_glm = 1
98 integer,
parameter :: divb_powel = 2
99 integer,
parameter :: divb_janhunen = 3
100 integer,
parameter :: divb_linde = 4
101 integer,
parameter :: divb_lindejanhunen = 5
102 integer,
parameter :: divb_lindepowel = 6
103 integer,
parameter :: divb_lindeglm = 7
104 integer,
parameter :: divb_ct = 8
145 logical :: compactres = .false.
163 logical,
protected :: radio_acoustic_filter = .false.
164 integer,
protected :: size_ra_filter = 1
168 logical :: dt_c = .false.
178 logical :: total_energy = .true.
182 logical :: gravity_energy
184 logical :: gravity_rhov = .false.
186 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
188 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
190 character(len=std_len) :: typedivbdiff =
'all'
230 subroutine rmhd_read_params(files)
233 character(len=*),
intent(in) :: files(:)
251 do n = 1,
size(files)
252 open(
unitpar, file=trim(files(n)), status=
"old")
253 read(
unitpar, rmhd_list,
end=111)
257 end subroutine rmhd_read_params
260 subroutine rmhd_write_info(fh)
262 integer,
intent(in) :: fh
264 integer,
parameter :: n_par = 1
265 double precision :: values(n_par)
266 integer,
dimension(MPI_STATUS_SIZE) :: st
267 character(len=name_len) :: names(n_par)
269 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
273 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
274 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
275 end subroutine rmhd_write_info
301 if(
mype==0)
write(*,*)
'WARNING: set rmhd_partial_ionization=F when eq_state_units=F'
307 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
310 physics_type =
"rmhd"
325 phys_total_energy=total_energy
327 gravity_energy=.true.
332 gravity_energy=.false.
338 if(
mype==0)
write(*,*)
'WARNING: reset rmhd_trac_type=1 for 1D simulation'
343 if(
mype==0)
write(*,*)
'WARNING: set rmhd_trac_mask==bigdouble for global TRAC method'
352 type_divb = divb_none
355 type_divb = divb_multigrid
357 mg%operator_type = mg_laplacian
364 case (
'powel',
'powell')
365 type_divb = divb_powel
367 type_divb = divb_janhunen
369 type_divb = divb_linde
370 case (
'lindejanhunen')
371 type_divb = divb_lindejanhunen
373 type_divb = divb_lindepowel
377 type_divb = divb_lindeglm
382 call mpistop(
'Unknown divB fix')
385 allocate(start_indices(number_species),stop_indices(number_species))
392 mom(:) = var_set_momentum(
ndir)
398 e_ = var_set_energy()
407 mag(:) = var_set_bfield(
ndir)
411 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
417 r_e = var_set_radiation_energy()
430 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
443 te_ = var_set_auxvar(
'Te',
'Te')
452 stop_indices(1)=nwflux
482 allocate(iw_vector(nvector))
483 iw_vector(1) = mom(1) - 1
484 iw_vector(2) = mag(1) - 1
487 if (.not.
allocated(flux_type))
then
488 allocate(flux_type(
ndir, nwflux))
489 flux_type = flux_default
490 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
491 call mpistop(
"phys_check error: flux_type has wrong shape")
494 if(nwflux>mag(
ndir))
then
496 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
501 flux_type(:,
psi_)=flux_special
503 flux_type(idir,mag(idir))=flux_special
507 flux_type(idir,mag(idir))=flux_tvdlf
513 phys_get_dt => rmhd_get_dt
514 phys_get_cmax => rmhd_get_cmax_origin
515 phys_get_a2max => rmhd_get_a2max
516 phys_get_tcutoff => rmhd_get_tcutoff
517 phys_get_h_speed => rmhd_get_h_speed
519 phys_get_cbounds => rmhd_get_cbounds_split_rho
521 phys_get_cbounds => rmhd_get_cbounds
524 phys_to_primitive => rmhd_to_primitive_split_rho
526 phys_to_conserved => rmhd_to_conserved_split_rho
529 phys_to_primitive => rmhd_to_primitive_origin
531 phys_to_conserved => rmhd_to_conserved_origin
535 phys_get_flux => rmhd_get_flux_split
537 phys_get_flux => rmhd_get_flux
541 phys_add_source_geom => rmhd_add_source_geom_split
543 phys_add_source_geom => rmhd_add_source_geom
545 phys_add_source => rmhd_add_source
546 phys_check_params => rmhd_check_params
547 phys_write_info => rmhd_write_info
549 phys_handle_small_values => rmhd_handle_small_values_origin
550 rmhd_handle_small_values => rmhd_handle_small_values_origin
551 phys_check_w => rmhd_check_w_origin
557 phys_get_pthermal => rmhd_get_pthermal_origin
561 phys_set_equi_vars => set_equi_vars_grid
564 if(type_divb==divb_glm)
then
565 phys_modify_wlr => rmhd_modify_wlr
570 rmhd_get_rfactor=>rfactor_from_temperature_ionization
571 phys_update_temperature => rmhd_update_temperature
575 rmhd_get_rfactor=>rfactor_from_constant_ionization
592 transverse_ghost_cells = 1
593 phys_get_ct_velocity => rmhd_get_ct_velocity_average
594 phys_update_faces => rmhd_update_faces_average
596 transverse_ghost_cells = 1
597 phys_get_ct_velocity => rmhd_get_ct_velocity_contact
598 phys_update_faces => rmhd_update_faces_contact
600 transverse_ghost_cells = 2
601 phys_get_ct_velocity => rmhd_get_ct_velocity_hll
602 phys_update_faces => rmhd_update_faces_hll
604 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
607 phys_modify_wlr => rmhd_modify_wlr
609 phys_boundary_adjust => rmhd_boundary_adjust
618 call rmhd_physical_units()
627 call mpistop(
'Radiation formalism unknown')
634 call mpistop(
"thermal conduction needs rmhd_energy=T")
637 call mpistop(
"hyperbolic thermal conduction needs rmhd_energy=T")
647 call add_sts_method(rmhd_get_tc_dt_rmhd,rmhd_sts_set_source_tc_rmhd,e_,1,e_,1,.false.)
649 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot_with_equi
651 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot
654 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint_with_equi
656 tc_fl%has_equi = .true.
657 tc_fl%get_temperature_equi => rmhd_get_temperature_equi
658 tc_fl%get_rho_equi => rmhd_get_rho_equi
660 tc_fl%has_equi = .false.
663 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint
675 te_fl_rmhd%get_var_Rfactor => rmhd_get_rfactor
677 phys_te_images => rmhd_te_images
690 if (particles_eta < zero) particles_eta =
rmhd_eta
691 if (particles_etah < zero) particles_eta =
rmhd_etah
693 write(*,*)
'*****Using particles: with rmhd_eta, rmhd_etah :',
rmhd_eta,
rmhd_etah
694 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
706 subroutine rmhd_te_images
711 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
713 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
715 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
717 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
720 call mpistop(
"Error in synthesize emission: Unknown convert_type")
722 end subroutine rmhd_te_images
728 subroutine rmhd_sts_set_source_tc_rmhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
732 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
733 double precision,
intent(in) :: x(ixi^s,1:
ndim)
734 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
735 double precision,
intent(in) :: my_dt
736 logical,
intent(in) :: fix_conserve_at_step
738 end subroutine rmhd_sts_set_source_tc_rmhd
740 function rmhd_get_tc_dt_rmhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
746 integer,
intent(in) :: ixi^
l, ixo^
l
747 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
748 double precision,
intent(in) :: w(ixi^s,1:nw)
749 double precision :: dtnew
752 end function rmhd_get_tc_dt_rmhd
754 subroutine rmhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
756 integer,
intent(in) :: ixi^
l,ixo^
l
757 double precision,
intent(inout) :: w(ixi^s,1:nw)
758 double precision,
intent(in) :: x(ixi^s,1:
ndim)
759 integer,
intent(in) :: step
760 character(len=140) :: error_msg
762 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
763 call rmhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
764 end subroutine rmhd_tc_handle_small_e
767 subroutine tc_params_read_rmhd(fl)
769 type(tc_fluid),
intent(inout) :: fl
770 double precision :: tc_k_para=0d0
771 double precision :: tc_k_perp=0d0
774 logical :: tc_perpendicular=.false.
775 logical :: tc_saturate=.false.
776 character(len=std_len) :: tc_slope_limiter=
"MC"
778 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp
782 read(
unitpar, tc_list,
end=111)
786 fl%tc_perpendicular = tc_perpendicular
787 fl%tc_saturate = tc_saturate
788 fl%tc_k_para = tc_k_para
789 fl%tc_k_perp = tc_k_perp
790 select case(tc_slope_limiter)
792 fl%tc_slope_limiter = 0
795 fl%tc_slope_limiter = 1
798 fl%tc_slope_limiter = 2
801 fl%tc_slope_limiter = 3
804 fl%tc_slope_limiter = 4
806 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod")
808 end subroutine tc_params_read_rmhd
812 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
815 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
816 double precision,
intent(in) :: x(ixi^s,1:
ndim)
817 double precision :: delx(ixi^s,1:
ndim)
818 double precision :: xc(ixi^s,1:
ndim),xshift^
d
819 integer :: idims, ixc^
l, hxo^
l, ix, idims2
825 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
829 hxo^
l=ixo^
l-
kr(idims,^
d);
835 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
838 xshift^
d=half*(one-
kr(^
d,idims));
845 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
849 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
851 end subroutine set_equi_vars_grid_faces
854 subroutine set_equi_vars_grid(igrid)
857 integer,
intent(in) :: igrid
863 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
864 end subroutine set_equi_vars_grid
867 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
869 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
870 double precision,
intent(in) :: w(ixi^s, 1:nw)
871 double precision,
intent(in) :: x(ixi^s,1:
ndim)
872 double precision :: wnew(ixo^s, 1:nwc)
879 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
885 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
889 wnew(ixo^s,
e_)=w(ixo^s,
e_)
893 if(
b0field .and. total_energy)
then
894 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
895 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
898 end function convert_vars_splitting
900 subroutine rmhd_check_params
908 if (
rmhd_gamma <= 0.0d0)
call mpistop (
"Error: rmhd_gamma <= 0")
909 if (
rmhd_adiab < 0.0d0)
call mpistop (
"Error: rmhd_adiab < 0")
913 call mpistop (
"Error: rmhd_gamma <= 0 or rmhd_gamma == 1")
914 inv_gamma_1=1.d0/gamma_1
921 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
926 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
933 end subroutine rmhd_check_params
947 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
948 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
951 mg%bc(ib, mg_iphi)%bc_type = mg_bc_dirichlet
952 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
956 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
957 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
965 call mpistop(
"divE_multigrid warning: unknown b.c. ")
970 subroutine rmhd_physical_units()
972 double precision :: mp,kb,miu0,c_lightspeed
973 double precision :: a,
b
1118 end subroutine rmhd_physical_units
1120 subroutine rmhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1122 logical,
intent(in) :: primitive
1123 integer,
intent(in) :: ixi^
l, ixo^
l
1124 double precision,
intent(in) :: w(ixi^s,nw)
1125 logical,
intent(inout) :: flag(ixi^s,1:nw)
1126 double precision :: tmp
1130 {
do ix^db=ixomin^db,ixomax^db\}
1144 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1148 if(tmp<small_e) flag(ix^
d,
e_) = .true.
1153 end subroutine rmhd_check_w_origin
1156 subroutine rmhd_to_conserved_origin(ixI^L,ixO^L,w,x)
1158 integer,
intent(in) :: ixi^
l, ixo^
l
1159 double precision,
intent(inout) :: w(ixi^s, nw)
1160 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1163 {
do ix^db=ixomin^db,ixomax^db\}
1165 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1167 +(^
c&w(ix^
d,
b^
c_)**2+))
1171 end subroutine rmhd_to_conserved_origin
1174 subroutine rmhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
1176 integer,
intent(in) :: ixi^
l, ixo^
l
1177 double precision,
intent(inout) :: w(ixi^s, nw)
1178 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1179 double precision :: rho
1182 {
do ix^db=ixomin^db,ixomax^db\}
1185 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1186 +half*((^
c&w(ix^
d,
m^
c_)**2+)*rho&
1187 +(^
c&w(ix^
d,
b^
c_)**2+))
1191 end subroutine rmhd_to_conserved_split_rho
1194 subroutine rmhd_to_primitive_origin(ixI^L,ixO^L,w,x)
1196 integer,
intent(in) :: ixi^
l, ixo^
l
1197 double precision,
intent(inout) :: w(ixi^s, nw)
1198 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1199 double precision :: inv_rho
1204 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_origin')
1207 {
do ix^db=ixomin^db,ixomax^db\}
1208 inv_rho = 1.d0/w(ix^
d,
rho_)
1212 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1214 +(^
c&w(ix^
d,
b^
c_)**2+)))
1216 end subroutine rmhd_to_primitive_origin
1219 subroutine rmhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
1221 integer,
intent(in) :: ixi^
l, ixo^
l
1222 double precision,
intent(inout) :: w(ixi^s, nw)
1223 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1224 double precision :: inv_rho
1229 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_split_rho')
1232 {
do ix^db=ixomin^db,ixomax^db\}
1237 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1239 (^
c&w(ix^
d,
m^
c_)**2+)+(^
c&w(ix^
d,
b^
c_)**2+)))
1241 end subroutine rmhd_to_primitive_split_rho
1246 integer,
intent(in) :: ixi^
l, ixo^
l
1247 double precision,
intent(inout) :: w(ixi^s, nw)
1248 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1253 {
do ix^db=ixomin^db,ixomax^db\}
1256 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1258 +(^
c&w(ix^
d,
b^
c_)**2+))
1261 {
do ix^db=ixomin^db,ixomax^db\}
1263 w(ix^d,
e_)=w(ix^d,
e_)&
1264 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1265 +(^
c&w(ix^d,
b^
c_)**2+))
1273 integer,
intent(in) :: ixi^
l, ixo^
l
1274 double precision,
intent(inout) :: w(ixi^s, nw)
1275 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1280 {
do ix^db=ixomin^db,ixomax^db\}
1283 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1285 +(^
c&w(ix^
d,
b^
c_)**2+))
1288 {
do ix^db=ixomin^db,ixomax^db\}
1290 w(ix^d,
e_)=w(ix^d,
e_)&
1291 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1292 +(^
c&w(ix^d,
b^
c_)**2+))
1296 if(fix_small_values)
then
1297 call rmhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'rmhd_e_to_ei')
1301 subroutine rmhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
1304 logical,
intent(in) :: primitive
1305 integer,
intent(in) :: ixi^
l,ixo^
l
1306 double precision,
intent(inout) :: w(ixi^s,1:nw)
1307 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1308 character(len=*),
intent(in) :: subname
1309 double precision :: rho
1310 integer :: idir, ix^
d
1311 logical :: flag(ixi^s,1:nw)
1313 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
1317 {
do ix^db=ixomin^db,ixomax^db\}
1327 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
1339 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))&
1343 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))
1350 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
1352 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
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+))
1364 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
1366 {
do ix^db=iximin^db,iximax^db\}
1372 w(ix^d,
e_)=w(ix^d,
e_)&
1373 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1376 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
1378 if(.not.primitive)
then
1381 {
do ix^db=iximin^db,iximax^db\}
1387 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
1388 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
1389 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+)))
1392 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
1395 end subroutine rmhd_handle_small_values_origin
1400 integer,
intent(in) :: ixi^
l, ixo^
l
1401 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
1402 double precision,
intent(out) :: v(ixi^s,
ndir)
1403 double precision :: rho(ixi^s)
1407 rho(ixo^s)=1.d0/rho(ixo^s)
1410 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
1415 subroutine rmhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
1417 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1418 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1419 double precision,
intent(inout) :: cmax(ixi^s)
1420 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1424 {
do ix^db=ixomin^db,ixomax^db \}
1435 cfast2=b2*inv_rho+cmax(ix^
d)
1436 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
1437 if(avmincs2<zero) avmincs2=zero
1438 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1439 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
1442 {
do ix^db=ixomin^db,ixomax^db \}
1452 b2=(^
c&w(ix^d,
b^
c_)**2+)
1453 cfast2=b2*inv_rho+cmax(ix^d)
1454 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1455 if(avmincs2<zero) avmincs2=zero
1456 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1457 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
1460 end subroutine rmhd_get_cmax_origin
1462 subroutine rmhd_get_a2max(w,x,ixI^L,ixO^L,a2max)
1464 integer,
intent(in) :: ixi^
l, ixo^
l
1465 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1466 double precision,
intent(inout) :: a2max(
ndim)
1467 double precision :: a2(ixi^s,
ndim,nw)
1468 integer :: gxo^
l,hxo^
l,jxo^
l,kxo^
l,i,j
1473 hxo^
l=ixo^
l-
kr(i,^
d);
1474 gxo^
l=hxo^
l-
kr(i,^
d);
1475 jxo^
l=ixo^
l+
kr(i,^
d);
1476 kxo^
l=jxo^
l+
kr(i,^
d);
1477 a2(ixo^s,i,1:nw)=abs(-w(kxo^s,1:nw)+16.d0*w(jxo^s,1:nw)&
1478 -30.d0*w(ixo^s,1:nw)+16.d0*w(hxo^s,1:nw)-w(gxo^s,1:nw))
1479 a2max(i)=maxval(a2(ixo^s,i,1:nw))/12.d0/
dxlevel(i)**2
1481 end subroutine rmhd_get_a2max
1484 subroutine rmhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
1487 integer,
intent(in) :: ixi^
l,ixo^
l
1488 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1489 double precision,
intent(out) :: tco_local,tmax_local
1491 double precision,
intent(inout) :: w(ixi^s,1:nw)
1492 double precision,
parameter :: trac_delta=0.25d0
1493 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s)
1494 double precision,
dimension(ixI^S,1:ndir) :: bunitvec
1495 double precision,
dimension(ixI^S,1:ndim) :: gradt
1496 double precision :: bdir(
ndim)
1497 double precision :: ltrc,ltrp,altr(ixi^s)
1498 integer :: idims,jxo^
l,hxo^
l,ixa^
d,ixb^
d,ix^
d
1499 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
1500 logical :: lrlt(ixi^s)
1503 call rmhd_get_temperature_from_te(w,x,ixi^
l,ixi^
l,te)
1505 call rmhd_get_rfactor(w,x,ixi^
l,ixi^
l,te)
1506 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
1509 tmax_local=maxval(te(ixo^s))
1519 lts(ixo^s)=0.5d0*abs(te(jxo^s)-te(hxo^s))/te(ixo^s)
1521 where(lts(ixo^s) > trac_delta)
1524 if(any(lrlt(ixo^s)))
then
1525 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
1536 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
1537 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1538 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
1539 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
1541 call mpistop(
"rmhd_trac_type not allowed for 1D simulation")
1553 gradt(ixo^s,idims)=tmp1(ixo^s)
1557 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))+
block%B0(ixo^s,:,0)
1559 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))
1565 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
1568 if(sum(bdir(:)**2) .gt. zero)
then
1569 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
1571 block%special_values(3:ndim+2)=bdir(1:ndim)
1573 tmp1(ixo^s)=dsqrt(sum(bunitvec(ixo^s,:)**2,dim=ndim+1))
1574 where(tmp1(ixo^s)/=0.d0)
1575 tmp1(ixo^s)=1.d0/tmp1(ixo^s)
1577 tmp1(ixo^s)=bigdouble
1581 bunitvec(ixo^s,idims)=bunitvec(ixo^s,idims)*tmp1(ixo^s)
1584 lts(ixo^s)=abs(sum(gradt(ixo^s,1:ndim)*bunitvec(ixo^s,1:ndim),dim=ndim+1))/te(ixo^s)
1586 if(slab_uniform)
then
1587 lts(ixo^s)=minval(dxlevel)*lts(ixo^s)
1589 lts(ixo^s)=minval(block%ds(ixo^s,:),dim=ndim+1)*lts(ixo^s)
1592 where(lts(ixo^s) > trac_delta)
1595 if(any(lrlt(ixo^s)))
then
1596 block%special_values(1)=maxval(te(ixo^s), mask=lrlt(ixo^s))
1598 block%special_values(1)=zero
1600 block%special_values(2)=tmax_local
1619 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1620 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1621 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1624 {
do ix^db=ixpmin^db,ixpmax^db\}
1626 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))+block%B0(ix^d,^
c,0)\
1628 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))\
1630 tmp1(ix^d)=1.d0/(dsqrt(^
c&bunitvec(ix^d,^
c)**2+)+smalldouble)
1632 ^d&bunitvec({ix^d},^d)=bunitvec({ix^d},^d)*tmp1({ix^d})\
1634 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec({ix^d},^d)+)/te(ix^d)
1636 if(slab_uniform)
then
1637 lts(ix^d)=min(^d&dxlevel(^d))*lts(ix^d)
1639 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
1641 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
1646 hxo^l=ixp^l-kr(idims,^d);
1647 jxo^l=ixp^l+kr(idims,^d);
1649 altr(ixp^s)=0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1651 altr(ixp^s)=altr(ixp^s)+0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1654 block%wextra(ixp^s,
tcoff_)=te(ixp^s)*altr(ixp^s)**0.4d0
1658 call mpistop(
"unknown rmhd_trac_type")
1661 end subroutine rmhd_get_tcutoff
1664 subroutine rmhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
1667 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1668 double precision,
intent(in) :: wprim(ixi^s, nw)
1669 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1670 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
1672 double precision :: csound(ixi^s,
ndim)
1673 double precision,
allocatable :: tmp(:^
d&)
1674 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
1678 allocate(tmp(ixa^s))
1680 call rmhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
1681 csound(ixa^s,id)=tmp(ixa^s)
1684 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
1685 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
1686 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
1687 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))
1691 ixamax^
d=ixcmax^
d+
kr(id,^
d);
1692 ixamin^
d=ixcmin^
d+
kr(id,^
d);
1693 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)))
1694 ixamax^
d=ixcmax^
d-
kr(id,^
d);
1695 ixamin^
d=ixcmin^
d-
kr(id,^
d);
1696 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)))
1701 ixamax^
d=jxcmax^
d+
kr(id,^
d);
1702 ixamin^
d=jxcmin^
d+
kr(id,^
d);
1703 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)))
1704 ixamax^
d=jxcmax^
d-
kr(id,^
d);
1705 ixamin^
d=jxcmin^
d-
kr(id,^
d);
1706 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)))
1710 end subroutine rmhd_get_h_speed
1713 subroutine rmhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1715 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1716 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1717 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1718 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1719 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1720 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1721 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1723 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1724 double precision :: umean, dmean, tmp1, tmp2, tmp3
1731 call rmhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1732 call rmhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1733 if(
present(cmin))
then
1734 {
do ix^db=ixomin^db,ixomax^db\}
1735 tmp1=sqrt(wlp(ix^
d,
rho_))
1736 tmp2=sqrt(wrp(ix^
d,
rho_))
1737 tmp3=1.d0/(tmp1+tmp2)
1738 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1739 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1740 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1741 cmin(ix^
d,1)=umean-dmean
1742 cmax(ix^
d,1)=umean+dmean
1744 if(h_correction)
then
1745 {
do ix^db=ixomin^db,ixomax^db\}
1746 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1747 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1751 {
do ix^db=ixomin^db,ixomax^db\}
1752 tmp1=sqrt(wlp(ix^d,
rho_))
1753 tmp2=sqrt(wrp(ix^d,
rho_))
1754 tmp3=1.d0/(tmp1+tmp2)
1755 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1756 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1757 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1758 cmax(ix^d,1)=abs(umean)+dmean
1762 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1763 call rmhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
1764 if(
present(cmin))
then
1765 {
do ix^db=ixomin^db,ixomax^db\}
1766 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1767 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1769 if(h_correction)
then
1770 {
do ix^db=ixomin^db,ixomax^db\}
1771 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1772 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1776 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1780 call rmhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
1781 call rmhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
1782 if(
present(cmin))
then
1783 {
do ix^db=ixomin^db,ixomax^db\}
1784 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1785 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1786 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1788 if(h_correction)
then
1789 {
do ix^db=ixomin^db,ixomax^db\}
1790 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1791 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1795 {
do ix^db=ixomin^db,ixomax^db\}
1796 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1797 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1801 end subroutine rmhd_get_cbounds
1804 subroutine rmhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1806 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1807 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1808 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1809 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1810 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1811 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1812 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1813 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1814 double precision :: umean, dmean, tmp1, tmp2, tmp3
1821 call rmhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1822 call rmhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1823 if(
present(cmin))
then
1824 {
do ix^db=ixomin^db,ixomax^db\}
1827 tmp3=1.d0/(tmp1+tmp2)
1828 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1829 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1830 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1831 cmin(ix^
d,1)=umean-dmean
1832 cmax(ix^
d,1)=umean+dmean
1834 if(h_correction)
then
1835 {
do ix^db=ixomin^db,ixomax^db\}
1836 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1837 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1841 {
do ix^db=ixomin^db,ixomax^db\}
1844 tmp3=1.d0/(tmp1+tmp2)
1845 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1846 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1847 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1848 cmax(ix^d,1)=abs(umean)+dmean
1852 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1853 call rmhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
1854 if(
present(cmin))
then
1855 {
do ix^db=ixomin^db,ixomax^db\}
1856 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1857 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1859 if(h_correction)
then
1860 {
do ix^db=ixomin^db,ixomax^db\}
1861 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1862 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1866 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1870 call rmhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
1871 call rmhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
1872 if(
present(cmin))
then
1873 {
do ix^db=ixomin^db,ixomax^db\}
1874 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1875 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1876 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1878 if(h_correction)
then
1879 {
do ix^db=ixomin^db,ixomax^db\}
1880 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1881 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1885 {
do ix^db=ixomin^db,ixomax^db\}
1886 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1887 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1891 end subroutine rmhd_get_cbounds_split_rho
1894 subroutine rmhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1897 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1898 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1899 double precision,
intent(in) :: cmax(ixi^s)
1900 double precision,
intent(in),
optional :: cmin(ixi^s)
1901 type(ct_velocity),
intent(inout):: vcts
1903 end subroutine rmhd_get_ct_velocity_average
1905 subroutine rmhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1908 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1909 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1910 double precision,
intent(in) :: cmax(ixi^s)
1911 double precision,
intent(in),
optional :: cmin(ixi^s)
1912 type(ct_velocity),
intent(inout):: vcts
1915 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
1917 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
1919 end subroutine rmhd_get_ct_velocity_contact
1921 subroutine rmhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1924 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1925 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1926 double precision,
intent(in) :: cmax(ixi^s)
1927 double precision,
intent(in),
optional :: cmin(ixi^s)
1928 type(ct_velocity),
intent(inout):: vcts
1930 integer :: idime,idimn
1932 if(.not.
allocated(vcts%vbarC))
then
1933 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
1934 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
1937 if(
present(cmin))
then
1938 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
1939 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1941 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1942 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
1945 idimn=mod(idim,
ndir)+1
1946 idime=mod(idim+1,
ndir)+1
1948 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
1949 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
1950 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
1951 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1952 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1954 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
1955 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
1956 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
1957 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1958 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1960 end subroutine rmhd_get_ct_velocity_hll
1963 subroutine rmhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
1965 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1966 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1967 double precision,
intent(out):: csound(ixo^s)
1968 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
1969 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1970 double precision :: prad_max(ixo^s)
1975 if(radio_acoustic_filter)
then
1976 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
1980 {
do ix^db=ixomin^db,ixomax^db \}
1981 inv_rho=1.d0/w(ix^
d,
rho_)
1982 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1984 csound(ix^
d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
1989 cfast2=b2*inv_rho+csound(ix^
d)
1990 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
1992 if(avmincs2<zero) avmincs2=zero
1993 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1996 {
do ix^db=ixomin^db,ixomax^db \}
1997 inv_rho=1.d0/w(ix^d,
rho_)
1998 prad_max(ix^d)=maxval(prad_tensor(ix^d,:,:))
2000 csound(ix^d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+prad_max(ix^d))*inv_rho
2004 b2=(^
c&w(ix^d,
b^
c_)**2+)
2005 cfast2=b2*inv_rho+csound(ix^d)
2006 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2007 if(avmincs2<zero) avmincs2=zero
2008 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2011 end subroutine rmhd_get_csound_prim
2014 subroutine rmhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
2016 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2017 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2018 double precision,
intent(out):: csound(ixo^s)
2019 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
2020 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2021 double precision :: prad_max(ixo^s)
2026 if (radio_acoustic_filter)
then
2027 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2032 {
do ix^db=ixomin^db,ixomax^db \}
2035 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2040 cfast2=b2*inv_rho+csound(ix^
d)
2041 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
2043 if(avmincs2<zero) avmincs2=zero
2044 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2047 {
do ix^db=ixomin^db,ixomax^db \}
2050 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
2052 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
2054 b2=(^
c&w(ix^d,
b^
c_)**2+)
2055 cfast2=b2*inv_rho+csound(ix^d)
2056 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2057 if(avmincs2<zero) avmincs2=zero
2058 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2061 end subroutine rmhd_get_csound_prim_split
2064 subroutine rmhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
2068 integer,
intent(in) :: ixi^
l, ixo^
l
2069 double precision,
intent(in) :: w(ixi^s,nw)
2070 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2071 double precision,
intent(out):: pth(ixi^s)
2075 {
do ix^db=ixomin^db,ixomax^db\}
2080 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)&
2081 +(^
c&w(ix^
d,
b^
c_)**2+)))
2086 if(check_small_values.and..not.fix_small_values)
then
2087 {
do ix^db=ixomin^db,ixomax^db\}
2088 if(pth(ix^d)<small_pressure)
then
2089 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
2090 " encountered when call rmhd_get_pthermal"
2091 write(*,*)
"Iteration: ", it,
" Time: ", global_time
2092 write(*,*)
"Location: ", x(ix^d,:)
2093 write(*,*)
"Cell number: ", ix^d
2095 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
2098 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
2099 write(*,*)
"Saving status at the previous time step"
2104 end subroutine rmhd_get_pthermal_origin
2107 subroutine rmhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
2109 integer,
intent(in) :: ixi^
l, ixo^
l
2110 double precision,
intent(in) :: w(ixi^s, 1:nw)
2111 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2112 double precision,
intent(out):: res(ixi^s)
2113 res(ixo^s) = w(ixo^s,
te_)
2114 end subroutine rmhd_get_temperature_from_te
2117 subroutine rmhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
2119 integer,
intent(in) :: ixi^
l, ixo^
l
2120 double precision,
intent(in) :: w(ixi^s, 1:nw)
2121 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2122 double precision,
intent(out):: res(ixi^s)
2123 double precision :: r(ixi^s)
2125 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2126 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
2127 end subroutine rmhd_get_temperature_from_eint
2130 subroutine rmhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
2132 integer,
intent(in) :: ixi^
l, ixo^
l
2133 double precision,
intent(in) :: w(ixi^s, 1:nw)
2134 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2135 double precision,
intent(out):: res(ixi^s)
2136 double precision :: r(ixi^s)
2138 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2140 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
2141 end subroutine rmhd_get_temperature_from_etot
2143 subroutine rmhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
2145 integer,
intent(in) :: ixi^
l, ixo^
l
2146 double precision,
intent(in) :: w(ixi^s, 1:nw)
2147 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2148 double precision,
intent(out):: res(ixi^s)
2149 double precision :: r(ixi^s)
2151 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2154 end subroutine rmhd_get_temperature_from_etot_with_equi
2156 subroutine rmhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
2158 integer,
intent(in) :: ixi^
l, ixo^
l
2159 double precision,
intent(in) :: w(ixi^s, 1:nw)
2160 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2161 double precision,
intent(out):: res(ixi^s)
2162 double precision :: r(ixi^s)
2164 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2167 end subroutine rmhd_get_temperature_from_eint_with_equi
2169 subroutine rmhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
2171 integer,
intent(in) :: ixi^
l, ixo^
l
2172 double precision,
intent(in) :: w(ixi^s, 1:nw)
2173 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2174 double precision,
intent(out):: res(ixi^s)
2175 double precision :: r(ixi^s)
2177 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2179 end subroutine rmhd_get_temperature_equi
2181 subroutine rmhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
2183 integer,
intent(in) :: ixi^
l, ixo^
l
2184 double precision,
intent(in) :: w(ixi^s, 1:nw)
2185 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2186 double precision,
intent(out):: res(ixi^s)
2188 end subroutine rmhd_get_rho_equi
2190 subroutine rmhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
2192 integer,
intent(in) :: ixi^
l, ixo^
l
2193 double precision,
intent(in) :: w(ixi^s, 1:nw)
2194 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2195 double precision,
intent(out):: res(ixi^s)
2197 end subroutine rmhd_get_pe_equi
2200 subroutine rmhd_get_p_total(w,x,ixI^L,ixO^L,p)
2202 integer,
intent(in) :: ixi^
l, ixo^
l
2203 double precision,
intent(in) :: w(ixi^s,nw)
2204 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2205 double precision,
intent(out) :: p(ixi^s)
2208 p(ixo^s) = p(ixo^s) + 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
2209 end subroutine rmhd_get_p_total
2216 integer,
intent(in) :: ixi^
l, ixo^
l, nth
2217 double precision,
intent(in) :: w(ixi^s, 1:nw)
2218 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2219 double precision,
intent(out):: prad(ixo^s, 1:
ndim, 1:
ndim)
2227 call mpistop(
'Radiation formalism unknown')
2234 integer,
intent(in) :: ixi^
l, ixo^
l
2235 double precision,
intent(in) :: w(ixi^s, 1:nw)
2236 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2237 double precision :: pth(ixi^s)
2238 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2239 double precision :: prad_max(ixo^s)
2240 double precision,
intent(out) :: pth_plus_prad(ixi^s)
2245 {
do ix^
d = ixomin^
d,ixomax^
d\}
2246 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2249 if (radio_acoustic_filter)
then
2250 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2252 pth_plus_prad(ixo^s) = pth(ixo^s) + prad_max(ixo^s)
2256 subroutine rmhd_radio_acoustic_filter(x, ixI^L, ixO^L, prad_max)
2258 integer,
intent(in) :: ixi^
l, ixo^
l
2259 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2260 double precision,
intent(inout) :: prad_max(ixo^s)
2261 double precision :: tmp_prad(ixi^s)
2262 integer :: ix^
d, filter, idim
2264 if (size_ra_filter .lt. 1)
call mpistop(
"ra filter of size < 1 makes no sense")
2265 if (size_ra_filter .gt.
nghostcells)
call mpistop(
"ra filter of size < nghostcells makes no sense")
2267 tmp_prad(ixi^s) = zero
2268 tmp_prad(ixo^s) = prad_max(ixo^s)
2269 do filter = 1,size_ra_filter
2272 {
do ix^
d = ixomin^
d,ixomax^
d\}
2273 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d+filter*
kr(idim,^
d)))
2274 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d-filter*
kr(idim,^
d)))
2278 end subroutine rmhd_radio_acoustic_filter
2283 integer,
intent(in) :: ixi^
l, ixo^
l
2284 double precision,
intent(in) :: w(ixi^s, 1:nw)
2285 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2286 double precision :: pth(ixi^s)
2287 double precision,
intent(out):: tgas(ixi^s)
2290 tgas(ixi^s) = pth(ixi^s)/w(ixi^s,
rho_)
2298 integer,
intent(in) :: ixi^
l, ixo^
l
2299 double precision,
intent(in) :: w(ixi^s, 1:nw)
2300 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2301 double precision,
intent(out):: trad(ixi^s)
2308 subroutine rmhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
2312 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2314 double precision,
intent(in) :: wc(ixi^s,nw)
2316 double precision,
intent(in) :: w(ixi^s,nw)
2317 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2318 double precision,
intent(out) :: f(ixi^s,nwflux)
2319 double precision :: vhall(ixi^s,1:
ndir)
2320 double precision :: ptotal
2323 {
do ix^db=ixomin^db,ixomax^db\}
2328 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2330 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2333 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2334 -w(ix^
d,mag(idim))*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2339 {
do ix^db=ixomin^db,ixomax^db\}
2340 f(ix^d,mag(idim))=w(ix^d,
psi_)
2342 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
2346 {
do ix^db=ixomin^db,ixomax^db\}
2347 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2354 {
do ix^db=ixomin^db,ixomax^db\}
2359 {
do ix^db=ixomin^db,ixomax^db\}
2360 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^d&w({ix^d},
b^d_)**2+)+smalldouble)
2364 end subroutine rmhd_get_flux
2367 subroutine rmhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
2370 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2372 double precision,
intent(in) :: wc(ixi^s,nw)
2374 double precision,
intent(in) :: w(ixi^s,nw)
2375 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2376 double precision,
intent(out) :: f(ixi^s,nwflux)
2377 double precision :: vhall(ixi^s,1:
ndir)
2378 double precision :: ptotal, btotal(ixo^s,1:
ndir)
2381 {
do ix^db=ixomin^db,ixomax^db\}
2389 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2398 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
2402 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
2403 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2405 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
2409 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2412 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
2416 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2417 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2421 {
do ix^db=ixomin^db,ixomax^db\}
2422 f(ix^d,mag(idim))=w(ix^d,
psi_)
2424 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
2428 {
do ix^db=ixomin^db,ixomax^db\}
2429 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2436 {
do ix^db=ixomin^db,ixomax^db\}
2441 {
do ix^db=ixomin^db,ixomax^db\}
2442 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
2446 end subroutine rmhd_get_flux_split
2450 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
2453 integer,
intent(in) :: ixi^
l, ixo^
l
2454 double precision,
dimension(:^D&,:),
intent(inout) :: ff
2455 double precision,
intent(out) :: src(ixi^s)
2457 double precision :: ffc(ixi^s,1:
ndim)
2458 double precision :: dxinv(
ndim)
2459 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
2465 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
2467 ixbmin^
d=ixcmin^
d+ix^
d;
2468 ixbmax^
d=ixcmax^
d+ix^
d;
2471 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
2473 ff(ixi^s,1:ndim)=0.d0
2475 ixb^l=ixo^l-kr(idims,^d);
2476 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
2478 if({ ix^d==0 .and. ^d==idims | .or.})
then
2479 ixbmin^d=ixcmin^d-ix^d;
2480 ixbmax^d=ixcmax^d-ix^d;
2481 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
2484 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
2487 if(slab_uniform)
then
2489 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
2490 ixb^l=ixo^l-kr(idims,^d);
2491 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2495 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
2496 ixb^l=ixo^l-kr(idims,^d);
2497 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2499 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
2501 end subroutine get_flux_on_cell_face
2504 subroutine rmhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2510 integer,
intent(in) :: ixi^
l, ixo^
l
2511 double precision,
intent(in) :: qdt,dtfactor
2512 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2513 double precision,
intent(inout) :: w(ixi^s,1:nw)
2514 logical,
intent(in) :: qsourcesplit
2515 logical,
intent(inout) :: active
2521 if (.not. qsourcesplit)
then
2524 call add_pe0_divv(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2527 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
2532 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2537 call add_source_res2(qdt,ixi^
l,ixo^
l,wct,w,x)
2541 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
2547 select case (type_divb)
2552 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2555 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2558 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2559 case (divb_janhunen)
2561 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2562 case (divb_lindejanhunen)
2564 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2565 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2566 case (divb_lindepowel)
2568 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2569 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2570 case (divb_lindeglm)
2572 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2573 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2574 case (divb_multigrid)
2579 call mpistop(
'Unknown divB fix')
2589 w,x,gravity_energy,gravity_rhov,qsourcesplit,active)
2595 call rmhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,w,x,qsourcesplit,active)
2598 if(.not.qsourcesplit)
then
2600 call rmhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
2603 end subroutine rmhd_add_source
2605 subroutine rmhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,w,x,qsourcesplit,active)
2611 integer,
intent(in) :: ixi^
l, ixo^
l
2612 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
2613 double precision,
intent(in) :: wct(ixi^s,1:nw)
2614 double precision,
intent(inout) :: w(ixi^s,1:nw)
2615 logical,
intent(in) :: qsourcesplit
2616 logical,
intent(inout) :: active
2617 double precision :: cmax(ixi^s)
2624 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2629 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2635 call mpistop(
'Radiation formalism unknown')
2637 end subroutine rmhd_add_radiation_source
2639 subroutine add_pe0_divv(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2642 integer,
intent(in) :: ixi^
l, ixo^
l
2643 double precision,
intent(in) :: qdt,dtfactor
2644 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2645 double precision,
intent(inout) :: w(ixi^s,1:nw)
2646 double precision :: divv(ixi^s)
2662 end subroutine add_pe0_divv
2664 subroutine get_tau(ixI^L,ixO^L,w,Te,tau,sigT5)
2666 integer,
intent(in) :: ixi^
l, ixo^
l
2667 double precision,
dimension(ixI^S,1:nw),
intent(in) :: w
2668 double precision,
dimension(ixI^S),
intent(in) :: te
2669 double precision,
dimension(ixI^S),
intent(out) :: tau,sigt5
2670 double precision :: dxmin,taumin
2671 double precision,
dimension(ixI^S) :: sigt7,eint
2679 sigt7(ixo^s)=sigt5(ixo^s)*
block%wextra(ixo^s,
tcoff_)
2682 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2686 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2689 tau(ixo^s)=max(taumin*
dt,sigt7(ixo^s)/eint(ixo^s)/
cmax_global**2)
2690 end subroutine get_tau
2692 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
2694 integer,
intent(in) :: ixi^
l,ixo^
l
2695 double precision,
intent(in) :: qdt
2696 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
2697 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
2698 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
2699 double precision :: invdx
2700 double precision,
dimension(ixI^S) :: te,tau,sigt,htc_qsrc,tface,r
2701 double precision,
dimension(ixI^S) :: htc_esrc,bsum,bunit
2702 double precision,
dimension(ixI^S,1:ndim) :: btot
2704 integer :: hxc^
l,hxo^
l,ixc^
l,jxc^
l,jxo^
l,kxc^
l
2706 call rmhd_get_rfactor(wctprim,x,ixi^
l,ixi^
l,r)
2708 te(ixi^s)=wctprim(ixi^s,
p_)/(r(ixi^s)*w(ixi^s,
rho_))
2709 call get_tau(ixi^
l,ixo^
l,wctprim,te,tau,sigt)
2713 btot(ixo^s,idims)=wct(ixo^s,mag(idims))+
block%B0(ixo^s,idims,0)
2715 btot(ixo^s,idims)=wct(ixo^s,mag(idims))
2718 bsum(ixo^s)=sqrt(sum(btot(ixo^s,:)**2,dim=
ndim+1))+smalldouble
2722 ixcmin^
d=ixomin^
d-
kr(idims,^
d);ixcmax^
d=ixomax^
d;
2723 jxc^
l=ixc^
l+
kr(idims,^
d);
2724 kxc^
l=jxc^
l+
kr(idims,^
d);
2725 hxc^
l=ixc^
l-
kr(idims,^
d);
2726 hxo^
l=ixo^
l-
kr(idims,^
d);
2727 tface(ixc^s)=(7.d0*(te(ixc^s)+te(jxc^s))-(te(hxc^s)+te(kxc^s)))/12.d0
2728 bunit(ixo^s)=btot(ixo^s,idims)/bsum(ixo^s)
2729 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*bunit(ixo^s)*(tface(ixo^s)-tface(hxo^s))*invdx
2731 htc_qsrc(ixo^s)=(htc_qsrc(ixo^s)+wct(ixo^s,
q_))/tau(ixo^s)
2732 w(ixo^s,
q_)=w(ixo^s,
q_)-qdt*htc_qsrc(ixo^s)
2733 end subroutine add_hypertc_source
2736 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
2738 integer,
intent(in) :: ixi^
l, ixo^
l
2739 double precision,
intent(in) :: w(ixi^s,1:nw)
2740 double precision,
intent(inout) :: jxb(ixi^s,3)
2741 double precision :: a(ixi^s,3),
b(ixi^s,3)
2743 double precision :: current(ixi^s,7-2*
ndir:3)
2744 integer :: idir, idirmin
2749 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
2753 b(ixo^s, idir) = w(ixo^s,mag(idir))
2760 a(ixo^s,idir)=current(ixo^s,idir)
2763 end subroutine get_lorentz_force
2767 subroutine rmhd_gamma2_alfven(ixI^L, ixO^L, w, gamma_A2)
2769 integer,
intent(in) :: ixi^
l, ixo^
l
2770 double precision,
intent(in) :: w(ixi^s, nw)
2771 double precision,
intent(out) :: gamma_a2(ixo^s)
2772 double precision :: rho(ixi^s)
2778 rho(ixo^s) = w(ixo^s,
rho_)
2781 gamma_a2(ixo^s) = 1.0d0/(1.0d0+
rmhd_mag_en_all(w, ixi^
l, ixo^
l)/rho(ixo^s)*inv_squared_c)
2782 end subroutine rmhd_gamma2_alfven
2786 function rmhd_gamma_alfven(w, ixI^L, ixO^L)
result(gamma_A)
2788 integer,
intent(in) :: ixi^
l, ixo^
l
2789 double precision,
intent(in) :: w(ixi^s, nw)
2790 double precision :: gamma_a(ixo^s)
2792 call rmhd_gamma2_alfven(ixi^
l, ixo^
l, w, gamma_a)
2793 gamma_a = sqrt(gamma_a)
2794 end function rmhd_gamma_alfven
2798 integer,
intent(in) :: ixi^
l, ixo^
l
2799 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
2800 double precision,
intent(out) :: rho(ixi^s)
2805 rho(ixo^s) = w(ixo^s,
rho_)
2810 subroutine rmhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
2813 integer,
intent(in) :: ixi^
l,ixo^
l, ie
2814 double precision,
intent(inout) :: w(ixi^s,1:nw)
2815 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2816 character(len=*),
intent(in) :: subname
2817 double precision :: rho(ixi^s)
2819 logical :: flag(ixi^s,1:nw)
2823 where(w(ixo^s,ie)+
block%equi_vars(ixo^s,
equi_pe0_,0)*inv_gamma_1<small_e)&
2824 flag(ixo^s,ie)=.true.
2826 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
2828 if(any(flag(ixo^s,ie)))
then
2832 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e - &
2835 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
2841 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
2844 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
2849 end subroutine rmhd_handle_small_ei
2851 subroutine rmhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
2855 integer,
intent(in) :: ixi^
l, ixo^
l
2856 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2857 double precision,
intent(inout) :: w(ixi^s,1:nw)
2859 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
2867 end subroutine rmhd_update_temperature
2870 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2872 integer,
intent(in) :: ixi^
l, ixo^
l
2873 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2874 double precision,
intent(inout) :: w(ixi^s,1:nw)
2875 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
2886 a(ixo^s,idir)=
block%J0(ixo^s,idir)
2891 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2894 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2899 if(total_energy)
then
2902 b(ixo^s,:)=wct(ixo^s,mag(:))
2911 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2914 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2918 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
2921 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
2922 end subroutine add_source_b0split
2928 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
2932 integer,
intent(in) :: ixi^
l, ixo^
l
2933 double precision,
intent(in) :: qdt
2934 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2935 double precision,
intent(inout) :: w(ixi^s,1:nw)
2936 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim,jxo^
l,hxo^
l,ix
2937 integer :: lxo^
l, kxo^
l
2938 double precision :: tmp(ixi^s),tmp2(ixi^s)
2940 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
2941 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
2949 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2950 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
2955 gradeta(ixo^s,1:
ndim)=zero
2961 gradeta(ixo^s,idim)=tmp(ixo^s)
2967 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
2973 tmp2(ixi^s)=bf(ixi^s,idir)
2975 lxo^
l=ixo^
l+2*
kr(idim,^
d);
2976 jxo^
l=ixo^
l+
kr(idim,^
d);
2977 hxo^
l=ixo^
l-
kr(idim,^
d);
2978 kxo^
l=ixo^
l-2*
kr(idim,^
d);
2979 tmp(ixo^s)=tmp(ixo^s)+&
2980 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
2985 tmp2(ixi^s)=bf(ixi^s,idir)
2987 jxo^
l=ixo^
l+
kr(idim,^
d);
2988 hxo^
l=ixo^
l-
kr(idim,^
d);
2989 tmp(ixo^s)=tmp(ixo^s)+&
2990 (tmp2(jxo^s)-2.0d0*tmp2(ixo^s)+tmp2(hxo^s))/
dxlevel(idim)**2
2994 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
2997 do jdir=1,
ndim;
do kdir=idirmin,3
2998 if (
lvc(idir,jdir,kdir)/=0)
then
2999 if (
lvc(idir,jdir,kdir)==1)
then
3000 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
3002 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
3008 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
3009 if(total_energy)
then
3010 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
3015 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
3017 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
3018 end subroutine add_source_res1
3022 subroutine add_source_res2(qdt,ixI^L,ixO^L,wCT,w,x)
3026 integer,
intent(in) :: ixi^
l, ixo^
l
3027 double precision,
intent(in) :: qdt
3028 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3029 double precision,
intent(inout) :: w(ixi^s,1:nw)
3031 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
3032 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
3033 integer :: ixa^
l,idir,idirmin,idirmin1
3036 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3037 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
3045 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
rmhd_eta
3050 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
3058 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
3061 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
3065 tmp(ixo^s)=qdt*
rmhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
3067 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
3069 if(total_energy)
then
3072 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
3073 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
3076 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
3079 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res2')
3080 end subroutine add_source_res2
3084 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
3087 integer,
intent(in) :: ixi^
l, ixo^
l
3088 double precision,
intent(in) :: qdt
3089 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3090 double precision,
intent(inout) :: w(ixi^s,1:nw)
3092 double precision :: current(ixi^s,7-2*
ndir:3)
3093 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
3094 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
3097 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3098 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
3100 tmpvec(ixa^s,1:
ndir)=zero
3102 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
3105 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3107 tmpvec(ixa^s,1:
ndir)=zero
3108 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
3111 tmpvec2(ixa^s,1:
ndir)=zero
3112 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3114 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
3116 if(total_energy)
then
3119 tmpvec2(ixa^s,1:
ndir)=zero
3120 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
3121 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
3122 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
3123 end do;
end do;
end do
3125 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
3126 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
3128 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
3129 end subroutine add_source_hyperres
3131 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
3137 integer,
intent(in) :: ixi^
l, ixo^
l
3138 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3139 double precision,
intent(inout) :: w(ixi^s,1:nw)
3140 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
3159 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
3162 if(total_energy)
then
3171 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
3178 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
3181 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
3182 end subroutine add_source_glm
3185 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
3187 integer,
intent(in) :: ixi^
l, ixo^
l
3188 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3189 double precision,
intent(inout) :: w(ixi^s,1:nw)
3190 double precision :: divb(ixi^s), ba(1:
ndir)
3191 integer :: idir, ix^
d
3196 {
do ix^db=ixomin^db,ixomax^db\}
3201 if (total_energy)
then
3207 {
do ix^db=ixomin^db,ixomax^db\}
3209 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
3211 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
3212 if (total_energy)
then
3214 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
3218 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
3219 end subroutine add_source_powel
3221 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
3225 integer,
intent(in) :: ixi^
l, ixo^
l
3226 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3227 double precision,
intent(inout) :: w(ixi^s,1:nw)
3228 double precision :: divb(ixi^s)
3229 integer :: idir, ix^
d
3233 {
do ix^db=ixomin^db,ixomax^db\}
3237 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
3238 end subroutine add_source_janhunen
3240 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
3244 integer,
intent(in) :: ixi^
l, ixo^
l
3245 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3246 double precision,
intent(inout) :: w(ixi^s,1:nw)
3247 double precision :: divb(ixi^s),graddivb(ixi^s)
3248 integer :: idim, idir, ixp^
l, i^
d, iside
3249 logical,
dimension(-1:1^D&) :: leveljump
3256 if(i^
d==0|.and.) cycle
3257 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
3258 leveljump(i^
d)=.true.
3260 leveljump(i^
d)=.false.
3268 i^dd=kr(^dd,^d)*(2*iside-3);
3269 if (leveljump(i^dd))
then
3271 ixpmin^d=ixomin^d-i^d
3273 ixpmax^d=ixomax^d-i^d
3283 select case(typegrad)
3285 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
3287 call gradientl(divb,ixi^l,ixp^l,idim,graddivb)
3290 if (slab_uniform)
then
3291 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
3293 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
3294 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
3296 w(ixp^s,mag(idim))=w(ixp^s,mag(idim))+graddivb(ixp^s)
3298 if (typedivbdiff==
'all' .and. total_energy)
then
3300 w(ixp^s,
e_)=w(ixp^s,
e_)+wct(ixp^s,mag(idim))*graddivb(ixp^s)
3303 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
3304 end subroutine add_source_linde
3309 integer,
intent(in) :: ixi^
l, ixo^
l
3310 double precision,
intent(in) :: w(ixi^s,1:nw)
3311 double precision :: divb(ixi^s), dsurface(ixi^s)
3312 double precision :: invb(ixo^s)
3313 integer :: ixa^
l,idims
3315 call get_divb(w,ixi^
l,ixo^
l,divb)
3317 where(invb(ixo^s)/=0.d0)
3318 invb(ixo^s)=1.d0/invb(ixo^s)
3321 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
3323 ixamin^
d=ixomin^
d-1;
3324 ixamax^
d=ixomax^
d-1;
3325 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
3327 ixa^
l=ixo^
l-
kr(idims,^
d);
3328 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
3330 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
3331 block%dvolume(ixo^s)/dsurface(ixo^s)
3340 integer,
intent(in) :: ixo^
l, ixi^
l
3341 double precision,
intent(in) :: w(ixi^s,1:nw)
3342 integer,
intent(out) :: idirmin
3344 double precision :: current(ixi^s,7-2*
ndir:3)
3345 integer :: idir, idirmin0
3349 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
3350 block%J0(ixo^s,idirmin0:3)
3354 subroutine rmhd_get_dt(w,ixI^L,ixO^L,dtnew,dx^D,x)
3362 integer,
intent(in) :: ixi^
l, ixo^
l
3363 double precision,
intent(inout) :: dtnew
3364 double precision,
intent(in) ::
dx^
d
3365 double precision,
intent(in) :: w(ixi^s,1:nw)
3366 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3367 double precision :: dxarr(
ndim)
3368 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
3369 integer :: idirmin,idim
3373 if (.not. dt_c)
then
3384 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
3387 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
3405 call mpistop(
'Radiation formalism unknown')
3421 end subroutine rmhd_get_dt
3424 subroutine rmhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
3427 integer,
intent(in) :: ixi^
l, ixo^
l
3428 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
3429 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3430 double precision :: tmp,tmp1,invr,cot
3432 integer :: mr_,mphi_
3433 integer :: br_,bphi_
3436 br_=mag(1); bphi_=mag(1)-1+
phi_
3439 {
do ix^db=ixomin^db,ixomax^db\}
3442 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
3447 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
3452 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
3453 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
3454 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
3455 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
3456 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
3458 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
3459 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
3460 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
3463 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
3468 {
do ix^db=ixomin^db,ixomax^db\}
3470 if(local_timestep)
then
3471 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
3476 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
3482 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
3485 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
3486 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
3490 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
3496 cot=1.d0/tan(x(ix^d,2))
3500 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3501 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
3503 if(.not.stagger_grid)
then
3504 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3506 tmp=tmp+wprim(ix^d,
psi_)*cot
3508 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3513 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3514 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
3515 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
3517 if(.not.stagger_grid)
then
3518 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3520 tmp=tmp+wprim(ix^d,
psi_)*cot
3522 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3525 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
3526 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
3527 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
3528 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
3529 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
3531 if(.not.stagger_grid)
then
3532 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
3533 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
3534 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
3535 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
3536 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
3541 end subroutine rmhd_add_source_geom
3544 subroutine rmhd_add_source_geom_split(qdt,dtfactor, ixI^L,ixO^L,wCT,wprim,w,x)
3547 integer,
intent(in) :: ixi^
l, ixo^
l
3548 double precision,
intent(in) :: qdt, dtfactor, x(ixi^s,1:
ndim)
3549 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3550 double precision :: tmp(ixi^s),tmp1(ixi^s),tmp2(ixi^s),invrho(ixo^s),invr(ixo^s)
3551 integer :: iw,idir, h1x^
l{^nooned, h2x^
l}
3552 integer :: mr_,mphi_
3553 integer :: br_,bphi_
3556 br_=mag(1); bphi_=mag(1)-1+
phi_
3560 invrho(ixo^s) = 1d0/wct(ixo^s,
rho_)
3564 invr(ixo^s) =
block%dt(ixo^s) * dtfactor/x(ixo^s,1)
3566 invr(ixo^s) = qdt/x(ixo^s,1)
3571 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp)
3573 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*(tmp(ixo^s)-&
3574 wct(ixo^s,bphi_)**2+wct(ixo^s,mphi_)**2*invrho(ixo^s))
3575 w(ixo^s,mphi_)=w(ixo^s,mphi_)+qdt*invr(ixo^s)*(&
3576 -wct(ixo^s,mphi_)*wct(ixo^s,mr_)*invrho(ixo^s) &
3577 +wct(ixo^s,bphi_)*wct(ixo^s,br_))
3579 w(ixo^s,bphi_)=w(ixo^s,bphi_)+invr(ixo^s)*&
3580 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
3581 -wct(ixo^s,br_)*wct(ixo^s,mphi_)) &
3585 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*tmp(ixo^s)
3587 if(
rmhd_glm) w(ixo^s,br_)=w(ixo^s,br_)+wct(ixo^s,
psi_)*invr(ixo^s)
3589 h1x^
l=ixo^
l-
kr(1,^
d); {^nooned h2x^
l=ixo^
l-
kr(2,^
d);}
3590 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp1)
3591 tmp(ixo^s)=tmp1(ixo^s)
3593 tmp2(ixo^s)=sum(
block%B0(ixo^s,:,0)*wct(ixo^s,mag(:)),dim=
ndim+1)
3594 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3597 tmp(ixo^s)=tmp(ixo^s)*x(ixo^s,1) &
3598 *(
block%surfaceC(ixo^s,1)-
block%surfaceC(h1x^s,1))/
block%dvolume(ixo^s)
3601 tmp(ixo^s)=tmp(ixo^s)+wct(ixo^s,
mom(idir))**2*invrho(ixo^s)-wct(ixo^s,mag(idir))**2
3602 if(
b0field) tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,idir,0)*wct(ixo^s,mag(idir))
3605 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+tmp(ixo^s)*invr(ixo^s)
3608 w(ixo^s,mag(1))=w(ixo^s,mag(1))+invr(ixo^s)*2.0d0*wct(ixo^s,
psi_)
3612 tmp(ixo^s)=tmp1(ixo^s)
3614 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3617 tmp1(ixo^s) =
block%dt(ixo^s) * tmp(ixo^s)
3619 tmp1(ixo^s) = qdt * tmp(ixo^s)
3622 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp1(ixo^s) &
3623 *(
block%surfaceC(ixo^s,2)-
block%surfaceC(h2x^s,2)) &
3624 /
block%dvolume(ixo^s)
3625 tmp(ixo^s)=-(wct(ixo^s,
mom(1))*wct(ixo^s,
mom(2))*invrho(ixo^s) &
3626 -wct(ixo^s,mag(1))*wct(ixo^s,mag(2)))
3628 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(2)) &
3629 +wct(ixo^s,mag(1))*
block%B0(ixo^s,2,0)
3632 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(3))**2*invrho(ixo^s) &
3633 -wct(ixo^s,mag(3))**2)*dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3635 tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,3,0)*wct(ixo^s,mag(3))&
3636 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3639 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp(ixo^s)*invr(ixo^s)
3642 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(2)) &
3643 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(1)))*invrho(ixo^s)
3645 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,2,0) &
3646 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,1,0))*invrho(ixo^s)
3649 tmp(ixo^s)=tmp(ixo^s) &
3650 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
3652 w(ixo^s,mag(2))=w(ixo^s,mag(2))+tmp(ixo^s)*invr(ixo^s)
3657 tmp(ixo^s)=-(wct(ixo^s,
mom(3))*wct(ixo^s,
mom(1))*invrho(ixo^s) &
3658 -wct(ixo^s,mag(3))*wct(ixo^s,mag(1))) {^nooned &
3659 -(wct(ixo^s,
mom(2))*wct(ixo^s,
mom(3))*invrho(ixo^s) &
3660 -wct(ixo^s,mag(2))*wct(ixo^s,mag(3))) &
3661 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3663 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(3)) &
3664 +wct(ixo^s,mag(1))*
block%B0(ixo^s,3,0) {^nooned &
3665 +(
block%B0(ixo^s,2,0)*wct(ixo^s,mag(3)) &
3666 +wct(ixo^s,mag(2))*
block%B0(ixo^s,3,0)) &
3667 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3669 w(ixo^s,
mom(3))=w(ixo^s,
mom(3))+tmp(ixo^s)*invr(ixo^s)
3672 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(3)) &
3673 -wct(ixo^s,
mom(3))*wct(ixo^s,mag(1)))*invrho(ixo^s) {^nooned &
3674 -(wct(ixo^s,
mom(3))*wct(ixo^s,mag(2)) &
3675 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(3)))*dcos(x(ixo^s,2)) &
3676 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3678 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,3,0) &
3679 -wct(ixo^s,
mom(3))*
block%B0(ixo^s,1,0))*invrho(ixo^s){^nooned &
3680 -(wct(ixo^s,
mom(3))*
block%B0(ixo^s,2,0) &
3681 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,3,0))*dcos(x(ixo^s,2)) &
3682 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3684 w(ixo^s,mag(3))=w(ixo^s,mag(3))+tmp(ixo^s)*invr(ixo^s)
3688 end subroutine rmhd_add_source_geom_split
3693 integer,
intent(in) :: ixi^
l, ixo^
l
3694 double precision,
intent(in) :: w(ixi^s, nw)
3695 double precision :: mge(ixo^s)
3698 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
3700 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
3704 subroutine rmhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
3707 integer,
intent(in) :: ixi^
l, ixo^
l, idir
3708 double precision,
intent(in) :: qt
3709 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
3710 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
3712 double precision :: db(ixo^s), dpsi(ixo^s)
3716 {
do ix^db=ixomin^db,ixomax^db\}
3717 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3718 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3719 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3720 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3729 {
do ix^db=ixomin^db,ixomax^db\}
3730 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
3731 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
3732 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
3733 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
3734 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3736 if(total_energy)
then
3737 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
3738 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
3740 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3742 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3745 if(total_energy)
then
3746 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
3747 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
3751 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
3752 end subroutine rmhd_modify_wlr
3754 subroutine rmhd_boundary_adjust(igrid,psb)
3756 integer,
intent(in) :: igrid
3758 integer :: ib, idims, iside, ixo^
l, i^
d
3767 i^
d=
kr(^
d,idims)*(2*iside-3);
3768 if (neighbor_type(i^
d,igrid)/=1) cycle
3769 ib=(idims-1)*2+iside
3787 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
3791 end subroutine rmhd_boundary_adjust
3793 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
3795 integer,
intent(in) :: ixg^
l,ixo^
l,ib
3796 double precision,
intent(inout) :: w(ixg^s,1:nw)
3797 double precision,
intent(in) :: x(ixg^s,1:
ndim)
3798 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
3799 integer :: ix^
d,ixf^
l
3812 do ix1=ixfmax1,ixfmin1,-1
3813 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
3814 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3815 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3818 do ix1=ixfmax1,ixfmin1,-1
3819 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
3820 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
3821 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3822 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3823 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3824 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3825 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3839 do ix1=ixfmax1,ixfmin1,-1
3840 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3841 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3842 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3843 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3844 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3845 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3848 do ix1=ixfmax1,ixfmin1,-1
3849 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3850 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3851 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3852 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3853 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3854 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3855 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3856 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3857 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3858 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3859 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3860 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3861 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3862 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3863 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3864 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3865 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3866 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3880 do ix1=ixfmin1,ixfmax1
3881 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
3882 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3883 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3886 do ix1=ixfmin1,ixfmax1
3887 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
3888 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
3889 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3890 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3891 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3892 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3893 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3907 do ix1=ixfmin1,ixfmax1
3908 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3909 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3910 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3911 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3912 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3913 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3916 do ix1=ixfmin1,ixfmax1
3917 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3918 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3919 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3920 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3921 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3922 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3923 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3924 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3925 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3926 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3927 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3928 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3929 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3930 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3931 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3932 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3933 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3934 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3948 do ix2=ixfmax2,ixfmin2,-1
3949 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
3950 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3951 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3954 do ix2=ixfmax2,ixfmin2,-1
3955 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
3956 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
3957 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3958 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3959 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3960 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3961 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3975 do ix2=ixfmax2,ixfmin2,-1
3976 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3977 ix2+1,ixfmin3:ixfmax3,mag(2)) &
3978 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
3979 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
3980 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
3981 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
3984 do ix2=ixfmax2,ixfmin2,-1
3985 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
3986 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
3987 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
3988 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
3989 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
3990 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3991 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
3992 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
3993 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3994 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
3995 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
3996 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
3997 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
3998 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
3999 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
4000 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
4001 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
4002 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4016 do ix2=ixfmin2,ixfmax2
4017 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
4018 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
4019 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
4022 do ix2=ixfmin2,ixfmax2
4023 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
4024 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
4025 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
4026 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
4027 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
4028 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
4029 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
4043 do ix2=ixfmin2,ixfmax2
4044 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
4045 ix2-1,ixfmin3:ixfmax3,mag(2)) &
4046 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
4047 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
4048 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
4049 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
4052 do ix2=ixfmin2,ixfmax2
4053 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
4054 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
4055 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
4056 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
4057 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
4058 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4059 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
4060 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
4061 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4062 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
4063 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
4064 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
4065 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
4066 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
4067 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
4068 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
4069 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
4070 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4087 do ix3=ixfmax3,ixfmin3,-1
4088 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
4089 ixfmin2:ixfmax2,ix3+1,mag(3)) &
4090 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4091 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4092 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4093 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4096 do ix3=ixfmax3,ixfmin3,-1
4097 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
4098 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
4099 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4100 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
4101 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4102 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4103 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4104 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4105 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4106 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4107 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4108 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4109 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4110 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4111 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4112 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4113 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
4114 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4129 do ix3=ixfmin3,ixfmax3
4130 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
4131 ixfmin2:ixfmax2,ix3-1,mag(3)) &
4132 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4133 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4134 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4135 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4138 do ix3=ixfmin3,ixfmax3
4139 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
4140 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
4141 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4142 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
4143 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4144 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4145 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4146 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4147 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4148 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4149 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4150 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4151 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4152 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4153 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4154 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4155 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
4156 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4162 call mpistop(
"Special boundary is not defined for this region")
4164 end subroutine fixdivb_boundary
4172 double precision,
intent(in) :: qdt
4173 double precision,
intent(in) :: qt
4174 logical,
intent(inout) :: active
4176 integer,
parameter :: max_its = 50
4177 double precision :: residual_it(max_its), max_divb
4178 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
4179 double precision :: res
4180 double precision,
parameter :: max_residual = 1
d-3
4181 double precision,
parameter :: residual_reduction = 1
d-10
4182 integer :: iigrid, igrid
4183 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
4186 mg%operator_type = mg_laplacian
4193 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4194 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4197 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
4198 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4200 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4201 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4204 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4205 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4209 write(*,*)
"rmhd_clean_divb_multigrid warning: unknown boundary type"
4210 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4211 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4218 do iigrid = 1, igridstail
4219 igrid = igrids(iigrid);
4222 lvl =
mg%boxes(id)%lvl
4223 nc =
mg%box_size_lvl(lvl)
4229 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
4231 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
4232 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
4237 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
4240 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
4241 if (
mype == 0) print *,
"iteration vs residual"
4244 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
4245 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
4246 if (residual_it(n) < residual_reduction * max_divb)
exit
4248 if (
mype == 0 .and. n > max_its)
then
4249 print *,
"divb_multigrid warning: not fully converged"
4250 print *,
"current amplitude of divb: ", residual_it(max_its)
4251 print *,
"multigrid smallest grid: ", &
4252 mg%domain_size_lvl(:,
mg%lowest_lvl)
4253 print *,
"note: smallest grid ideally has <= 8 cells"
4254 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
4255 print *,
"note: dx/dy/dz should be similar"
4259 call mg_fas_vcycle(
mg, max_res=res)
4260 if (res < max_residual)
exit
4262 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
4266 do iigrid = 1, igridstail
4267 igrid = igrids(iigrid);
4274 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
4277 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
4279 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
4281 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
4294 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
4295 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
4297 if(total_energy)
then
4299 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
4302 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
4310 subroutine rmhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4314 integer,
intent(in) :: ixi^
l, ixo^
l
4315 double precision,
intent(in) :: qt,qdt
4317 double precision,
intent(in) :: wp(ixi^s,1:nw)
4318 type(state) :: sct, s
4319 type(ct_velocity) :: vcts
4320 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4321 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4323 double precision :: circ(ixi^s,1:
ndim)
4325 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4326 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
4327 integer :: idim1,idim2,idir,iwdim1,iwdim2
4329 associate(bfaces=>s%ws,x=>s%x)
4336 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4340 i1kr^
d=
kr(idim1,^
d);
4343 i2kr^
d=
kr(idim2,^
d);
4346 if (
lvc(idim1,idim2,idir)==1)
then
4348 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4350 {
do ix^db=ixcmin^db,ixcmax^db\}
4351 fe(ix^
d,idir)=quarter*&
4352 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
4353 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
4355 if(
rmhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
4357 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
4365 if(
associated(usr_set_electric_field)) &
4366 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4368 circ(ixi^s,1:ndim)=zero
4373 ixcmin^d=ixomin^d-kr(idim1,^d);
4375 ixa^l=ixc^l-kr(idim2,^d);
4378 if(lvc(idim1,idim2,idir)==1)
then
4380 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4383 else if(lvc(idim1,idim2,idir)==-1)
then
4385 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4391 {
do ix^db=ixcmin^db,ixcmax^db\}
4393 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4395 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4402 end subroutine rmhd_update_faces_average
4405 subroutine rmhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4410 integer,
intent(in) :: ixi^
l, ixo^
l
4411 double precision,
intent(in) :: qt, qdt
4413 double precision,
intent(in) :: wp(ixi^s,1:nw)
4414 type(state) :: sct, s
4415 type(ct_velocity) :: vcts
4416 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4417 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4419 double precision :: circ(ixi^s,1:
ndim)
4421 double precision :: ecc(ixi^s,
sdim:3)
4422 double precision :: ein(ixi^s,
sdim:3)
4424 double precision :: el(ixi^s),er(ixi^s)
4426 double precision :: elc,erc
4428 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4430 double precision :: jce(ixi^s,
sdim:3)
4432 double precision :: xs(ixgs^t,1:
ndim)
4433 double precision :: gradi(ixgs^t)
4434 integer :: ixc^
l,ixa^
l
4435 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
4437 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
4440 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4443 {
do ix^db=iximin^db,iximax^db\}
4446 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_)
4447 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_)
4448 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_)
4451 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
4458 {
do ix^db=iximin^db,iximax^db\}
4461 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
4462 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
4463 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4466 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4480 i1kr^d=kr(idim1,^d);
4483 i2kr^d=kr(idim2,^d);
4486 if (lvc(idim1,idim2,idir)==1)
then
4488 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4491 {
do ix^db=ixcmin^db,ixcmax^db\}
4492 fe(ix^d,idir)=quarter*&
4493 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
4494 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
4499 ixamax^d=ixcmax^d+i1kr^d;
4500 {
do ix^db=ixamin^db,ixamax^db\}
4501 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
4502 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
4505 do ix^db=ixcmin^db,ixcmax^db\}
4506 if(vnorm(ix^d,idim1)>0.d0)
then
4508 else if(vnorm(ix^d,idim1)<0.d0)
then
4509 elc=el({ix^d+i1kr^d})
4511 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
4513 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
4515 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
4516 erc=er({ix^d+i1kr^d})
4518 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
4520 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4525 ixamax^d=ixcmax^d+i2kr^d;
4526 {
do ix^db=ixamin^db,ixamax^db\}
4527 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
4528 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
4531 do ix^db=ixcmin^db,ixcmax^db\}
4532 if(vnorm(ix^d,idim2)>0.d0)
then
4534 else if(vnorm(ix^d,idim2)<0.d0)
then
4535 elc=el({ix^d+i2kr^d})
4537 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
4539 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
4541 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
4542 erc=er({ix^d+i2kr^d})
4544 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
4546 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4550 if(
rmhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
4552 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
4566 if (lvc(idim1,idim2,idir)==0) cycle
4568 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4569 ixamax^d=ixcmax^d-kr(idir,^d)+1;
4572 xs(ixa^s,:)=x(ixa^s,:)
4573 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
4574 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
4575 if (lvc(idim1,idim2,idir)==1)
then
4576 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4578 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4585 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4587 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
4591 {
do ix^db=ixomin^db,ixomax^db\}
4592 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4593 +ein(ix1,ix2-1,ix3-1,idir))
4594 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4595 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4597 else if(idir==2)
then
4598 {
do ix^db=ixomin^db,ixomax^db\}
4599 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4600 +ein(ix1-1,ix2,ix3-1,idir))
4601 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4602 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4605 {
do ix^db=ixomin^db,ixomax^db\}
4606 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
4607 +ein(ix1-1,ix2-1,ix3,idir))
4608 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4609 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4615 {
do ix^db=ixomin^db,ixomax^db\}
4616 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
4617 +ein(ix1-1,ix2-1,idir))
4618 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4619 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4624 block%w(ixo^s,nw)=block%w(ixo^s,nw)+jce(ixo^s,idir)
4630 if(
associated(usr_set_electric_field)) &
4631 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4633 circ(ixi^s,1:ndim)=zero
4638 ixcmin^d=ixomin^d-kr(idim1,^d);
4640 ixa^l=ixc^l-kr(idim2,^d);
4643 if(lvc(idim1,idim2,idir)==1)
then
4645 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4648 else if(lvc(idim1,idim2,idir)==-1)
then
4650 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4656 {
do ix^db=ixcmin^db,ixcmax^db\}
4658 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4660 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4667 end subroutine rmhd_update_faces_contact
4670 subroutine rmhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4675 integer,
intent(in) :: ixi^
l, ixo^
l
4676 double precision,
intent(in) :: qt, qdt
4678 double precision,
intent(in) :: wp(ixi^s,1:nw)
4679 type(state) :: sct, s
4680 type(ct_velocity) :: vcts
4681 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4682 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4684 double precision :: vtill(ixi^s,2)
4685 double precision :: vtilr(ixi^s,2)
4686 double precision :: bfacetot(ixi^s,
ndim)
4687 double precision :: btill(ixi^s,
ndim)
4688 double precision :: btilr(ixi^s,
ndim)
4689 double precision :: cp(ixi^s,2)
4690 double precision :: cm(ixi^s,2)
4691 double precision :: circ(ixi^s,1:
ndim)
4693 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4694 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
4695 integer :: idim1,idim2,idir,ix^
d
4697 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
4698 cbarmax=>vcts%cbarmax)
4711 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4724 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
4728 idim2=mod(idir+1,3)+1
4730 jxc^
l=ixc^
l+
kr(idim1,^
d);
4731 ixcp^
l=ixc^
l+
kr(idim2,^
d);
4735 vtill(ixi^s,2),vtilr(ixi^s,2))
4738 vtill(ixi^s,1),vtilr(ixi^s,1))
4744 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
4745 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
4747 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
4748 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
4751 btill(ixi^s,idim1),btilr(ixi^s,idim1))
4754 btill(ixi^s,idim2),btilr(ixi^s,idim2))
4758 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
4759 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
4761 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
4762 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
4766 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
4767 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
4768 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
4769 /(cp(ixc^s,1)+cm(ixc^s,1)) &
4770 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
4771 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
4772 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
4773 /(cp(ixc^s,2)+cm(ixc^s,2))
4776 if(
rmhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
4777 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
4791 circ(ixi^s,1:
ndim)=zero
4796 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
4800 if(
lvc(idim1,idim2,idir)/=0)
then
4801 hxc^
l=ixc^
l-
kr(idim2,^
d);
4803 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4804 +
lvc(idim1,idim2,idir)&
4810 {
do ix^db=ixcmin^db,ixcmax^db\}
4812 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
4814 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
4820 end subroutine rmhd_update_faces_hll
4823 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
4828 integer,
intent(in) :: ixi^
l, ixo^
l
4830 double precision,
intent(in) :: wp(ixi^s,1:nw)
4831 type(state),
intent(in) :: sct, s
4833 double precision :: jce(ixi^s,
sdim:3)
4836 double precision :: jcc(ixi^s,7-2*
ndir:3)
4838 double precision :: xs(ixgs^t,1:
ndim)
4840 double precision :: eta(ixi^s)
4841 double precision :: gradi(ixgs^t)
4842 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
4844 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
4850 if (
lvc(idim1,idim2,idir)==0) cycle
4852 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4853 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
4856 xs(ixb^s,:)=x(ixb^s,:)
4857 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
4858 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
4859 if (
lvc(idim1,idim2,idir)==1)
then
4860 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4862 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4877 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4878 jcc(ixc^s,idir)=0.d0
4880 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4881 ixamin^
d=ixcmin^
d+ix^
d;
4882 ixamax^
d=ixcmax^
d+ix^
d;
4883 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
4885 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
4886 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
4891 end subroutine get_resistive_electric_field
4897 integer,
intent(in) :: ixo^
l
4906 do ix^db=ixomin^db,ixomax^db\}
4908 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4909 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
4910 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4911 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
4912 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
4913 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
4916 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4917 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
4918 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4919 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
4959 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
4960 double precision,
intent(inout) :: ws(ixis^s,1:nws)
4961 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4962 double precision :: adummy(ixis^s,1:3)
4967 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
4970 integer,
intent(in) :: ixi^
l, ixo^
l
4971 double precision,
intent(in) :: w(ixi^s,1:nw)
4972 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4973 double precision,
intent(out):: rfactor(ixi^s)
4974 double precision :: iz_h(ixo^s),iz_he(ixo^s)
4978 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)
4979 end subroutine rfactor_from_temperature_ionization
4981 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
4983 integer,
intent(in) :: ixi^
l, ixo^
l
4984 double precision,
intent(in) :: w(ixi^s,1:nw)
4985 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4986 double precision,
intent(out):: rfactor(ixi^s)
4989 end subroutine rfactor_from_constant_ionization
Module for including anisotropic flux limited diffusion (AFLD)-approximation in Radiation-hydrodynami...
subroutine afld_get_diffcoef_central(w, wct, x, ixil, ixol)
Calculates cell-centered diffusion coefficient to be used in multigrid.
subroutine, public get_afld_rad_force(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
subroutine, public afld_init(he_abundance, rhd_radiation_diffusion, afld_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine, public afld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
subroutine, public afld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
subroutine, public get_afld_energy_interact(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine cak_get_dt(w, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine cak_init(phys_gamma)
Initialize the module.
subroutine cak_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter const_rad_a
subroutine reconstruct(ixil, ixcl, idir, q, ql, qr)
Reconstruct scalar q within ixO^L to 1/2 dx in direction idir Return both left and right reconstructe...
subroutine b_from_vector_potentiala(ixisl, ixil, ixol, ws, x, a)
calculate magnetic field from vector potential A at cell edges
subroutine add_convert_method(phys_convert_vars, nwc, dataset_names, file_suffix)
Module for flux conservation near refinement boundaries.
Nicolas Moens Module for including flux limited diffusion (FLD)-approximation in Radiation-hydrodynam...
subroutine, public get_fld_rad_force(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
subroutine, public fld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
subroutine, public fld_init(he_abundance, radiation_diffusion, energy_interact, r_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine fld_get_diffcoef_central(w, wct, x, ixil, ixol)
Calculates cell-centered diffusion coefficient to be used in multigrid.
character(len=8) fld_diff_scheme
Which method to solve diffusion part.
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
Module with basic grid data structures.
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
subroutine, public get_divb(w, ixil, ixol, divb, nth_in)
Calculate div B within ixO.
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
Module with geometry-related routines (e.g., divergence, curl)
subroutine divvector(qvec, ixil, ixol, divq, nth_in)
integer, parameter spherical
integer, parameter cylindrical
subroutine curlvector(qvec, ixil, ixol, curlvec, idirmin, idirmin0, ndir0, fourthorder)
Calculate curl of a vector qvec within ixL Options to employ standard second order CD evaluations use...
subroutine gradient(q, ixil, ixol, idir, gradq, nth_in)
subroutine gradientf(q, x, ixil, ixol, idir, gradq, nth_in, pm_in)
subroutine gradientl(q, ixil, ixol, idir, gradq)
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
double precision dtdiffpar
For resistive MHD, the time step is also limited by the diffusion time: .
character(len=std_len) typegrad
double precision unit_charge
Physical scaling factor for charge.
integer, parameter bc_noinflow
double precision small_pressure
integer ixghi
Upper index of grid block arrays.
pure subroutine cross_product(ixil, ixol, a, b, axb)
Cross product of two vectors.
integer, dimension(3, 3, 3) lvc
Levi-Civita tensor.
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
double precision unit_opacity
Physical scaling factor for Opacity.
integer, parameter unitpar
file handle for IO
integer, parameter bc_asymm
double precision unit_mass
Physical scaling factor for mass.
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision phys_trac_mask
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
double precision unit_numberdensity
Physical scaling factor for number density.
character(len=std_len) convert_type
Which format to use when converting.
double precision unit_pressure
Physical scaling factor for pressure.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision unit_length
Physical scaling factor for length.
logical stagger_grid
True for using stagger grid.
double precision cmax_global
global fastest wave speed needed in fd scheme and glm method
logical use_particles
Use particles module or not.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer icomm
The MPI communicator.
double precision bdip
amplitude of background dipolar, quadrupolar, octupolar, user's field
integer b0i
background magnetic field location indicator
integer mype
The rank of the current MPI task.
double precision, dimension(:), allocatable, parameter d
logical local_timestep
each cell has its own timestep or not
double precision dt
global time step
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ixm
the mesh range of a physical block without ghost cells
integer ierrmpi
A global MPI error return code.
logical autoconvert
If true, already convert to output format during the run.
logical slab
Cartesian geometry or not.
integer, parameter bc_periodic
integer, parameter bc_special
boundary condition types
double precision unit_magneticfield
Physical scaling factor for magnetic field.
double precision unit_velocity
Physical scaling factor for velocity.
double precision c_norm
Normalised speed of light.
logical b0field
split magnetic field as background B0 field
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision unit_temperature
Physical scaling factor for temperature.
double precision unit_radflux
Physical scaling factor for radiation flux.
integer, parameter bc_cont
logical si_unit
Use SI units (.true.) or use cgs units (.false.)
double precision, dimension(:,:), allocatable dx
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(w, ixil, ixol, dtnew, dxd, x)
subroutine gravity_init()
Initialize the module.
subroutine gravity_add_source(qdt, ixil, ixol, wct, wctprim, w, x, energy, rhov, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
module ionization degree - get ionization degree for given temperature
subroutine ionization_degree_from_temperature(ixil, ixol, te, iz_h, iz_he)
subroutine ionization_degree_init()
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
type(mg_t) mg
Data structure containing the multigrid tree.
Module containing all the particle routines.
subroutine particles_init()
Initialize particle data and parameters.
This module defines the procedures of a physics module. It contains function pointers for the various...
Radiation-magneto-hydrodynamics module.
subroutine, public get_current(w, ixil, ixol, idirmin, current)
Calculate idirmin and the idirmin:3 components of the common current array make sure that dxlevel(^D)...
integer, public, protected rmhd_trac_type
Which TRAC method is used.
character(len=8), public rmhd_pressure
In the case of no rmhd_energy, how to compute pressure.
subroutine, public rmhd_phys_init()
logical, public, protected rmhd_thermal_conduction
Whether thermal conduction is used.
double precision, public rmhd_gamma
The adiabatic index.
character(len=8), public rmhd_radiation_formalism
Formalism to treat radiation.
logical, public divbwave
Add divB wave in Roe solver.
integer, public, protected rmhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
double precision, public, protected h_ion_fr
Ionization fraction of H H_ion_fr = H+/(H+ + H)
integer, dimension(2 *^nd), public, protected boundary_divbfix_skip
To skip * layer of ghost cells during divB=0 fix for boundary.
logical, public, protected rmhd_hyperbolic_thermal_conduction
Whether thermal conduction is used.
double precision, public, protected rr
logical, public rmhd_equi_thermal
double precision, public rmhd_etah
Hall resistivity.
logical, public, protected rmhd_radiation_diffusion
Treat radiation energy diffusion.
subroutine, public rmhd_face_to_center(ixol, s)
calculate cell-center values from face-center values
procedure(sub_get_pthermal), pointer, public rmhd_get_pthermal
integer, public, protected psi_
Indices of the GLM psi.
type(tc_fluid), allocatable, public tc_fl
type of fluid for thermal conduction
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
subroutine, public b_from_vector_potential(ixisl, ixil, ixol, ws, x)
calculate magnetic field from vector potential
logical, public, protected rmhd_cak_force
Whether CAK radiation line force is activated.
logical, public, protected rmhd_radiation_force
Treat radiation fld_Rad_force.
logical, public, protected rmhd_glm
Whether GLM-MHD is used to control div B.
double precision, public, protected small_r_e
The smallest allowed radiation energy.
double precision, public rmhd_eta_hyper
The MHD hyper-resistivity.
logical, public clean_initial_divb
clean initial divB
integer, public, protected rmhd_n_tracer
Number of tracer species.
logical, public, protected rmhd_particles
Whether particles module is added.
integer, public, protected b
double precision, public kbmpmua4
kb/(m_p mu)* 1/a_rad**4,
integer, public, protected m
subroutine, public rmhd_get_trad(w, x, ixil, ixol, trad)
Calculates radiation temperature.
integer, public equi_rho0_
equi vars indices in the stateequi_vars array
double precision, public rmhd_adiab
The adiabatic constant.
subroutine, public rmhd_get_pthermal_plus_pradiation(w, x, ixil, ixol, pth_plus_prad)
Calculates the sum of the gas pressure and the max Prad tensor element.
integer, public, protected q_
Index of the heat flux q.
integer, public, protected tweight_
logical, public has_equi_rho0
whether split off equilibrium density
double precision, public rmhd_eta
The MHD resistivity.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
subroutine, public get_normalized_divb(w, ixil, ixol, divb)
get dimensionless div B = |divB| * volume / area / |B|
integer, public, protected rho_
Index of the density (in the w array)
integer, public, protected c_
double precision function, dimension(ixo^s), public rmhd_mag_en_all(w, ixil, ixol)
Compute 2 times total magnetic energy.
type(te_fluid), allocatable, public te_fl_rmhd
type of fluid for thermal emission synthesis
logical, public, protected rmhd_gravity
Whether gravity is added.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
logical, public, protected rmhd_glm_extended
Whether extended GLM-MHD is used with additional sources.
logical, public, protected rmhd_viscosity
Whether viscosity is added.
logical, public, protected rmhd_partial_ionization
Whether plasma is partially ionized.
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
integer, public, protected e_
Index of the energy density (-1 if not present)
logical, public, protected rmhd_radiation_advection
Treat radiation advection.
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
subroutine, public rmhd_get_rho(w, x, ixil, ixol, rho)
integer, dimension(:), allocatable, public, protected tracer
Indices of the tracers.
logical, public, protected rmhd_energy_interact
Treat radiation-gas energy interaction.
subroutine, public rmhd_get_tgas(w, x, ixil, ixol, tgas)
Calculates gas temperature.
character(len=std_len), public, protected type_ct
Method type of constrained transport.
procedure(sub_convert), pointer, public rmhd_to_conserved
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
logical, public partial_energy
Whether an internal or hydrodynamic energy equation is used.
procedure(sub_convert), pointer, public rmhd_to_primitive
logical, public, protected rmhd_dump_full_vars
whether dump full variables (when splitting is used) in a separate dat file
logical, public, protected rmhd_trac
Whether TRAC method is used.
subroutine, public rmhd_clean_divb_multigrid(qdt, qt, active)
subroutine, public rmhd_set_mg_bounds
Set the boundaries for the diffusion of E.
subroutine, public rmhd_get_v(w, x, ixil, ixol, v)
Calculate v vector.
double precision, public hypertc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
logical, public has_equi_pe0
whether split off equilibrium thermal pressure
subroutine, public rmhd_get_pradiation(w, x, ixil, ixol, prad, nth)
Calculate radiation pressure within ixO^L.
integer, public, protected te_
Indices of temperature.
logical, public, protected source_split_divb
Whether divB cleaning sources are added splitting from fluid solver.
integer, public, protected r_e
Index of the radiation energy.
procedure(sub_get_pthermal), pointer, public rmhd_get_temperature
character(len=std_len), public, protected typedivbfix
Method type to clean divergence of B.
logical, public, protected b0field_forcefree
B0 field is force-free.
double precision, public rmhd_glm_alpha
GLM-MHD parameter: ratio of the diffusive and advective time scales for div b taking values within [0...
integer, public, protected rmhd_divb_nth
Whether divB is computed with a fourth order approximation.
subroutine, public rmhd_ei_to_e(ixil, ixol, w, x)
Transform internal energy to total energy.
integer, public equi_pe0_
double precision, public, protected he_ion_fr
Ionization fraction of He He_ion_fr = (He2+ + He+)/(He2+ + He+ + He)
logical, public, protected rmhd_energy
Whether an energy equation is used.
logical, dimension(2 *^nd), public, protected boundary_divbfix
To control divB=0 fix for boundary.
double precision, public, protected rmhd_trac_mask
Height of the mask used in the TRAC method.
logical, public, protected eq_state_units
subroutine, public rmhd_e_to_ei(ixil, ixol, w, x)
Transform total energy to internal energy.
logical, public, protected rmhd_4th_order
MHD fourth order.
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method 1) in amrvac.par in sts_list set the following parameters which have...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
double precision function, public get_tc_dt_mhd(w, ixil, ixol, dxd, x, fl)
Get the explicut timestep for the TC (mhd implementation)
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine, public tc_get_mhd_params(fl, read_mhd_params)
Init TC coefficients: MHD case.
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_equi_vars), pointer usr_set_equi_vars
procedure(special_mg_bc), pointer usr_special_mg_bc
procedure(set_electric_field), pointer usr_set_electric_field
The module add viscous source terms and check time step.
subroutine viscosity_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
subroutine viscosity_init(phys_wider_stencil)
Initialize the module.
subroutine viscosity_get_dt(w, ixil, ixol, dtnew, dxd, x)
The data structure that contains information about a tree node/grid block.