MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_advance.t
Go to the documentation of this file.
1!> Module containing all the time stepping schemes
3
4 implicit none
5 private
6
7 !> Whether to conserve fluxes at the current sub-step
8 logical :: fix_conserve_at_step = .true.
9
10 !> Per-rank compute-only accumulator for lb_diagnose (sums the iigrid
11 !> block-loop wall time across all substages within one full advance call,
12 !> excluding ghostcell exchanges and flux conservation collectives).
13 double precision :: lb_compute_accum = 0.0d0
14
15 public :: advance
16 public :: process
17 public :: process_advanced
18
19contains
20
21 !> Advance all the grids over one time step, including all sources
22 subroutine advance(iit)
24 use mod_particles, only: handle_particles
25 use mod_eos
29
30 integer, intent(in) :: iit
31
32 integer :: iigrid, igrid, idimsplit
33
34 ! ---- per-rank load-balance diagnostic (gated by lb_diagnose) ----
35 double precision :: t_advance_start, t_advance_local
36 double precision :: t_dummy(1)
37 double precision, allocatable, save :: t_all_ranks(:)
38 double precision, allocatable, save :: c_all_ranks(:)
39 double precision, allocatable, save :: tc_all_ranks(:)
40 double precision, allocatable, save :: cool_all_ranks(:)
41 double precision :: cmax, cmean, ratioc
42 double precision :: tcmax, tcmean, ratiotc
43 double precision :: coolmax, coolmean, ratiocool
44 integer, save :: lb_log_unit = -1
45 logical, save :: lb_first_call = .true.
46 integer :: ipe
47 double precision :: tmax, tmean, ratio
48 character(len=256) :: lb_log_name
49 ! ----------------------------------------------------------------
50
51 if (lb_diagnose) then
52 if (lb_first_call .and. mype==0) then
53 allocate(t_all_ranks(npe))
54 allocate(c_all_ranks(npe))
55 allocate(tc_all_ranks(npe))
56 allocate(cool_all_ranks(npe))
57 write(lb_log_name,'(a,a)') trim(base_filename), 'rank_timing.log'
58 open(newunit=lb_log_unit, file=trim(lb_log_name), status='replace', action='write')
59 write(lb_log_unit,'(a)',advance='no') '# it time '
60 do ipe=0,npe-1
61 write(lb_log_unit,'(a,i0,a)',advance='no') 't_rank',ipe,' '
62 end do
63 do ipe=0,npe-1
64 write(lb_log_unit,'(a,i0,a)',advance='no') 'c_rank',ipe,' '
65 end do
66 do ipe=0,npe-1
67 write(lb_log_unit,'(a,i0,a)',advance='no') 't_tc_rank',ipe,' '
68 end do
69 do ipe=0,npe-1
70 write(lb_log_unit,'(a,i0,a)',advance='no') 't_cool_rank',ipe,' '
71 end do
72 write(lb_log_unit,'(a)') 'tmax tmean R cmax cmean Rc tcmax tcmean Rtc coolmax coolmean Rcool'
73 flush(lb_log_unit)
74 lb_first_call = .false.
75 else if (lb_first_call) then
76 lb_first_call = .false.
77 end if
78 t_advance_start = mpi_wtime()
79 lb_compute_accum = 0.0d0
80 lb_tc_accum = 0.0d0
81 lb_cool_accum = 0.0d0
82 end if
83
84 ! Per-block cost reset for the cost-weighted load balancer.
85 ! Cleared every step before the iigrid loops fill it.
86 if (lb_automatic) block_cost = 0.0d0
87
88 ! split source addition
89 call add_split_source(prior=.true.) !> calculates temperature based on conservative state
90
91 if(dimsplit) then
92 if((iit/2)*2==iit .or. typedimsplit=='xy') then
93 ! do the sweeps in order of increasing idim,
94 do idimsplit=1,ndim
95 call advect(idimsplit,idimsplit)
96 end do
97 else
98 ! If the parity of "iit" is odd and typedimsplit=xyyx,
99 ! do sweeps backwards
100 do idimsplit=ndim,1,-1
101 call advect(idimsplit,idimsplit)
102 end do
103 end if
104 else
105 ! Add fluxes from all directions at once
106 call advect(1,ndim)
107 end if
108
109 ! split source addition
110 call add_split_source(prior=.false.) !> calculates temperature based on conservative state
111
112 if(use_particles) call handle_particles
113
114 !$OMP PARALLEL DO PRIVATE(igrid)
115 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
116 call eos%update_eos(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
117 end do
118 !$OMP END PARALLEL DO
119
120 ! Cost-weighted load balancer: per-block measurements in block_cost
121 ! (per-rank, per-igrid) are folded into the global Morton-indexed
122 ! costlist via EWMA blend inside get_Morton_range_costed when
123 ! load_balance is next invoked. No end-of-advance work needed here.
124
125 if (lb_diagnose) then
126 t_advance_local = mpi_wtime() - t_advance_start
127 if (mype==0) then
128 call mpi_gather(t_advance_local,1,mpi_double_precision, &
129 t_all_ranks,1,mpi_double_precision,0,icomm,ierrmpi)
130 call mpi_gather(lb_compute_accum,1,mpi_double_precision, &
131 c_all_ranks,1,mpi_double_precision,0,icomm,ierrmpi)
132 call mpi_gather(lb_tc_accum,1,mpi_double_precision, &
133 tc_all_ranks,1,mpi_double_precision,0,icomm,ierrmpi)
134 call mpi_gather(lb_cool_accum,1,mpi_double_precision, &
135 cool_all_ranks,1,mpi_double_precision,0,icomm,ierrmpi)
136 tmax = maxval(t_all_ranks)
137 tmean = sum(t_all_ranks)/dble(npe)
138 cmax = maxval(c_all_ranks)
139 cmean = sum(c_all_ranks)/dble(npe)
140 tcmax = maxval(tc_all_ranks)
141 tcmean = sum(tc_all_ranks)/dble(npe)
142 coolmax = maxval(cool_all_ranks)
143 coolmean = sum(cool_all_ranks)/dble(npe)
144 if (tmean > 0.0d0) then
145 ratio = tmax/tmean
146 else
147 ratio = 1.0d0
148 end if
149 if (cmean > 0.0d0) then
150 ratioc = cmax/cmean
151 else
152 ratioc = 1.0d0
153 end if
154 if (tcmean > 0.0d0) then
155 ratiotc = tcmax/tcmean
156 else
157 ratiotc = 1.0d0
158 end if
159 if (coolmean > 0.0d0) then
160 ratiocool = coolmax/coolmean
161 else
162 ratiocool = 1.0d0
163 end if
164 write(lb_log_unit,'(i10,1x,es16.8,1x)',advance='no') it, global_time
165 do ipe=1,npe
166 write(lb_log_unit,'(es14.6,1x)',advance='no') t_all_ranks(ipe)
167 end do
168 do ipe=1,npe
169 write(lb_log_unit,'(es14.6,1x)',advance='no') c_all_ranks(ipe)
170 end do
171 do ipe=1,npe
172 write(lb_log_unit,'(es14.6,1x)',advance='no') tc_all_ranks(ipe)
173 end do
174 do ipe=1,npe
175 write(lb_log_unit,'(es14.6,1x)',advance='no') cool_all_ranks(ipe)
176 end do
177 write(lb_log_unit,'(12(es14.6,1x))') &
178 tmax, tmean, ratio, cmax, cmean, ratioc, &
179 tcmax, tcmean, ratiotc, coolmax, coolmean, ratiocool
180 flush(lb_log_unit)
181 else
182 call mpi_gather(t_advance_local,1,mpi_double_precision, &
183 t_dummy,1,mpi_double_precision,0,icomm,ierrmpi)
184 call mpi_gather(lb_compute_accum,1,mpi_double_precision, &
185 t_dummy,1,mpi_double_precision,0,icomm,ierrmpi)
186 call mpi_gather(lb_tc_accum,1,mpi_double_precision, &
187 t_dummy,1,mpi_double_precision,0,icomm,ierrmpi)
188 call mpi_gather(lb_cool_accum,1,mpi_double_precision, &
189 t_dummy,1,mpi_double_precision,0,icomm,ierrmpi)
190 end if
191 end if
192
193 end subroutine advance
194
195 !> Advance all grids over one time step, but without taking dimensional
196 !> splitting or split source terms into account
197 subroutine advect(idim^LIM)
201 use mod_comm_lib, only: mpistop
202
203 integer, intent(in) :: idim^lim
204 integer :: iigrid, igrid
205
206 call init_comm_fix_conserve(idim^lim,nwflux)
207 fix_conserve_at_step = time_advance .and. levmax>levmin
208
209 ! copy w instead of wold because of potential use of dimsplit or sourcesplit
210 !$OMP PARALLEL DO PRIVATE(igrid)
211 do iigrid=1,igridstail; igrid=igrids(iigrid);
212 ps1(igrid)%w=ps(igrid)%w
213 if(stagger_grid) ps1(igrid)%ws=ps(igrid)%ws
214 end do
215 !$OMP END PARALLEL DO
216
217 istep = 0
218
219 select case (t_stepper)
220 case (onestep)
221 select case (t_integrator)
222 case (forward_euler)
223 call advect1(flux_method,one,idim^lim,global_time,ps1,global_time,ps)
224
225 case (imex_euler)
226 call advect1(flux_method,one,idim^lim,global_time,ps,global_time,ps1)
227 call global_implicit_update(one,dt,global_time+dt,ps,ps1)
228
229 case (imex_sp)
230 call global_implicit_update(one,dt,global_time,ps,ps1)
231 !$OMP PARALLEL DO PRIVATE(igrid)
232 do iigrid=1,igridstail; igrid=igrids(iigrid);
233 ps1(igrid)%w=ps(igrid)%w
234 if(stagger_grid) ps1(igrid)%ws=ps(igrid)%ws
235 end do
236 !$OMP END PARALLEL DO
237 call advect1(flux_method,one,idim^lim,global_time,ps1,global_time,ps)
238
239 case default
240 call mpistop("unkown onestep time_integrator in advect")
241 end select
242
243 case (twostep)
244 select case (t_integrator)
246 ! PC or explicit midpoint
247 ! predictor step
248 fix_conserve_at_step = .false.
249 call advect1(typepred1,half,idim^lim,global_time,ps,global_time,ps1)
250 ! corrector step
251 fix_conserve_at_step = time_advance .and. levmax>levmin
252 call advect1(flux_method,one,idim^lim,global_time+half*dt,ps1,global_time,ps)
253
254 case (rk2_alf)
255 ! RK2 with alfa parameter, where rk_a21=alfa
256 call advect1(flux_method,rk_a21, idim^lim,global_time,ps,global_time,ps1)
257 !$OMP PARALLEL DO PRIVATE(igrid)
258 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
259 ps(igrid)%w = ps(igrid)%w+rk_b1*(ps1(igrid)%w-ps(igrid)%w)/rk_a21
260 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws+(one-rk_b2)*(ps1(igrid)%ws-ps(igrid)%ws)/rk_a21
261 end do
262 !$OMP END PARALLEL DO
263 call advect1(flux_method,rk_b2,idim^lim,global_time+rk_a21*dt,ps1,global_time+rk_b1*dt,ps)
264
265 case (ssprk2)
266 ! ssprk2 or Heun's method
267 call advect1(flux_method,one, idim^lim,global_time,ps,global_time,ps1)
268 !$OMP PARALLEL DO PRIVATE(igrid)
269 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
270 ps(igrid)%w = half*ps(igrid)%w+half*ps1(igrid)%w
271 if(stagger_grid) ps(igrid)%ws = half*ps(igrid)%ws+half*ps1(igrid)%ws
272 end do
273 !$OMP END PARALLEL DO
274 call advect1(flux_method,half,idim^lim,global_time+dt,ps1,global_time+half*dt,ps)
275
276 case (imex_midpoint)
277 call advect1(flux_method,half, idim^lim,global_time,ps,global_time,ps1)
278 call global_implicit_update(half,dt,global_time+half*dt,ps2,ps1)
279 !$OMP PARALLEL DO PRIVATE(igrid)
280 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
281 ps(igrid)%w = ps(igrid)%w+2.0d0*(ps2(igrid)%w-ps1(igrid)%w)
282 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws+2.0d0*(ps2(igrid)%ws-ps1(igrid)%ws)
283 end do
284 !$OMP END PARALLEL DO
285 call advect1(flux_method,one, idim^lim,global_time+half*dt,ps2,global_time,ps)
286
287 case (imex_trapezoidal)
288 call advect1(flux_method,one, idim^lim,global_time,ps,global_time,ps1)
289 !$OMP PARALLEL DO PRIVATE(igrid)
290 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
291 ps2(igrid)%w = half*(ps(igrid)%w+ps1(igrid)%w)
292 if(stagger_grid) ps2(igrid)%ws = half*(ps(igrid)%ws+ps1(igrid)%ws)
293 end do
294 !$OMP END PARALLEL DO
295 call evaluate_implicit(global_time,ps)
296 !$OMP PARALLEL DO PRIVATE(igrid)
297 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
298 ps1(igrid)%w = ps1(igrid)%w+half*dt*ps(igrid)%w
299 if(stagger_grid) ps1(igrid)%ws = ps1(igrid)%ws+half*dt*ps(igrid)%ws
300 end do
301 !$OMP END PARALLEL DO
302 !$OMP PARALLEL DO PRIVATE(igrid)
303 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
304 ps(igrid)%w = ps2(igrid)%w+half*dt*ps(igrid)%w
305 if(stagger_grid) ps(igrid)%ws = ps2(igrid)%ws+half*dt*ps(igrid)%ws
306 end do
307 !$OMP END PARALLEL DO
308 call getbc(global_time+dt,dt,ps1,iwstart,nwgc)
309 call global_implicit_update(half,dt,global_time+dt,ps2,ps1)
310 !$OMP PARALLEL DO PRIVATE(igrid)
311 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
312 ps(igrid)%w = ps(igrid)%w+ps2(igrid)%w-ps1(igrid)%w
313 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws+ps2(igrid)%ws-ps1(igrid)%ws
314 end do
315 !$OMP END PARALLEL DO
316 call advect1(flux_method,half, idim^lim,global_time+dt,ps2,global_time+half*dt,ps)
317
318 case (imex_222)
319 ! One-parameter family of schemes (parameter is imex222_lambda) from
320 ! Pareschi&Russo 2005, which is L-stable (for default lambda) and
321 ! asymptotically SSP.
322 ! See doi.org/10.1007/s10915-004-4636-4 (table II)
323 ! See doi.org/10.1016/j.apnum.2016.10.018 for interesting values of lambda
324
325 ! Preallocate ps2 as y^n for the implicit update
326 !$OMP PARALLEL DO PRIVATE(igrid)
327 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
328 ps2(igrid)%w = ps(igrid)%w
329 if(stagger_grid) ps2(igrid)%ws = ps(igrid)%ws
330 end do
331 !$OMP END PARALLEL DO
332 ! Solve xi1 = y^n + lambda.dt.F_im(xi1)
333 call global_implicit_update(imex222_lambda, dt, global_time, ps2, ps)
334
335 ! Set ps1 = y^n + dt.F_ex(xi1)
336 call advect1(flux_method, one, idim^lim, global_time, ps2, global_time, ps1)
337 ! Set ps2 = dt.F_im(xi1) (is at t^n)
338 ! Set ps = y^n + dt/2 . F(xi1) (is at t^n+dt/2)
339 ! Set ps1 = y^n + dt.F_ex(xi1) + (1-2.lambda).dt.F_im(xi1) and enforce BC (at t^n+dt)
340 !$OMP PARALLEL DO PRIVATE(igrid)
341 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
342 ps2(igrid)%w = (ps2(igrid)%w - ps(igrid)%w) / imex222_lambda
343 if(stagger_grid) ps2(igrid)%ws = (ps2(igrid)%ws - ps(igrid)%ws) / imex222_lambda
344 end do
345 !$OMP END PARALLEL DO
346 !$OMP PARALLEL DO PRIVATE(igrid)
347 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
348 ps(igrid)%w = half*(ps(igrid)%w + ps1(igrid)%w + ps2(igrid)%w)
349 if(stagger_grid) ps(igrid)%ws = half*(ps(igrid)%ws + ps1(igrid)%ws + ps2(igrid)%ws)
350 end do
351 !$OMP END PARALLEL DO
352 !$OMP PARALLEL DO PRIVATE(igrid)
353 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
354 ps1(igrid)%w = ps1(igrid)%w + (1.0d0 - 2.0d0*imex222_lambda)*ps2(igrid)%w
355 if(stagger_grid) ps1(igrid)%ws = ps1(igrid)%ws + (1.0d0 - 2.0d0*imex222_lambda)*ps2(igrid)%ws
356 end do
357 !$OMP END PARALLEL DO
358 call getbc(global_time+dt,dt,ps1,iwstart,nwgc)
359
360 ! Preallocate ps2 as xi1 for the implicit update (is at t^n)
361 !$OMP PARALLEL DO PRIVATE(igrid)
362 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
363 ps2(igrid)%w = 2.0d0*ps2(igrid)%w - ps1(igrid)%w - imex222_lambda*ps2(igrid)%w
364 if(stagger_grid) ps2(igrid)%ws = 2.0d0*ps2(igrid)%ws - ps1(igrid)%ws - imex222_lambda*ps2(igrid)%ws
365 end do
366 !$OMP END PARALLEL DO
367 ! Solve xi2 = (ps1) + lambda.dt.F_im(xi2)
368 call global_implicit_update(imex222_lambda, dt, global_time, ps2, ps1)
369
370 ! Add dt/2.F_im(xi2) to ps
371 !$OMP PARALLEL DO PRIVATE(igrid)
372 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
373 ps(igrid)%w = ps(igrid)%w + (ps2(igrid)%w - ps1(igrid)%w) / (2.0d0 * imex222_lambda)
374 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws + (ps2(igrid)%ws - ps1(igrid)%ws) / (2.0d0 * imex222_lambda)
375 end do
376 !$OMP END PARALLEL DO
377 ! Set ps = y^n + dt/2.(F(xi1)+F(xi2)) = y^(n+1)
378 call advect1(flux_method, half, idim^lim, global_time+dt, ps2, global_time+half*dt, ps)
379
380 case default
381 call mpistop("unkown twostep time_integrator in advect")
382 end select
383
384 case (threestep)
385 select case (t_integrator)
386 case (ssprk3)
387 ! this is SSPRK(3,3) Gottlieb-Shu 1998 or SSP(3,2) depending on ssprk_order (3 vs 2)
388 call advect1(flux_method,rk_beta11, idim^lim,global_time,ps,global_time,ps1)
389 !$OMP PARALLEL DO PRIVATE(igrid)
390 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
391 ps2(igrid)%w=rk_alfa21*ps(igrid)%w+rk_alfa22*ps1(igrid)%w
392 if(stagger_grid) ps2(igrid)%ws=rk_alfa21*ps(igrid)%ws+rk_alfa22*ps1(igrid)%ws
393 end do
394 !$OMP END PARALLEL DO
395 call advect1(flux_method,rk_beta22, idim^lim,global_time+rk_c2*dt,ps1,global_time+rk_alfa22*rk_c2*dt,ps2)
396 !$OMP PARALLEL DO PRIVATE(igrid)
397 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
398 ps(igrid)%w=rk_alfa31*ps(igrid)%w+rk_alfa33*ps2(igrid)%w
399 if(stagger_grid) ps(igrid)%ws=rk_alfa31*ps(igrid)%ws+rk_alfa33*ps2(igrid)%ws
400 end do
401 !$OMP END PARALLEL DO
402 call advect1(flux_method,rk_beta33, idim^lim,global_time+rk_c3*dt,ps2,global_time+(1.0d0-rk_beta33)*dt,ps)
403
404 case (rk3_bt)
405 ! this is a general threestep RK according to its Butcher Table
406 call advect1(flux_method,rk3_a21, idim^lim,global_time,ps,global_time,ps1)
407 !$OMP PARALLEL DO PRIVATE(igrid)
408 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
409 ps3(igrid)%w=(ps1(igrid)%w-ps(igrid)%w)/rk3_a21
410 if(stagger_grid) ps3(igrid)%ws=(ps1(igrid)%ws-ps(igrid)%ws)/rk3_a21
411 end do
412 !$OMP END PARALLEL DO
413 !$OMP PARALLEL DO PRIVATE(igrid)
414 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
415 ps2(igrid)%w=ps(igrid)%w+rk3_a31*ps3(igrid)%w
416 if(stagger_grid) ps2(igrid)%ws=ps(igrid)%ws+rk3_a31*ps3(igrid)%ws
417 end do
418 !$OMP END PARALLEL DO
419 call advect1(flux_method,rk3_a32, idim^lim,global_time+rk3_c2*dt,ps1,global_time+rk3_a31*dt,ps2)
420 !$OMP PARALLEL DO PRIVATE(igrid)
421 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
422 ps(igrid)%w=ps(igrid)%w+rk3_b1*ps3(igrid)%w &
423 +rk3_b2*(ps2(igrid)%w-(ps(igrid)%w+rk3_a31*ps3(igrid)%w))/rk3_a32
424 if(stagger_grid)then
425 ps(igrid)%ws=ps(igrid)%ws+rk3_b1*ps3(igrid)%ws &
426 +rk3_b2*(ps2(igrid)%ws-(ps(igrid)%ws+rk3_a31*ps3(igrid)%ws))/rk3_a32
427 endif
428 end do
429 !$OMP END PARALLEL DO
430 call advect1(flux_method,rk3_b3, idim^lim,global_time+rk3_c3*dt,ps2,global_time+(1.0d0-rk3_b3)*dt,ps)
431
432 case (imex_ars3)
433 ! this is IMEX scheme ARS3
434 call advect1(flux_method,ars_gamma, idim^lim,global_time,ps,global_time,ps1)
435 !$OMP PARALLEL DO PRIVATE(igrid)
436 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
437 ps4(igrid)%w=(ps1(igrid)%w-ps(igrid)%w)/ars_gamma
438 if(stagger_grid) ps4(igrid)%ws=(ps1(igrid)%ws-ps(igrid)%ws)/ars_gamma
439 end do
440 !$OMP END PARALLEL DO
441 call global_implicit_update(ars_gamma,dt,global_time+ars_gamma*dt,ps2,ps1)
442 !$OMP PARALLEL DO PRIVATE(igrid)
443 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
444 ps1(igrid)%w=(ps2(igrid)%w-ps1(igrid)%w)/ars_gamma
445 if(stagger_grid) ps1(igrid)%ws=(ps2(igrid)%ws-ps1(igrid)%ws)/ars_gamma
446 end do
447 !$OMP END PARALLEL DO
448 !$OMP PARALLEL DO PRIVATE(igrid)
449 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
450 ps3(igrid)%w=ps(igrid)%w+(ars_gamma-1.0d0)*ps4(igrid)%w+(1.0d0-2.0d0*ars_gamma)*ps1(igrid)%w
451 if(stagger_grid) then
452 ps3(igrid)%ws=ps(igrid)%ws+(ars_gamma-1.0d0)*ps4(igrid)%ws+(1.0d0-2.0d0*ars_gamma)*ps1(igrid)%ws
453 endif
454 end do
455 !$OMP END PARALLEL DO
456 call advect1(flux_method,2.0d0*(1.0d0-ars_gamma), idim^lim,global_time+ars_gamma*dt,ps2,global_time+(ars_gamma-1.0d0)*dt,ps3)
457 !$OMP PARALLEL DO PRIVATE(igrid)
458 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
459 ps2(igrid)%w=ps1(igrid)%w+(ps3(igrid)%w-(ps(igrid)%w+ &
460 (ars_gamma-1.0d0)*ps4(igrid)%w+(1.0d0-2.0d0*ars_gamma)*ps1(igrid)%w))/(2.0d0*(1.0d0-ars_gamma))
461 if(stagger_grid) then
462 ps2(igrid)%ws=ps1(igrid)%ws+(ps3(igrid)%ws-(ps(igrid)%ws+ &
463 (ars_gamma-1.0d0)*ps4(igrid)%ws+(1.0d0-2.0d0*ars_gamma)*ps1(igrid)%ws))/(2.0d0*(1.0d0-ars_gamma))
464 endif
465 end do
466 !$OMP END PARALLEL DO
467 call global_implicit_update(ars_gamma,dt,global_time+(1.0d0-ars_gamma)*dt,ps4,ps3)
468 !$OMP PARALLEL DO PRIVATE(igrid)
469 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
470 ps(igrid)%w=ps(igrid)%w+half*ps2(igrid)%w &
471 +half*(ps4(igrid)%w-ps3(igrid)%w)/ars_gamma
472 if(stagger_grid) then
473 ps(igrid)%ws=ps(igrid)%ws+half*ps2(igrid)%ws &
474 +half*(ps4(igrid)%ws-ps3(igrid)%ws)/ars_gamma
475 endif
476 end do
477 !$OMP END PARALLEL DO
478 call advect1(flux_method,half, idim^lim,global_time+(1.0d0-ars_gamma)*dt,ps4,global_time+half*dt,ps)
479
480 case (imex_232)
481 ! this is IMEX_ARK(2,3,2) or IMEX_SSP(2,3,2)
482 call advect1(flux_method,imex_a21, idim^lim,global_time,ps,global_time,ps1)
483 !$OMP PARALLEL DO PRIVATE(igrid)
484 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
485 ps4(igrid)%w=(ps1(igrid)%w-ps(igrid)%w)/imex_a21
486 ps3(igrid)%w=ps(igrid)%w
487 if(stagger_grid) then
488 ps4(igrid)%ws=(ps1(igrid)%ws-ps(igrid)%ws)/imex_a21
489 ps3(igrid)%ws=ps(igrid)%ws
490 endif
491 end do
492 !$OMP END PARALLEL DO
493 call evaluate_implicit(global_time,ps3)
494 !$OMP PARALLEL DO PRIVATE(igrid)
495 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
496 ps1(igrid)%w=ps1(igrid)%w+imex_ha21*dt*ps3(igrid)%w
497 if(stagger_grid) ps1(igrid)%ws=ps1(igrid)%ws+imex_ha21*dt*ps3(igrid)%ws
498 end do
499 !$OMP END PARALLEL DO
500 call getbc(global_time+imex_a21*dt,dt,ps1,iwstart,nwgc)
501 call global_implicit_update(imex_ha22,dt,global_time+imex_c2*dt,ps2,ps1)
502 !$OMP PARALLEL DO PRIVATE(igrid)
503 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
504 ps(igrid)%w=ps(igrid)%w+imex_a31*ps4(igrid)%w &
505 +imex_b1*dt*ps3(igrid)%w+imex_b2*(ps2(igrid)%w-ps1(igrid)%w)/imex_ha22
506 if(stagger_grid) then
507 ps(igrid)%ws=ps(igrid)%ws+imex_a31*ps4(igrid)%ws &
508 +imex_b1*dt*ps3(igrid)%ws+imex_b2*(ps2(igrid)%ws-ps1(igrid)%ws)/imex_ha22
509 endif
510 end do
511 !$OMP END PARALLEL DO
512 !$OMP PARALLEL DO PRIVATE(igrid)
513 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
514 ps3(igrid)%w=ps1(igrid)%w-imex_a21*ps4(igrid)%w &
515 -imex_ha21*dt*ps3(igrid)%w+imex_b1*dt*ps3(igrid)%w
516 if(stagger_grid) then
517 ps3(igrid)%ws=ps1(igrid)%ws-imex_a21*ps4(igrid)%ws &
518 -imex_ha21*dt*ps3(igrid)%ws+imex_b1*dt*ps3(igrid)%ws
519 endif
520 end do
521 !$OMP END PARALLEL DO
522 call advect1(flux_method,imex_a32, idim^lim,global_time+imex_c2*dt,ps2,global_time+imex_a31*dt,ps)
523 !$OMP PARALLEL DO PRIVATE(igrid)
524 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
525 ps2(igrid)%w=(ps(igrid)%w-ps3(igrid)%w-imex_a31*ps4(igrid)%w)/imex_a32 &
526 +(1.0d0-imex_b2/imex_a32)*(ps2(igrid)%w-ps1(igrid)%w)/imex_ha22
527 if(stagger_grid) then
528 ps2(igrid)%ws=(ps(igrid)%ws-ps3(igrid)%ws-imex_a31*ps4(igrid)%ws)/imex_a32 &
529 +(1.0d0-imex_b2/imex_a32)*(ps2(igrid)%ws-ps1(igrid)%ws)/imex_ha22
530 endif
531 end do
532 !$OMP END PARALLEL DO
533 !$OMP PARALLEL DO PRIVATE(igrid)
534 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
535 ps1(igrid)%w=ps3(igrid)%w+imex_b1*ps4(igrid)%w+imex_b2*ps2(igrid)%w
536 if(stagger_grid) then
537 ps1(igrid)%ws=ps3(igrid)%ws+imex_b1*ps4(igrid)%ws+imex_b2*ps2(igrid)%ws
538 endif
539 end do
540 !$OMP END PARALLEL DO
541 call global_implicit_update(imex_b3,dt,global_time+imex_c3*dt,ps2,ps)
542 !$OMP PARALLEL DO PRIVATE(igrid)
543 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
544 ps(igrid)%w=ps1(igrid)%w+ps2(igrid)%w-ps(igrid)%w
545 if(stagger_grid) then
546 ps(igrid)%ws=ps1(igrid)%ws+ps2(igrid)%ws-ps(igrid)%ws
547 endif
548 end do
549 !$OMP END PARALLEL DO
550 call advect1(flux_method,imex_b3, idim^lim,global_time+imex_c3*dt,ps2,global_time+(1.0d0-imex_b3)*dt,ps)
551
552 case (imex_cb3a)
553 ! Third order IMEX scheme with low-storage implementation (4 registers).
554 ! From Cavaglieri&Bewley 2015, see doi.org/10.1016/j.jcp.2015.01.031
555 ! (scheme called "IMEXRKCB3a" there). Uses 3 explicit and 2 implicit stages.
556 ! Parameters are in imex_bj, imex_cj (same for implicit/explicit),
557 ! imex_aij (implicit tableau) and imex_haij (explicit tableau).
558 call advect1(flux_method, imex_ha21, idim^lim, global_time, ps, global_time, ps1)
559 call global_implicit_update(imex_a22, dt, global_time+imex_c2*dt, ps2, ps1)
560 !$OMP PARALLEL DO PRIVATE(igrid)
561 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
562 ps3(igrid)%w = ps(igrid)%w + imex_a32/imex_a22 * (ps2(igrid)%w - ps1(igrid)%w)
563 ps(igrid)%w = ps(igrid)%w + imex_b2 /imex_a22 * (ps2(igrid)%w - ps1(igrid)%w)
564 ps1(igrid)%w = ps3(igrid)%w
565 if(stagger_grid) ps3(igrid)%ws = ps(igrid)%ws + imex_a32/imex_a22 * (ps2(igrid)%ws - ps1(igrid)%ws)
566 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws + imex_b2 /imex_a22 * (ps2(igrid)%ws - ps1(igrid)%ws)
567 if(stagger_grid) ps1(igrid)%ws = ps3(igrid)%ws
568 end do
569 !$OMP END PARALLEL DO
570 call advect1(flux_method, imex_ha32, idim^lim, global_time+imex_c2*dt, ps2, global_time, ps3)
571 !$OMP PARALLEL DO PRIVATE(igrid)
572 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
573 ps(igrid)%w = ps(igrid)%w + imex_b2 /imex_ha32 * (ps3(igrid)%w - ps1(igrid)%w)
574 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws + imex_b2 /imex_ha32 * (ps3(igrid)%ws - ps1(igrid)%ws)
575 end do
576 call global_implicit_update(imex_a33, dt, global_time+imex_c3*dt, ps1, ps3)
577 !$OMP PARALLEL DO PRIVATE(igrid)
578 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
579 ps(igrid)%w = ps(igrid)%w + imex_b3 /imex_a33 * (ps1(igrid)%w - ps3(igrid)%w)
580 if(stagger_grid) ps(igrid)%ws = ps(igrid)%ws + imex_b3 /imex_a33 * (ps1(igrid)%ws - ps3(igrid)%ws)
581 end do
582 !$OMP END PARALLEL DO
583 call advect1(flux_method, imex_b3, idim^lim, global_time+imex_c3*dt, ps1, global_time+imex_b2*dt, ps)
584
585 case default
586 call mpistop("unkown threestep time_integrator in advect")
587 end select
588
589 case (fourstep)
590 select case (t_integrator)
591 case (ssprk4)
592 ! SSPRK(4,3) or SSP(4,2) depending on ssprk_order (3 vs 2)
593 ! ssprk43: Strong stability preserving 4 stage RK 3rd order by Ruuth and Spiteri
594 ! Ruuth & Spiteri J. S C, 17 (2002) p. 211 - 220
595 ! supposed to be stable up to CFL=2.
596 ! ssp42: stable up to CFL=3
597 call advect1(flux_method,rk_beta11, idim^lim,global_time,ps,global_time,ps1)
598 !$OMP PARALLEL DO PRIVATE(igrid)
599 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
600 ps2(igrid)%w=rk_alfa21*ps(igrid)%w+rk_alfa22*ps1(igrid)%w
601 if(stagger_grid) ps2(igrid)%ws=rk_alfa21*ps(igrid)%ws+rk_alfa22*ps1(igrid)%ws
602 end do
603 !$OMP END PARALLEL DO
604 call advect1(flux_method,rk_beta22, idim^lim,global_time+rk_c2*dt,ps1,global_time+rk_alfa22*rk_c2*dt,ps2)
605 !$OMP PARALLEL DO PRIVATE(igrid)
606 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
607 ps1(igrid)%w=rk_alfa31*ps(igrid)%w+rk_alfa33*ps2(igrid)%w
608 if(stagger_grid) ps1(igrid)%ws=rk_alfa31*ps(igrid)%ws+rk_alfa33*ps2(igrid)%ws
609 end do
610 !$OMP END PARALLEL DO
611 call advect1(flux_method,rk_beta33, idim^lim,global_time+rk_c3*dt,ps2,global_time+rk_alfa33*rk_c3*dt,ps1)
612 !$OMP PARALLEL DO PRIVATE(igrid)
613 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
614 ps(igrid)%w=rk_alfa41*ps(igrid)%w+rk_alfa44*ps1(igrid)%w
615 if(stagger_grid) ps(igrid)%ws=rk_alfa41*ps(igrid)%ws+rk_alfa44*ps1(igrid)%ws
616 end do
617 !$OMP END PARALLEL DO
618 call advect1(flux_method,rk_beta44, idim^lim,global_time+rk_c4*dt,ps1,global_time+(1.0d0-rk_beta44)*dt,ps)
619
620 case (rk4)
621 ! the standard RK(4,4) method
622 !$OMP PARALLEL DO PRIVATE(igrid)
623 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
624 ps2(igrid)%w=ps(igrid)%w
625 ps3(igrid)%w=ps(igrid)%w
626 if(stagger_grid) then
627 ps2(igrid)%ws=ps(igrid)%ws
628 ps3(igrid)%ws=ps(igrid)%ws
629 endif
630 end do
631 !$OMP END PARALLEL DO
632 call advect1(flux_method,half, idim^lim,global_time,ps,global_time,ps1)
633 call advect1(flux_method,half, idim^lim,global_time+half*dt,ps1,global_time,ps2)
634 call advect1(flux_method,1.0d0, idim^lim,global_time+half*dt,ps2,global_time,ps3)
635 !$OMP PARALLEL DO PRIVATE(igrid)
636 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
637 ps(igrid)%w=(1.0d0/3.0d0)*(-ps(igrid)%w+ps1(igrid)%w+2.0d0*ps2(igrid)%w+ps3(igrid)%w)
638 if(stagger_grid) ps(igrid)%ws=(1.0d0/3.0d0) &
639 *(-ps(igrid)%ws+ps1(igrid)%ws+2.0d0*ps2(igrid)%ws+ps3(igrid)%ws)
640 end do
641 !$OMP END PARALLEL DO
642 call advect1(flux_method,1.0d0/6.0d0, idim^lim,global_time+dt,ps3,global_time+dt*5.0d0/6.0d0,ps)
643
644 case default
645 call mpistop("unkown fourstep time_integrator in advect")
646 end select
647
648 case (fivestep)
649 select case (t_integrator)
650 case (ssprk5)
651 ! SSPRK(5,4) by Ruuth and Spiteri
652 !bcexch = .false.
653 call advect1(flux_method,rk_beta11, idim^lim,global_time,ps,global_time,ps1)
654 !$OMP PARALLEL DO PRIVATE(igrid)
655 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
656 ps2(igrid)%w=rk_alfa21*ps(igrid)%w+rk_alfa22*ps1(igrid)%w
657 if(stagger_grid) ps2(igrid)%ws=rk_alfa21*ps(igrid)%ws+rk_alfa22*ps1(igrid)%ws
658 end do
659 !$OMP END PARALLEL DO
660 call advect1(flux_method,rk_beta22, idim^lim,global_time+rk_c2*dt,ps1,global_time+rk_alfa22*rk_c2*dt,ps2)
661 !$OMP PARALLEL DO PRIVATE(igrid)
662 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
663 ps1(igrid)%w=rk_alfa31*ps(igrid)%w+rk_alfa33*ps2(igrid)%w
664 if(stagger_grid) ps1(igrid)%ws=rk_alfa31*ps(igrid)%ws+rk_alfa33*ps2(igrid)%ws
665 end do
666 !$OMP END PARALLEL DO
667 call advect1(flux_method,rk_beta33, idim^lim,global_time+rk_c3*dt,ps2,global_time+rk_alfa33*rk_c3*dt,ps1)
668 !$OMP PARALLEL DO PRIVATE(igrid)
669 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
670 ps3(igrid)%w=rk_alfa53*ps2(igrid)%w+rk_alfa54*ps1(igrid)%w
671 if(stagger_grid) ps3(igrid)%ws=rk_alfa53*ps2(igrid)%ws+rk_alfa54*ps1(igrid)%ws
672 end do
673 !$OMP END PARALLEL DO
674 !$OMP PARALLEL DO PRIVATE(igrid)
675 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
676 ps2(igrid)%w=rk_alfa41*ps(igrid)%w+rk_alfa44*ps1(igrid)%w
677 if(stagger_grid) ps2(igrid)%ws=rk_alfa41*ps(igrid)%ws+rk_alfa44*ps1(igrid)%ws
678 end do
679 !$OMP END PARALLEL DO
680 call advect1(flux_method,rk_beta44, idim^lim,global_time+rk_c4*dt,ps1,global_time+rk_alfa44*rk_c4*dt,ps2)
681 !$OMP PARALLEL DO PRIVATE(igrid)
682 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
683 ps(igrid)%w=ps3(igrid)%w+rk_alfa55*ps2(igrid)%w &
684 +(rk_beta54/rk_beta44)*(ps2(igrid)%w-(rk_alfa41*ps(igrid)%w+rk_alfa44*ps1(igrid)%w))
685 if(stagger_grid) then
686 ps(igrid)%ws=ps3(igrid)%ws+rk_alfa55*ps2(igrid)%ws &
687 +(rk_beta54/rk_beta44)*(ps2(igrid)%ws-(rk_alfa41*ps(igrid)%ws+rk_alfa44*ps1(igrid)%ws))
688 endif
689 end do
690 !$OMP END PARALLEL DO
691 !bcexch = .true.
692 call advect1(flux_method,rk_beta55, idim^lim,global_time+rk_c5*dt,ps2,global_time+(1.0d0-rk_beta55)*dt,ps)
693
694 case default
695 call mpistop("unkown fivestep time_integrator in advect")
696 end select
697
698 case default
699 call mpistop("unkown time_stepper in advect")
700 end select
701
702 end subroutine advect
703
704 !> Implicit global update step within IMEX schemes, advance psa=psb+dtfactor*qdt*F_im(psa)
705 subroutine global_implicit_update(dtfactor,qdt,qtC,psa,psb)
709
710 type(state), target :: psa(max_blocks) !< Compute implicit part from this state and update it
711 type(state), target :: psb(max_blocks) !< Will be unchanged, as on entry
712 double precision, intent(in) :: qdt !< overall time step dt
713 double precision, intent(in) :: qtc !< Both states psa and psb at this time level
714 double precision, intent(in) :: dtfactor !< Advance psa=psb+dtfactor*qdt*F_im(psa)
715
716 integer :: iigrid, igrid
717
718 !> First copy all variables from a to b, this is necessary to account for
719 ! quantities in w with no implicit sourceterm
720 do iigrid=1,igridstail; igrid=igrids(iigrid);
721 psa(igrid)%w = psb(igrid)%w
722 if(stagger_grid) psa(igrid)%ws = psb(igrid)%ws
723 end do
724
725 if (associated(phys_implicit_update)) then
726 call phys_implicit_update(dtfactor,qdt,qtc,psa,psb)
727 end if
728
729 ! enforce boundary conditions for psa
730 call getbc(qtc,0.d0,psa,iwstart,nwgc)
731
732 end subroutine global_implicit_update
733
734 !> Evaluate Implicit part in place, i.e. psa==>F_im(psa)
735 subroutine evaluate_implicit(qtC,psa)
738 type(state), target :: psa(max_blocks) !< Compute implicit part from this state and update it
739 double precision, intent(in) :: qtc !< psa at this time level
740
741 if (associated(phys_evaluate_implicit)) then
742 call phys_evaluate_implicit(qtc,psa)
743 end if
744 end subroutine evaluate_implicit
745
746 !> Integrate all grids by one partial step
747 subroutine advect1(method,dtfactor,idim^LIM,qtC,psa,qt,psb)
751 use mod_physics
752 use mod_eos
753
754 integer, intent(in) :: idim^lim
755 type(state), target :: psa(max_blocks) !< Compute fluxes based on this state
756 type(state), target :: psb(max_blocks) !< Update solution on this state
757 double precision, intent(in) :: dtfactor !< Advance over dtfactor * dt
758 double precision, intent(in) :: qtc
759 double precision, intent(in) :: qt
760 integer, intent(in) :: method(nlevelshi)
761
762 double precision :: qdt
763 double precision :: lb_t0_advect1, lb_t0_block
764 integer :: iigrid, igrid
765
766 istep = istep+1
767
768 if(associated(phys_special_advance)) then
769 call phys_special_advance(qtc,psa)
770 end if
771
772 qdt=dtfactor*dt
773 ! opedit: Just advance the active grids:
774 if (lb_diagnose) lb_t0_advect1 = mpi_wtime()
775 !$OMP PARALLEL DO PRIVATE(igrid,lb_t0_block)
776 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
777 if (lb_automatic) lb_t0_block = mpi_wtime()
778 block=>ps(igrid)
779 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
780 call eos%update_eos(ixg^ll,ixg^ll,psa(igrid)%w,psa(igrid)%x)
781 call advect1_grid(igrid,method(block%level),qdt,dtfactor,ixg^ll,idim^lim,&
782 qtc,psa(igrid),qt,psb(igrid),rnode(rpdx1_:rnodehi,igrid),ps(igrid)%x)
783 if (lb_automatic) block_cost(igrid) = block_cost(igrid) + (mpi_wtime() - lb_t0_block)
784 end do
785 !$OMP END PARALLEL DO
786 if (lb_diagnose) lb_compute_accum = lb_compute_accum + (mpi_wtime() - lb_t0_advect1)
787
788 ! opedit: Send flux for all grids, expects sends for all
789 ! nsend_fc(^D), set in connectivity.t.
790
791 if (fix_conserve_global .and. fix_conserve_at_step) then
792 call recvflux(idim^lim)
793 call sendflux(idim^lim)
794 call fix_conserve(psb,idim^lim,1,nwflux)
795 if(stagger_grid) then
796 call fix_edges(psb,idim^lim)
797 ! fill the cell-center values from the updated staggered variables
798 !$OMP PARALLEL DO PRIVATE(igrid)
799 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
800 call phys_face_to_center(ixm^ll,psb(igrid))
801 end do
802 !$OMP END PARALLEL DO
803 end if
804 end if
805
806 ! For all grids: fill ghost cells
807 call getbc(qt+qdt,qdt,psb,iwstart,nwgc)
808
809 end subroutine advect1
810
811 !> Advance a single grid over one partial time step
812 subroutine advect1_grid(igrid,method,qdt,dtfactor,ixI^L,idim^LIM,qtC,sCT,qt,s,dxs,x)
813
814 ! integrate one grid by one partial step
817 use mod_tvd
818 use mod_source, only: addsource2
821 use mod_comm_lib, only: mpistop
823
824 integer, intent(in) :: igrid,method
825 integer, intent(in) :: ixi^l, idim^lim
826 double precision, intent(in) :: qdt, dtfactor, qtc, qt, dxs(ndim), x(ixi^s,1:ndim)
827 type(state), target :: sct, s
828
829 ! cell face flux
830 double precision :: fc(ixi^s,1:nwflux,1:ndim)
831 ! cell edge flux
832 double precision :: fe(ixi^s,sdim:3)
833 double precision :: wprim(ixi^s,1:nw)
834 integer :: ixo^l
835
836 ! for mf module
837 if(iwstart>1) fc=0.d0
838
839 ixo^l=ixi^l^lsubnghostcells;
840 select case (method)
842 call finite_volume(method,qdt,dtfactor,ixi^l,ixo^l,idim^lim,qtc,sct,qt,s,fc,fe,dxs,x)
843 case (fs_cd,fs_cd4)
844 call centdiff(method,qdt,dtfactor,ixi^l,ixo^l,idim^lim,qtc,sct,qt,s,fc,fe,dxs,x)
845 case (fs_hancock)
846 call hancock(qdt,dtfactor,ixi^l,ixo^l,idim^lim,qtc,sct,qt,s,dxs,x)
847 case (fs_fd)
848 call fd(qdt,dtfactor,ixi^l,ixo^l,idim^lim,qtc,sct,qt,s,fc,fe,dxs,x)
849 case (fs_tvd)
850 call centdiff(fs_cd,qdt,dtfactor,ixi^l,ixo^l,idim^lim,qtc,sct,qt,s,fc,fe,dxs,x)
851 call tvdlimit(method,qdt,ixi^l,ixo^l,idim^lim,sct,qt+qdt,s,fc,dxs,x)
852 case (fs_source)
853 fc=0.d0
854 fe=0.d0
855 wprim=sct%w
856 call phys_to_primitive(ixi^l,ixi^l,wprim,x)
857 call addsource2(qdt*dble(idimmax-idimmin+1)/dble(ndim),&
858 dtfactor*dble(idimmax-idimmin+1)/dble(ndim),&
859 ixi^l,ixo^l,1,nw,qtc,sct%w,wprim,qt,s%w,x,.false.)
860 case (fs_nul)
861 ! There is nothing to do
862 case default
863 call mpistop("unknown flux scheme in advect1_grid")
864 end select
865
866 ! opedit: Obviously, flux is stored only for active grids.
867 ! but we know in fix_conserve wether there is a passive neighbor
868 ! but we know in conserve_fix wether there is a passive neighbor
869 ! via neighbor_active(i^D,igrid) thus we skip the correction for those.
870 ! This violates strict conservation when the active/passive interface
871 ! coincides with a coarse/fine interface.
872 if (fix_conserve_global .and. fix_conserve_at_step) then
873 call store_flux(igrid,fc,idim^lim,nwflux)
874 if(stagger_grid) call store_edge(igrid,ixg^ll,fe,idim^lim)
875 end if
876
877 end subroutine advect1_grid
878
879 !> process is a user entry in time loop, before output and advance
880 !> allows to modify solution, add extra variables, etc.
881 !> Warning: CFL dt already determined (and is not recomputed)!
882 subroutine process(iit,qt)
886 ! .. scalars ..
887 integer,intent(in) :: iit
888 double precision, intent(in):: qt
889
890 integer:: iigrid, igrid
891
892 if (associated(usr_process_global)) then
893 call usr_process_global(iit,qt)
894 end if
895
896 if (associated(usr_process_grid)) then
897 !$OMP PARALLEL DO PRIVATE(igrid)
898 do iigrid=1,igridstail; igrid=igrids(iigrid);
899 ! next few lines ensure correct usage of routines like divvector etc
900 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
901 block=>ps(igrid)
902 call usr_process_grid(igrid,node(plevel_,igrid),ixg^ll,ixm^ll, &
903 qt,ps(igrid)%w,ps(igrid)%x)
904 end do
905 !$OMP END PARALLEL DO
906 call getbc(qt,dt,ps,iwstart,nwgc)
907 end if
908 end subroutine process
909
910 !> process_advanced is user entry in time loop, just after advance
911 !> allows to modify solution, add extra variables, etc.
912 !> added for handling two-way coupled PIC-MHD
913 !> Warning: w is now at global_time^(n+1), global time and iteration at global_time^n, it^n
914 subroutine process_advanced(iit,qt)
919 ! .. scalars ..
920 integer,intent(in) :: iit
921 double precision, intent(in):: qt
922
923 integer:: iigrid, igrid
924
925 if (associated(usr_process_adv_global)) then
926 call usr_process_adv_global(iit,qt)
927 end if
928
929 if (associated(usr_process_adv_grid)) then
930 !$OMP PARALLEL DO PRIVATE(igrid)
931 do iigrid=1,igridstail; igrid=igrids(iigrid);
932 ! next few lines ensure correct usage of routines like divvector etc
933 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
934 block=>ps(igrid)
935
936 call usr_process_adv_grid(igrid,node(plevel_,igrid),ixg^ll,ixm^ll, &
937 qt,ps(igrid)%w,ps(igrid)%x)
938 end do
939 !$OMP END PARALLEL DO
940 call getbc(qt,dt,ps,iwstart,nwgc)
941 end if
942 end subroutine process_advanced
943
944end module mod_advance
Module containing all the time stepping schemes.
Definition mod_advance.t:2
subroutine, public process_advanced(iit, qt)
process_advanced is user entry in time loop, just after advance allows to modify solution,...
subroutine, public advance(iit)
Advance all the grids over one time step, including all sources.
Definition mod_advance.t:23
subroutine, public process(iit, qt)
process is a user entry in time loop, before output and advance allows to modify solution,...
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Equation of state for AMRVAC, handled through a single eos_container object.
Definition mod_eos.t:30
Module with finite difference methods for fluxes.
subroutine, public fd(qdt, dtfactor, ixil, ixol, idimslim, qtc, sct, qt, snew, fc, fe, dxs, x)
subroutine, public centdiff(method, qdt, dtfactor, ixil, ixol, idimslim, qtc, sct, qt, s, fc, fe, dxs, x)
Module with finite volume methods for fluxes.
subroutine, public finite_volume(method, qdt, dtfactor, ixil, ixol, idimslim, qtc, sct, qt, snew, fc, fe, dxs, x)
finite volume method
subroutine, public hancock(qdt, dtfactor, ixil, ixol, idimslim, qtc, sct, qt, snew, dxs, x)
The non-conservative Hancock predictor for TVDLF.
Module for flux conservation near refinement boundaries.
subroutine, public init_comm_fix_conserve(idimlim, nwfluxin)
subroutine, public fix_edges(psuse, idimlim)
subroutine, public recvflux(idimlim)
subroutine, public sendflux(idimlim)
subroutine, public store_flux(igrid, fc, idimlim, nwfluxin)
subroutine, public store_edge(igrid, ixil, fe, idimlim)
subroutine, public fix_conserve(psb, idimlim, nw0, nwfluxin)
update ghost cells of all blocks including physical boundaries
subroutine getbc(time, qdt, psb, nwstart, nwbc)
do update ghost cells of all blocks including physical boundaries
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.
integer, dimension(:), allocatable typepred1
The spatial discretization for the predictor step when using a two step PC method.
integer, parameter imex_euler
logical lb_diagnose
Per-rank load-balance timing diagnostic toggle (off by default). When .true., per-rank wall times are...
double precision, dimension(:), allocatable block_cost
Per-step per-block (per-rank, indexed by igrid) cost accumulator. Reset at start of each advance call...
double precision global_time
The global simulation time.
integer istep
Index of the sub-step in a multi-step time integrator.
integer it
Number of time steps taken.
double precision ars_gamma
IMEX_ARS3 parameter ars_gamma.
integer, parameter ndim
Number of spatial dimensions for grid variables.
integer, parameter nlevelshi
The maximum number of levels in the grid refinement.
logical stagger_grid
True for using stagger grid.
logical use_particles
Use particles module or not.
integer icomm
The MPI communicator.
integer, parameter imex_trapezoidal
integer mype
The rank of the current MPI task.
double precision dt
global time step
double precision imex222_lambda
IMEX-222(lambda) one-parameter family of schemes.
integer ierrmpi
A global MPI error return code.
integer, dimension(:), allocatable flux_method
Which flux scheme of spatial discretization to use (per grid level)
double precision, dimension(:), allocatable, parameter d
integer npe
The number of MPI tasks.
integer, parameter fs_hll
flux schemes
logical lb_automatic
Cost-weighted automatic load balancer toggle (off by default). When .true., the SFC partitioner cuts ...
logical time_advance
do time evolving
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision rk_a21
RK2(alfa) method parameters from Butcher tableau.
integer, parameter predictor_corrector
integer, parameter sdim
starting dimension for electric field
integer, parameter forward_euler
logical fix_conserve_global
Whether to apply flux conservation at refinement boundaries.
character(len=std_len) typedimsplit
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
integer t_stepper
time stepper type
character(len=std_len) base_filename
Base file name for simulation output, which will be followed by a number.
integer, parameter rnodehi
grid location info (corner coordinates and grid spacing)
integer max_blocks
The maximum number of grid blocks in a processor.
double precision imex_a22
IMEX_CB3a extra parameters.
integer t_integrator
time integrator method
integer, parameter fs_hancock
integer, dimension(:,:), allocatable node
integer, parameter imex_midpoint
Module containing all the particle routines.
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition mod_physics.t:4
procedure(sub_convert), pointer phys_to_primitive
Definition mod_physics.t:52
procedure(sub_evaluate_implicit), pointer phys_evaluate_implicit
Definition mod_physics.t:89
procedure(sub_implicit_update), pointer phys_implicit_update
Definition mod_physics.t:88
procedure(sub_face_to_center), pointer phys_face_to_center
Definition mod_physics.t:87
procedure(sub_special_advance), pointer phys_special_advance
Definition mod_physics.t:75
module radiative cooling – add optically thin radiative cooling
double precision, public lb_cool_accum
Per-rank cooling-only compute accumulator for lb_diagnose. Sums the wall time spent inside radiative_...
Module for handling split source terms (split from the fluxes)
Definition mod_source.t:2
subroutine, public addsource2(qdt, dtfactor, ixil, ixol, iwlim, qtc, wct, wctprim, qt, w, x, qsourcesplit, src_active)
Add source within ixO for iws: w=w+qdt*S[wCT].
Definition mod_source.t:138
subroutine, public add_split_source(prior)
Definition mod_source.t:24
Generic supertimestepping method which can be used for multiple source terms in the governing equatio...
double precision, public lb_tc_accum
Per-rank TC/STS compute accumulator for lb_diagnose. Sums the wall time spent inside the iigrid block...
Subroutines for TVD-MUSCL schemes.
Definition mod_tvd.t:2
subroutine, public tvdlimit(method, qdt, ixil, ixol, idimlim, s, qt, snew, fc, dxs, x)
Definition mod_tvd.t:14
Module with all the methods that users can customize in AMRVAC.
procedure(process_grid), pointer usr_process_grid
procedure(process_adv_grid), pointer usr_process_adv_grid
procedure(process_global), pointer usr_process_global
procedure(process_adv_global), pointer usr_process_adv_global