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