MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_gimli.t
Go to the documentation of this file.
1!> Module for reading in Legolas .ldat data as initial condition
3 use, intrinsic :: iso_fortran_env
5 use mod_hd_phys, only: rho_hd=>rho_, mom_hd=>mom, p_hd=>p_
6 use mod_mhd_phys, only: rho_mhd=>rho_, mom_mhd=>mom, p_mhd=>p_
7 use mod_functions_bfield, only: mag_mhd=>mag
8
9 implicit none
10 public
11
12 integer, parameter :: dp = real64
13 integer :: idirmin0, idirmin
14
15 complex(dp), parameter :: ic = (0.0d0, 1.0d0)
16
17 integer :: ef_gridpts
18 real(dp) :: k2, k3
19 integer :: mhd_bool
20 real(dp), allocatable :: ef_grid(:)
21 complex(dp), allocatable :: rho(:)
22 complex(dp), allocatable :: v1(:)
23 complex(dp), allocatable :: v2(:)
24 complex(dp), allocatable :: v3(:)
25 complex(dp), allocatable :: p(:)
26 complex(dp), allocatable :: b1(:)
27 complex(dp), allocatable :: b2(:)
28 complex(dp), allocatable :: b3(:)
29
30 integer :: rho_idx, p_idx
31 integer, allocatable :: mom_idx(:), mag_idx(:)
32
33contains
34
35 subroutine read_legolas_data(legolas_file, file_id)
36 character(len=100), intent(in) :: legolas_file
37 integer, intent(in) :: file_id
38
39 open( &
40 unit=file_id+mype, &
41 file=legolas_file, &
42 form='unformatted' &
43 )
44
45 ! need to read physics_type because mod_physics not yet loaded at this point
46 read(file_id+mype) mhd_bool
47 read(file_id+mype) ef_gridpts
48 read(file_id+mype) k2, k3
49
51 read(file_id+mype) ef_grid
52 read(file_id+mype) rho
53 read(file_id+mype) v1
54 read(file_id+mype) v2
55 read(file_id+mype) v3
56 read(file_id+mype) p
57 if (mhd_bool == 1) then
58 read(file_id+mype) b1
59 read(file_id+mype) b2
60 read(file_id+mype) b3
61 end if
62
63 if (mhd_bool == 1) then
66 else
69 end if
70
71 close(file_id+mype)
72 end subroutine read_legolas_data
73
74 subroutine allocate_arrays(gridpts)
75 integer, intent(in) :: gridpts
76
77 allocate(ef_grid(gridpts))
78 allocate(rho(gridpts))
79 allocate(v1, v2, p, mold=rho)
80 if (ndim >= 3) allocate(v3, mold=rho)
81 if (mhd_bool == 1) then
82 allocate(b1, b2, mold=rho)
83 if (ndim >= 3) allocate(b3, mold=rho)
84 end if
85 end subroutine allocate_arrays
86
87 subroutine add_perturbation_to_w_array(ixI^L, ixO^L, w, w_index, x)
88 integer, intent(in) :: ixI^L, ixO^L
89 real(dp), intent(inout) :: w(ixI^S, nw)
90 integer, intent(in) :: w_index
91 real(dp), intent(in) :: x(ixI^S, ndim)
92 complex(dp) :: amplitude, exp_factor(ixI^S), quantity, values(ef_gridpts)
93 integer :: idx^D
94 real(dp) :: k1 = 0.0d0
95
96 call w_index_to_array(w_index, values)
97 exp_factor = {exp(ic * k^d * x(ixi^s, ^d))|*}
98
99 {do idx^d = iximin^d, iximax^d|\}
100 call ef_amplitude(x(idx^d, 1), ef_grid, values, amplitude)
101 quantity = amplitude * exp_factor(idx^d)
102 w(idx^d, w_index) = w(idx^d, w_index) + quantity%re
103 {end do|\}
104 end subroutine add_perturbation_to_w_array
105
107 if (mhd_bool == 1) then
108 rho_idx = rho_mhd
109 p_idx = p_mhd
110
111 if (.not. allocated(mom_idx)) allocate(mom_idx(size(mom_mhd)))
112 mom_idx = mom_mhd
113
114 if (.not. allocated(mag_idx)) allocate(mag_idx(size(mag_mhd)))
115 mag_idx = mag_mhd
116 else
117 rho_idx = rho_hd
118 p_idx = p_hd
119
120 if (.not. allocated(mom_idx)) allocate(mom_idx(size(mom_hd)))
121 mom_idx = mom_hd
122
123 end if
124 end subroutine init_gimli_indices
125
126 subroutine w_index_to_array(w_index, array)
127 integer, intent(in) :: w_index
128 complex(dp), intent(inout) :: array(ef_gridpts)
129
130 call init_gimli_indices()
131
132 if (w_index == rho_idx) then
133 array = rho
134 else if (w_index == mom_idx(1)) then
135 array = v1
136 else if (w_index == mom_idx(2)) then
137 array = v2
138 end if
139
140 if (ndim >= 3) then
141 if (w_index == mom_idx(3)) then
142 array = v3
143 end if
144 end if
145 if (w_index == p_idx) then
146 array = p
147 end if
148 if (mhd_bool == 1) then
149 if (w_index == mag_idx(1)) then
150 array = b1
151 else if (w_index == mag_idx(2)) then
152 array = b2
153 end if
154 if (ndim >= 3) then
155 if (w_index == mag_idx(3)) then
156 array = b3
157 end if
158 end if
159 end if
160 end subroutine w_index_to_array
161
162 subroutine ef_amplitude(x, grid, array, amplitude)
164 real(dp), intent(in) :: x, grid(ef_gridpts)
165 complex(dp), intent(in) :: array(ef_gridpts)
166 complex(dp), intent(out) :: amplitude
167 integer :: idl, idu
168
169 if (x <= grid(1) .and. xprobmin1 <= x) then
170 amplitude = array(1)
171
172 if (coordinate==cylindrical .and. grid(1) > 0) then
173 if (x >= grid(1)/2) then
174 amplitude = (x - grid(1)/2) * array(1) / grid(1)
175 else
176 amplitude = 0.d0
177 end if
178 end if
179 else if (x >= grid(size(grid)) .and. x <= xprobmax1) then
180 amplitude = array(size(grid))
181 else if (x < xprobmin1 .or. x > xprobmax1) then
182 amplitude = 0.d0
183 else
184 idl = maxloc(grid, mask=(grid < x), dim=1)
185 idu = minloc(grid, mask=(grid > x), dim=1)
186 amplitude = array(idl) + (x - grid(idl)) * &
187 (array(idu) - array(idl)) / (grid(idu) - grid(idl))
188 end if
189 end subroutine ef_amplitude
190
191 ! subroutine custom analytics log file
192 ! called in "usr_print_log => analytics_log" in mod_usr.t
193 subroutine analytics_log
196
197 integer, parameter :: n_modes = 2
198 integer, parameter :: my_unit = 123
199 character(len=80) :: fmt_string = '(9(es12.4))', filename
200 logical, save :: alive, visited=.false.
201 double precision :: volume, magn_avg
202 double precision :: Tmax, Tmin, vmax, B1max, B2max, B3max
203
204 ! First output the standard log file:
206
207 ! Now make the custom _c.log file:
208 call get_minmax_temperature(tmax,tmin)
209 call get_max_velocity(vmax)
210 if (mhd_bool == 1) then
211 call get_max_b(b1max, b2max, b3max)
212 call get_volume_average_func(magnetic, magn_avg, volume)
213 end if
214
215 filename = trim(base_filename) // "_c.log"
216
217 if (.not. visited) then
218 ! Delete the log when not doing a restart run
219 if (restart_from_file == undefined .or. reset_time) then
220 open(unit=my_unit,file=trim(filename),form='formatted',status='replace')
221 write(my_unit,'(a)') ''
222 if (mhd_bool == 1) then
223 write(my_unit,'(a)') '#Global_time Tmax Tmin vmax B1max B2max B3max mag_avg'
224 else
225 write(my_unit,'(a)') '#Global_time Tmax Tmin vmax'
226 end if
227 end if
228 visited = .true.
229 end if
230
231 if (mype == 0) then
232 write(filename,"(a)") filename
233 inquire(file=filename,exist=alive)
234 if(alive) then
235 open(unit=my_unit,file=filename,form='formatted',status='old',access='append')
236 else
237 open(unit=my_unit,file=filename,form='formatted',status='new')
238 endif
239
240 ! if number of output doubles is increase, don't forget to change the fmt_string above
241 if (mhd_bool == 1) then
242 write(my_unit, fmt_string) global_time, tmax, tmin, vmax, b1max, b2max, b3max, magn_avg
243 else
244 write(my_unit, fmt_string) global_time, tmax, tmin, vmax
245 end if
246 close(my_unit)
247 end if
248 end subroutine analytics_log
249
250 pure function magnetic(w_vec, w_size) result(magn_energy)
252 integer, intent(in) :: w_size
253 double precision, intent(in) :: w_vec(w_size)
254 double precision :: magn_energy
255
256 magn_energy = 0.5d0 * sum(w_vec(mag_mhd(:))**2,dim=ndir+1)
257 end function magnetic
258
259 ! Calculate both min and max of temperature on grid in one go.
260 subroutine get_minmax_temperature(Tmax, Tmin)
263
264 double precision, intent(out) :: Tmax, Tmin
265
266 integer :: iigrid, igrid, iw
267 double precision :: Tmax_mype, Tmax_recv, Tmin_mype, Tmin_recv
268 double precision :: w(ixG^T,1:nw), wlocal(ixG^T,1:nw), xlocal(ixG^T,1:nw)
269 double precision :: Te(ixG^T), pth(ixG^T), rho(ixG^T)
270
271 tmax_mype = -bigdouble
272 tmin_mype = bigdouble
273
274 !Loop over all the grids
275 do iigrid = 1, igridstail
276 igrid = igrids(iigrid)
277
278 wlocal(ixg^t,1:nw) = ps(igrid)%w(ixg^t,1:nw)
279 xlocal(ixg^t,1:ndim) = ps(igrid)%x(ixg^t,1:ndim)
280 call phys_get_pthermal(wlocal,xlocal,ixg^ll,ixg^ll,pth)
281 call phys_get_rho(wlocal,xlocal,ixg^ll,ixg^ll,rho)
282 te(ixg^t) = pth(ixg^t)/rho(ixg^t)
283
284 ! Compare values on current grid to temporary max/min
285 tmax_mype = max(tmax_mype,maxval(te(ixm^t)))
286 tmin_mype = min(tmin_mype,minval(te(ixm^t)))
287 end do
288
289 ! Make the information available on all tasks
290 call mpi_allreduce(tmax_mype, tmax_recv, 1, mpi_double_precision, &
291 mpi_max, icomm, ierrmpi)
292 call mpi_allreduce(tmin_mype, tmin_recv, 1, mpi_double_precision, &
293 mpi_min, icomm, ierrmpi)
294
295 tmax = tmax_recv
296 tmin = tmin_recv
297
298 end subroutine get_minmax_temperature
299
300 subroutine get_max_velocity(vmax)
302 use mod_physics, only: phys_get_v
303
304 double precision, intent(out) :: vmax
305
306 integer :: iigrid, igrid, iw
307 double precision :: vmax_mype,vmax_recv
308 double precision :: v_vec(ixG^T,1:ndir), v(ixG^T)
309
310 vmax_mype = -bigdouble
311
312 !Loop over all the grids
313 do iigrid = 1, igridstail
314 igrid = igrids(iigrid)
315
316 call phys_get_v(ps(igrid)%w, ps(igrid)%x, ixg^ll, ixg^ll, v_vec)
317
318 v(ixm^t) = sqrt(sum(v_vec(ixm^t,:)**2,dim=ndir+1))
319
320 vmax_mype =max(vmax_mype ,maxval(v(ixm^t)))
321
322 end do
323
324 ! Make the information available on all tasks
325 call mpi_allreduce(vmax_mype, vmax_recv, 1, mpi_double_precision, &
326 mpi_max, icomm, ierrmpi)
327
328 vmax = vmax_recv
329
330 end subroutine get_max_velocity
331
332 subroutine get_max_b(B1max, B2max, B3max)
334
335 double precision, intent(out) :: B1max, B2max, B3max
336
337 integer :: iigrid, igrid, iw
338 double precision :: B1max_mype, B1max_recv
339 double precision :: B2max_mype, B2max_recv
340 double precision :: B3max_mype, B3max_recv
341
342 b1max_mype = -bigdouble
343 b2max_mype = -bigdouble
344 b3max_mype = -bigdouble
345
346 !Loop over all the grids
347 do iigrid = 1, igridstail
348 igrid = igrids(iigrid)
349
350 b1max_mype = max(b1max_mype, maxval(ps(igrid)%w(ixg^t, mag_mhd(1))))
351 b2max_mype = max(b2max_mype, maxval(ps(igrid)%w(ixg^t, mag_mhd(2))))
352 if (ndir >= 3) then
353 b3max_mype = max(b3max_mype, maxval(ps(igrid)%w(ixg^t, mag_mhd(3))))
354 end if
355 end do
356
357 ! Make the information available on all tasks
358 call mpi_allreduce(b1max_mype, b1max_recv, 1, mpi_double_precision, &
359 mpi_max, icomm, ierrmpi)
360 call mpi_allreduce(b2max_mype, b2max_recv, 1, mpi_double_precision, &
361 mpi_max, icomm, ierrmpi)
362 call mpi_allreduce(b3max_mype, b3max_recv, 1, mpi_double_precision, &
363 mpi_max, icomm, ierrmpi)
364
365 b1max = b1max_recv
366 b2max = b2max_recv
367 b3max = b3max_recv
368
369 end subroutine get_max_b
370
371end module mod_gimli
372!
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
Module with geometry-related routines (e.g., divergence, curl)
Definition mod_geometry.t:2
integer coordinate
Definition mod_geometry.t:7
integer, parameter cylindrical
Module for reading in Legolas .ldat data as initial condition.
Definition mod_gimli.t:2
integer mhd_bool
Definition mod_gimli.t:19
integer, parameter dp
Definition mod_gimli.t:12
integer, dimension(:), allocatable mom_idx
Definition mod_gimli.t:31
complex(dp), dimension(:), allocatable b2
Definition mod_gimli.t:27
real(dp), dimension(:), allocatable ef_grid
Definition mod_gimli.t:20
integer, dimension(:), allocatable mag_idx
Definition mod_gimli.t:31
integer ef_gridpts
Definition mod_gimli.t:17
subroutine get_minmax_temperature(tmax, tmin)
Definition mod_gimli.t:261
subroutine analytics_log
Definition mod_gimli.t:194
complex(dp), dimension(:), allocatable p
Definition mod_gimli.t:25
subroutine read_legolas_data(legolas_file, file_id)
Definition mod_gimli.t:36
complex(dp), dimension(:), allocatable v1
Definition mod_gimli.t:22
integer idirmin
Definition mod_gimli.t:13
integer p_idx
Definition mod_gimli.t:30
real(dp) k3
Definition mod_gimli.t:18
subroutine add_perturbation_to_w_array(ixil, ixol, w, w_index, x)
Definition mod_gimli.t:88
integer idirmin0
Definition mod_gimli.t:13
subroutine ef_amplitude(x, grid, array, amplitude)
Definition mod_gimli.t:163
subroutine get_max_b(b1max, b2max, b3max)
Definition mod_gimli.t:333
complex(dp), parameter ic
Definition mod_gimli.t:15
real(dp) k2
Definition mod_gimli.t:18
complex(dp), dimension(:), allocatable v3
Definition mod_gimli.t:24
subroutine get_max_velocity(vmax)
Definition mod_gimli.t:301
subroutine init_gimli_indices()
Definition mod_gimli.t:107
complex(dp), dimension(:), allocatable b1
Definition mod_gimli.t:26
integer rho_idx
Definition mod_gimli.t:30
subroutine allocate_arrays(gridpts)
Definition mod_gimli.t:75
subroutine w_index_to_array(w_index, array)
Definition mod_gimli.t:127
complex(dp), dimension(:), allocatable b3
Definition mod_gimli.t:28
complex(dp), dimension(:), allocatable rho
Definition mod_gimli.t:21
complex(dp), dimension(:), allocatable v2
Definition mod_gimli.t:23
pure double precision function magnetic(w_vec, w_size)
Definition mod_gimli.t:251
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.
Definition mod_hd_phys.t:2
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
Definition mod_hd_phys.t:57
integer, public, protected rho_
Index of the density (in the w array)
Definition mod_hd_phys.t:54
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
Definition mod_hd_phys.t:69
Module for reading input and writing output.
subroutine get_volume_average_func(func, f_avg, volume)
Compute the volume average of func(w) over the leaves of the grid.
subroutine printlog_default
Write volume-averaged values and other information to the log file.
Magneto-hydrodynamics module.
Definition mod_mhd_phys.t:2
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition mod_physics.t:4
procedure(sub_get_pthermal), pointer phys_get_pthermal
Definition mod_physics.t:70
procedure(sub_get_rho), pointer phys_get_rho
Definition mod_physics.t:63
procedure(sub_get_v), pointer phys_get_v
Definition mod_physics.t:62