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.)
430 te_ = var_set_auxvar(
'Te',
'Te')
439 stop_indices(1)=nwflux
469 allocate(iw_vector(nvector))
470 iw_vector(1) = mom(1) - 1
471 iw_vector(2) = mag(1) - 1
474 if (.not.
allocated(flux_type))
then
475 allocate(flux_type(
ndir, nwflux))
476 flux_type = flux_default
477 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
478 call mpistop(
"phys_check error: flux_type has wrong shape")
481 if(nwflux>mag(
ndir))
then
483 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
488 flux_type(:,
psi_)=flux_special
490 flux_type(idir,mag(idir))=flux_special
494 flux_type(idir,mag(idir))=flux_tvdlf
500 phys_get_dt => rmhd_get_dt
501 phys_get_cmax => rmhd_get_cmax_origin
502 phys_get_a2max => rmhd_get_a2max
503 phys_get_tcutoff => rmhd_get_tcutoff
504 phys_get_h_speed => rmhd_get_h_speed
506 phys_get_cbounds => rmhd_get_cbounds_split_rho
508 phys_get_cbounds => rmhd_get_cbounds
511 phys_to_primitive => rmhd_to_primitive_split_rho
513 phys_to_conserved => rmhd_to_conserved_split_rho
516 phys_to_primitive => rmhd_to_primitive_origin
518 phys_to_conserved => rmhd_to_conserved_origin
522 phys_get_flux => rmhd_get_flux_split
524 phys_get_flux => rmhd_get_flux
528 phys_add_source_geom => rmhd_add_source_geom_split
530 phys_add_source_geom => rmhd_add_source_geom
532 phys_add_source => rmhd_add_source
533 phys_check_params => rmhd_check_params
534 phys_write_info => rmhd_write_info
536 phys_handle_small_values => rmhd_handle_small_values_origin
537 rmhd_handle_small_values => rmhd_handle_small_values_origin
538 phys_check_w => rmhd_check_w_origin
544 phys_get_pthermal => rmhd_get_pthermal_origin
548 phys_set_equi_vars => set_equi_vars_grid
551 if(type_divb==divb_glm)
then
552 phys_modify_wlr => rmhd_modify_wlr
557 rmhd_get_rfactor=>rfactor_from_temperature_ionization
558 phys_update_temperature => rmhd_update_temperature
562 rmhd_get_rfactor=>rfactor_from_constant_ionization
579 transverse_ghost_cells = 1
580 phys_get_ct_velocity => rmhd_get_ct_velocity_average
581 phys_update_faces => rmhd_update_faces_average
583 transverse_ghost_cells = 1
584 phys_get_ct_velocity => rmhd_get_ct_velocity_contact
585 phys_update_faces => rmhd_update_faces_contact
587 transverse_ghost_cells = 2
588 phys_get_ct_velocity => rmhd_get_ct_velocity_hll
589 phys_update_faces => rmhd_update_faces_hll
591 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
594 phys_modify_wlr => rmhd_modify_wlr
596 phys_boundary_adjust => rmhd_boundary_adjust
605 call rmhd_physical_units()
614 call mpistop(
'Radiation formalism unknown')
627 call mpistop(
"thermal conduction needs rmhd_energy=T")
630 call mpistop(
"hyperbolic thermal conduction needs rmhd_energy=T")
640 call add_sts_method(rmhd_get_tc_dt_rmhd,rmhd_sts_set_source_tc_rmhd,e_,1,e_,1,.false.)
642 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot_with_equi
644 tc_fl%get_temperature_from_conserved => rmhd_get_temperature_from_etot
647 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint_with_equi
649 tc_fl%has_equi = .true.
650 tc_fl%get_temperature_equi => rmhd_get_temperature_equi
651 tc_fl%get_rho_equi => rmhd_get_rho_equi
653 tc_fl%has_equi = .false.
656 tc_fl%get_temperature_from_eint => rmhd_get_temperature_from_eint
668 te_fl_rmhd%get_var_Rfactor => rmhd_get_rfactor
670 phys_te_images => rmhd_te_images
683 if (particles_eta < zero) particles_eta =
rmhd_eta
684 if (particles_etah < zero) particles_eta =
rmhd_etah
686 write(*,*)
'*****Using particles: with rmhd_eta, rmhd_etah :',
rmhd_eta,
rmhd_etah
687 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
699 subroutine rmhd_te_images
704 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
706 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
708 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
710 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
713 call mpistop(
"Error in synthesize emission: Unknown convert_type")
715 end subroutine rmhd_te_images
721 subroutine rmhd_sts_set_source_tc_rmhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
725 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
726 double precision,
intent(in) :: x(ixi^s,1:
ndim)
727 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
728 double precision,
intent(in) :: my_dt
729 logical,
intent(in) :: fix_conserve_at_step
731 end subroutine rmhd_sts_set_source_tc_rmhd
733 function rmhd_get_tc_dt_rmhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
739 integer,
intent(in) :: ixi^
l, ixo^
l
740 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
741 double precision,
intent(in) :: w(ixi^s,1:nw)
742 double precision :: dtnew
745 end function rmhd_get_tc_dt_rmhd
747 subroutine rmhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
749 integer,
intent(in) :: ixi^
l,ixo^
l
750 double precision,
intent(inout) :: w(ixi^s,1:nw)
751 double precision,
intent(in) :: x(ixi^s,1:
ndim)
752 integer,
intent(in) :: step
753 character(len=140) :: error_msg
755 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
756 call rmhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
757 end subroutine rmhd_tc_handle_small_e
760 subroutine tc_params_read_rmhd(fl)
762 type(tc_fluid),
intent(inout) :: fl
763 double precision :: tc_k_para=0d0
764 double precision :: tc_k_perp=0d0
767 logical :: tc_perpendicular=.false.
768 logical :: tc_saturate=.false.
769 character(len=std_len) :: tc_slope_limiter=
"MC"
771 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp
775 read(
unitpar, tc_list,
end=111)
779 fl%tc_perpendicular = tc_perpendicular
780 fl%tc_saturate = tc_saturate
781 fl%tc_k_para = tc_k_para
782 fl%tc_k_perp = tc_k_perp
783 select case(tc_slope_limiter)
785 fl%tc_slope_limiter = 0
788 fl%tc_slope_limiter = 1
791 fl%tc_slope_limiter = 2
794 fl%tc_slope_limiter = 3
797 fl%tc_slope_limiter = 4
799 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod")
801 end subroutine tc_params_read_rmhd
805 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
808 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
809 double precision,
intent(in) :: x(ixi^s,1:
ndim)
810 double precision :: delx(ixi^s,1:
ndim)
811 double precision :: xc(ixi^s,1:
ndim),xshift^
d
812 integer :: idims, ixc^
l, hxo^
l, ix, idims2
818 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
822 hxo^
l=ixo^
l-
kr(idims,^
d);
828 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
831 xshift^
d=half*(one-
kr(^
d,idims));
838 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
842 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
844 end subroutine set_equi_vars_grid_faces
847 subroutine set_equi_vars_grid(igrid)
850 integer,
intent(in) :: igrid
856 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
857 end subroutine set_equi_vars_grid
860 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
862 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
863 double precision,
intent(in) :: w(ixi^s, 1:nw)
864 double precision,
intent(in) :: x(ixi^s,1:
ndim)
865 double precision :: wnew(ixo^s, 1:nwc)
872 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
878 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
882 wnew(ixo^s,
e_)=w(ixo^s,
e_)
886 if(
b0field .and. total_energy)
then
887 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
888 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
891 end function convert_vars_splitting
893 subroutine rmhd_check_params
901 if (
rmhd_gamma <= 0.0d0)
call mpistop (
"Error: rmhd_gamma <= 0")
902 if (
rmhd_adiab < 0.0d0)
call mpistop (
"Error: rmhd_adiab < 0")
906 call mpistop (
"Error: rmhd_gamma <= 0 or rmhd_gamma == 1")
907 inv_gamma_1=1.d0/gamma_1
914 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
919 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
926 end subroutine rmhd_check_params
940 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
941 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
944 mg%bc(ib, mg_iphi)%bc_type = mg_bc_dirichlet
945 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
949 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
950 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
958 call mpistop(
"divE_multigrid warning: unknown b.c. ")
963 subroutine rmhd_physical_units()
965 double precision :: mp,kb,miu0,c_lightspeed
966 double precision :: a,
b
1111 end subroutine rmhd_physical_units
1113 subroutine rmhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1115 logical,
intent(in) :: primitive
1116 integer,
intent(in) :: ixi^
l, ixo^
l
1117 double precision,
intent(in) :: w(ixi^s,nw)
1118 logical,
intent(inout) :: flag(ixi^s,1:nw)
1119 double precision :: tmp
1123 {
do ix^db=ixomin^db,ixomax^db\}
1137 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1141 if(tmp<small_e) flag(ix^
d,
e_) = .true.
1146 end subroutine rmhd_check_w_origin
1149 subroutine rmhd_to_conserved_origin(ixI^L,ixO^L,w,x)
1151 integer,
intent(in) :: ixi^
l, ixo^
l
1152 double precision,
intent(inout) :: w(ixi^s, nw)
1153 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1156 {
do ix^db=ixomin^db,ixomax^db\}
1158 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1160 +(^
c&w(ix^
d,
b^
c_)**2+))
1164 end subroutine rmhd_to_conserved_origin
1167 subroutine rmhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
1169 integer,
intent(in) :: ixi^
l, ixo^
l
1170 double precision,
intent(inout) :: w(ixi^s, nw)
1171 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1172 double precision :: rho
1175 {
do ix^db=ixomin^db,ixomax^db\}
1178 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1179 +half*((^
c&w(ix^
d,
m^
c_)**2+)*rho&
1180 +(^
c&w(ix^
d,
b^
c_)**2+))
1184 end subroutine rmhd_to_conserved_split_rho
1187 subroutine rmhd_to_primitive_origin(ixI^L,ixO^L,w,x)
1189 integer,
intent(in) :: ixi^
l, ixo^
l
1190 double precision,
intent(inout) :: w(ixi^s, nw)
1191 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1192 double precision :: inv_rho
1197 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_origin')
1200 {
do ix^db=ixomin^db,ixomax^db\}
1201 inv_rho = 1.d0/w(ix^
d,
rho_)
1205 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1207 +(^
c&w(ix^
d,
b^
c_)**2+)))
1209 end subroutine rmhd_to_primitive_origin
1212 subroutine rmhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
1214 integer,
intent(in) :: ixi^
l, ixo^
l
1215 double precision,
intent(inout) :: w(ixi^s, nw)
1216 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1217 double precision :: inv_rho
1222 call rmhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'rmhd_to_primitive_split_rho')
1225 {
do ix^db=ixomin^db,ixomax^db\}
1230 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1232 (^
c&w(ix^
d,
m^
c_)**2+)+(^
c&w(ix^
d,
b^
c_)**2+)))
1234 end subroutine rmhd_to_primitive_split_rho
1239 integer,
intent(in) :: ixi^
l, ixo^
l
1240 double precision,
intent(inout) :: w(ixi^s, nw)
1241 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1246 {
do ix^db=ixomin^db,ixomax^db\}
1249 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1251 +(^
c&w(ix^
d,
b^
c_)**2+))
1254 {
do ix^db=ixomin^db,ixomax^db\}
1256 w(ix^d,
e_)=w(ix^d,
e_)&
1257 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1258 +(^
c&w(ix^d,
b^
c_)**2+))
1266 integer,
intent(in) :: ixi^
l, ixo^
l
1267 double precision,
intent(inout) :: w(ixi^s, nw)
1268 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1273 {
do ix^db=ixomin^db,ixomax^db\}
1276 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1278 +(^
c&w(ix^
d,
b^
c_)**2+))
1281 {
do ix^db=ixomin^db,ixomax^db\}
1283 w(ix^d,
e_)=w(ix^d,
e_)&
1284 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1285 +(^
c&w(ix^d,
b^
c_)**2+))
1289 if(fix_small_values)
then
1290 call rmhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'rmhd_e_to_ei')
1294 subroutine rmhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
1297 logical,
intent(in) :: primitive
1298 integer,
intent(in) :: ixi^
l,ixo^
l
1299 double precision,
intent(inout) :: w(ixi^s,1:nw)
1300 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1301 character(len=*),
intent(in) :: subname
1302 double precision :: rho
1303 integer :: idir, ix^
d
1304 logical :: flag(ixi^s,1:nw)
1306 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
1310 {
do ix^db=ixomin^db,ixomax^db\}
1320 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
1332 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))&
1336 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))
1343 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
1345 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
1348 {
do ix^db=iximin^db,iximax^db\}
1354 w(ix^d,
e_)=w(ix^d,
e_)&
1355 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1357 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
1359 {
do ix^db=iximin^db,iximax^db\}
1365 w(ix^d,
e_)=w(ix^d,
e_)&
1366 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
1369 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
1371 if(.not.primitive)
then
1374 {
do ix^db=iximin^db,iximax^db\}
1380 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
1381 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
1382 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+)))
1385 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
1388 end subroutine rmhd_handle_small_values_origin
1393 integer,
intent(in) :: ixi^
l, ixo^
l
1394 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
1395 double precision,
intent(out) :: v(ixi^s,
ndir)
1396 double precision :: rho(ixi^s)
1400 rho(ixo^s)=1.d0/rho(ixo^s)
1403 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
1408 subroutine rmhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
1410 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1411 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1412 double precision,
intent(inout) :: cmax(ixi^s)
1413 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
1417 {
do ix^db=ixomin^db,ixomax^db \}
1428 cfast2=b2*inv_rho+cmax(ix^
d)
1429 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
1430 if(avmincs2<zero) avmincs2=zero
1431 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1432 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
1435 {
do ix^db=ixomin^db,ixomax^db \}
1445 b2=(^
c&w(ix^d,
b^
c_)**2+)
1446 cfast2=b2*inv_rho+cmax(ix^d)
1447 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
1448 if(avmincs2<zero) avmincs2=zero
1449 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1450 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
1453 end subroutine rmhd_get_cmax_origin
1455 subroutine rmhd_get_a2max(w,x,ixI^L,ixO^L,a2max)
1457 integer,
intent(in) :: ixi^
l, ixo^
l
1458 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1459 double precision,
intent(inout) :: a2max(
ndim)
1460 double precision :: a2(ixi^s,
ndim,nw)
1461 integer :: gxo^
l,hxo^
l,jxo^
l,kxo^
l,i,j
1466 hxo^
l=ixo^
l-
kr(i,^
d);
1467 gxo^
l=hxo^
l-
kr(i,^
d);
1468 jxo^
l=ixo^
l+
kr(i,^
d);
1469 kxo^
l=jxo^
l+
kr(i,^
d);
1470 a2(ixo^s,i,1:nw)=abs(-w(kxo^s,1:nw)+16.d0*w(jxo^s,1:nw)&
1471 -30.d0*w(ixo^s,1:nw)+16.d0*w(hxo^s,1:nw)-w(gxo^s,1:nw))
1472 a2max(i)=maxval(a2(ixo^s,i,1:nw))/12.d0/
dxlevel(i)**2
1474 end subroutine rmhd_get_a2max
1477 subroutine rmhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
1480 integer,
intent(in) :: ixi^
l,ixo^
l
1481 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1482 double precision,
intent(out) :: tco_local,tmax_local
1484 double precision,
intent(inout) :: w(ixi^s,1:nw)
1485 double precision,
parameter :: trac_delta=0.25d0
1486 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s)
1487 double precision,
dimension(ixI^S,1:ndir) :: bunitvec
1488 double precision,
dimension(ixI^S,1:ndim) :: gradt
1489 double precision :: bdir(
ndim)
1490 double precision :: ltrc,ltrp,altr(ixi^s)
1491 integer :: idims,jxo^
l,hxo^
l,ixa^
d,ixb^
d,ix^
d
1492 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
1493 logical :: lrlt(ixi^s)
1496 call rmhd_get_temperature_from_te(w,x,ixi^
l,ixi^
l,te)
1498 call rmhd_get_rfactor(w,x,ixi^
l,ixi^
l,te)
1499 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
1502 tmax_local=maxval(te(ixo^s))
1512 lts(ixo^s)=0.5d0*abs(te(jxo^s)-te(hxo^s))/te(ixo^s)
1514 where(lts(ixo^s) > trac_delta)
1517 if(any(lrlt(ixo^s)))
then
1518 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
1529 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
1530 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1531 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
1532 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
1534 call mpistop(
"rmhd_trac_type not allowed for 1D simulation")
1546 gradt(ixo^s,idims)=tmp1(ixo^s)
1550 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))+
block%B0(ixo^s,:,0)
1552 bunitvec(ixo^s,:)=w(ixo^s,iw_mag(:))
1558 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
1561 if(sum(bdir(:)**2) .gt. zero)
then
1562 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
1564 block%special_values(3:ndim+2)=bdir(1:ndim)
1566 tmp1(ixo^s)=dsqrt(sum(bunitvec(ixo^s,:)**2,dim=ndim+1))
1567 where(tmp1(ixo^s)/=0.d0)
1568 tmp1(ixo^s)=1.d0/tmp1(ixo^s)
1570 tmp1(ixo^s)=bigdouble
1574 bunitvec(ixo^s,idims)=bunitvec(ixo^s,idims)*tmp1(ixo^s)
1577 lts(ixo^s)=abs(sum(gradt(ixo^s,1:ndim)*bunitvec(ixo^s,1:ndim),dim=ndim+1))/te(ixo^s)
1579 if(slab_uniform)
then
1580 lts(ixo^s)=minval(dxlevel)*lts(ixo^s)
1582 lts(ixo^s)=minval(block%ds(ixo^s,:),dim=ndim+1)*lts(ixo^s)
1585 where(lts(ixo^s) > trac_delta)
1588 if(any(lrlt(ixo^s)))
then
1589 block%special_values(1)=maxval(te(ixo^s), mask=lrlt(ixo^s))
1591 block%special_values(1)=zero
1593 block%special_values(2)=tmax_local
1612 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1613 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1614 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1617 {
do ix^db=ixpmin^db,ixpmax^db\}
1619 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))+block%B0(ix^d,^
c,0)\
1621 ^
c&bunitvec(ix^d,^
c)=w(ix^d,iw_mag(^
c))\
1623 tmp1(ix^d)=1.d0/(dsqrt(^
c&bunitvec(ix^d,^
c)**2+)+smalldouble)
1625 ^d&bunitvec({ix^d},^d)=bunitvec({ix^d},^d)*tmp1({ix^d})\
1627 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec({ix^d},^d)+)/te(ix^d)
1629 if(slab_uniform)
then
1630 lts(ix^d)=min(^d&dxlevel(^d))*lts(ix^d)
1632 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
1634 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
1639 hxo^l=ixp^l-kr(idims,^d);
1640 jxo^l=ixp^l+kr(idims,^d);
1642 altr(ixp^s)=0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1644 altr(ixp^s)=altr(ixp^s)+0.25d0*(lts(hxo^s)+two*lts(ixp^s)+lts(jxo^s))*bunitvec(ixp^s,idims)**2
1647 block%wextra(ixp^s,
tcoff_)=te(ixp^s)*altr(ixp^s)**0.4d0
1651 call mpistop(
"unknown rmhd_trac_type")
1654 end subroutine rmhd_get_tcutoff
1657 subroutine rmhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
1660 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1661 double precision,
intent(in) :: wprim(ixi^s, nw)
1662 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1663 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
1665 double precision :: csound(ixi^s,
ndim)
1666 double precision,
allocatable :: tmp(:^
d&)
1667 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
1671 allocate(tmp(ixa^s))
1673 call rmhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
1674 csound(ixa^s,id)=tmp(ixa^s)
1677 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
1678 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
1679 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
1680 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))
1684 ixamax^
d=ixcmax^
d+
kr(id,^
d);
1685 ixamin^
d=ixcmin^
d+
kr(id,^
d);
1686 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)))
1687 ixamax^
d=ixcmax^
d-
kr(id,^
d);
1688 ixamin^
d=ixcmin^
d-
kr(id,^
d);
1689 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)))
1694 ixamax^
d=jxcmax^
d+
kr(id,^
d);
1695 ixamin^
d=jxcmin^
d+
kr(id,^
d);
1696 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)))
1697 ixamax^
d=jxcmax^
d-
kr(id,^
d);
1698 ixamin^
d=jxcmin^
d-
kr(id,^
d);
1699 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)))
1703 end subroutine rmhd_get_h_speed
1706 subroutine rmhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1708 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1709 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1710 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1711 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1712 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1713 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1714 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1716 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1717 double precision :: umean, dmean, tmp1, tmp2, tmp3
1724 call rmhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1725 call rmhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1726 if(
present(cmin))
then
1727 {
do ix^db=ixomin^db,ixomax^db\}
1728 tmp1=sqrt(wlp(ix^
d,
rho_))
1729 tmp2=sqrt(wrp(ix^
d,
rho_))
1730 tmp3=1.d0/(tmp1+tmp2)
1731 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1732 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1733 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1734 cmin(ix^
d,1)=umean-dmean
1735 cmax(ix^
d,1)=umean+dmean
1737 if(h_correction)
then
1738 {
do ix^db=ixomin^db,ixomax^db\}
1739 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1740 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1744 {
do ix^db=ixomin^db,ixomax^db\}
1745 tmp1=sqrt(wlp(ix^d,
rho_))
1746 tmp2=sqrt(wrp(ix^d,
rho_))
1747 tmp3=1.d0/(tmp1+tmp2)
1748 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1749 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1750 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1751 cmax(ix^d,1)=abs(umean)+dmean
1755 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1756 call rmhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
1757 if(
present(cmin))
then
1758 {
do ix^db=ixomin^db,ixomax^db\}
1759 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1760 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1762 if(h_correction)
then
1763 {
do ix^db=ixomin^db,ixomax^db\}
1764 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1765 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1769 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1773 call rmhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
1774 call rmhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
1775 if(
present(cmin))
then
1776 {
do ix^db=ixomin^db,ixomax^db\}
1777 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1778 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1779 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1781 if(h_correction)
then
1782 {
do ix^db=ixomin^db,ixomax^db\}
1783 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1784 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1788 {
do ix^db=ixomin^db,ixomax^db\}
1789 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1790 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1794 end subroutine rmhd_get_cbounds
1797 subroutine rmhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1799 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1800 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1801 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1802 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1803 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1804 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1805 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1806 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
1807 double precision :: umean, dmean, tmp1, tmp2, tmp3
1814 call rmhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
1815 call rmhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
1816 if(
present(cmin))
then
1817 {
do ix^db=ixomin^db,ixomax^db\}
1820 tmp3=1.d0/(tmp1+tmp2)
1821 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
1822 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
1823 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
1824 cmin(ix^
d,1)=umean-dmean
1825 cmax(ix^
d,1)=umean+dmean
1827 if(h_correction)
then
1828 {
do ix^db=ixomin^db,ixomax^db\}
1829 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1830 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1834 {
do ix^db=ixomin^db,ixomax^db\}
1837 tmp3=1.d0/(tmp1+tmp2)
1838 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
1839 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
1840 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
1841 cmax(ix^d,1)=abs(umean)+dmean
1845 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1846 call rmhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
1847 if(
present(cmin))
then
1848 {
do ix^db=ixomin^db,ixomax^db\}
1849 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
1850 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
1852 if(h_correction)
then
1853 {
do ix^db=ixomin^db,ixomax^db\}
1854 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1855 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1859 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
1863 call rmhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
1864 call rmhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
1865 if(
present(cmin))
then
1866 {
do ix^db=ixomin^db,ixomax^db\}
1867 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1868 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
1869 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1871 if(h_correction)
then
1872 {
do ix^db=ixomin^db,ixomax^db\}
1873 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1874 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1878 {
do ix^db=ixomin^db,ixomax^db\}
1879 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
1880 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
1884 end subroutine rmhd_get_cbounds_split_rho
1887 subroutine rmhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1890 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1891 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1892 double precision,
intent(in) :: cmax(ixi^s)
1893 double precision,
intent(in),
optional :: cmin(ixi^s)
1894 type(ct_velocity),
intent(inout):: vcts
1896 end subroutine rmhd_get_ct_velocity_average
1898 subroutine rmhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1901 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1902 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1903 double precision,
intent(in) :: cmax(ixi^s)
1904 double precision,
intent(in),
optional :: cmin(ixi^s)
1905 type(ct_velocity),
intent(inout):: vcts
1908 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
1910 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
1912 end subroutine rmhd_get_ct_velocity_contact
1914 subroutine rmhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
1917 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1918 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1919 double precision,
intent(in) :: cmax(ixi^s)
1920 double precision,
intent(in),
optional :: cmin(ixi^s)
1921 type(ct_velocity),
intent(inout):: vcts
1923 integer :: idime,idimn
1925 if(.not.
allocated(vcts%vbarC))
then
1926 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
1927 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
1930 if(
present(cmin))
then
1931 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
1932 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1934 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
1935 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
1938 idimn=mod(idim,
ndir)+1
1939 idime=mod(idim+1,
ndir)+1
1941 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
1942 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
1943 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
1944 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1945 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1947 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
1948 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
1949 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
1950 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
1951 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
1953 end subroutine rmhd_get_ct_velocity_hll
1956 subroutine rmhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
1958 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1959 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1960 double precision,
intent(out):: csound(ixo^s)
1961 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
1962 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
1963 double precision :: prad_max(ixo^s)
1968 if(radio_acoustic_filter)
then
1969 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
1973 {
do ix^db=ixomin^db,ixomax^db \}
1974 inv_rho=1.d0/w(ix^
d,
rho_)
1975 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1977 csound(ix^
d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
1982 cfast2=b2*inv_rho+csound(ix^
d)
1983 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
1985 if(avmincs2<zero) avmincs2=zero
1986 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
1989 {
do ix^db=ixomin^db,ixomax^db \}
1990 inv_rho=1.d0/w(ix^d,
rho_)
1991 prad_max(ix^d)=maxval(prad_tensor(ix^d,:,:))
1993 csound(ix^d)=max(
rmhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+prad_max(ix^d))*inv_rho
1997 b2=(^
c&w(ix^d,
b^
c_)**2+)
1998 cfast2=b2*inv_rho+csound(ix^d)
1999 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2000 if(avmincs2<zero) avmincs2=zero
2001 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2004 end subroutine rmhd_get_csound_prim
2007 subroutine rmhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
2009 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2010 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2011 double precision,
intent(out):: csound(ixo^s)
2012 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
2013 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2014 double precision :: prad_max(ixo^s)
2019 if (radio_acoustic_filter)
then
2020 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2025 {
do ix^db=ixomin^db,ixomax^db \}
2028 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2033 cfast2=b2*inv_rho+csound(ix^
d)
2034 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
2036 if(avmincs2<zero) avmincs2=zero
2037 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2040 {
do ix^db=ixomin^db,ixomax^db \}
2043 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
2045 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
2047 b2=(^
c&w(ix^d,
b^
c_)**2+)
2048 cfast2=b2*inv_rho+csound(ix^d)
2049 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2050 if(avmincs2<zero) avmincs2=zero
2051 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2054 end subroutine rmhd_get_csound_prim_split
2057 subroutine rmhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
2061 integer,
intent(in) :: ixi^
l, ixo^
l
2062 double precision,
intent(in) :: w(ixi^s,nw)
2063 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2064 double precision,
intent(out):: pth(ixi^s)
2068 {
do ix^db=ixomin^db,ixomax^db\}
2073 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)&
2074 +(^
c&w(ix^
d,
b^
c_)**2+)))
2079 if(check_small_values.and..not.fix_small_values)
then
2080 {
do ix^db=ixomin^db,ixomax^db\}
2081 if(pth(ix^d)<small_pressure)
then
2082 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
2083 " encountered when call rmhd_get_pthermal"
2084 write(*,*)
"Iteration: ", it,
" Time: ", global_time
2085 write(*,*)
"Location: ", x(ix^d,:)
2086 write(*,*)
"Cell number: ", ix^d
2088 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
2091 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
2092 write(*,*)
"Saving status at the previous time step"
2097 end subroutine rmhd_get_pthermal_origin
2100 subroutine rmhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
2102 integer,
intent(in) :: ixi^
l, ixo^
l
2103 double precision,
intent(in) :: w(ixi^s, 1:nw)
2104 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2105 double precision,
intent(out):: res(ixi^s)
2106 res(ixo^s) = w(ixo^s,
te_)
2107 end subroutine rmhd_get_temperature_from_te
2110 subroutine rmhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
2112 integer,
intent(in) :: ixi^
l, ixo^
l
2113 double precision,
intent(in) :: w(ixi^s, 1:nw)
2114 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2115 double precision,
intent(out):: res(ixi^s)
2116 double precision :: r(ixi^s)
2118 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2119 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
2120 end subroutine rmhd_get_temperature_from_eint
2123 subroutine rmhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
2125 integer,
intent(in) :: ixi^
l, ixo^
l
2126 double precision,
intent(in) :: w(ixi^s, 1:nw)
2127 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2128 double precision,
intent(out):: res(ixi^s)
2129 double precision :: r(ixi^s)
2131 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2133 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
2134 end subroutine rmhd_get_temperature_from_etot
2136 subroutine rmhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
2138 integer,
intent(in) :: ixi^
l, ixo^
l
2139 double precision,
intent(in) :: w(ixi^s, 1:nw)
2140 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2141 double precision,
intent(out):: res(ixi^s)
2142 double precision :: r(ixi^s)
2144 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2147 end subroutine rmhd_get_temperature_from_etot_with_equi
2149 subroutine rmhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
2151 integer,
intent(in) :: ixi^
l, ixo^
l
2152 double precision,
intent(in) :: w(ixi^s, 1:nw)
2153 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2154 double precision,
intent(out):: res(ixi^s)
2155 double precision :: r(ixi^s)
2157 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2160 end subroutine rmhd_get_temperature_from_eint_with_equi
2162 subroutine rmhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
2164 integer,
intent(in) :: ixi^
l, ixo^
l
2165 double precision,
intent(in) :: w(ixi^s, 1:nw)
2166 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2167 double precision,
intent(out):: res(ixi^s)
2168 double precision :: r(ixi^s)
2170 call rmhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
2172 end subroutine rmhd_get_temperature_equi
2174 subroutine rmhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
2176 integer,
intent(in) :: ixi^
l, ixo^
l
2177 double precision,
intent(in) :: w(ixi^s, 1:nw)
2178 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2179 double precision,
intent(out):: res(ixi^s)
2181 end subroutine rmhd_get_rho_equi
2183 subroutine rmhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
2185 integer,
intent(in) :: ixi^
l, ixo^
l
2186 double precision,
intent(in) :: w(ixi^s, 1:nw)
2187 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2188 double precision,
intent(out):: res(ixi^s)
2190 end subroutine rmhd_get_pe_equi
2193 subroutine rmhd_get_p_total(w,x,ixI^L,ixO^L,p)
2195 integer,
intent(in) :: ixi^
l, ixo^
l
2196 double precision,
intent(in) :: w(ixi^s,nw)
2197 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2198 double precision,
intent(out) :: p(ixi^s)
2201 p(ixo^s) = p(ixo^s) + 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
2202 end subroutine rmhd_get_p_total
2209 integer,
intent(in) :: ixi^
l, ixo^
l, nth
2210 double precision,
intent(in) :: w(ixi^s, 1:nw)
2211 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2212 double precision,
intent(out):: prad(ixo^s, 1:
ndim, 1:
ndim)
2220 call mpistop(
'Radiation formalism unknown')
2227 integer,
intent(in) :: ixi^
l, ixo^
l
2228 double precision,
intent(in) :: w(ixi^s, 1:nw)
2229 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2230 double precision :: pth(ixi^s)
2231 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
2232 double precision :: prad_max(ixo^s)
2233 double precision,
intent(out) :: pth_plus_prad(ixi^s)
2238 {
do ix^
d = ixomin^
d,ixomax^
d\}
2239 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
2242 if (radio_acoustic_filter)
then
2243 call rmhd_radio_acoustic_filter(x, ixi^
l, ixo^
l, prad_max)
2245 pth_plus_prad(ixo^s) = pth(ixo^s) + prad_max(ixo^s)
2249 subroutine rmhd_radio_acoustic_filter(x, ixI^L, ixO^L, prad_max)
2251 integer,
intent(in) :: ixi^
l, ixo^
l
2252 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2253 double precision,
intent(inout) :: prad_max(ixo^s)
2254 double precision :: tmp_prad(ixi^s)
2255 integer :: ix^
d, filter, idim
2257 if (size_ra_filter .lt. 1)
call mpistop(
"ra filter of size < 1 makes no sense")
2258 if (size_ra_filter .gt.
nghostcells)
call mpistop(
"ra filter of size < nghostcells makes no sense")
2260 tmp_prad(ixi^s) = zero
2261 tmp_prad(ixo^s) = prad_max(ixo^s)
2262 do filter = 1,size_ra_filter
2265 {
do ix^
d = ixomin^
d,ixomax^
d\}
2266 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d+filter*
kr(idim,^
d)))
2267 prad_max(ix^
d) = min(tmp_prad(ix^
d),tmp_prad(ix^
d-filter*
kr(idim,^
d)))
2271 end subroutine rmhd_radio_acoustic_filter
2276 integer,
intent(in) :: ixi^
l, ixo^
l
2277 double precision,
intent(in) :: w(ixi^s, 1:nw)
2278 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2279 double precision :: pth(ixi^s)
2280 double precision,
intent(out):: tgas(ixi^s)
2283 tgas(ixi^s) = pth(ixi^s)/w(ixi^s,
rho_)
2291 integer,
intent(in) :: ixi^
l, ixo^
l
2292 double precision,
intent(in) :: w(ixi^s, 1:nw)
2293 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2294 double precision,
intent(out):: trad(ixi^s)
2301 subroutine rmhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
2305 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2307 double precision,
intent(in) :: wc(ixi^s,nw)
2309 double precision,
intent(in) :: w(ixi^s,nw)
2310 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2311 double precision,
intent(out) :: f(ixi^s,nwflux)
2312 double precision :: vhall(ixi^s,1:
ndir)
2313 double precision :: ptotal
2316 {
do ix^db=ixomin^db,ixomax^db\}
2321 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2323 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2326 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2327 -w(ix^
d,mag(idim))*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2332 {
do ix^db=ixomin^db,ixomax^db\}
2333 f(ix^d,mag(idim))=w(ix^d,
psi_)
2335 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
2339 {
do ix^db=ixomin^db,ixomax^db\}
2340 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2347 {
do ix^db=ixomin^db,ixomax^db\}
2352 {
do ix^db=ixomin^db,ixomax^db\}
2353 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^
c&w({ix^d},
b^
c_)**2+)+smalldouble)
2357 end subroutine rmhd_get_flux
2360 subroutine rmhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
2363 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2365 double precision,
intent(in) :: wc(ixi^s,nw)
2367 double precision,
intent(in) :: w(ixi^s,nw)
2368 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2369 double precision,
intent(out) :: f(ixi^s,nwflux)
2370 double precision :: vhall(ixi^s,1:
ndir)
2371 double precision :: ptotal, btotal(ixo^s,1:
ndir)
2374 {
do ix^db=ixomin^db,ixomax^db\}
2382 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
2391 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
2395 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
2396 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2398 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
2402 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
2405 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
2409 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
2410 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
2414 {
do ix^db=ixomin^db,ixomax^db\}
2415 f(ix^d,mag(idim))=w(ix^d,
psi_)
2417 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
2421 {
do ix^db=ixomin^db,ixomax^db\}
2422 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2429 {
do ix^db=ixomin^db,ixomax^db\}
2434 {
do ix^db=ixomin^db,ixomax^db\}
2435 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
2439 end subroutine rmhd_get_flux_split
2443 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
2446 integer,
intent(in) :: ixi^
l, ixo^
l
2447 double precision,
dimension(:^D&,:),
intent(inout) :: ff
2448 double precision,
intent(out) :: src(ixi^s)
2450 double precision :: ffc(ixi^s,1:
ndim)
2451 double precision :: dxinv(
ndim)
2452 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
2458 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
2460 ixbmin^
d=ixcmin^
d+ix^
d;
2461 ixbmax^
d=ixcmax^
d+ix^
d;
2464 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
2466 ff(ixi^s,1:ndim)=0.d0
2468 ixb^l=ixo^l-kr(idims,^d);
2469 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
2471 if({ ix^d==0 .and. ^d==idims | .or.})
then
2472 ixbmin^d=ixcmin^d-ix^d;
2473 ixbmax^d=ixcmax^d-ix^d;
2474 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
2477 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
2480 if(slab_uniform)
then
2482 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
2483 ixb^l=ixo^l-kr(idims,^d);
2484 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2488 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
2489 ixb^l=ixo^l-kr(idims,^d);
2490 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
2492 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
2494 end subroutine get_flux_on_cell_face
2497 subroutine rmhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2503 integer,
intent(in) :: ixi^
l, ixo^
l
2504 double precision,
intent(in) :: qdt,dtfactor
2505 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2506 double precision,
intent(inout) :: w(ixi^s,1:nw)
2507 logical,
intent(in) :: qsourcesplit
2508 logical,
intent(inout) :: active
2514 if (.not. qsourcesplit)
then
2517 call add_pe0_divv(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2520 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
2525 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wctprim,w,x)
2530 call add_source_res2(qdt,ixi^
l,ixo^
l,wct,w,x)
2534 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
2540 select case (type_divb)
2545 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2548 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2551 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2552 case (divb_janhunen)
2554 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2555 case (divb_lindejanhunen)
2557 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2558 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2559 case (divb_lindepowel)
2561 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2562 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
2563 case (divb_lindeglm)
2565 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
2566 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
2567 case (divb_multigrid)
2572 call mpistop(
'Unknown divB fix')
2582 w,x,gravity_energy,qsourcesplit,active)
2588 call rmhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,w,x,qsourcesplit,active)
2591 if(.not.qsourcesplit)
then
2593 call rmhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
2596 end subroutine rmhd_add_source
2598 subroutine rmhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,w,x,qsourcesplit,active)
2604 integer,
intent(in) :: ixi^
l, ixo^
l
2605 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
2606 double precision,
intent(in) :: wct(ixi^s,1:nw)
2607 double precision,
intent(inout) :: w(ixi^s,1:nw)
2608 logical,
intent(in) :: qsourcesplit
2609 logical,
intent(inout) :: active
2610 double precision :: cmax(ixi^s)
2617 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2622 call rmhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_e_interact')
2628 call mpistop(
'Radiation formalism unknown')
2630 end subroutine rmhd_add_radiation_source
2632 subroutine add_pe0_divv(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2635 integer,
intent(in) :: ixi^
l, ixo^
l
2636 double precision,
intent(in) :: qdt,dtfactor
2637 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2638 double precision,
intent(inout) :: w(ixi^s,1:nw)
2639 double precision :: divv(ixi^s)
2655 end subroutine add_pe0_divv
2657 subroutine get_tau(ixI^L,ixO^L,w,Te,tau,sigT5)
2659 integer,
intent(in) :: ixi^
l, ixo^
l
2660 double precision,
dimension(ixI^S,1:nw),
intent(in) :: w
2661 double precision,
dimension(ixI^S),
intent(in) :: te
2662 double precision,
dimension(ixI^S),
intent(out) :: tau,sigt5
2663 double precision :: dxmin,taumin
2664 double precision,
dimension(ixI^S) :: sigt7,eint
2672 sigt7(ixo^s)=sigt5(ixo^s)*
block%wextra(ixo^s,
tcoff_)
2675 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2679 sigt7(ixo^s)=sigt5(ixo^s)*te(ixo^s)
2682 tau(ixo^s)=max(taumin*
dt,sigt7(ixo^s)/eint(ixo^s)/
cmax_global**2)
2683 end subroutine get_tau
2685 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
2687 integer,
intent(in) :: ixi^
l,ixo^
l
2688 double precision,
intent(in) :: qdt
2689 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
2690 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
2691 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
2692 double precision :: invdx
2693 double precision,
dimension(ixI^S) :: te,tau,sigt,htc_qsrc,tface,r
2694 double precision,
dimension(ixI^S) :: htc_esrc,bsum,bunit
2695 double precision,
dimension(ixI^S,1:ndim) :: btot
2697 integer :: hxc^
l,hxo^
l,ixc^
l,jxc^
l,jxo^
l,kxc^
l
2699 call rmhd_get_rfactor(wctprim,x,ixi^
l,ixi^
l,r)
2702 te(ixi^s)=wctprim(ixi^s,
p_)/(r(ixi^s)*w(ixi^s,
rho_))
2703 call get_tau(ixi^
l,ixo^
l,wctprim,te,tau,sigt)
2707 btot(ixo^s,idims)=wct(ixo^s,mag(idims))+
block%B0(ixo^s,idims,0)
2709 btot(ixo^s,idims)=wct(ixo^s,mag(idims))
2712 bsum(ixo^s)=sqrt(sum(btot(ixo^s,:)**2,dim=
ndim+1))+smalldouble
2716 ixcmin^
d=ixomin^
d-
kr(idims,^
d);ixcmax^
d=ixomax^
d;
2717 jxc^
l=ixc^
l+
kr(idims,^
d);
2718 kxc^
l=jxc^
l+
kr(idims,^
d);
2719 hxc^
l=ixc^
l-
kr(idims,^
d);
2720 hxo^
l=ixo^
l-
kr(idims,^
d);
2721 tface(ixc^s)=(7.d0*(te(ixc^s)+te(jxc^s))-(te(hxc^s)+te(kxc^s)))/12.d0
2722 bunit(ixo^s)=btot(ixo^s,idims)/bsum(ixo^s)
2723 htc_qsrc(ixo^s)=htc_qsrc(ixo^s)+sigt(ixo^s)*bunit(ixo^s)*(tface(ixo^s)-tface(hxo^s))*invdx
2725 htc_qsrc(ixo^s)=(htc_qsrc(ixo^s)+wct(ixo^s,
q_))/tau(ixo^s)
2726 w(ixo^s,
q_)=w(ixo^s,
q_)-qdt*htc_qsrc(ixo^s)
2727 end subroutine add_hypertc_source
2730 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
2732 integer,
intent(in) :: ixi^
l, ixo^
l
2733 double precision,
intent(in) :: w(ixi^s,1:nw)
2734 double precision,
intent(inout) :: jxb(ixi^s,3)
2735 double precision :: a(ixi^s,3),
b(ixi^s,3)
2737 double precision :: current(ixi^s,7-2*
ndir:3)
2738 integer :: idir, idirmin
2743 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
2747 b(ixo^s, idir) = w(ixo^s,mag(idir))
2754 a(ixo^s,idir)=current(ixo^s,idir)
2757 end subroutine get_lorentz_force
2761 subroutine rmhd_gamma2_alfven(ixI^L, ixO^L, w, gamma_A2)
2763 integer,
intent(in) :: ixi^
l, ixo^
l
2764 double precision,
intent(in) :: w(ixi^s, nw)
2765 double precision,
intent(out) :: gamma_a2(ixo^s)
2766 double precision :: rho(ixi^s)
2772 rho(ixo^s) = w(ixo^s,
rho_)
2775 gamma_a2(ixo^s) = 1.0d0/(1.0d0+
rmhd_mag_en_all(w, ixi^
l, ixo^
l)/rho(ixo^s)*inv_squared_c)
2776 end subroutine rmhd_gamma2_alfven
2780 function rmhd_gamma_alfven(w, ixI^L, ixO^L)
result(gamma_A)
2782 integer,
intent(in) :: ixi^
l, ixo^
l
2783 double precision,
intent(in) :: w(ixi^s, nw)
2784 double precision :: gamma_a(ixo^s)
2786 call rmhd_gamma2_alfven(ixi^
l, ixo^
l, w, gamma_a)
2787 gamma_a = sqrt(gamma_a)
2788 end function rmhd_gamma_alfven
2792 integer,
intent(in) :: ixi^
l, ixo^
l
2793 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
2794 double precision,
intent(out) :: rho(ixi^s)
2799 rho(ixo^s) = w(ixo^s,
rho_)
2804 subroutine rmhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
2807 integer,
intent(in) :: ixi^
l,ixo^
l, ie
2808 double precision,
intent(inout) :: w(ixi^s,1:nw)
2809 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2810 character(len=*),
intent(in) :: subname
2811 double precision :: rho(ixi^s)
2813 logical :: flag(ixi^s,1:nw)
2817 where(w(ixo^s,ie)+
block%equi_vars(ixo^s,
equi_pe0_,0)*inv_gamma_1<small_e)&
2818 flag(ixo^s,ie)=.true.
2820 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
2822 if(any(flag(ixo^s,ie)))
then
2826 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e - &
2829 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
2835 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
2838 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
2843 end subroutine rmhd_handle_small_ei
2845 subroutine rmhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
2849 integer,
intent(in) :: ixi^
l, ixo^
l
2850 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2851 double precision,
intent(inout) :: w(ixi^s,1:nw)
2853 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
2861 end subroutine rmhd_update_temperature
2864 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x)
2866 integer,
intent(in) :: ixi^
l, ixo^
l
2867 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2868 double precision,
intent(inout) :: w(ixi^s,1:nw)
2869 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
2880 a(ixo^s,idir)=
block%J0(ixo^s,idir)
2885 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2888 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2893 if(total_energy)
then
2896 b(ixo^s,:)=wct(ixo^s,mag(:))
2905 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
2908 axb(ixo^s,:)=axb(ixo^s,:)*qdt
2912 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
2915 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
2916 end subroutine add_source_b0split
2922 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
2926 integer,
intent(in) :: ixi^
l, ixo^
l
2927 double precision,
intent(in) :: qdt
2928 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
2929 double precision,
intent(inout) :: w(ixi^s,1:nw)
2930 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim,jxo^
l,hxo^
l,ix
2931 integer :: lxo^
l, kxo^
l
2932 double precision :: tmp(ixi^s),tmp2(ixi^s)
2934 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
2935 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
2943 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
2944 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
2949 gradeta(ixo^s,1:
ndim)=zero
2955 gradeta(ixo^s,idim)=tmp(ixo^s)
2961 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
2967 tmp2(ixi^s)=bf(ixi^s,idir)
2969 lxo^
l=ixo^
l+2*
kr(idim,^
d);
2970 jxo^
l=ixo^
l+
kr(idim,^
d);
2971 hxo^
l=ixo^
l-
kr(idim,^
d);
2972 kxo^
l=ixo^
l-2*
kr(idim,^
d);
2973 tmp(ixo^s)=tmp(ixo^s)+&
2974 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
2979 tmp2(ixi^s)=bf(ixi^s,idir)
2981 jxo^
l=ixo^
l+
kr(idim,^
d);
2982 hxo^
l=ixo^
l-
kr(idim,^
d);
2983 tmp(ixo^s)=tmp(ixo^s)+&
2984 (tmp2(jxo^s)-2.0d0*tmp2(ixo^s)+tmp2(hxo^s))/
dxlevel(idim)**2
2988 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
2991 do jdir=1,
ndim;
do kdir=idirmin,3
2992 if (
lvc(idir,jdir,kdir)/=0)
then
2993 if (
lvc(idir,jdir,kdir)==1)
then
2994 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
2996 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
3002 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
3003 if(total_energy)
then
3004 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
3009 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
3011 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
3012 end subroutine add_source_res1
3016 subroutine add_source_res2(qdt,ixI^L,ixO^L,wCT,w,x)
3020 integer,
intent(in) :: ixi^
l, ixo^
l
3021 double precision,
intent(in) :: qdt
3022 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3023 double precision,
intent(inout) :: w(ixi^s,1:nw)
3025 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
3026 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
3027 integer :: ixa^
l,idir,idirmin,idirmin1
3030 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3031 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
3039 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
rmhd_eta
3044 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
3052 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
3055 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
3059 tmp(ixo^s)=qdt*
rmhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
3061 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
3063 if(total_energy)
then
3066 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
3067 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
3070 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
3073 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res2')
3074 end subroutine add_source_res2
3078 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
3081 integer,
intent(in) :: ixi^
l, ixo^
l
3082 double precision,
intent(in) :: qdt
3083 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3084 double precision,
intent(inout) :: w(ixi^s,1:nw)
3086 double precision :: current(ixi^s,7-2*
ndir:3)
3087 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
3088 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
3091 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
3092 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
3094 tmpvec(ixa^s,1:
ndir)=zero
3096 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
3099 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3101 tmpvec(ixa^s,1:
ndir)=zero
3102 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
3105 tmpvec2(ixa^s,1:
ndir)=zero
3106 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
3108 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
3110 if(total_energy)
then
3113 tmpvec2(ixa^s,1:
ndir)=zero
3114 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
3115 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
3116 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
3117 end do;
end do;
end do
3119 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
3120 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
3122 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
3123 end subroutine add_source_hyperres
3125 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
3131 integer,
intent(in) :: ixi^
l, ixo^
l
3132 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3133 double precision,
intent(inout) :: w(ixi^s,1:nw)
3134 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
3153 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
3156 if(total_energy)
then
3165 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
3172 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
3175 if (
fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
3176 end subroutine add_source_glm
3179 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
3181 integer,
intent(in) :: ixi^
l, ixo^
l
3182 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3183 double precision,
intent(inout) :: w(ixi^s,1:nw)
3184 double precision :: divb(ixi^s), ba(1:
ndir)
3185 integer :: idir, ix^
d
3190 {
do ix^db=ixomin^db,ixomax^db\}
3195 if (total_energy)
then
3201 {
do ix^db=ixomin^db,ixomax^db\}
3203 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
3205 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
3206 if (total_energy)
then
3208 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
3212 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
3213 end subroutine add_source_powel
3215 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
3219 integer,
intent(in) :: ixi^
l, ixo^
l
3220 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3221 double precision,
intent(inout) :: w(ixi^s,1:nw)
3222 double precision :: divb(ixi^s)
3223 integer :: idir, ix^
d
3227 {
do ix^db=ixomin^db,ixomax^db\}
3231 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
3232 end subroutine add_source_janhunen
3234 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
3238 integer,
intent(in) :: ixi^
l, ixo^
l
3239 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
3240 double precision,
intent(inout) :: w(ixi^s,1:nw)
3241 double precision :: divb(ixi^s),graddivb(ixi^s)
3242 integer :: idim, idir, ixp^
l, i^
d, iside
3243 logical,
dimension(-1:1^D&) :: leveljump
3250 if(i^
d==0|.and.) cycle
3251 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
3252 leveljump(i^
d)=.true.
3254 leveljump(i^
d)=.false.
3262 i^dd=kr(^dd,^d)*(2*iside-3);
3263 if (leveljump(i^dd))
then
3265 ixpmin^d=ixomin^d-i^d
3267 ixpmax^d=ixomax^d-i^d
3277 select case(typegrad)
3279 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
3281 call gradientl(divb,ixi^l,ixp^l,idim,graddivb)
3284 if (slab_uniform)
then
3285 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
3287 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
3288 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
3290 w(ixp^s,mag(idim))=w(ixp^s,mag(idim))+graddivb(ixp^s)
3292 if (typedivbdiff==
'all' .and. total_energy)
then
3294 w(ixp^s,
e_)=w(ixp^s,
e_)+wct(ixp^s,mag(idim))*graddivb(ixp^s)
3297 if (fix_small_values)
call rmhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
3298 end subroutine add_source_linde
3303 integer,
intent(in) :: ixi^
l, ixo^
l
3304 double precision,
intent(in) :: w(ixi^s,1:nw)
3305 double precision :: divb(ixi^s), dsurface(ixi^s)
3306 double precision :: invb(ixo^s)
3307 integer :: ixa^
l,idims
3309 call get_divb(w,ixi^
l,ixo^
l,divb)
3311 where(invb(ixo^s)/=0.d0)
3312 invb(ixo^s)=1.d0/invb(ixo^s)
3315 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
3317 ixamin^
d=ixomin^
d-1;
3318 ixamax^
d=ixomax^
d-1;
3319 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
3321 ixa^
l=ixo^
l-
kr(idims,^
d);
3322 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
3324 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
3325 block%dvolume(ixo^s)/dsurface(ixo^s)
3334 integer,
intent(in) :: ixo^
l, ixi^
l
3335 double precision,
intent(in) :: w(ixi^s,1:nw)
3336 integer,
intent(out) :: idirmin
3338 double precision :: current(ixi^s,7-2*
ndir:3)
3339 integer :: idir, idirmin0
3343 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
3344 block%J0(ixo^s,idirmin0:3)
3348 subroutine rmhd_get_dt(w,ixI^L,ixO^L,dtnew,dx^D,x)
3356 integer,
intent(in) :: ixi^
l, ixo^
l
3357 double precision,
intent(inout) :: dtnew
3358 double precision,
intent(in) ::
dx^
d
3359 double precision,
intent(in) :: w(ixi^s,1:nw)
3360 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3361 double precision :: dxarr(
ndim)
3362 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
3363 integer :: idirmin,idim
3367 if (.not. dt_c)
then
3378 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
3381 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
3399 call mpistop(
'Radiation formalism unknown')
3415 end subroutine rmhd_get_dt
3418 subroutine rmhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
3421 integer,
intent(in) :: ixi^
l, ixo^
l
3422 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
3423 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3424 double precision :: tmp,tmp1,invr,cot
3426 integer :: mr_,mphi_
3427 integer :: br_,bphi_
3430 br_=mag(1); bphi_=mag(1)-1+
phi_
3433 {
do ix^db=ixomin^db,ixomax^db\}
3436 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
3441 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
3446 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
3447 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
3448 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
3449 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
3450 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
3452 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
3453 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
3454 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
3457 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
3462 {
do ix^db=ixomin^db,ixomax^db\}
3464 if(local_timestep)
then
3465 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
3470 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
3476 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
3479 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
3480 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
3484 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
3490 cot=1.d0/tan(x(ix^d,2))
3494 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3495 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
3497 if(.not.stagger_grid)
then
3498 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3500 tmp=tmp+wprim(ix^d,
psi_)*cot
3502 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3507 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
3508 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
3509 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
3511 if(.not.stagger_grid)
then
3512 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
3514 tmp=tmp+wprim(ix^d,
psi_)*cot
3516 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
3519 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
3520 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
3521 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
3522 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
3523 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
3525 if(.not.stagger_grid)
then
3526 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
3527 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
3528 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
3529 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
3530 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
3535 end subroutine rmhd_add_source_geom
3538 subroutine rmhd_add_source_geom_split(qdt,dtfactor, ixI^L,ixO^L,wCT,wprim,w,x)
3541 integer,
intent(in) :: ixi^
l, ixo^
l
3542 double precision,
intent(in) :: qdt, dtfactor, x(ixi^s,1:
ndim)
3543 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
3544 double precision :: tmp(ixi^s),tmp1(ixi^s),tmp2(ixi^s),invrho(ixo^s),invr(ixo^s)
3545 integer :: iw,idir, h1x^
l{^nooned, h2x^
l}
3546 integer :: mr_,mphi_
3547 integer :: br_,bphi_
3550 br_=mag(1); bphi_=mag(1)-1+
phi_
3554 invrho(ixo^s) = 1d0/wct(ixo^s,
rho_)
3558 invr(ixo^s) =
block%dt(ixo^s) * dtfactor/x(ixo^s,1)
3560 invr(ixo^s) = qdt/x(ixo^s,1)
3565 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp)
3567 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*(tmp(ixo^s)-&
3568 wct(ixo^s,bphi_)**2+wct(ixo^s,mphi_)**2*invrho(ixo^s))
3569 w(ixo^s,mphi_)=w(ixo^s,mphi_)+qdt*invr(ixo^s)*(&
3570 -wct(ixo^s,mphi_)*wct(ixo^s,mr_)*invrho(ixo^s) &
3571 +wct(ixo^s,bphi_)*wct(ixo^s,br_))
3573 w(ixo^s,bphi_)=w(ixo^s,bphi_)+invr(ixo^s)*&
3574 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
3575 -wct(ixo^s,br_)*wct(ixo^s,mphi_)) &
3579 w(ixo^s,mr_)=w(ixo^s,mr_)+invr(ixo^s)*tmp(ixo^s)
3581 if(
rmhd_glm) w(ixo^s,br_)=w(ixo^s,br_)+wct(ixo^s,
psi_)*invr(ixo^s)
3583 h1x^
l=ixo^
l-
kr(1,^
d); {^nooned h2x^
l=ixo^
l-
kr(2,^
d);}
3584 call rmhd_get_p_total(wct,x,ixi^
l,ixo^
l,tmp1)
3585 tmp(ixo^s)=tmp1(ixo^s)
3587 tmp2(ixo^s)=sum(
block%B0(ixo^s,:,0)*wct(ixo^s,mag(:)),dim=
ndim+1)
3588 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3591 tmp(ixo^s)=tmp(ixo^s)*x(ixo^s,1) &
3592 *(
block%surfaceC(ixo^s,1)-
block%surfaceC(h1x^s,1))/
block%dvolume(ixo^s)
3595 tmp(ixo^s)=tmp(ixo^s)+wct(ixo^s,
mom(idir))**2*invrho(ixo^s)-wct(ixo^s,mag(idir))**2
3596 if(
b0field) tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,idir,0)*wct(ixo^s,mag(idir))
3599 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+tmp(ixo^s)*invr(ixo^s)
3602 w(ixo^s,mag(1))=w(ixo^s,mag(1))+invr(ixo^s)*2.0d0*wct(ixo^s,
psi_)
3606 tmp(ixo^s)=tmp1(ixo^s)
3608 tmp(ixo^s)=tmp(ixo^s)+tmp2(ixo^s)
3611 tmp1(ixo^s) =
block%dt(ixo^s) * tmp(ixo^s)
3613 tmp1(ixo^s) = qdt * tmp(ixo^s)
3616 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp1(ixo^s) &
3617 *(
block%surfaceC(ixo^s,2)-
block%surfaceC(h2x^s,2)) &
3618 /
block%dvolume(ixo^s)
3619 tmp(ixo^s)=-(wct(ixo^s,
mom(1))*wct(ixo^s,
mom(2))*invrho(ixo^s) &
3620 -wct(ixo^s,mag(1))*wct(ixo^s,mag(2)))
3622 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(2)) &
3623 +wct(ixo^s,mag(1))*
block%B0(ixo^s,2,0)
3626 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(3))**2*invrho(ixo^s) &
3627 -wct(ixo^s,mag(3))**2)*dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3629 tmp(ixo^s)=tmp(ixo^s)-2.0d0*
block%B0(ixo^s,3,0)*wct(ixo^s,mag(3))&
3630 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2))
3633 w(ixo^s,
mom(2))=w(ixo^s,
mom(2))+tmp(ixo^s)*invr(ixo^s)
3636 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(2)) &
3637 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(1)))*invrho(ixo^s)
3639 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,2,0) &
3640 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,1,0))*invrho(ixo^s)
3643 tmp(ixo^s)=tmp(ixo^s) &
3644 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
3646 w(ixo^s,mag(2))=w(ixo^s,mag(2))+tmp(ixo^s)*invr(ixo^s)
3651 tmp(ixo^s)=-(wct(ixo^s,
mom(3))*wct(ixo^s,
mom(1))*invrho(ixo^s) &
3652 -wct(ixo^s,mag(3))*wct(ixo^s,mag(1))) {^nooned &
3653 -(wct(ixo^s,
mom(2))*wct(ixo^s,
mom(3))*invrho(ixo^s) &
3654 -wct(ixo^s,mag(2))*wct(ixo^s,mag(3))) &
3655 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3657 tmp(ixo^s)=tmp(ixo^s)+
block%B0(ixo^s,1,0)*wct(ixo^s,mag(3)) &
3658 +wct(ixo^s,mag(1))*
block%B0(ixo^s,3,0) {^nooned &
3659 +(
block%B0(ixo^s,2,0)*wct(ixo^s,mag(3)) &
3660 +wct(ixo^s,mag(2))*
block%B0(ixo^s,3,0)) &
3661 *dcos(x(ixo^s,2))/dsin(x(ixo^s,2)) }
3663 w(ixo^s,
mom(3))=w(ixo^s,
mom(3))+tmp(ixo^s)*invr(ixo^s)
3666 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(3)) &
3667 -wct(ixo^s,
mom(3))*wct(ixo^s,mag(1)))*invrho(ixo^s) {^nooned &
3668 -(wct(ixo^s,
mom(3))*wct(ixo^s,mag(2)) &
3669 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(3)))*dcos(x(ixo^s,2)) &
3670 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3672 tmp(ixo^s)=tmp(ixo^s)+(wct(ixo^s,
mom(1))*
block%B0(ixo^s,3,0) &
3673 -wct(ixo^s,
mom(3))*
block%B0(ixo^s,1,0))*invrho(ixo^s){^nooned &
3674 -(wct(ixo^s,
mom(3))*
block%B0(ixo^s,2,0) &
3675 -wct(ixo^s,
mom(2))*
block%B0(ixo^s,3,0))*dcos(x(ixo^s,2)) &
3676 *invrho(ixo^s)/dsin(x(ixo^s,2)) }
3678 w(ixo^s,mag(3))=w(ixo^s,mag(3))+tmp(ixo^s)*invr(ixo^s)
3682 end subroutine rmhd_add_source_geom_split
3687 integer,
intent(in) :: ixi^
l, ixo^
l
3688 double precision,
intent(in) :: w(ixi^s, nw)
3689 double precision :: mge(ixo^s)
3692 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
3694 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
3698 subroutine rmhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
3701 integer,
intent(in) :: ixi^
l, ixo^
l, idir
3702 double precision,
intent(in) :: qt
3703 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
3704 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
3706 double precision :: db(ixo^s), dpsi(ixo^s)
3710 {
do ix^db=ixomin^db,ixomax^db\}
3711 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3712 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3713 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3714 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
3723 {
do ix^db=ixomin^db,ixomax^db\}
3724 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
3725 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
3726 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
3727 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
3728 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3730 if(total_energy)
then
3731 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
3732 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
3734 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3736 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
3739 if(total_energy)
then
3740 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
3741 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
3745 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
3746 end subroutine rmhd_modify_wlr
3748 subroutine rmhd_boundary_adjust(igrid,psb)
3750 integer,
intent(in) :: igrid
3752 integer :: ib, idims, iside, ixo^
l, i^
d
3761 i^
d=
kr(^
d,idims)*(2*iside-3);
3762 if (neighbor_type(i^
d,igrid)/=1) cycle
3763 ib=(idims-1)*2+iside
3781 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
3785 end subroutine rmhd_boundary_adjust
3787 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
3789 integer,
intent(in) :: ixg^
l,ixo^
l,ib
3790 double precision,
intent(inout) :: w(ixg^s,1:nw)
3791 double precision,
intent(in) :: x(ixg^s,1:
ndim)
3792 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
3793 integer :: ix^
d,ixf^
l
3806 do ix1=ixfmax1,ixfmin1,-1
3807 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
3808 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3809 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3812 do ix1=ixfmax1,ixfmin1,-1
3813 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
3814 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
3815 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3816 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3817 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3818 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3819 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3833 do ix1=ixfmax1,ixfmin1,-1
3834 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3835 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3836 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3837 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3838 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3839 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3842 do ix1=ixfmax1,ixfmin1,-1
3843 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3844 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3845 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3846 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3847 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3848 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3849 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3850 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3851 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3852 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3853 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3854 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3855 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3856 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3857 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3858 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3859 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3860 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3874 do ix1=ixfmin1,ixfmax1
3875 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
3876 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
3877 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
3880 do ix1=ixfmin1,ixfmax1
3881 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
3882 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
3883 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
3884 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
3885 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
3886 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
3887 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
3901 do ix1=ixfmin1,ixfmax1
3902 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3903 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
3904 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
3905 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
3906 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
3907 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
3910 do ix1=ixfmin1,ixfmax1
3911 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
3912 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
3913 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
3914 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
3915 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
3916 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
3917 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
3918 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
3919 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
3920 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
3921 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
3922 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
3923 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
3924 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
3925 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3926 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
3927 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
3928 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
3942 do ix2=ixfmax2,ixfmin2,-1
3943 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
3944 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
3945 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
3948 do ix2=ixfmax2,ixfmin2,-1
3949 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
3950 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
3951 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
3952 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
3953 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
3954 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
3955 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
3969 do ix2=ixfmax2,ixfmin2,-1
3970 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
3971 ix2+1,ixfmin3:ixfmax3,mag(2)) &
3972 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
3973 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
3974 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
3975 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
3978 do ix2=ixfmax2,ixfmin2,-1
3979 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
3980 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
3981 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
3982 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
3983 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
3984 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3985 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
3986 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
3987 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
3988 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
3989 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
3990 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
3991 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
3992 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
3993 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
3994 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
3995 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
3996 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4010 do ix2=ixfmin2,ixfmax2
4011 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
4012 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
4013 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
4016 do ix2=ixfmin2,ixfmax2
4017 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
4018 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
4019 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
4020 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
4021 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
4022 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
4023 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
4037 do ix2=ixfmin2,ixfmax2
4038 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
4039 ix2-1,ixfmin3:ixfmax3,mag(2)) &
4040 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
4041 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
4042 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
4043 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
4046 do ix2=ixfmin2,ixfmax2
4047 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
4048 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
4049 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
4050 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
4051 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
4052 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4053 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
4054 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
4055 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
4056 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
4057 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
4058 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
4059 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
4060 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
4061 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
4062 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
4063 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
4064 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
4081 do ix3=ixfmax3,ixfmin3,-1
4082 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
4083 ixfmin2:ixfmax2,ix3+1,mag(3)) &
4084 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4085 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4086 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4087 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4090 do ix3=ixfmax3,ixfmin3,-1
4091 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
4092 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
4093 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4094 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
4095 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4096 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4097 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4098 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4099 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4100 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4101 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4102 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4103 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4104 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4105 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4106 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4107 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
4108 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4123 do ix3=ixfmin3,ixfmax3
4124 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
4125 ixfmin2:ixfmax2,ix3-1,mag(3)) &
4126 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
4127 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
4128 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
4129 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
4132 do ix3=ixfmin3,ixfmax3
4133 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
4134 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
4135 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
4136 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
4137 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
4138 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4139 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
4140 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
4141 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
4142 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
4143 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
4144 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
4145 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
4146 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
4147 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
4148 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
4149 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
4150 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
4156 call mpistop(
"Special boundary is not defined for this region")
4158 end subroutine fixdivb_boundary
4166 double precision,
intent(in) :: qdt
4167 double precision,
intent(in) :: qt
4168 logical,
intent(inout) :: active
4170 integer,
parameter :: max_its = 50
4171 double precision :: residual_it(max_its), max_divb
4172 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
4173 double precision :: res
4174 double precision,
parameter :: max_residual = 1
d-3
4175 double precision,
parameter :: residual_reduction = 1
d-10
4176 integer :: iigrid, igrid
4177 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
4180 mg%operator_type = mg_laplacian
4187 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4188 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4191 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
4192 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4194 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4195 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4198 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4199 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4203 write(*,*)
"rmhd_clean_divb_multigrid warning: unknown boundary type"
4204 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
4205 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
4212 do iigrid = 1, igridstail
4213 igrid = igrids(iigrid);
4216 lvl =
mg%boxes(id)%lvl
4217 nc =
mg%box_size_lvl(lvl)
4223 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
4225 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
4226 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
4231 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
4234 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
4235 if (
mype == 0) print *,
"iteration vs residual"
4238 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
4239 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
4240 if (residual_it(n) < residual_reduction * max_divb)
exit
4242 if (
mype == 0 .and. n > max_its)
then
4243 print *,
"divb_multigrid warning: not fully converged"
4244 print *,
"current amplitude of divb: ", residual_it(max_its)
4245 print *,
"multigrid smallest grid: ", &
4246 mg%domain_size_lvl(:,
mg%lowest_lvl)
4247 print *,
"note: smallest grid ideally has <= 8 cells"
4248 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
4249 print *,
"note: dx/dy/dz should be similar"
4253 call mg_fas_vcycle(
mg, max_res=res)
4254 if (res < max_residual)
exit
4256 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
4260 do iigrid = 1, igridstail
4261 igrid = igrids(iigrid);
4268 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
4271 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
4273 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
4275 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
4288 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
4289 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
4291 if(total_energy)
then
4293 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
4296 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
4304 subroutine rmhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4308 integer,
intent(in) :: ixi^
l, ixo^
l
4309 double precision,
intent(in) :: qt,qdt
4311 double precision,
intent(in) :: wp(ixi^s,1:nw)
4312 type(state) :: sct, s
4313 type(ct_velocity) :: vcts
4314 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4315 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4317 double precision :: circ(ixi^s,1:
ndim)
4319 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4320 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
4321 integer :: idim1,idim2,idir,iwdim1,iwdim2
4323 associate(bfaces=>s%ws,x=>s%x)
4330 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4334 i1kr^
d=
kr(idim1,^
d);
4337 i2kr^
d=
kr(idim2,^
d);
4340 if (
lvc(idim1,idim2,idir)==1)
then
4342 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4344 {
do ix^db=ixcmin^db,ixcmax^db\}
4345 fe(ix^
d,idir)=quarter*&
4346 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
4347 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
4349 if(
rmhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
4351 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
4359 if(
associated(usr_set_electric_field)) &
4360 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4362 circ(ixi^s,1:ndim)=zero
4367 ixcmin^d=ixomin^d-kr(idim1,^d);
4369 ixa^l=ixc^l-kr(idim2,^d);
4372 if(lvc(idim1,idim2,idir)==1)
then
4374 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4377 else if(lvc(idim1,idim2,idir)==-1)
then
4379 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4385 {
do ix^db=ixcmin^db,ixcmax^db\}
4387 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4389 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4396 end subroutine rmhd_update_faces_average
4399 subroutine rmhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4404 integer,
intent(in) :: ixi^
l, ixo^
l
4405 double precision,
intent(in) :: qt, qdt
4407 double precision,
intent(in) :: wp(ixi^s,1:nw)
4408 type(state) :: sct, s
4409 type(ct_velocity) :: vcts
4410 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4411 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4413 double precision :: circ(ixi^s,1:
ndim)
4415 double precision :: ecc(ixi^s,
sdim:3)
4416 double precision :: ein(ixi^s,
sdim:3)
4418 double precision :: el(ixi^s),er(ixi^s)
4420 double precision :: elc,erc
4422 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4424 double precision :: jce(ixi^s,
sdim:3)
4426 double precision :: xs(ixgs^t,1:
ndim)
4427 double precision :: gradi(ixgs^t)
4428 integer :: ixc^
l,ixa^
l
4429 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
4431 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
4434 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4437 {
do ix^db=iximin^db,iximax^db\}
4440 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_)
4441 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_)
4442 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_)
4445 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
4452 {
do ix^db=iximin^db,iximax^db\}
4455 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
4456 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
4457 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4460 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
4474 i1kr^d=kr(idim1,^d);
4477 i2kr^d=kr(idim2,^d);
4480 if (lvc(idim1,idim2,idir)==1)
then
4482 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4485 {
do ix^db=ixcmin^db,ixcmax^db\}
4486 fe(ix^d,idir)=quarter*&
4487 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
4488 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
4493 ixamax^d=ixcmax^d+i1kr^d;
4494 {
do ix^db=ixamin^db,ixamax^db\}
4495 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
4496 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
4499 do ix^db=ixcmin^db,ixcmax^db\}
4500 if(vnorm(ix^d,idim1)>0.d0)
then
4502 else if(vnorm(ix^d,idim1)<0.d0)
then
4503 elc=el({ix^d+i1kr^d})
4505 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
4507 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
4509 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
4510 erc=er({ix^d+i1kr^d})
4512 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
4514 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4519 ixamax^d=ixcmax^d+i2kr^d;
4520 {
do ix^db=ixamin^db,ixamax^db\}
4521 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
4522 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
4525 do ix^db=ixcmin^db,ixcmax^db\}
4526 if(vnorm(ix^d,idim2)>0.d0)
then
4528 else if(vnorm(ix^d,idim2)<0.d0)
then
4529 elc=el({ix^d+i2kr^d})
4531 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
4533 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
4535 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
4536 erc=er({ix^d+i2kr^d})
4538 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
4540 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
4544 if(
rmhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
4546 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
4560 if (lvc(idim1,idim2,idir)==0) cycle
4562 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4563 ixamax^d=ixcmax^d-kr(idir,^d)+1;
4566 xs(ixa^s,:)=x(ixa^s,:)
4567 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
4568 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
4569 if (lvc(idim1,idim2,idir)==1)
then
4570 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4572 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4579 ixcmin^d=ixomin^d+kr(idir,^d)-1;
4581 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
4585 {
do ix^db=ixomin^db,ixomax^db\}
4586 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4587 +ein(ix1,ix2-1,ix3-1,idir))
4588 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4589 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4591 else if(idir==2)
then
4592 {
do ix^db=ixomin^db,ixomax^db\}
4593 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
4594 +ein(ix1-1,ix2,ix3-1,idir))
4595 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4596 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4599 {
do ix^db=ixomin^db,ixomax^db\}
4600 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
4601 +ein(ix1-1,ix2-1,ix3,idir))
4602 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4603 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4609 {
do ix^db=ixomin^db,ixomax^db\}
4610 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
4611 +ein(ix1-1,ix2-1,idir))
4612 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
4613 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
4618 block%w(ixo^s,nw)=block%w(ixo^s,nw)+jce(ixo^s,idir)
4624 if(
associated(usr_set_electric_field)) &
4625 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
4627 circ(ixi^s,1:ndim)=zero
4632 ixcmin^d=ixomin^d-kr(idim1,^d);
4634 ixa^l=ixc^l-kr(idim2,^d);
4637 if(lvc(idim1,idim2,idir)==1)
then
4639 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4642 else if(lvc(idim1,idim2,idir)==-1)
then
4644 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4650 {
do ix^db=ixcmin^db,ixcmax^db\}
4652 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
4654 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
4661 end subroutine rmhd_update_faces_contact
4664 subroutine rmhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
4669 integer,
intent(in) :: ixi^
l, ixo^
l
4670 double precision,
intent(in) :: qt, qdt
4672 double precision,
intent(in) :: wp(ixi^s,1:nw)
4673 type(state) :: sct, s
4674 type(ct_velocity) :: vcts
4675 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
4676 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
4678 double precision :: vtill(ixi^s,2)
4679 double precision :: vtilr(ixi^s,2)
4680 double precision :: bfacetot(ixi^s,
ndim)
4681 double precision :: btill(ixi^s,
ndim)
4682 double precision :: btilr(ixi^s,
ndim)
4683 double precision :: cp(ixi^s,2)
4684 double precision :: cm(ixi^s,2)
4685 double precision :: circ(ixi^s,1:
ndim)
4687 double precision,
dimension(ixI^S,sdim:3) :: e_resi
4688 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
4689 integer :: idim1,idim2,idir,ix^
d
4691 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
4692 cbarmax=>vcts%cbarmax)
4705 if(
rmhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
4718 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
4722 idim2=mod(idir+1,3)+1
4724 jxc^
l=ixc^
l+
kr(idim1,^
d);
4725 ixcp^
l=ixc^
l+
kr(idim2,^
d);
4729 vtill(ixi^s,2),vtilr(ixi^s,2))
4732 vtill(ixi^s,1),vtilr(ixi^s,1))
4738 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
4739 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
4741 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
4742 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
4745 btill(ixi^s,idim1),btilr(ixi^s,idim1))
4748 btill(ixi^s,idim2),btilr(ixi^s,idim2))
4752 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
4753 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
4755 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
4756 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
4760 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
4761 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
4762 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
4763 /(cp(ixc^s,1)+cm(ixc^s,1)) &
4764 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
4765 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
4766 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
4767 /(cp(ixc^s,2)+cm(ixc^s,2))
4770 if(
rmhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
4771 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
4785 circ(ixi^s,1:
ndim)=zero
4790 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
4794 if(
lvc(idim1,idim2,idir)/=0)
then
4795 hxc^
l=ixc^
l-
kr(idim2,^
d);
4797 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4798 +
lvc(idim1,idim2,idir)&
4804 {
do ix^db=ixcmin^db,ixcmax^db\}
4806 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
4808 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
4814 end subroutine rmhd_update_faces_hll
4817 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
4822 integer,
intent(in) :: ixi^
l, ixo^
l
4824 double precision,
intent(in) :: wp(ixi^s,1:nw)
4825 type(state),
intent(in) :: sct, s
4827 double precision :: jce(ixi^s,
sdim:3)
4830 double precision :: jcc(ixi^s,7-2*
ndir:3)
4832 double precision :: xs(ixgs^t,1:
ndim)
4834 double precision :: eta(ixi^s)
4835 double precision :: gradi(ixgs^t)
4836 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
4838 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
4844 if (
lvc(idim1,idim2,idir)==0) cycle
4846 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4847 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
4850 xs(ixb^s,:)=x(ixb^s,:)
4851 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
4852 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
4853 if (
lvc(idim1,idim2,idir)==1)
then
4854 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
4856 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
4871 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4872 jcc(ixc^s,idir)=0.d0
4874 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4875 ixamin^
d=ixcmin^
d+ix^
d;
4876 ixamax^
d=ixcmax^
d+ix^
d;
4877 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
4879 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
4880 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
4885 end subroutine get_resistive_electric_field
4891 integer,
intent(in) :: ixo^
l
4900 do ix^db=ixomin^db,ixomax^db\}
4902 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4903 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
4904 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4905 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
4906 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
4907 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
4910 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
4911 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
4912 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
4913 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
4953 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
4954 double precision,
intent(inout) :: ws(ixis^s,1:nws)
4955 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4956 double precision :: adummy(ixis^s,1:3)
4961 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
4964 integer,
intent(in) :: ixi^
l, ixo^
l
4965 double precision,
intent(in) :: w(ixi^s,1:nw)
4966 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4967 double precision,
intent(out):: rfactor(ixi^s)
4968 double precision :: iz_h(ixo^s),iz_he(ixo^s)
4972 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)
4973 end subroutine rfactor_from_temperature_ionization
4975 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
4977 integer,
intent(in) :: ixi^
l, ixo^
l
4978 double precision,
intent(in) :: w(ixi^s,1:nw)
4979 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4980 double precision,
intent(out):: rfactor(ixi^s)
4983 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_init(phys_wider_stencil)
Initialize the module.
subroutine viscosity_get_dt(w, ixil, ixol, dtnew, dxd, x)
procedure(sub_add_source), pointer, public viscosity_add_source
The data structure that contains information about a tree node/grid block.