3 use,
intrinsic :: iso_fortran_env
14 integer,
parameter ::
dp = real64
17 complex(dp),
parameter ::
ic = (0.0d0, 1.0d0)
23 complex(dp),
allocatable ::
rho(:)
24 complex(dp),
allocatable ::
v1(:)
25 complex(dp),
allocatable ::
v2(:)
26 complex(dp),
allocatable ::
v3(:)
27 complex(dp),
allocatable ::
p(:)
28 complex(dp),
allocatable ::
b1(:)
29 complex(dp),
allocatable ::
b2(:)
30 complex(dp),
allocatable ::
b3(:)
38 character(len=100),
intent(in) :: legolas_file
39 integer,
intent(in) :: file_id
77 integer,
intent(in) :: gridpts
80 allocate(
rho(gridpts))
90 integer,
intent(in) :: ixI^L, ixO^L
91 real(dp),
intent(inout) :: w(ixI^S, nw)
92 integer,
intent(in) :: w_index
93 real(dp),
intent(in) :: x(ixI^S, ndim)
94 complex(dp) :: amplitude, exp_factor(ixI^S), quantity, values(ef_gridpts)
96 real(dp) :: k1 = 0.0d0
99 exp_factor = {exp(
ic * k^d * x(ixi^s, ^d))|*}
101 {
do idx^d = iximin^d, iximax^d|\}
103 quantity = amplitude * exp_factor(idx^d)
104 w(idx^d, w_index) = w(idx^d, w_index) + quantity%re
129 integer,
intent(in) :: w_index
130 complex(dp),
intent(inout) :: array(ef_gridpts)
136 else if (w_index ==
mom_idx(1))
then
138 else if (w_index ==
mom_idx(2))
then
143 if (w_index ==
mom_idx(3))
then
147 if (w_index ==
p_idx)
then
151 if (w_index ==
mag_idx(1))
then
153 else if (w_index ==
mag_idx(2))
then
157 if (w_index ==
mag_idx(3))
then
166 real(dp),
intent(in) :: x, grid(ef_gridpts)
167 complex(dp),
intent(in) :: array(ef_gridpts)
168 complex(dp),
intent(out) :: amplitude
172 if (x <= grid(1) .and. xprobmin1 <= x)
then
176 if (
k2 .ne. 0.0d0)
then
181 amplitude = array(1) * (x / grid(1))**alpha
183 else if (x >= grid(
size(grid)) .and. x <= xprobmax1)
then
184 amplitude = array(
size(grid))
185 else if (x < xprobmin1 .or. x > xprobmax1)
then
188 idl = maxloc(grid, mask=(grid < x), dim=1)
189 idu = minloc(grid, mask=(grid > x), dim=1)
190 amplitude = array(idl) + (x - grid(idl)) * &
191 (array(idu) - array(idl)) / (grid(idu) - grid(idl))
201 integer,
parameter :: n_modes = 2
202 integer,
parameter :: my_unit = 123
203 character(len=80) :: fmt_string =
'(9(es12.4))', filename
204 logical,
save :: alive, visited=.false.
205 double precision :: volume, magn_avg
206 double precision :: Tmax, Tmin, vmax, B1max, B2max, B3max
221 if (
mype == 0 .and. .not. visited)
then
224 open(unit=my_unit,file=trim(filename),form=
'formatted',status=
'replace')
226 write(my_unit,
'(a)')
'global_time Tmax Tmin vmax B1max B2max B3max mag_avg'
228 write(my_unit,
'(a)')
'global_time Tmax Tmin vmax'
235 write(filename,
"(a)") filename
236 inquire(file=filename,exist=alive)
238 open(unit=my_unit,file=filename,form=
'formatted',status=
'old',access=
'append')
240 open(unit=my_unit,file=filename,form=
'formatted',status=
'new')
245 write(my_unit, fmt_string)
global_time, tmax, tmin, vmax, b1max, b2max, b3max, magn_avg
247 write(my_unit, fmt_string)
global_time, tmax, tmin, vmax
253 pure function magnetic(w_vec, w_size)
result(magn_energy)
255 integer,
intent(in) :: w_size
256 double precision,
intent(in) :: w_vec(w_size)
257 double precision :: magn_energy
259 magn_energy = 0.5d0 * sum(w_vec(mag_mhd(:))**2,dim=
ndir+1)
266 double precision,
intent(out) :: Tmax, Tmin
268 integer :: iigrid, igrid
269 double precision :: Tmax_mype, Tmax_recv, Tmin_mype, Tmin_recv
270 double precision :: wlocal(ixG^T,1:nw), xlocal(ixG^T,1:ndim)
271 double precision :: Te(ixG^T), pth(ixG^T), rho(ixG^T), Rfactor(ixG^T)
273 tmax_mype = -bigdouble
274 tmin_mype = bigdouble
277 do iigrid = 1, igridstail
278 igrid = igrids(iigrid)
280 wlocal(ixg^t,1:nw) = ps(igrid)%w(ixg^t,1:nw)
281 xlocal(ixg^t,1:ndim) = ps(igrid)%x(ixg^t,1:ndim)
282 call eos%get_thermal_pressure(wlocal,xlocal,ixg^
ll,ixg^
ll,pth)
283 call eos%get_rho(wlocal,xlocal,ixg^
ll,
ixm^
ll,rho)
284 call eos%get_Rfactor(wlocal,xlocal,ixg^
ll,ixg^
ll,rfactor)
288 tmax_mype = max(tmax_mype,maxval(te(
ixm^t)))
289 tmin_mype = min(tmin_mype,minval(te(
ixm^t)))
293 call mpi_allreduce(tmax_mype, tmax_recv, 1, mpi_double_precision, &
295 call mpi_allreduce(tmin_mype, tmin_recv, 1, mpi_double_precision, &
307 double precision,
intent(out) :: vmax
309 integer :: iigrid, igrid
310 double precision :: vmax_mype,vmax_recv
311 double precision :: v_vec(ixG^T,1:ndir), v(ixG^T)
313 vmax_mype = -bigdouble
316 do iigrid = 1, igridstail
317 igrid = igrids(iigrid)
321 v(
ixm^t) = sqrt(sum(v_vec(
ixm^t,:)**2,dim=ndir+1))
323 vmax_mype =max(vmax_mype ,maxval(v(
ixm^t)))
328 call mpi_allreduce(vmax_mype, vmax_recv, 1, mpi_double_precision, &
338 double precision,
intent(out) :: B1max, B2max, B3max
340 integer :: iigrid, igrid
341 double precision :: B1max_mype, B1max_recv
342 double precision :: B2max_mype, B2max_recv
343 double precision :: B3max_mype, B3max_recv
345 b1max_mype = -bigdouble
346 b2max_mype = -bigdouble
347 b3max_mype = -bigdouble
350 do iigrid = 1, igridstail
351 igrid = igrids(iigrid)
353 b1max_mype = max(b1max_mype, maxval(ps(igrid)%w(ixg^t, mag_mhd(1))))
354 b2max_mype = max(b2max_mype, maxval(ps(igrid)%w(ixg^t, mag_mhd(2))))
356 b3max_mype = max(b3max_mype, maxval(ps(igrid)%w(ixg^t, mag_mhd(3))))
361 call mpi_allreduce(b1max_mype, b1max_recv, 1, mpi_double_precision, &
363 call mpi_allreduce(b2max_mype, b2max_recv, 1, mpi_double_precision, &
365 call mpi_allreduce(b3max_mype, b3max_recv, 1, mpi_double_precision, &
372 if (b2max == -bigdouble) b2max = 0.d0
373 if (b3max == -bigdouble) b3max = 0.d0
377 subroutine symm(ixI^L,ixO^L,w,x,w_index,boundary)
379 integer,
intent(in) :: ixI^L, ixO^L, w_index
380 double precision,
intent(in) :: x(ixI^S, 1:ndim)
381 double precision,
intent(inout) :: w(ixI^S, 1:nw)
382 character(len=*),
intent(in) :: boundary
384 select case (boundary)
386 w(ixo^s, w_index) = w(ixomin1-1:ixomin1-nghostcells:-1^%1ixo^s, w_index)
388 w(ixo^s, w_index) = w(ixomax1+nghostcells:ixomax1+1:-1^%1ixo^s, w_index)
390 call mpistop(
'Unknown boundary side: ' // trim(boundary))
395 subroutine split_symm(ixI^L,ixO^L,w,x,w_index,equi_w,boundary)
397 integer,
intent(in) :: ixI^L, ixO^L, w_index
398 double precision,
intent(in) :: x(ixI^S, 1:ndim)
399 double precision,
intent(inout) :: w(ixI^S, 1:nw)
400 double precision,
intent(in) :: equi_w(ixI^S)
401 character(len=*),
intent(in) :: boundary
403 select case (boundary)
405 w(ixo^s, w_index) = equi_w(ixo^s) &
406 + (w(ixomin1-1:ixomin1-nghostcells:-1^%1ixo^s, w_index) - equi_w(ixomin1-1:ixomin1-nghostcells:-1^%1ixo^s))
408 w(ixo^s, w_index) = equi_w(ixo^s) &
409 + (w(ixomax1+nghostcells:ixomax1+1:-1^%1ixo^s, w_index) - equi_w(ixomax1+nghostcells:ixomax1+1:-1^%1ixo^s))
411 call mpistop(
'Unknown boundary side: ' // trim(boundary))
418 integer,
intent(in) :: ixI^L, ixO^L, w_index
419 double precision,
intent(in) :: x(ixI^S, 1:ndim)
420 double precision,
intent(inout) :: w(ixI^S, 1:nw)
421 character(len=*),
intent(in) :: boundary
424 select case (boundary)
426 do ix1 = ixomin1, ixomax1
427 w(ix1^%1ixo^s, w_index) = 2.0d0 * w(ix1-1^%1ixo^s, w_index) &
428 - w(ix1-2^%1ixo^s, w_index)
431 do ix1 = ixomax1, ixomin1, -1
432 w(ix1^%1ixo^s, w_index) = 2.0d0 * w(ix1+1^%1ixo^s, w_index) &
433 - w(ix1+2^%1ixo^s, w_index)
436 call mpistop(
'Unknown boundary side: ' // trim(boundary))
443 integer,
intent(in) :: ixI^L, ixO^L, w_index
444 double precision,
intent(in) :: x(ixI^S, 1:ndim)
445 double precision,
intent(inout) :: w(ixI^S, 1:nw)
446 double precision,
intent(in) :: equi_w(ixI^S)
447 character(len=*),
intent(in) :: boundary
450 select case (boundary)
452 do ix1 = ixomin1, ixomax1
453 w(ix1^%1ixo^s, w_index) = equi_w(ix1^%1ixo^s) &
454 + 2.0d0 * (w(ix1-1^%1ixo^s, w_index) - equi_w(ix1-1^%1ixo^s)) &
455 - (w(ix1-2^%1ixo^s, w_index) - equi_w(ix1-2^%1ixo^s))
458 do ix1 = ixomax1, ixomin1, -1
459 w(ix1^%1ixo^s, w_index) = equi_w(ix1^%1ixo^s) &
460 + 2.0d0 * (w(ix1+1^%1ixo^s, w_index) - equi_w(ix1+1^%1ixo^s)) &
461 - (w(ix1+2^%1ixo^s, w_index) - equi_w(ix1+2^%1ixo^s))
464 call mpistop(
'Unknown boundary side: ' // trim(boundary))
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Equation of state for AMRVAC, handled through a single eos_container object.
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
Module with geometry-related routines (e.g., divergence, curl)
integer, parameter cylindrical
Module for reading in Legolas .ldat data as initial condition.
integer, dimension(:), allocatable mom_idx
complex(dp), dimension(:), allocatable b2
real(dp), dimension(:), allocatable ef_grid
integer, dimension(:), allocatable mag_idx
subroutine get_minmax_temperature(tmax, tmin)
complex(dp), dimension(:), allocatable p
subroutine read_legolas_data(legolas_file, file_id)
complex(dp), dimension(:), allocatable v1
subroutine symm(ixil, ixol, w, x, w_index, boundary)
subroutine split_symm(ixil, ixol, w, x, w_index, equi_w, boundary)
subroutine add_perturbation_to_w_array(ixil, ixol, w, w_index, x)
subroutine ef_amplitude(x, grid, array, amplitude)
subroutine get_max_b(b1max, b2max, b3max)
complex(dp), parameter ic
subroutine extrapolate(ixil, ixol, w, x, w_index, boundary)
complex(dp), dimension(:), allocatable v3
subroutine get_max_velocity(vmax)
subroutine init_gimli_indices()
subroutine split_extrapolate(ixil, ixol, w, x, w_index, equi_w, boundary)
complex(dp), dimension(:), allocatable b1
subroutine allocate_arrays(gridpts)
subroutine w_index_to_array(w_index, array)
complex(dp), dimension(:), allocatable b3
complex(dp), dimension(:), allocatable rho
complex(dp), dimension(:), allocatable v2
pure double precision function magnetic(w_vec, w_size)
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
double precision global_time
The global simulation time.
double precision unit_numberdensity
Physical scaling factor for number density.
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.
integer icomm
The MPI communicator.
logical reset_time
If true, reset iteration count and global_time to original values, and start writing snapshots at ind...
integer mype
The rank of the current MPI task.
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.
double precision unit_magneticfield
Physical scaling factor for magnetic field.
double precision unit_velocity
Physical scaling factor for velocity.
character(len=std_len) restart_from_file
If not 'unavailable', resume from snapshot with this base file name.
double precision unit_temperature
Physical scaling factor for temperature.
character(len= *), parameter undefined
character(len=std_len) base_filename
Base file name for simulation output, which will be followed by a number.
Hydrodynamics physics module.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
integer, public, protected rho_
Whether plasma is partially ionized.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
Magneto-hydrodynamics module.
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_get_v), pointer phys_get_v