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 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
186 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
188 character(len=std_len) :: typedivbdiff =
'all'
228 subroutine rmhd_read_params(files)
231 character(len=*),
intent(in) :: files(:)
249 do n = 1,
size(files)
250 open(
unitpar, file=trim(files(n)), status=
"old")
251 read(
unitpar, rmhd_list,
end=111)
255 end subroutine rmhd_read_params
258 subroutine rmhd_write_info(fh)
260 integer,
intent(in) :: fh
262 integer,
parameter :: n_par = 1
263 double precision :: values(n_par)
264 integer,
dimension(MPI_STATUS_SIZE) :: st
265 character(len=name_len) :: names(n_par)
267 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
271 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
272 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
273 end subroutine rmhd_write_info
299 if(
mype==0)
write(*,*)
'WARNING: set rmhd_partial_ionization=F when eq_state_units=F'
305 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
308 physics_type =
"rmhd"
323 phys_total_energy=total_energy
325 gravity_energy=.true.
327 gravity_energy=.false.
333 if(
mype==0)
write(*,*)
'WARNING: reset rmhd_trac_type=1 for 1D simulation'
338 if(
mype==0)
write(*,*)
'WARNING: set rmhd_trac_mask==bigdouble for global TRAC method'
347 type_divb = divb_none
350 type_divb = divb_multigrid
352 mg%operator_type = mg_laplacian
359 case (
'powel',
'powell')
360 type_divb = divb_powel
362 type_divb = divb_janhunen
364 type_divb = divb_linde
365 case (
'lindejanhunen')
366 type_divb = divb_lindejanhunen
368 type_divb = divb_lindepowel
372 type_divb = divb_lindeglm
377 call mpistop(
'Unknown divB fix')
380 allocate(start_indices(number_species),stop_indices(number_species))
387 mom(:) = var_set_momentum(
ndir)
393 e_ = var_set_energy()
402 mag(:) = var_set_bfield(
ndir)
406 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
412 r_e = var_set_radiation_energy()
425 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
438 te_ = var_set_auxvar(
'Te',
'Te')
447 stop_indices(1)=nwflux
477 allocate(iw_vector(nvector))
478 iw_vector(1) = mom(1) - 1
479 iw_vector(2) = mag(1) - 1
482 if (.not.
allocated(flux_type))
then
483 allocate(flux_type(
ndir, nwflux))
484 flux_type = flux_default
485 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
486 call mpistop(
"phys_check error: flux_type has wrong shape")
489 if(nwflux>mag(
ndir))
then
491 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
496 flux_type(:,
psi_)=flux_special
498 flux_type(idir,mag(idir))=flux_special
502 flux_type(idir,mag(idir))=flux_tvdlf
508 phys_get_dt => rmhd_get_dt
509 phys_get_cmax => rmhd_get_cmax_origin
510 phys_get_a2max => rmhd_get_a2max
511 phys_get_tcutoff => rmhd_get_tcutoff
512 phys_get_h_speed => rmhd_get_h_speed
514 phys_get_cbounds => rmhd_get_cbounds_split_rho
516 phys_get_cbounds => rmhd_get_cbounds
519 phys_to_primitive => rmhd_to_primitive_split_rho
521 phys_to_conserved => rmhd_to_conserved_split_rho
524 phys_to_primitive => rmhd_to_primitive_origin
526 phys_to_conserved => rmhd_to_conserved_origin
530 phys_get_flux => rmhd_get_flux_split
532 phys_get_flux => rmhd_get_flux
536 phys_add_source_geom => rmhd_add_source_geom_split
538 phys_add_source_geom => rmhd_add_source_geom
540 phys_add_source => rmhd_add_source
541 phys_check_params => rmhd_check_params
542 phys_write_info => rmhd_write_info
544 phys_handle_small_values => rmhd_handle_small_values_origin
545 rmhd_handle_small_values => rmhd_handle_small_values_origin
546 phys_check_w => rmhd_check_w_origin
552 phys_get_pthermal => rmhd_get_pthermal_origin
556 phys_set_equi_vars => set_equi_vars_grid
559 if(type_divb==divb_glm)
then
560 phys_modify_wlr => rmhd_modify_wlr
565 rmhd_get_rfactor=>rfactor_from_temperature_ionization
566 phys_update_temperature => rmhd_update_temperature
570 rmhd_get_rfactor=>rfactor_from_constant_ionization
587 transverse_ghost_cells = 1
588 phys_get_ct_velocity => rmhd_get_ct_velocity_average
589 phys_update_faces => rmhd_update_faces_average
591 transverse_ghost_cells = 1
592 phys_get_ct_velocity => rmhd_get_ct_velocity_contact
593 phys_update_faces => rmhd_update_faces_contact
595 transverse_ghost_cells = 2
596 phys_get_ct_velocity => rmhd_get_ct_velocity_hll
597 phys_update_faces => rmhd_update_faces_hll
599 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
602 phys_modify_wlr => rmhd_modify_wlr
604 phys_boundary_adjust => rmhd_boundary_adjust
613 call rmhd_physical_units()
622 call mpistop(
'Radiation formalism unknown')
629 call mpistop(
"thermal conduction needs rmhd_energy=T")
632 call mpistop(
"hyperbolic thermal conduction needs rmhd_energy=T")
642 call add_sts_method(rmhd_get_tc_dt_rmhd,rmhd_sts_set_source_tc_rmhd,e_,1,e_,1,.false.)
644 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot_with_equi
646 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot
649 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint_with_equi
651 tc_fl%has_equi = .true.
652 tc_fl%get_temperature_equi => rmhd_get_temperature_equi
653 tc_fl%get_rho_equi => rmhd_get_rho_equi
655 tc_fl%has_equi = .false.
658 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint
670 te_fl_rmhd%get_var_Rfactor => rmhd_get_rfactor
672 phys_te_images => rmhd_te_images
685 if (particles_eta < zero) particles_eta =
rmhd_eta
686 if (particles_etah < zero) particles_eta =
rmhd_etah
688 write(*,*)
'*****Using particles: with rmhd_eta, rmhd_etah :',
rmhd_eta,
rmhd_etah
689 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
701 subroutine rmhd_te_images
706 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
708 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
710 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
712 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
715 call mpistop(
"Error in synthesize emission: Unknown convert_type")
717 end subroutine rmhd_te_images
723 subroutine rmhd_sts_set_source_tc_rmhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
727 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
728 double precision,
intent(in) :: x(ixi^s,1:
ndim)
729 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
730 double precision,
intent(in) :: my_dt
731 logical,
intent(in) :: fix_conserve_at_step
733 end subroutine rmhd_sts_set_source_tc_rmhd
735 function rmhd_get_tc_dt_rmhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
741 integer,
intent(in) :: ixi^
l, ixo^
l
742 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
743 double precision,
intent(in) :: w(ixi^s,1:nw)
744 double precision :: dtnew
747 end function rmhd_get_tc_dt_rmhd
749 subroutine rmhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
751 integer,
intent(in) :: ixi^
l,ixo^
l
752 double precision,
intent(inout) :: w(ixi^s,1:nw)
753 double precision,
intent(in) :: x(ixi^s,1:
ndim)
754 integer,
intent(in) :: step
755 character(len=140) :: error_msg
757 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
758 call rmhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
759 end subroutine rmhd_tc_handle_small_e
762 subroutine tc_params_read_rmhd(fl)
764 type(tc_fluid),
intent(inout) :: fl
765 double precision :: tc_k_para=0d0
766 double precision :: tc_k_perp=0d0
769 logical :: tc_perpendicular=.false.
770 logical :: tc_saturate=.false.
771 character(len=std_len) :: tc_slope_limiter=
"MC"
773 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp
777 read(
unitpar, tc_list,
end=111)
781 fl%tc_perpendicular = tc_perpendicular
782 fl%tc_saturate = tc_saturate
783 fl%tc_k_para = tc_k_para
784 fl%tc_k_perp = tc_k_perp
785 select case(tc_slope_limiter)
787 fl%tc_slope_limiter = 0
790 fl%tc_slope_limiter = 1
793 fl%tc_slope_limiter = 2
796 fl%tc_slope_limiter = 3
799 fl%tc_slope_limiter = 4
801 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod")
803 end subroutine tc_params_read_rmhd
807 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
810 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
811 double precision,
intent(in) :: x(ixi^s,1:
ndim)
812 double precision :: delx(ixi^s,1:
ndim)
813 double precision :: xc(ixi^s,1:
ndim),xshift^
d
814 integer :: idims, ixc^
l, hxo^
l, ix, idims2
820 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
824 hxo^
l=ixo^
l-
kr(idims,^
d);
830 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
833 xshift^
d=half*(one-
kr(^
d,idims));
840 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
844 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
846 end subroutine set_equi_vars_grid_faces
849 subroutine set_equi_vars_grid(igrid)
852 integer,
intent(in) :: igrid
858 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
859 end subroutine set_equi_vars_grid
862 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
864 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
865 double precision,
intent(in) :: w(ixi^s, 1:nw)
866 double precision,
intent(in) :: x(ixi^s,1:
ndim)
867 double precision :: wnew(ixo^s, 1:nwc)
874 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
880 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
884 wnew(ixo^s,
e_)=w(ixo^s,
e_)
888 if(
b0field .and. total_energy)
then
889 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
890 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
893 end function convert_vars_splitting
895 subroutine rmhd_check_params
903 if (
rmhd_gamma <= 0.0d0)
call mpistop (
"Error: rmhd_gamma <= 0")
904 if (
rmhd_adiab < 0.0d0)
call mpistop (
"Error: rmhd_adiab < 0")
908 call mpistop (
"Error: rmhd_gamma <= 0 or rmhd_gamma == 1")
909 inv_gamma_1=1.d0/gamma_1
916 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
921 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
928 end subroutine rmhd_check_params
942 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
943 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
946 mg%bc(ib, mg_iphi)%bc_type = mg_bc_dirichlet
947 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
951 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
952 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
960 call mpistop(
"divE_multigrid warning: unknown b.c. ")
965 subroutine rmhd_physical_units()
967 double precision :: mp,kb,miu0,c_lightspeed
968 double precision :: a,
b
1113 end subroutine rmhd_physical_units
1115 subroutine rmhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1117 logical,
intent(in) :: primitive
1118 integer,
intent(in) :: ixi^
l, ixo^
l
1119 double precision,
intent(in) :: w(ixi^s,nw)
1120 logical,
intent(inout) :: flag(ixi^s,1:nw)
1121 double precision :: tmp
1125 {
do ix^db=ixomin^db,ixomax^db\}
1139 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1143 if(tmp<small_e) flag(ix^
d,
e_) = .true.
1148 end subroutine rmhd_check_w_origin
1151 subroutine rmhd_to_conserved_origin(ixI^L,ixO^L,w,x)
1153 integer,
intent(in) :: ixi^
l, ixo^
l
1154 double precision,
intent(inout) :: w(ixi^s, nw)
1155 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1158 {
do ix^db=ixomin^db,ixomax^db\}
1160 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1162 +(^
c&w(ix^
d,
b^
c_)**2+))
1166 end subroutine rmhd_to_conserved_origin
1169 subroutine rmhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
1171 integer,
intent(in) :: ixi^
l, ixo^
l
1172 double precision,
intent(inout) :: w(ixi^s, nw)
1173 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1174 double precision :: rho
1177 {
do ix^db=ixomin^db,ixomax^db\}
1180 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1181 +half*((^
c&w(ix^
d,
m^
c_)**2+)*rho&
1182 +(^
c&w(ix^
d,
b^
c_)**2+))
1186 end subroutine rmhd_to_conserved_split_rho
1189 subroutine rmhd_to_primitive_origin(ixI^L,ixO^L,w,x)
1191 integer,
intent(in) :: ixi^
l, ixo^
l
1192 double precision,
intent(inout) :: w(ixi^s, nw)
1193 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1194 double precision :: inv_rho
1199 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_origin')
1202 {
do ix^db=ixomin^db,ixomax^db\}
1203 inv_rho = 1.d0/w(ix^
d,
rho_)
1207 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1209 +(^
c&w(ix^
d,
b^
c_)**2+)))
1211 end subroutine rmhd_to_primitive_origin
1214 subroutine rmhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
1216 integer,
intent(in) :: ixi^
l, ixo^
l
1217 double precision,
intent(inout) :: w(ixi^s, nw)
1218 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1219 double precision :: inv_rho
1224 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_split_rho')
1227 {
do ix^db=ixomin^db,ixomax^db\}
1232 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1234 (^
c&w(ix^
d,
m^
c_)**2+)+(^
c&w(ix^
d,
b^
c_)**2+)))
1236 end subroutine rmhd_to_primitive_split_rho
1241 integer,
intent(in) :: ixi^
l, ixo^
l
1242 double precision,
intent(inout) :: w(ixi^s, nw)
1243 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1248 {
do ix^db=ixomin^db,ixomax^db\}
1251 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1253 +(^
c&w(ix^
d,
b^
c_)**2+))
1256 {
do ix^db=ixomin^db,ixomax^db\}
1258 w(ix^d,
e_)=w(ix^d,
e_)&
1259 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1260 +(^
c&w(ix^d,
b^
c_)**2+))
1268 integer,
intent(in) :: ixi^
l, ixo^
l
1269 double precision,
intent(inout) :: w(ixi^s, nw)
1270 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1275 {
do ix^db=ixomin^db,ixomax^db\}
1278 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1280 +(^
c&w(ix^
d,
b^
c_)**2+))
1283 {
do ix^db=ixomin^db,ixomax^db\}
1285 w(ix^d,
e_)=w(ix^d,
e_)&
1286 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1287 +(^
c&w(ix^d,
b^
c_)**2+))
1291 if(fix_small_values)
then
1292 call rmhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'rmhd_e_to_ei')
1296 subroutine rmhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
1299 logical,
intent(in) :: primitive
1300 integer,
intent(in) :: ixi^
l,ixo^
l
1301 double precision,
intent(inout) :: w(ixi^s,1:nw)
1302 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1303 character(len=*),
intent(in) :: subname
1304 double precision :: rho
1305 integer :: idir, ix^
d
1306 logical :: flag(ixi^s,1:nw)
1308 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
1312 {
do ix^db=ixomin^db,ixomax^db\}
1322 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
1334 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))&
1338 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))
1345 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
1347 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
1350 {
do ix^db=iximin^db,iximax^db\}
1356 w(ix^d,
e_)=w(ix^d,
e_)&
1357 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1359 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
1361 {
do ix^db=iximin^db,iximax^db\}
1367 w(ix^d,
e_)=w(ix^d,
e_)&
1368 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1371 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
1373 if(.not.primitive)
then
1376 {
do ix^db=iximin^db,iximax^db\}
1382 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
1383 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
1384 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+)))
1387 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
1390 end subroutine rmhd_handle_small_values_origin
1395 integer,
intent(in) :: ixi^
l, ixo^
l
1396 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
1397 double precision,
intent(out) :: v(ixi^s,
ndir)
1398 double precision :: rho(ixi^s)
1402 rho(ixo^s)=1.d0/rho(ixo^s)
1405 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
1410 subroutine rmhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
1412 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1413 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1414 double precision,
intent(inout) :: cmax(ixi^s)
1415 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1419 {
do ix^db=ixomin^db,ixomax^db \}
1430 cfast2=b2*inv_rho+cmax(ix^
d)
1431 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
1432 if(avmincs2<zero) avmincs2=zero
1433 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1434 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
1437 {
do ix^db=ixomin^db,ixomax^db \}
1447 b2=(^
c&w(ix^d,
b^
c_)**2+)
1448 cfast2=b2*inv_rho+cmax(ix^d)
1449 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1450 if(avmincs2<zero) avmincs2=zero
1451 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1452 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
1455 end subroutine rmhd_get_cmax_origin
1457 subroutine rmhd_get_a2max(w,x,ixI^L,ixO^L,a2max)
1459 integer,
intent(in) :: ixi^
l, ixo^
l
1460 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1461 double precision,
intent(inout) :: a2max(
ndim)
1462 double precision :: a2(ixi^s,
ndim,nw)
1463 integer :: gxo^
l,hxo^
l,jxo^
l,kxo^
l,i,j
1468 hxo^
l=ixo^
l-
kr(i,^
d);
1469 gxo^
l=hxo^
l-
kr(i,^
d);
1470 jxo^
l=ixo^
l+
kr(i,^
d);
1471 kxo^
l=jxo^
l+
kr(i,^
d);
1472 a2(ixo^s,i,1:nw)=abs(-w(kxo^s,1:nw)+16.d0*w(jxo^s,1:nw)&
1473 -30.d0*w(ixo^s,1:nw)+16.d0*w(hxo^s,1:nw)-w(gxo^s,1:nw))
1474 a2max(i)=maxval(a2(ixo^s,i,1:nw))/12.d0/
dxlevel(i)**2
1476 end subroutine rmhd_get_a2max
1479 subroutine rmhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
1482 integer,
intent(in) :: ixi^
l,ixo^
l
1483 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1484 double precision,
intent(out) :: tco_local,tmax_local
1486 double precision,
intent(inout) :: w(ixi^s,1:nw)
1487 double precision,
parameter :: trac_delta=0.25d0
1488 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s)
1489 double precision,
dimension(ixI^S,1:ndir) :: bunitvec
1490 double precision,
dimension(ixI^S,1:ndim) :: gradt
1491 double precision :: bdir(
ndim)
1492 double precision :: ltrc,ltrp,altr(ixi^s)
1493 integer :: idims,jxo^
l,hxo^
l,ixa^
d,ixb^
d,ix^
d
1494 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
1495 logical :: lrlt(ixi^s)
1498 call rmhd_get_temperature_from_te(w,x,ixi^
l,ixi^
l,te)
1500 call rmhd_get_rfactor(w,x,ixi^
l,ixi^
l,te)
1501 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
1504 tmax_local=maxval(te(ixo^s))
1514 lts(ixo^s)=0.5d0*abs(te(jxo^s)-te(hxo^s))/te(ixo^s)
1516 where(lts(ixo^s) > trac_delta)
1519 if(any(lrlt(ixo^s)))
then
1520 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
1531 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
1532 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1533 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
1534 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
1536 call mpistop(
"rmhd_trac_type not allowed for 1D simulation")
1548 gradt(ixo^s,idims)=tmp1(ixo^s)
1552 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))+
block%B0(ixo^s,:,0)
1554 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))
1560 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
1563 if(sum(bdir(:)**2) .gt. zero)
then
1564 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
1566 block%special_values(3:ndim+2)=bdir(1:ndim)
1568 tmp1(ixo^s)=dsqrt(sum(bunitvec(ixo^s,:)**2,dim=ndim+1))
1569 where(tmp1(ixo^s)/=0.d0)
1570 tmp1(ixo^s)=1.d0/tmp1(ixo^s)
1572 tmp1(ixo^s)=bigdouble
1576 bunitvec(ixo^s,idims)=bunitvec(ixo^s,idims)*tmp1(ixo^s)
1579 lts(ixo^s)=abs(sum(gradt(ixo^s,1:ndim)*bunitvec(ixo^s,1:ndim),dim=ndim+1))/te(ixo^s)
1581 if(slab_uniform)
then
1582 lts(ixo^s)=minval(dxlevel)*lts(ixo^s)
1584 lts(ixo^s)=minval(block%ds(ixo^s,:),dim=ndim+1)*lts(ixo^s)
1587 where(lts(ixo^s) > trac_delta)
1590 if(any(lrlt(ixo^s)))
then
1591 block%special_values(1)=maxval(te(ixo^s), mask=lrlt(ixo^s))
1593 block%special_values(1)=zero
1595 block%special_values(2)=tmax_local
1614 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1615 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1616 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1619 {
do ix^db=ixpmin^db,ixpmax^db\}
1621 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))+block%B0(ix^d,^
c,0)\
1623 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))\
1625 tmp1(ix^d)=1.d0/(dsqrt(^
c&bunitvec(ix^d,^
c)**2+)+smalldouble)
1627 ^d&bunitvec({ix^d},^d)=bunitvec({ix^d},^d)*tmp1({ix^d})\
1629 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec({ix^d},^d)+)/te(ix^d)
1631 if(slab_uniform)
then
1632 lts(ix^d)=min(^d&dxlevel(^d))*lts(ix^d)
1634 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
1636 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
1641 hxo^l=ixp^l-kr(idims,^d);
1642 jxo^l=ixp^l+kr(idims,^d);
1644 altr(ixp^s)=0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1646 altr(ixp^s)=altr(ixp^s)+0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1649 block%wextra(ixp^s,
tcoff_)=te(ixp^s)*altr(ixp^s)**0.4d0
1653 call mpistop(
"unknown rmhd_trac_type")
1656 end subroutine rmhd_get_tcutoff
1659 subroutine rmhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
1662 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1663 double precision,
intent(in) :: wprim(ixi^s, nw)
1664 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1665 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
1667 double precision :: csound(ixi^s,
ndim)
1668 double precision,
allocatable :: tmp(:^
d&)
1669 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
1673 allocate(tmp(ixa^s))
1675 call rmhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
1676 csound(ixa^s,id)=tmp(ixa^s)
1679 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
1680 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
1681 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
1682 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))
1686 ixamax^
d=ixcmax^
d+
kr(id,^
d);
1687 ixamin^
d=ixcmin^
d+
kr(id,^
d);
1688 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)))
1689 ixamax^
d=ixcmax^
d-
kr(id,^
d);
1690 ixamin^
d=ixcmin^
d-
kr(id,^
d);
1691 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)))
1696 ixamax^
d=jxcmax^
d+
kr(id,^
d);
1697 ixamin^
d=jxcmin^
d+
kr(id,^
d);
1698 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)))
1699 ixamax^
d=jxcmax^
d-
kr(id,^
d);
1700 ixamin^
d=jxcmin^
d-
kr(id,^
d);
1701 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)))
1705 end subroutine rmhd_get_h_speed
1708 subroutine rmhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1710 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1711 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1712 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1713 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1714 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1715 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1716 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1718 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1719 double precision :: umean, dmean, tmp1, tmp2, tmp3
1726 call rmhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1727 call rmhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1728 if(
present(cmin))
then
1729 {
do ix^db=ixomin^db,ixomax^db\}
1730 tmp1=sqrt(wlp(ix^
d,
rho_))
1731 tmp2=sqrt(wrp(ix^
d,
rho_))
1732 tmp3=1.d0/(tmp1+tmp2)
1733 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1734 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1735 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1736 cmin(ix^
d,1)=umean-dmean
1737 cmax(ix^
d,1)=umean+dmean
1739 if(h_correction)
then
1740 {
do ix^db=ixomin^db,ixomax^db\}
1741 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1742 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1746 {
do ix^db=ixomin^db,ixomax^db\}
1747 tmp1=sqrt(wlp(ix^d,
rho_))
1748 tmp2=sqrt(wrp(ix^d,
rho_))
1749 tmp3=1.d0/(tmp1+tmp2)
1750 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1751 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1752 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1753 cmax(ix^d,1)=abs(umean)+dmean
1757 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1758 call rmhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
1759 if(
present(cmin))
then
1760 {
do ix^db=ixomin^db,ixomax^db\}
1761 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1762 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1764 if(h_correction)
then
1765 {
do ix^db=ixomin^db,ixomax^db\}
1766 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1767 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1771 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1775 call rmhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
1776 call rmhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
1777 if(
present(cmin))
then
1778 {
do ix^db=ixomin^db,ixomax^db\}
1779 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1780 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1781 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1783 if(h_correction)
then
1784 {
do ix^db=ixomin^db,ixomax^db\}
1785 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1786 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1790 {
do ix^db=ixomin^db,ixomax^db\}
1791 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1792 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1796 end subroutine rmhd_get_cbounds
1799 subroutine rmhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1801 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1802 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1803 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1804 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1805 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1806 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1807 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1808 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1809 double precision :: umean, dmean, tmp1, tmp2, tmp3
1816 call rmhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1817 call rmhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1818 if(
present(cmin))
then
1819 {
do ix^db=ixomin^db,ixomax^db\}
1822 tmp3=1.d0/(tmp1+tmp2)
1823 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1824 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1825 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1826 cmin(ix^
d,1)=umean-dmean
1827 cmax(ix^
d,1)=umean+dmean
1829 if(h_correction)
then
1830 {
do ix^db=ixomin^db,ixomax^db\}
1831 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1832 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1836 {
do ix^db=ixomin^db,ixomax^db\}
1839 tmp3=1.d0/(tmp1+tmp2)
1840 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1841 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1842 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1843 cmax(ix^d,1)=abs(umean)+dmean
1847 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1848 call rmhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
1849 if(
present(cmin))
then
1850 {
do ix^db=ixomin^db,ixomax^db\}
1851 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1852 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1854 if(h_correction)
then
1855 {
do ix^db=ixomin^db,ixomax^db\}
1856 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1857 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1861 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1865 call rmhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
1866 call rmhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
1867 if(
present(cmin))
then
1868 {
do ix^db=ixomin^db,ixomax^db\}
1869 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1870 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1871 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1873 if(h_correction)
then
1874 {
do ix^db=ixomin^db,ixomax^db\}
1875 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1876 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1880 {
do ix^db=ixomin^db,ixomax^db\}
1881 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1882 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1886 end subroutine rmhd_get_cbounds_split_rho
1889 subroutine rmhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1892 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1893 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1894 double precision,
intent(in) :: cmax(ixi^s)
1895 double precision,
intent(in),
optional :: cmin(ixi^s)
1896 type(ct_velocity),
intent(inout):: vcts
1898 end subroutine rmhd_get_ct_velocity_average
1900 subroutine rmhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1903 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1904 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1905 double precision,
intent(in) :: cmax(ixi^s)
1906 double precision,
intent(in),
optional :: cmin(ixi^s)
1907 type(ct_velocity),
intent(inout):: vcts
1910 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
1912 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
1914 end subroutine rmhd_get_ct_velocity_contact
1916 subroutine rmhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1919 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1920 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1921 double precision,
intent(in) :: cmax(ixi^s)
1922 double precision,
intent(in),
optional :: cmin(ixi^s)
1923 type(ct_velocity),
intent(inout):: vcts
1925 integer :: idime,idimn
1927 if(.not.
allocated(vcts%vbarC))
then
1928 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
1929 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
1932 if(
present(cmin))
then
1933 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
1934 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1936 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1937 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
1940 idimn=mod(idim,
ndir)+1
1941 idime=mod(idim+1,
ndir)+1
1943 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
1944 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
1945 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
1946 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1947 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1949 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
1950 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
1951 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
1952 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1953 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1955 end subroutine rmhd_get_ct_velocity_hll
1958 subroutine rmhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
1960 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1961 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1962 double precision,
intent(out):: csound(ixo^s)
1963 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
1964 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1965 double precision :: prad_max(ixo^s)
1970 if(radio_acoustic_filter)
then
1971 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
1975 {
do ix^db=ixomin^db,ixomax^db \}
1976 inv_rho=1.d0/w(ix^
d,
rho_)
1977 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1979 csound(ix^
d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
1984 cfast2=b2*inv_rho+csound(ix^
d)
1985 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
1987 if(avmincs2<zero) avmincs2=zero
1988 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1991 {
do ix^db=ixomin^db,ixomax^db \}
1992 inv_rho=1.d0/w(ix^d,
rho_)
1993 prad_max(ix^d)=maxval(prad_tensor(ix^d,:,:))
1995 csound(ix^d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+prad_max(ix^d))*inv_rho
1999 b2=(^
c&w(ix^d,
b^
c_)**2+)
2000 cfast2=b2*inv_rho+csound(ix^d)
2001 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2002 if(avmincs2<zero) avmincs2=zero
2003 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2006 end subroutine rmhd_get_csound_prim
2009 subroutine rmhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
2011 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2012 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2013 double precision,
intent(out):: csound(ixo^s)
2014 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
2015 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2016 double precision :: prad_max(ixo^s)
2021 if (radio_acoustic_filter)
then
2022 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2027 {
do ix^db=ixomin^db,ixomax^db \}
2030 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2035 cfast2=b2*inv_rho+csound(ix^
d)
2036 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
2038 if(avmincs2<zero) avmincs2=zero
2039 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2042 {
do ix^db=ixomin^db,ixomax^db \}
2045 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
2047 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
2049 b2=(^
c&w(ix^d,
b^
c_)**2+)
2050 cfast2=b2*inv_rho+csound(ix^d)
2051 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2052 if(avmincs2<zero) avmincs2=zero
2053 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2056 end subroutine rmhd_get_csound_prim_split
2059 subroutine rmhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
2063 integer,
intent(in) :: ixi^
l, ixo^
l
2064 double precision,
intent(in) :: w(ixi^s,nw)
2065 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2066 double precision,
intent(out):: pth(ixi^s)
2070 {
do ix^db=ixomin^db,ixomax^db\}
2075 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)&
2076 +(^
c&w(ix^
d,
b^
c_)**2+)))
2081 if(check_small_values.and..not.fix_small_values)
then
2082 {
do ix^db=ixomin^db,ixomax^db\}
2083 if(pth(ix^d)<small_pressure)
then
2084 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
2085 " encountered when call rmhd_get_pthermal"
2086 write(*,*)
"Iteration: ", it,
" Time: ", global_time
2087 write(*,*)
"Location: ", x(ix^d,:)
2088 write(*,*)
"Cell number: ", ix^d
2090 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
2093 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
2094 write(*,*)
"Saving status at the previous time step"
2099 end subroutine rmhd_get_pthermal_origin
2102 subroutine rmhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
2104 integer,
intent(in) :: ixi^
l, ixo^
l
2105 double precision,
intent(in) :: w(ixi^s, 1:nw)
2106 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2107 double precision,
intent(out):: res(ixi^s)
2108 res(ixo^s) = w(ixo^s,
te_)
2109 end subroutine rmhd_get_temperature_from_te
2112 subroutine rmhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
2114 integer,
intent(in) :: ixi^
l, ixo^
l
2115 double precision,
intent(in) :: w(ixi^s, 1:nw)
2116 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2117 double precision,
intent(out):: res(ixi^s)
2118 double precision :: r(ixi^s)
2120 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2121 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
2122 end subroutine rmhd_get_temperature_from_eint
2125 subroutine rmhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
2127 integer,
intent(in) :: ixi^
l, ixo^
l
2128 double precision,
intent(in) :: w(ixi^s, 1:nw)
2129 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2130 double precision,
intent(out):: res(ixi^s)
2131 double precision :: r(ixi^s)
2133 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2135 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
2136 end subroutine rmhd_get_temperature_from_etot
2138 subroutine rmhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
2140 integer,
intent(in) :: ixi^
l, ixo^
l
2141 double precision,
intent(in) :: w(ixi^s, 1:nw)
2142 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2143 double precision,
intent(out):: res(ixi^s)
2144 double precision :: r(ixi^s)
2146 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2149 end subroutine rmhd_get_temperature_from_etot_with_equi
2151 subroutine rmhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
2153 integer,
intent(in) :: ixi^
l, ixo^
l
2154 double precision,
intent(in) :: w(ixi^s, 1:nw)
2155 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2156 double precision,
intent(out):: res(ixi^s)
2157 double precision :: r(ixi^s)
2159 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2162 end subroutine rmhd_get_temperature_from_eint_with_equi
2164 subroutine rmhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
2166 integer,
intent(in) :: ixi^
l, ixo^
l
2167 double precision,
intent(in) :: w(ixi^s, 1:nw)
2168 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2169 double precision,
intent(out):: res(ixi^s)
2170 double precision :: r(ixi^s)
2172 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2174 end subroutine rmhd_get_temperature_equi
2176 subroutine rmhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
2178 integer,
intent(in) :: ixi^
l, ixo^
l
2179 double precision,
intent(in) :: w(ixi^s, 1:nw)
2180 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2181 double precision,
intent(out):: res(ixi^s)
2183 end subroutine rmhd_get_rho_equi
2185 subroutine rmhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
2187 integer,
intent(in) :: ixi^
l, ixo^
l
2188 double precision,
intent(in) :: w(ixi^s, 1:nw)
2189 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2190 double precision,
intent(out):: res(ixi^s)
2192 end subroutine rmhd_get_pe_equi
2195 subroutine rmhd_get_p_total(w,x,ixI^L,ixO^L,p)
2197 integer,
intent(in) :: ixi^
l, ixo^
l
2198 double precision,
intent(in) :: w(ixi^s,nw)
2199 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2200 double precision,
intent(out) :: p(ixi^s)
2203 p(ixo^s) = p(ixo^s) + 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
2204 end subroutine rmhd_get_p_total
2211 integer,
intent(in) :: ixi^
l, ixo^
l, nth
2212 double precision,
intent(in) :: w(ixi^s, 1:nw)
2213 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2214 double precision,
intent(out):: prad(ixo^s, 1:
ndim, 1:
ndim)
2222 call mpistop(
'Radiation formalism unknown')
2229 integer,
intent(in) :: ixi^
l, ixo^
l
2230 double precision,
intent(in) :: w(ixi^s, 1:nw)
2231 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2232 double precision :: pth(ixi^s)
2233 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2234 double precision :: prad_max(ixo^s)
2235 double precision,
intent(out) :: pth_plus_prad(ixi^s)
2240 {
do ix^
d = ixomin^
d,ixomax^
d\}
2241 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2244 if (radio_acoustic_filter)
then
2245 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2247 pth_plus_prad(ixo^s) = pth(ixo^s) + prad_max(ixo^s)
2251 subroutine rmhd_radio_acoustic_filter(x, ixI^L, ixO^L, prad_max)
2253 integer,
intent(in) :: ixi^
l, ixo^
l
2254 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2255 double precision,
intent(inout) :: prad_max(ixo^s)
2256 double precision :: tmp_prad(ixi^s)
2257 integer :: ix^
d, filter, idim
2259 if (size_ra_filter .lt. 1)
call mpistop(
"ra filter of size < 1 makes no sense")
2260 if (size_ra_filter .gt.
nghostcells)
call mpistop(
"ra filter of size < nghostcells makes no sense")
2262 tmp_prad(ixi^s) = zero
2263 tmp_prad(ixo^s) = prad_max(ixo^s)
2264 do filter = 1,size_ra_filter
2267 {
do ix^
d = ixomin^
d,ixomax^
d\}
2268 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d+filter*
kr(idim,^
d)))
2269 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d-filter*
kr(idim,^
d)))
2273 end subroutine rmhd_radio_acoustic_filter
2278 integer,
intent(in) :: ixi^
l, ixo^
l
2279 double precision,
intent(in) :: w(ixi^s, 1:nw)
2280 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2281 double precision :: pth(ixi^s)
2282 double precision,
intent(out):: tgas(ixi^s)
2285 tgas(ixi^s) = pth(ixi^s)/w(ixi^s,
rho_)
2293 integer,
intent(in) :: ixi^
l, ixo^
l
2294 double precision,
intent(in) :: w(ixi^s, 1:nw)
2295 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2296 double precision,
intent(out):: trad(ixi^s)
2303 subroutine rmhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
2307 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2309 double precision,
intent(in) :: wc(ixi^s,nw)
2311 double precision,
intent(in) :: w(ixi^s,nw)
2312 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2313 double precision,
intent(out) :: f(ixi^s,nwflux)
2314 double precision :: vhall(ixi^s,1:
ndir)
2315 double precision :: ptotal
2318 {
do ix^db=ixomin^db,ixomax^db\}
2323 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2325 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2328 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2329 -w(ix^
d,mag(idim))*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2334 {
do ix^db=ixomin^db,ixomax^db\}
2335 f(ix^d,mag(idim))=w(ix^d,
psi_)
2337 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
2341 {
do ix^db=ixomin^db,ixomax^db\}
2342 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2349 {
do ix^db=ixomin^db,ixomax^db\}
2354 {
do ix^db=ixomin^db,ixomax^db\}
2355 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)
2359 end subroutine rmhd_get_flux
2362 subroutine rmhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
2365 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2367 double precision,
intent(in) :: wc(ixi^s,nw)
2369 double precision,
intent(in) :: w(ixi^s,nw)
2370 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2371 double precision,
intent(out) :: f(ixi^s,nwflux)
2372 double precision :: vhall(ixi^s,1:
ndir)
2373 double precision :: ptotal, btotal(ixo^s,1:
ndir)
2376 {
do ix^db=ixomin^db,ixomax^db\}
2384 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2393 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
2397 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
2398 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2400 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
2404 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2407 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
2411 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2412 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2416 {
do ix^db=ixomin^db,ixomax^db\}
2417 f(ix^d,mag(idim))=w(ix^d,
psi_)
2419 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
2423 {
do ix^db=ixomin^db,ixomax^db\}
2424 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2431 {
do ix^db=ixomin^db,ixomax^db\}
2436 {
do ix^db=ixomin^db,ixomax^db\}
2437 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
2441 end subroutine rmhd_get_flux_split
2445 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
2448 integer,
intent(in) :: ixi^
l, ixo^
l
2449 double precision,
dimension(:^D&,:),
intent(inout) :: ff
2450 double precision,
intent(out) :: src(ixi^s)
2452 double precision :: ffc(ixi^s,1:
ndim)
2453 double precision :: dxinv(
ndim)
2454 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
2460 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
2462 ixbmin^
d=ixcmin^
d+ix^
d;
2463 ixbmax^
d=ixcmax^
d+ix^
d;
2466 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
2468 ff(ixi^s,1:ndim)=0.d0
2470 ixb^l=ixo^l-kr(idims,^d);
2471 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
2473 if({ ix^d==0 .and. ^d==idims | .or.})
then
2474 ixbmin^d=ixcmin^d-ix^d;
2475 ixbmax^d=ixcmax^d-ix^d;
2476 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
2479 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
2482 if(slab_uniform)
then
2484 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
2485 ixb^l=ixo^l-kr(idims,^d);
2486 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2490 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
2491 ixb^l=ixo^l-kr(idims,^d);
2492 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2494 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
2496 end subroutine get_flux_on_cell_face
2499 subroutine rmhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2505 integer,
intent(in) :: ixi^
l, ixo^
l
2506 double precision,
intent(in) :: qdt,dtfactor
2507 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2508 double precision,
intent(inout) :: w(ixi^s,1:nw)
2509 logical,
intent(in) :: qsourcesplit
2510 logical,
intent(inout) :: active
2516 if (.not. qsourcesplit)
then
2519 call add_pe0_divv(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2522 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
2527 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2532 call add_source_res2(qdt,ixi^
l,ixo^
l,wct,w,x)
2536 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
2542 select case (type_divb)
2547 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2550 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2553 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2554 case (divb_janhunen)
2556 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2557 case (divb_lindejanhunen)
2559 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2560 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2561 case (divb_lindepowel)
2563 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2564 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2565 case (divb_lindeglm)
2567 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2568 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2569 case (divb_multigrid)
2574 call mpistop(
'Unknown divB fix')
2584 w,x,gravity_energy,qsourcesplit,active)
2590 call rmhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,w,x,qsourcesplit,active)
2593 if(.not.qsourcesplit)
then
2595 call rmhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
2598 end subroutine rmhd_add_source
2600 subroutine rmhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,w,x,qsourcesplit,active)
2606 integer,
intent(in) :: ixi^
l, ixo^
l
2607 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
2608 double precision,
intent(in) :: wct(ixi^s,1:nw)
2609 double precision,
intent(inout) :: w(ixi^s,1:nw)
2610 logical,
intent(in) :: qsourcesplit
2611 logical,
intent(inout) :: active
2612 double precision :: cmax(ixi^s)
2619 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2624 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2630 call mpistop(
'Radiation formalism unknown')
2632 end subroutine rmhd_add_radiation_source
2634 subroutine add_pe0_divv(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2637 integer,
intent(in) :: ixi^
l, ixo^
l
2638 double precision,
intent(in) :: qdt,dtfactor
2639 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2640 double precision,
intent(inout) :: w(ixi^s,1:nw)
2641 double precision :: divv(ixi^s)
2657 end subroutine add_pe0_divv
2659 subroutine get_tau(ixI^L,ixO^L,w,Te,tau,sigT5)
2661 integer,
intent(in) :: ixi^
l, ixo^
l
2662 double precision,
dimension(ixI^S,1:nw),
intent(in) :: w
2663 double precision,
dimension(ixI^S),
intent(in) :: te
2664 double precision,
dimension(ixI^S),
intent(out) :: tau,sigt5
2665 double precision :: dxmin,taumin
2666 double precision,
dimension(ixI^S) :: sigt7,eint
2674 sigt7(ixo^s)=sigt5(ixo^s)*
block%wextra(ixo^s,
tcoff_)
2677 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2681 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2684 tau(ixo^s)=max(taumin*
dt,sigt7(ixo^s)/eint(ixo^s)/
cmax_global**2)
2685 end subroutine get_tau
2687 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
2689 integer,
intent(in) :: ixi^
l,ixo^
l
2690 double precision,
intent(in) :: qdt
2691 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
2692 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
2693 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
2694 double precision :: invdx
2695 double precision,
dimension(ixI^S) :: te,tau,sigt,htc_qsrc,tface,r
2696 double precision,
dimension(ixI^S) :: htc_esrc,bsum,bunit
2697 double precision,
dimension(ixI^S,1:ndim) :: btot
2699 integer :: hxc^
l,hxo^
l,ixc^
l,jxc^
l,jxo^
l,kxc^
l
2701 call rmhd_get_rfactor(wctprim,x,ixi^
l,ixi^
l,r)
2703 te(ixi^s)=wctprim(ixi^s,
p_)/(r(ixi^s)*w(ixi^s,
rho_))
2704 call get_tau(ixi^
l,ixo^
l,wctprim,te,tau,sigt)
2708 btot(ixo^s,idims)=wct(ixo^s,mag(idims))+
block%B0(ixo^s,idims,0)
2710 btot(ixo^s,idims)=wct(ixo^s,mag(idims))
2713 bsum(ixo^s)=sqrt(sum(btot(ixo^s,:)**2,dim=
ndim+1))+smalldouble
2717 ixcmin^
d=ixomin^
d-
kr(idims,^
d);ixcmax^
d=ixomax^
d;
2718 jxc^
l=ixc^
l+
kr(idims,^
d);
2719 kxc^
l=jxc^
l+
kr(idims,^
d);
2720 hxc^
l=ixc^
l-
kr(idims,^
d);
2721 hxo^
l=ixo^
l-
kr(idims,^
d);
2722 tface(ixc^s)=(7.d0*(te(ixc^s)+te(jxc^s))-(te(hxc^s)+te(kxc^s)))/12.d0
2723 bunit(ixo^s)=btot(ixo^s,idims)/bsum(ixo^s)
2724 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*bunit(ixo^s)*(tface(ixo^s)-tface(hxo^s))*invdx
2726 htc_qsrc(ixo^s)=(htc_qsrc(ixo^s)+wct(ixo^s,
q_))/tau(ixo^s)
2727 w(ixo^s,
q_)=w(ixo^s,
q_)-qdt*htc_qsrc(ixo^s)
2728 end subroutine add_hypertc_source
2731 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
2733 integer,
intent(in) :: ixi^
l, ixo^
l
2734 double precision,
intent(in) :: w(ixi^s,1:nw)
2735 double precision,
intent(inout) :: jxb(ixi^s,3)
2736 double precision :: a(ixi^s,3),
b(ixi^s,3)
2738 double precision :: current(ixi^s,7-2*
ndir:3)
2739 integer :: idir, idirmin
2744 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
2748 b(ixo^s, idir) = w(ixo^s,mag(idir))
2755 a(ixo^s,idir)=current(ixo^s,idir)
2758 end subroutine get_lorentz_force
2762 subroutine rmhd_gamma2_alfven(ixI^L, ixO^L, w, gamma_A2)
2764 integer,
intent(in) :: ixi^
l, ixo^
l
2765 double precision,
intent(in) :: w(ixi^s, nw)
2766 double precision,
intent(out) :: gamma_a2(ixo^s)
2767 double precision :: rho(ixi^s)
2773 rho(ixo^s) = w(ixo^s,
rho_)
2776 gamma_a2(ixo^s) = 1.0d0/(1.0d0+
rmhd_mag_en_all(w, ixi^
l, ixo^
l)/rho(ixo^s)*inv_squared_c)
2777 end subroutine rmhd_gamma2_alfven
2781 function rmhd_gamma_alfven(w, ixI^L, ixO^L)
result(gamma_A)
2783 integer,
intent(in) :: ixi^
l, ixo^
l
2784 double precision,
intent(in) :: w(ixi^s, nw)
2785 double precision :: gamma_a(ixo^s)
2787 call rmhd_gamma2_alfven(ixi^
l, ixo^
l, w, gamma_a)
2788 gamma_a = sqrt(gamma_a)
2789 end function rmhd_gamma_alfven
2793 integer,
intent(in) :: ixi^
l, ixo^
l
2794 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
2795 double precision,
intent(out) :: rho(ixi^s)
2800 rho(ixo^s) = w(ixo^s,
rho_)
2805 subroutine rmhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
2808 integer,
intent(in) :: ixi^
l,ixo^
l, ie
2809 double precision,
intent(inout) :: w(ixi^s,1:nw)
2810 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2811 character(len=*),
intent(in) :: subname
2812 double precision :: rho(ixi^s)
2814 logical :: flag(ixi^s,1:nw)
2818 where(w(ixo^s,ie)+
block%equi_vars(ixo^s,
equi_pe0_,0)*inv_gamma_1<small_e)&
2819 flag(ixo^s,ie)=.true.
2821 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
2823 if(any(flag(ixo^s,ie)))
then
2827 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e - &
2830 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
2836 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
2839 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
2844 end subroutine rmhd_handle_small_ei
2846 subroutine rmhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
2850 integer,
intent(in) :: ixi^
l, ixo^
l
2851 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2852 double precision,
intent(inout) :: w(ixi^s,1:nw)
2854 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
2862 end subroutine rmhd_update_temperature
2865 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2867 integer,
intent(in) :: ixi^
l, ixo^
l
2868 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2869 double precision,
intent(inout) :: w(ixi^s,1:nw)
2870 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
2881 a(ixo^s,idir)=
block%J0(ixo^s,idir)
2886 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2889 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2894 if(total_energy)
then
2897 b(ixo^s,:)=wct(ixo^s,mag(:))
2906 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2909 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2913 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
2916 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
2917 end subroutine add_source_b0split
2923 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
2927 integer,
intent(in) :: ixi^
l, ixo^
l
2928 double precision,
intent(in) :: qdt
2929 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2930 double precision,
intent(inout) :: w(ixi^s,1:nw)
2931 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim,jxo^
l,hxo^
l,ix
2932 integer :: lxo^
l, kxo^
l
2933 double precision :: tmp(ixi^s),tmp2(ixi^s)
2935 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
2936 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
2944 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2945 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
2950 gradeta(ixo^s,1:
ndim)=zero
2956 gradeta(ixo^s,idim)=tmp(ixo^s)
2962 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
2968 tmp2(ixi^s)=bf(ixi^s,idir)
2970 lxo^
l=ixo^
l+2*
kr(idim,^
d);
2971 jxo^
l=ixo^
l+
kr(idim,^
d);
2972 hxo^
l=ixo^
l-
kr(idim,^
d);
2973 kxo^
l=ixo^
l-2*
kr(idim,^
d);
2974 tmp(ixo^s)=tmp(ixo^s)+&
2975 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
2980 tmp2(ixi^s)=bf(ixi^s,idir)
2982 jxo^
l=ixo^
l+
kr(idim,^
d);
2983 hxo^
l=ixo^
l-
kr(idim,^
d);
2984 tmp(ixo^s)=tmp(ixo^s)+&
2985 (tmp2(jxo^s)-2.0d0*tmp2(ixo^s)+tmp2(hxo^s))/
dxlevel(idim)**2
2989 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
2992 do jdir=1,
ndim;
do kdir=idirmin,3
2993 if (
lvc(idir,jdir,kdir)/=0)
then
2994 if (
lvc(idir,jdir,kdir)==1)
then
2995 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
2997 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
3003 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
3004 if(total_energy)
then
3005 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
3010 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
3012 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
3013 end subroutine add_source_res1
3017 subroutine add_source_res2(qdt,ixI^L,ixO^L,wCT,w,x)
3021 integer,
intent(in) :: ixi^
l, ixo^
l
3022 double precision,
intent(in) :: qdt
3023 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3024 double precision,
intent(inout) :: w(ixi^s,1:nw)
3026 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
3027 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
3028 integer :: ixa^
l,idir,idirmin,idirmin1
3031 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3032 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
3040 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
rmhd_eta
3045 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
3053 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
3056 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
3060 tmp(ixo^s)=qdt*
rmhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
3062 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
3064 if(total_energy)
then
3067 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
3068 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
3071 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
3074 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res2')
3075 end subroutine add_source_res2
3079 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
3082 integer,
intent(in) :: ixi^
l, ixo^
l
3083 double precision,
intent(in) :: qdt
3084 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3085 double precision,
intent(inout) :: w(ixi^s,1:nw)
3087 double precision :: current(ixi^s,7-2*
ndir:3)
3088 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
3089 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
3092 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3093 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
3095 tmpvec(ixa^s,1:
ndir)=zero
3097 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
3100 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3102 tmpvec(ixa^s,1:
ndir)=zero
3103 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
3106 tmpvec2(ixa^s,1:
ndir)=zero
3107 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3109 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
3111 if(total_energy)
then
3114 tmpvec2(ixa^s,1:
ndir)=zero
3115 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
3116 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
3117 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
3118 end do;
end do;
end do
3120 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
3121 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
3123 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
3124 end subroutine add_source_hyperres
3126 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
3132 integer,
intent(in) :: ixi^
l, ixo^
l
3133 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3134 double precision,
intent(inout) :: w(ixi^s,1:nw)
3135 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
3154 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
3157 if(total_energy)
then
3166 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
3173 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
3176 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
3177 end subroutine add_source_glm
3180 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
3182 integer,
intent(in) :: ixi^
l, ixo^
l
3183 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3184 double precision,
intent(inout) :: w(ixi^s,1:nw)
3185 double precision :: divb(ixi^s), ba(1:
ndir)
3186 integer :: idir, ix^
d
3191 {
do ix^db=ixomin^db,ixomax^db\}
3196 if (total_energy)
then
3202 {
do ix^db=ixomin^db,ixomax^db\}
3204 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
3206 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
3207 if (total_energy)
then
3209 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
3213 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
3214 end subroutine add_source_powel
3216 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
3220 integer,
intent(in) :: ixi^
l, ixo^
l
3221 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3222 double precision,
intent(inout) :: w(ixi^s,1:nw)
3223 double precision :: divb(ixi^s)
3224 integer :: idir, ix^
d
3228 {
do ix^db=ixomin^db,ixomax^db\}
3232 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
3233 end subroutine add_source_janhunen
3235 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
3239 integer,
intent(in) :: ixi^
l, ixo^
l
3240 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3241 double precision,
intent(inout) :: w(ixi^s,1:nw)
3242 double precision :: divb(ixi^s),graddivb(ixi^s)
3243 integer :: idim, idir, ixp^
l, i^
d, iside
3244 logical,
dimension(-1:1^D&) :: leveljump
3251 if(i^
d==0|.and.) cycle
3252 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
3253 leveljump(i^
d)=.true.
3255 leveljump(i^
d)=.false.
3263 i^dd=kr(^dd,^d)*(2*iside-3);
3264 if (leveljump(i^dd))
then
3266 ixpmin^d=ixomin^d-i^d
3268 ixpmax^d=ixomax^d-i^d
3278 select case(typegrad)
3280 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
3282 call gradientl(divb,ixi^l,ixp^l,idim,graddivb)
3285 if (slab_uniform)
then
3286 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
3288 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
3289 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
3291 w(ixp^s,mag(idim))=w(ixp^s,mag(idim))+graddivb(ixp^s)
3293 if (typedivbdiff==
'all' .and. total_energy)
then
3295 w(ixp^s,
e_)=w(ixp^s,
e_)+wct(ixp^s,mag(idim))*graddivb(ixp^s)
3298 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
3299 end subroutine add_source_linde
3304 integer,
intent(in) :: ixi^
l, ixo^
l
3305 double precision,
intent(in) :: w(ixi^s,1:nw)
3306 double precision :: divb(ixi^s), dsurface(ixi^s)
3307 double precision :: invb(ixo^s)
3308 integer :: ixa^
l,idims
3310 call get_divb(w,ixi^
l,ixo^
l,divb)
3312 where(invb(ixo^s)/=0.d0)
3313 invb(ixo^s)=1.d0/invb(ixo^s)
3316 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
3318 ixamin^
d=ixomin^
d-1;
3319 ixamax^
d=ixomax^
d-1;
3320 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
3322 ixa^
l=ixo^
l-
kr(idims,^
d);
3323 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
3325 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
3326 block%dvolume(ixo^s)/dsurface(ixo^s)
3335 integer,
intent(in) :: ixo^
l, ixi^
l
3336 double precision,
intent(in) :: w(ixi^s,1:nw)
3337 integer,
intent(out) :: idirmin
3339 double precision :: current(ixi^s,7-2*
ndir:3)
3340 integer :: idir, idirmin0
3344 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
3345 block%J0(ixo^s,idirmin0:3)
3349 subroutine rmhd_get_dt(w,ixI^L,ixO^L,dtnew,dx^D,x)
3357 integer,
intent(in) :: ixi^
l, ixo^
l
3358 double precision,
intent(inout) :: dtnew
3359 double precision,
intent(in) ::
dx^
d
3360 double precision,
intent(in) :: w(ixi^s,1:nw)
3361 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3362 double precision :: dxarr(
ndim)
3363 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
3364 integer :: idirmin,idim
3368 if (.not. dt_c)
then
3379 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
3382 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
3400 call mpistop(
'Radiation formalism unknown')
3416 end subroutine rmhd_get_dt
3419 subroutine rmhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
3422 integer,
intent(in) :: ixi^
l, ixo^
l
3423 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
3424 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3425 double precision :: tmp,tmp1,invr,cot
3427 integer :: mr_,mphi_
3428 integer :: br_,bphi_
3431 br_=mag(1); bphi_=mag(1)-1+
phi_
3434 {
do ix^db=ixomin^db,ixomax^db\}
3437 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
3442 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
3447 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
3448 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
3449 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
3450 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
3451 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
3453 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
3454 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
3455 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
3458 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
3463 {
do ix^db=ixomin^db,ixomax^db\}
3465 if(local_timestep)
then
3466 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
3471 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
3477 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
3480 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
3481 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
3485 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
3491 cot=1.d0/tan(x(ix^d,2))
3495 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3496 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
3498 if(.not.stagger_grid)
then
3499 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3501 tmp=tmp+wprim(ix^d,
psi_)*cot
3503 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3508 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3509 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
3510 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
3512 if(.not.stagger_grid)
then
3513 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3515 tmp=tmp+wprim(ix^d,
psi_)*cot
3517 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3520 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
3521 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
3522 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
3523 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
3524 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
3526 if(.not.stagger_grid)
then
3527 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
3528 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
3529 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
3530 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
3531 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
3536 end subroutine rmhd_add_source_geom
3539 subroutine rmhd_add_source_geom_split(qdt,dtfactor, ixI^L,ixO^L,wCT,wprim,w,x)
3542 integer,
intent(in) :: ixi^
l, ixo^
l
3543 double precision,
intent(in) :: qdt, dtfactor, x(ixi^s,1:
ndim)
3544 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3545 double precision :: tmp(ixi^s),tmp1(ixi^s),tmp2(ixi^s),invrho(ixo^s),invr(ixo^s)
3546 integer :: iw,idir, h1x^
l{^nooned, h2x^
l}
3547 integer :: mr_,mphi_
3548 integer :: br_,bphi_
3551 br_=mag(1); bphi_=mag(1)-1+
phi_
3555 invrho(ixo^s) = 1d0/wct(ixo^s,
rho_)
3559 invr(ixo^s) =
block%dt(ixo^s) * dtfactor/x(ixo^s,1)
3561 invr(ixo^s) = qdt/x(ixo^s,1)
3566 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp)
3568 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*(tmp(ixo^s)-&
3569 wct(ixo^s,bphi_)**2+wct(ixo^s,mphi_)**2*invrho(ixo^s))
3570 w(ixo^s,mphi_)=w(ixo^s,mphi_)+qdt*invr(ixo^s)*(&
3571 -wct(ixo^s,mphi_)*wct(ixo^s,mr_)*invrho(ixo^s) &
3572 +wct(ixo^s,bphi_)*wct(ixo^s,br_))
3574 w(ixo^s,bphi_)=w(ixo^s,bphi_)+invr(ixo^s)*&
3575 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
3576 -wct(ixo^s,br_)*wct(ixo^s,mphi_)) &
3580 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*tmp(ixo^s)
3582 if(
rmhd_glm) w(ixo^s,br_)=w(ixo^s,br_)+wct(ixo^s,
psi_)*invr(ixo^s)
3584 h1x^
l=ixo^
l-
kr(1,^
d); {^nooned h2x^
l=ixo^
l-
kr(2,^
d);}
3585 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp1)
3586 tmp(ixo^s)=tmp1(ixo^s)
3588 tmp2(ixo^s)=sum(
block%B0(ixo^s,:,0)*wct(ixo^s,mag(:)),dim=
ndim+1)
3589 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3592 tmp(ixo^s)=tmp(ixo^s)*x(ixo^s,1) &
3593 *(
block%surfaceC(ixo^s,1)-
block%surfaceC(h1x^s,1))/
block%dvolume(ixo^s)
3596 tmp(ixo^s)=tmp(ixo^s)+wct(ixo^s,
mom(idir))**2*invrho(ixo^s)-wct(ixo^s,mag(idir))**2
3597 if(
b0field) tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,idir,0)*wct(ixo^s,mag(idir))
3600 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+tmp(ixo^s)*invr(ixo^s)
3603 w(ixo^s,mag(1))=w(ixo^s,mag(1))+invr(ixo^s)*2.0d0*wct(ixo^s,
psi_)
3607 tmp(ixo^s)=tmp1(ixo^s)
3609 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3612 tmp1(ixo^s) =
block%dt(ixo^s) * tmp(ixo^s)
3614 tmp1(ixo^s) = qdt * tmp(ixo^s)
3617 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp1(ixo^s) &
3618 *(
block%surfaceC(ixo^s,2)-
block%surfaceC(h2x^s,2)) &
3619 /
block%dvolume(ixo^s)
3620 tmp(ixo^s)=-(wct(ixo^s,
mom(1))*wct(ixo^s,
mom(2))*invrho(ixo^s) &
3621 -wct(ixo^s,mag(1))*wct(ixo^s,mag(2)))
3623 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(2)) &
3624 +wct(ixo^s,mag(1))*
block%B0(ixo^s,2,0)
3627 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(3))**2*invrho(ixo^s) &
3628 -wct(ixo^s,mag(3))**2)*dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3630 tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,3,0)*wct(ixo^s,mag(3))&
3631 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3634 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp(ixo^s)*invr(ixo^s)
3637 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(2)) &
3638 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(1)))*invrho(ixo^s)
3640 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,2,0) &
3641 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,1,0))*invrho(ixo^s)
3644 tmp(ixo^s)=tmp(ixo^s) &
3645 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
3647 w(ixo^s,mag(2))=w(ixo^s,mag(2))+tmp(ixo^s)*invr(ixo^s)
3652 tmp(ixo^s)=-(wct(ixo^s,
mom(3))*wct(ixo^s,
mom(1))*invrho(ixo^s) &
3653 -wct(ixo^s,mag(3))*wct(ixo^s,mag(1))) {^nooned &
3654 -(wct(ixo^s,
mom(2))*wct(ixo^s,
mom(3))*invrho(ixo^s) &
3655 -wct(ixo^s,mag(2))*wct(ixo^s,mag(3))) &
3656 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3658 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(3)) &
3659 +wct(ixo^s,mag(1))*
block%B0(ixo^s,3,0) {^nooned &
3660 +(
block%B0(ixo^s,2,0)*wct(ixo^s,mag(3)) &
3661 +wct(ixo^s,mag(2))*
block%B0(ixo^s,3,0)) &
3662 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3664 w(ixo^s,
mom(3))=w(ixo^s,
mom(3))+tmp(ixo^s)*invr(ixo^s)
3667 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(3)) &
3668 -wct(ixo^s,
mom(3))*wct(ixo^s,mag(1)))*invrho(ixo^s) {^nooned &
3669 -(wct(ixo^s,
mom(3))*wct(ixo^s,mag(2)) &
3670 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(3)))*dcos(x(ixo^s,2)) &
3671 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3673 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,3,0) &
3674 -wct(ixo^s,
mom(3))*
block%B0(ixo^s,1,0))*invrho(ixo^s){^nooned &
3675 -(wct(ixo^s,
mom(3))*
block%B0(ixo^s,2,0) &
3676 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,3,0))*dcos(x(ixo^s,2)) &
3677 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3679 w(ixo^s,mag(3))=w(ixo^s,mag(3))+tmp(ixo^s)*invr(ixo^s)
3683 end subroutine rmhd_add_source_geom_split
3688 integer,
intent(in) :: ixi^
l, ixo^
l
3689 double precision,
intent(in) :: w(ixi^s, nw)
3690 double precision :: mge(ixo^s)
3693 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
3695 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
3699 subroutine rmhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
3702 integer,
intent(in) :: ixi^
l, ixo^
l, idir
3703 double precision,
intent(in) :: qt
3704 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
3705 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
3707 double precision :: db(ixo^s), dpsi(ixo^s)
3711 {
do ix^db=ixomin^db,ixomax^db\}
3712 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3713 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3714 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3715 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3724 {
do ix^db=ixomin^db,ixomax^db\}
3725 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
3726 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
3727 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
3728 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
3729 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3731 if(total_energy)
then
3732 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
3733 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
3735 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3737 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3740 if(total_energy)
then
3741 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
3742 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
3746 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
3747 end subroutine rmhd_modify_wlr
3749 subroutine rmhd_boundary_adjust(igrid,psb)
3751 integer,
intent(in) :: igrid
3753 integer :: ib, idims, iside, ixo^
l, i^
d
3762 i^
d=
kr(^
d,idims)*(2*iside-3);
3763 if (neighbor_type(i^
d,igrid)/=1) cycle
3764 ib=(idims-1)*2+iside
3782 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
3786 end subroutine rmhd_boundary_adjust
3788 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
3790 integer,
intent(in) :: ixg^
l,ixo^
l,ib
3791 double precision,
intent(inout) :: w(ixg^s,1:nw)
3792 double precision,
intent(in) :: x(ixg^s,1:
ndim)
3793 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
3794 integer :: ix^
d,ixf^
l
3807 do ix1=ixfmax1,ixfmin1,-1
3808 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
3809 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3810 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3813 do ix1=ixfmax1,ixfmin1,-1
3814 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
3815 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
3816 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3817 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3818 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3819 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3820 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3834 do ix1=ixfmax1,ixfmin1,-1
3835 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3836 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3837 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3838 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3839 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3840 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3843 do ix1=ixfmax1,ixfmin1,-1
3844 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3845 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3846 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3847 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3848 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3849 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3850 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3851 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3852 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3853 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3854 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3855 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3856 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3857 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3858 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3859 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3860 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3861 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3875 do ix1=ixfmin1,ixfmax1
3876 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
3877 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3878 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3881 do ix1=ixfmin1,ixfmax1
3882 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
3883 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
3884 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3885 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3886 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3887 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3888 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3902 do ix1=ixfmin1,ixfmax1
3903 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3904 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3905 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3906 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3907 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3908 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3911 do ix1=ixfmin1,ixfmax1
3912 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3913 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3914 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3915 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3916 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3917 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3918 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3919 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3920 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3921 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3922 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3923 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3924 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3925 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3926 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3927 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3928 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3929 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3943 do ix2=ixfmax2,ixfmin2,-1
3944 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
3945 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3946 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3949 do ix2=ixfmax2,ixfmin2,-1
3950 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
3951 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
3952 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3953 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3954 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3955 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3956 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3970 do ix2=ixfmax2,ixfmin2,-1
3971 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3972 ix2+1,ixfmin3:ixfmax3,mag(2)) &
3973 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
3974 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
3975 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
3976 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
3979 do ix2=ixfmax2,ixfmin2,-1
3980 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
3981 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
3982 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
3983 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
3984 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
3985 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3986 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
3987 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
3988 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3989 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
3990 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
3991 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
3992 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
3993 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
3994 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3995 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
3996 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
3997 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4011 do ix2=ixfmin2,ixfmax2
4012 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
4013 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
4014 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
4017 do ix2=ixfmin2,ixfmax2
4018 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
4019 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
4020 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
4021 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
4022 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
4023 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
4024 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
4038 do ix2=ixfmin2,ixfmax2
4039 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
4040 ix2-1,ixfmin3:ixfmax3,mag(2)) &
4041 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
4042 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
4043 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
4044 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
4047 do ix2=ixfmin2,ixfmax2
4048 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
4049 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
4050 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
4051 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
4052 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
4053 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4054 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
4055 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
4056 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4057 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
4058 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
4059 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
4060 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
4061 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
4062 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
4063 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
4064 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
4065 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4082 do ix3=ixfmax3,ixfmin3,-1
4083 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
4084 ixfmin2:ixfmax2,ix3+1,mag(3)) &
4085 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4086 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4087 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4088 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4091 do ix3=ixfmax3,ixfmin3,-1
4092 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
4093 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
4094 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4095 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
4096 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4097 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4098 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4099 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4100 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4101 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4102 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4103 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4104 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4105 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4106 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4107 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4108 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
4109 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4124 do ix3=ixfmin3,ixfmax3
4125 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
4126 ixfmin2:ixfmax2,ix3-1,mag(3)) &
4127 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4128 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4129 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4130 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4133 do ix3=ixfmin3,ixfmax3
4134 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
4135 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
4136 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4137 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
4138 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4139 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4140 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4141 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4142 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4143 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4144 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4145 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4146 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4147 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4148 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4149 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4150 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
4151 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4157 call mpistop(
"Special boundary is not defined for this region")
4159 end subroutine fixdivb_boundary
4167 double precision,
intent(in) :: qdt
4168 double precision,
intent(in) :: qt
4169 logical,
intent(inout) :: active
4171 integer,
parameter :: max_its = 50
4172 double precision :: residual_it(max_its), max_divb
4173 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
4174 double precision :: res
4175 double precision,
parameter :: max_residual = 1
d-3
4176 double precision,
parameter :: residual_reduction = 1
d-10
4177 integer :: iigrid, igrid
4178 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
4181 mg%operator_type = mg_laplacian
4188 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4189 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4192 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
4193 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4195 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4196 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4199 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4200 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4204 write(*,*)
"rmhd_clean_divb_multigrid warning: unknown boundary type"
4205 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4206 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4213 do iigrid = 1, igridstail
4214 igrid = igrids(iigrid);
4217 lvl =
mg%boxes(id)%lvl
4218 nc =
mg%box_size_lvl(lvl)
4224 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
4226 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
4227 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
4232 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
4235 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
4236 if (
mype == 0) print *,
"iteration vs residual"
4239 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
4240 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
4241 if (residual_it(n) < residual_reduction * max_divb)
exit
4243 if (
mype == 0 .and. n > max_its)
then
4244 print *,
"divb_multigrid warning: not fully converged"
4245 print *,
"current amplitude of divb: ", residual_it(max_its)
4246 print *,
"multigrid smallest grid: ", &
4247 mg%domain_size_lvl(:,
mg%lowest_lvl)
4248 print *,
"note: smallest grid ideally has <= 8 cells"
4249 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
4250 print *,
"note: dx/dy/dz should be similar"
4254 call mg_fas_vcycle(
mg, max_res=res)
4255 if (res < max_residual)
exit
4257 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
4261 do iigrid = 1, igridstail
4262 igrid = igrids(iigrid);
4269 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
4272 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
4274 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
4276 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
4289 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
4290 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
4292 if(total_energy)
then
4294 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
4297 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
4305 subroutine rmhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4309 integer,
intent(in) :: ixi^
l, ixo^
l
4310 double precision,
intent(in) :: qt,qdt
4312 double precision,
intent(in) :: wp(ixi^s,1:nw)
4313 type(state) :: sct, s
4314 type(ct_velocity) :: vcts
4315 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4316 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4318 double precision :: circ(ixi^s,1:
ndim)
4320 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4321 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
4322 integer :: idim1,idim2,idir,iwdim1,iwdim2
4324 associate(bfaces=>s%ws,x=>s%x)
4331 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4335 i1kr^
d=
kr(idim1,^
d);
4338 i2kr^
d=
kr(idim2,^
d);
4341 if (
lvc(idim1,idim2,idir)==1)
then
4343 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4345 {
do ix^db=ixcmin^db,ixcmax^db\}
4346 fe(ix^
d,idir)=quarter*&
4347 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
4348 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
4350 if(
rmhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
4352 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
4360 if(
associated(usr_set_electric_field)) &
4361 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4363 circ(ixi^s,1:ndim)=zero
4368 ixcmin^d=ixomin^d-kr(idim1,^d);
4370 ixa^l=ixc^l-kr(idim2,^d);
4373 if(lvc(idim1,idim2,idir)==1)
then
4375 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4378 else if(lvc(idim1,idim2,idir)==-1)
then
4380 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4386 {
do ix^db=ixcmin^db,ixcmax^db\}
4388 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4390 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4397 end subroutine rmhd_update_faces_average
4400 subroutine rmhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4405 integer,
intent(in) :: ixi^
l, ixo^
l
4406 double precision,
intent(in) :: qt, qdt
4408 double precision,
intent(in) :: wp(ixi^s,1:nw)
4409 type(state) :: sct, s
4410 type(ct_velocity) :: vcts
4411 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4412 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4414 double precision :: circ(ixi^s,1:
ndim)
4416 double precision :: ecc(ixi^s,
sdim:3)
4417 double precision :: ein(ixi^s,
sdim:3)
4419 double precision :: el(ixi^s),er(ixi^s)
4421 double precision :: elc,erc
4423 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4425 double precision :: jce(ixi^s,
sdim:3)
4427 double precision :: xs(ixgs^t,1:
ndim)
4428 double precision :: gradi(ixgs^t)
4429 integer :: ixc^
l,ixa^
l
4430 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
4432 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
4435 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4438 {
do ix^db=iximin^db,iximax^db\}
4441 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_)
4442 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_)
4443 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_)
4446 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
4453 {
do ix^db=iximin^db,iximax^db\}
4456 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
4457 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
4458 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4461 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4475 i1kr^d=kr(idim1,^d);
4478 i2kr^d=kr(idim2,^d);
4481 if (lvc(idim1,idim2,idir)==1)
then
4483 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4486 {
do ix^db=ixcmin^db,ixcmax^db\}
4487 fe(ix^d,idir)=quarter*&
4488 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
4489 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
4494 ixamax^d=ixcmax^d+i1kr^d;
4495 {
do ix^db=ixamin^db,ixamax^db\}
4496 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
4497 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
4500 do ix^db=ixcmin^db,ixcmax^db\}
4501 if(vnorm(ix^d,idim1)>0.d0)
then
4503 else if(vnorm(ix^d,idim1)<0.d0)
then
4504 elc=el({ix^d+i1kr^d})
4506 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
4508 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
4510 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
4511 erc=er({ix^d+i1kr^d})
4513 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
4515 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4520 ixamax^d=ixcmax^d+i2kr^d;
4521 {
do ix^db=ixamin^db,ixamax^db\}
4522 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
4523 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
4526 do ix^db=ixcmin^db,ixcmax^db\}
4527 if(vnorm(ix^d,idim2)>0.d0)
then
4529 else if(vnorm(ix^d,idim2)<0.d0)
then
4530 elc=el({ix^d+i2kr^d})
4532 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
4534 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
4536 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
4537 erc=er({ix^d+i2kr^d})
4539 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
4541 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4545 if(
rmhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
4547 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
4561 if (lvc(idim1,idim2,idir)==0) cycle
4563 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4564 ixamax^d=ixcmax^d-kr(idir,^d)+1;
4567 xs(ixa^s,:)=x(ixa^s,:)
4568 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
4569 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
4570 if (lvc(idim1,idim2,idir)==1)
then
4571 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4573 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4580 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4582 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
4586 {
do ix^db=ixomin^db,ixomax^db\}
4587 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4588 +ein(ix1,ix2-1,ix3-1,idir))
4589 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4590 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4592 else if(idir==2)
then
4593 {
do ix^db=ixomin^db,ixomax^db\}
4594 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4595 +ein(ix1-1,ix2,ix3-1,idir))
4596 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4597 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4600 {
do ix^db=ixomin^db,ixomax^db\}
4601 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
4602 +ein(ix1-1,ix2-1,ix3,idir))
4603 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4604 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4610 {
do ix^db=ixomin^db,ixomax^db\}
4611 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
4612 +ein(ix1-1,ix2-1,idir))
4613 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4614 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4619 block%w(ixo^s,nw)=block%w(ixo^s,nw)+jce(ixo^s,idir)
4625 if(
associated(usr_set_electric_field)) &
4626 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4628 circ(ixi^s,1:ndim)=zero
4633 ixcmin^d=ixomin^d-kr(idim1,^d);
4635 ixa^l=ixc^l-kr(idim2,^d);
4638 if(lvc(idim1,idim2,idir)==1)
then
4640 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4643 else if(lvc(idim1,idim2,idir)==-1)
then
4645 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4651 {
do ix^db=ixcmin^db,ixcmax^db\}
4653 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4655 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4662 end subroutine rmhd_update_faces_contact
4665 subroutine rmhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4670 integer,
intent(in) :: ixi^
l, ixo^
l
4671 double precision,
intent(in) :: qt, qdt
4673 double precision,
intent(in) :: wp(ixi^s,1:nw)
4674 type(state) :: sct, s
4675 type(ct_velocity) :: vcts
4676 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4677 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4679 double precision :: vtill(ixi^s,2)
4680 double precision :: vtilr(ixi^s,2)
4681 double precision :: bfacetot(ixi^s,
ndim)
4682 double precision :: btill(ixi^s,
ndim)
4683 double precision :: btilr(ixi^s,
ndim)
4684 double precision :: cp(ixi^s,2)
4685 double precision :: cm(ixi^s,2)
4686 double precision :: circ(ixi^s,1:
ndim)
4688 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4689 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
4690 integer :: idim1,idim2,idir,ix^
d
4692 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
4693 cbarmax=>vcts%cbarmax)
4706 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4719 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
4723 idim2=mod(idir+1,3)+1
4725 jxc^
l=ixc^
l+
kr(idim1,^
d);
4726 ixcp^
l=ixc^
l+
kr(idim2,^
d);
4730 vtill(ixi^s,2),vtilr(ixi^s,2))
4733 vtill(ixi^s,1),vtilr(ixi^s,1))
4739 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
4740 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
4742 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
4743 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
4746 btill(ixi^s,idim1),btilr(ixi^s,idim1))
4749 btill(ixi^s,idim2),btilr(ixi^s,idim2))
4753 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
4754 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
4756 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
4757 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
4761 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
4762 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
4763 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
4764 /(cp(ixc^s,1)+cm(ixc^s,1)) &
4765 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
4766 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
4767 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
4768 /(cp(ixc^s,2)+cm(ixc^s,2))
4771 if(
rmhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
4772 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
4786 circ(ixi^s,1:
ndim)=zero
4791 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
4795 if(
lvc(idim1,idim2,idir)/=0)
then
4796 hxc^
l=ixc^
l-
kr(idim2,^
d);
4798 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4799 +
lvc(idim1,idim2,idir)&
4805 {
do ix^db=ixcmin^db,ixcmax^db\}
4807 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
4809 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
4815 end subroutine rmhd_update_faces_hll
4818 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
4823 integer,
intent(in) :: ixi^
l, ixo^
l
4825 double precision,
intent(in) :: wp(ixi^s,1:nw)
4826 type(state),
intent(in) :: sct, s
4828 double precision :: jce(ixi^s,
sdim:3)
4831 double precision :: jcc(ixi^s,7-2*
ndir:3)
4833 double precision :: xs(ixgs^t,1:
ndim)
4835 double precision :: eta(ixi^s)
4836 double precision :: gradi(ixgs^t)
4837 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
4839 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
4845 if (
lvc(idim1,idim2,idir)==0) cycle
4847 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4848 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
4851 xs(ixb^s,:)=x(ixb^s,:)
4852 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
4853 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
4854 if (
lvc(idim1,idim2,idir)==1)
then
4855 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4857 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4872 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4873 jcc(ixc^s,idir)=0.d0
4875 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4876 ixamin^
d=ixcmin^
d+ix^
d;
4877 ixamax^
d=ixcmax^
d+ix^
d;
4878 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
4880 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
4881 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
4886 end subroutine get_resistive_electric_field
4892 integer,
intent(in) :: ixo^
l
4901 do ix^db=ixomin^db,ixomax^db\}
4903 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4904 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
4905 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4906 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
4907 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
4908 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
4911 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4912 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
4913 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4914 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
4954 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
4955 double precision,
intent(inout) :: ws(ixis^s,1:nws)
4956 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4957 double precision :: adummy(ixis^s,1:3)
4962 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
4965 integer,
intent(in) :: ixi^
l, ixo^
l
4966 double precision,
intent(in) :: w(ixi^s,1:nw)
4967 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4968 double precision,
intent(out):: rfactor(ixi^s)
4969 double precision :: iz_h(ixo^s),iz_he(ixo^s)
4973 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)
4974 end subroutine rfactor_from_temperature_ionization
4976 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
4978 integer,
intent(in) :: ixi^
l, ixo^
l
4979 double precision,
intent(in) :: w(ixi^s,1:nw)
4980 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4981 double precision,
intent(out):: rfactor(ixi^s)
4984 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, 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 explicit timestep for the TC (mhd implementation) Note: for multi-D MHD (1D MHD will use HD f...
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine, public tc_get_mhd_params(fl, read_mhd_params)
Init TC coefficients: MHD case.
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_equi_vars), pointer usr_set_equi_vars
procedure(special_mg_bc), pointer usr_special_mg_bc
procedure(set_electric_field), pointer usr_set_electric_field
The module add viscous source terms and check time step.
subroutine viscosity_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.