MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_supertimestepping.t
Go to the documentation of this file.
1!> Generic supertimestepping method
2!> which can be used for multiple source terms in the governing equations
3!> where each term introduces a sts_term type and all sts terms are stored in a pointer list
4!>
5!> user control is in
6!> 1) amrvac.par where namelist sts_list sets the following parameters which have default values:
7!> sts_dtpar=0.5,sts_ncycles=1000,sts_method=1,sourcetype_sts=2
8!> These parametes are shared for all the terms added
9!>
10!> Any STS-handled term is done via
11!> 2) program in the code a term with the subroutine add_sts_method
12!> This method takes as parameters a function which calculates the explicit timestep
13!> associated with the term and a subroutine which sets the source term
14!> for the variables startVar:endVar=startVar+nflux-1
15!> flux conservation (fixconserve) is done for the variables as specified by ixChangeStart, ixChangeN, ixChangeFixC
16!>
17!> 3) one can have hooks before_first_cycle, after_last_cycle (e.g. conversion from e_tot to e_int before first sts cycle
18!> and back from e_int to e_tot after the last STS cycle as used for the thermal conductivity module)
19!> add those hooks just afterwards with the subroutine set_conversion_methods_to_head
20!>
21!> 4) add the hook for error handling (e.g check small values in the thermal conductivity module)
22!> call set_error_handling_to_head which takes as parameter a subroutine
23!> this error handling subroutine is called before setting BC
24!>
26 use mod_geometry
27 use mod_comm_lib, only: mpistop
28 use mod_eos_container, only: eos !> pi temperature cache refresh via eos%update_eos
29 implicit none
30 private
31
32 public :: is_sts_initialized
33 public :: sts_init
35 public :: sts_add_source
36 public :: set_dt_sts_ncycles
38
39 !> Per-rank TC/STS compute accumulator for lb_diagnose. Sums the wall time
40 !> spent inside the iigrid block-loops that call sts_set_sources (the
41 !> per-block parabolic-conduction kernel) plus the per-block STS hooks
42 !> (before_first_cycle, after_last_cycle, sts_handle_errors,
43 !> phys_update_temperature). Excludes inter-rank ghostcell exchanges
44 !> (getbc) and flux-conservation collectives. Reset by mod_advance::advance
45 !> at the start of each step.
46 double precision, public :: lb_tc_accum = 0.0d0
47
48 ! input parameters from parameter file
49 !> the coefficient that multiplies the sts dt
50 double precision :: sts_dtpar=0.5d0
51
52 !The following is used only for method 2, not input parameter
53 double precision,parameter :: nu_sts = 0.5d0
54 !> the maximum number of subcycles
55 integer :: sts_ncycles=1000
56 integer :: sts_method = 1
57 integer, parameter :: sourcetype_sts_prior =0
58 integer, parameter :: sourcetype_sts_after =1
59 integer, parameter :: sourcetype_sts_split =2
61 !> Whether to conserve fluxes at the current partial step
62 logical :: fix_conserve_at_step = .true.
63 logical :: sts_initialized = .false.
64
65 abstract interface
66
67 !>interface for setting sources in the derived type
68 subroutine subr1(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
70 integer, intent(in) :: ixi^l, ixo^l, igrid, nflux
71 double precision, intent(in) :: x(ixi^s,1:ndim)
72 double precision, intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
73 double precision, intent(in) :: my_dt
74 logical, intent(in) :: fix_conserve_at_step
75 end subroutine subr1
76
77 !>interface for the function which gets the timestep in dtnew in the derived type
78 function subr2(w,ixG^L,ix^L,dx^D,x) result(dtnew)
80 integer, intent(in) :: ixg^l, ix^l
81 double precision, intent(in) :: dx^d, x(ixg^s,1:ndim)
82 double precision, intent(in) :: w(ixg^s,1:nw)
83 double precision :: dtnew
84 end function subr2
85
86 !>interface for error handling subroutine in the derived type
87 subroutine subr_e(w, x, ixI^L, ixO^L, step)
90 integer, intent(in) :: ixi^l,ixo^l
91 double precision, intent(inout) :: w(ixi^s,1:nw)
92 double precision, intent(in) :: x(ixi^s,1:ndim)
93 integer, intent(in) :: step
94 end subroutine subr_e
95
96 !>interface for the subroutines before_first_cycle and after_last_cycle in the derived type
97 subroutine subr5(ixI^L, ixO^L, w, x)
99 integer, intent(in) :: ixi^l, ixo^l
100 double precision, intent(in) :: x(ixi^s,1:ndim)
101 double precision, intent(inout) :: w(ixi^s,1:nw)
102 end subroutine subr5
103
104 !>for the subroutines in this module, which do not depend on the term, but
105 !>on the parameter sts_method = 1/2 in the parameter file
106 !>sts_add_source
107 subroutine subr3(dt)
108 double precision,intent(in) :: dt
109 end subroutine subr3
110
111 !>sts_get_ncycles
112 function subr4(dt,dtnew,dt_modified) result(s)
113 double precision,intent(in) :: dtnew
114 double precision,intent(inout) :: dt
115 logical,intent(inout) :: dt_modified
116 integer :: s
117 end function subr4
118
119 end interface
120
121 type sts_term
122
123 double precision :: dt_expl
124 integer, public :: s
125
126 !>types used for send/recv ghosts, see mod_ghostcells_update
127 integer, dimension(-1:1^D&) :: type_send_srl_sts_1, type_recv_srl_sts_1
128 integer, dimension(-1:1^D&) :: type_send_r_sts_1
129 integer, dimension( 0:3^D&) :: type_recv_r_sts_1
130 integer, dimension( 0:3^D&) :: type_recv_p_sts_1, type_send_p_sts_1
131
132 integer, dimension(-1:1^D&) :: type_send_srl_sts_2, type_recv_srl_sts_2
133 integer, dimension(-1:1^D&) :: type_send_r_sts_2
134 integer, dimension( 0:3^D&) :: type_recv_r_sts_2
135 integer, dimension( 0:3^D&) :: type_recv_p_sts_2, type_send_p_sts_2
136
137 integer :: startvar
138 integer :: endvar
139 !> number of flux involved in STS update
140 integer :: nflux
141 integer :: startwbc
142 integer :: nwbc
143 logical :: types_initialized
144 logical :: evolve_magnetic_field
145 procedure(subr1), pointer, nopass :: sts_set_sources
146 procedure(subr2), pointer, nopass :: sts_getdt
147 procedure(subr5), pointer, nopass :: sts_before_first_cycle, sts_after_last_cycle
148 procedure(subr_e), pointer, nopass :: sts_handle_errors
149 type(sts_term), pointer :: next
150
151 end type sts_term
152
153 type(sts_term), pointer :: head_sts_terms
154 !The following two subroutine/function pointers
155 !make the difference between the two STS methods implemented
156 procedure(subr3), pointer :: sts_add_source
157 procedure(subr4), pointer :: sts_get_ncycles
158
159contains
160
161 !> Initialize sts module
162 subroutine sts_init()
164 use mod_physics
165 if(.not. sts_initialized) then
166 nullify(head_sts_terms)
167 call sts_params_read(par_files)
168 sts_dtpar=sts_dtpar/dble(ndim)
169 sts_initialized = .true.
170 if(sts_method .eq. 1) then
171 sts_add_source => sts_add_source1
172 sts_get_ncycles => sts_get_ncycles1
173 else if(sts_method .eq. 2) then
174 sts_add_source => sts_add_source2
175 sts_get_ncycles => sts_get_ncycles2
176 else
177 call mpistop("Unknown sts method")
178 end if
179 endif
180
181 end subroutine sts_init
182
183 pure function is_sts_initialized() result(res)
184 logical :: res
185 if (sts_initialized) then
186 res = associated(head_sts_terms)
187 else
188 res = .false.
189 endif
190 end function is_sts_initialized
191
192 !> Read module parameters from par file
193 subroutine sts_params_read(files)
195 character(len=*), intent(in) :: files(:)
196 integer :: n
197
198 namelist /sts_list/ sts_dtpar,sts_ncycles,sts_method,sourcetype_sts
199
200 do n = 1, size(files)
201 open(unitpar, file=trim(files(n)), status="old")
202 read(unitpar, sts_list, end=111)
203111 close(unitpar)
204 end do
205
206 end subroutine sts_params_read
207
208 !> subroutine which added programatically a term to be calculated using STS
209 !> Params:
210 !> sts_getdt function calculates the explicit timestep for this term
211 !> sts_set_sources subroutine sets the source term
212 !> startVar, nflux (making endVar=startVar+nflux-1) indices of start and number of the variables that need fix conservation
213 !> startwbc, nwbc indices of start and number of the variables that need ghost cell exchange
214 !> These terms implemented by an element of the derived type sts_term are put in a linked list
215 subroutine add_sts_method(sts_getdt, sts_set_sources, startVar, nflux, startwbc, nwbc, evolve_B)
218
219 integer, intent(in) :: startvar, nflux, startwbc, nwbc
220 logical, intent(in) :: evolve_b
221
222 interface
223
224 subroutine sts_set_sources(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
227 integer, intent(in) :: ixi^l, ixo^l, igrid, nflux
228 double precision, intent(in) :: x(ixi^s,1:ndim)
229 double precision, intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
230 double precision, intent(in) :: my_dt
231 logical, intent(in) :: fix_conserve_at_step
232 end subroutine sts_set_sources
233
234 function sts_getdt(w,ixG^L,ix^L,dx^D,x) result(dtnew)
236 integer, intent(in) :: ixg^l, ix^l
237 double precision, intent(in) :: dx^d, x(ixg^s,1:ndim)
238 double precision, intent(in) :: w(ixg^s,1:nw)
239 double precision :: dtnew
240 end function sts_getdt
241
242 end interface
243
244 type(sts_term), pointer :: temp
245 allocate(temp)
246
247 temp%sts_getdt => sts_getdt
248 temp%sts_set_sources => sts_set_sources
249 temp%sts_before_first_cycle => null()
250 temp%sts_after_last_cycle => null()
251 temp%sts_handle_errors => null()
252 temp%startVar = startvar
253 temp%endVar= startvar+nflux-1
254 temp%nflux = nflux
255 temp%startwbc = startwbc
256 temp%nwbc = nwbc
257 temp%types_initialized = .false.
258 temp%evolve_magnetic_field=evolve_b
259
260 temp%next => head_sts_terms
261 head_sts_terms => temp
262
263 end subroutine add_sts_method
264
265 !> Set the hooks called before the first cycle and after the last cycle in the STS update
266 !> This method should be called after add_sts_method. The hooks are added to the last term added with this subroutine
267 !> Params: sts_before_first_cycle, sts_after_last_cycle subroutines which implement the hooks called before first cycle and after last cycle
268 subroutine set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
269 interface
270 subroutine sts_before_first_cycle(ixI^L, ixO^L, w, x)
272 integer, intent(in) :: ixi^l, ixo^l
273 double precision, intent(in) :: x(ixi^s,1:ndim)
274 double precision, intent(inout) :: w(ixi^s,1:nw)
275 end subroutine sts_before_first_cycle
276
277 subroutine sts_after_last_cycle(ixI^L, ixO^L, w, x)
279 integer, intent(in) :: ixi^l, ixo^l
280 double precision, intent(in) :: x(ixi^s,1:ndim)
281 double precision, intent(inout) :: w(ixi^s,1:nw)
282 end subroutine sts_after_last_cycle
283 end interface
284
285 head_sts_terms%sts_before_first_cycle => sts_before_first_cycle
286 head_sts_terms%sts_after_last_cycle => sts_after_last_cycle
287
288 end subroutine set_conversion_methods_to_head
289
290 !> Set the hook of error handling in the STS update. This method is called before updating the BC.
291 !> This method should be called after add_sts_method. The hook is added to the last term added with this subroutine.
292 !> Param: sts_error_handing the subroutine which handles the errors
293 subroutine set_error_handling_to_head(sts_error_handling)
294 interface
295 subroutine sts_error_handling(w, x, ixI^L, ixO^L, step)
298 integer, intent(in) :: ixi^l,ixo^l
299 double precision, intent(inout) :: w(ixi^s,1:nw)
300 double precision, intent(in) :: x(ixi^s,1:ndim)
301 integer, intent(in) :: step
302 end subroutine sts_error_handling
303 end interface
304 head_sts_terms%sts_handle_errors => sts_error_handling
305
306 end subroutine set_error_handling_to_head
307
308 !> method used to set the number of cycles for the STS1 method
309 function sts_get_ncycles1(dt,dtnew,dt_modified) result(is)
310 double precision,intent(in) :: dtnew
311 double precision,intent(inout) :: dt
312 logical,intent(inout) :: dt_modified
313 integer :: is
314
315 double precision :: ss
316
317 !!ss is now limit of dt because of sts_ncycles
318 ss = dtnew*((2.d0*sts_ncycles+1)**2-9.d0)/16.d0
319 if(dt>ss) then
320 dt_modified = .true.
321 dt = ss
322 is = sts_ncycles
323 else
324 ss = dt/dtnew
325 ! get number of sub-steps of supertime stepping (Meyer 2012 MNRAS 422,2102)
326 if(ss .le. 1.d0) then
327 is=1
328 else
329 is=ceiling((dsqrt(9.d0+16.d0*ss)-1.d0)*0.5d0)
330 is=is/2*2+1
331 end if
332 end if
333
334 end function sts_get_ncycles1
335
336 !> method used to set the number of cycles for the STS2 method
337 function sts_get_ncycles2(dt,dtnew,dt_modified) result(is)
338 double precision,intent(in) :: dtnew
339 double precision,intent(inout) :: dt
340 logical,intent(inout) :: dt_modified
341 integer :: is
342
343 double precision :: ss,rr
344 integer:: ncycles
345
346 rr = dt/dtnew
347 !print*, dt, " --DTEXPL-- ", dtnew, ", rr ",rr
348 ncycles = sts_ncycles
349 !print*, "NCYCLES BEFORE ",ncycles
350 ss=sum_chev(nu_sts,ncycles,rr)
351 !print*, "NCYCLES AFTER ",ncycles
352 is = ncycles
353 !print*, "SUMCHEV ", ss, " NCYCLES ", is
354 if(ss < rr) then
355 dt_modified = .true.
356 dt = ss * dtnew
357 endif
358
359 end function sts_get_ncycles2
360
361 !> This sets the explicit dt and calculates the number of cycles for each of the terms implemented with STS.
362 function set_dt_sts_ncycles(my_dt) result(dt_modified)
364
365 double precision,intent(inout) :: my_dt
366 double precision :: my_dt1
367 logical :: dt_modified, dt_modified1, dt_modified2
368
369 double precision :: dtnew,dtmin_mype
370 double precision :: dx^d, ss
371 integer:: iigrid, igrid, ncycles
372 type(sts_term), pointer :: temp,oldtemp
373 nullify(oldtemp)
374 temp => head_sts_terms
375 dt_modified = .false.
376 do while(associated(temp))
377 dt_modified2 = .false.
378 dtmin_mype=bigdouble
379 !$OMP PARALLEL DO PRIVATE(igrid,dx^D) REDUCTION(min:dtmin_mype)
380 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
381 ! maybe the following global variables are needed in get_dt!
382 ! next few lines ensure correct usage of routines like divvector etc
383 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
384 block=>ps(igrid)
385 ! end maybe the following global variables are needed in get_dt!!!!!!!
386 dx^d=rnode(rpdx^d_,igrid);
387 dtmin_mype=min(dtmin_mype, sts_dtpar * temp%sts_getdt(ps(igrid)%w,ixg^ll,ixm^ll,dx^d,ps(igrid)%x))
388 end do
389 !$OMP END PARALLEL DO
390 call mpi_allreduce(dtmin_mype,dtnew,1,mpi_double_precision,mpi_min,icomm,ierrmpi)
391 temp%s = sts_get_ncycles(my_dt,dtnew,dt_modified2)
392
393 !print*, "NCYCLES ", temp%s, dt_modified2, my_dt, dtnew
394 temp%dt_expl = dtnew
395
396 ! Note that as for some term it may happen that the dt is modified: it may be reduced if the
397 ! number of cycles is overpassed, the list has to be reiterated to update ncycles for previous
398 ! terms which did not modify dt TODO add pointer to previous and loop backward to update
399 if(dt_modified2) then
400 dt_modified = .true.
401 !reiterate all the other sts elements and recalculate s
402 oldtemp => head_sts_terms
403 my_dt1 = my_dt
404 dt_modified1 = .false.
405 do while(.not. associated(oldtemp,temp))
406 oldtemp%s = sts_get_ncycles(my_dt1,oldtemp%dt_expl,dt_modified1)
407 !check dt is not modified again, and this should not happen, except for bug in sts_get_ncycles1,2
408 if(dt_modified1) call mpistop("sts dt modified twice")
409 oldtemp=>oldtemp%next
410 end do
411 end if
412 temp=>temp%next
413
414 end do
415
416 end function set_dt_sts_ncycles
417
418 pure FUNCTION chev(j,nu,N)
419 use mod_constants
420
421 double precision, INTENT(IN) :: nu
422 INTEGER, INTENT(IN) :: j, n
423 double precision :: chev
424
425 chev = 1d0 / ((-1d0 + nu)*cos(((2d0*j - 1d0) / n)* (dpi/2d0)) + 1d0 + nu)
426
427 END FUNCTION chev
428
429 FUNCTION sum_chev(nu,N,limMax)
430 double precision, intent(in) :: nu,limmax
431 integer, intent(inout) :: n
432 double precision :: sum_chev, tmp
433
434 integer :: j
435
436 j=1
437 sum_chev = 0d0
438 do while (j < n .and. sum_chev < limmax)
439 sum_chev = sum_chev + chev(j,nu,n)
440 j=j+1
441 enddo
442 n=j-1
443 END FUNCTION sum_chev
444
445 !> Iterates all the terms implemented with STS and adds the sources
446 !> STS method 2 implementation
447 subroutine sts_add_source2(my_dt)
448 ! Turlough Downes 2006,2007
452 use mod_physics
453
454 double precision, intent(in) :: my_dt
455 double precision, allocatable :: bj(:)
456 double precision :: sumbj,dtj
457
458 integer:: iigrid, igrid, j, ixc^l
459 logical :: stagger_flag=.false., prolong_flag=.false., coarsen_flag=.false.
460 type(sts_term), pointer :: temp
461
462 ! do not fill physical boundary conditions
463 bcphys=.false.
464
465 fix_conserve_at_step = time_advance .and. levmax>levmin
466
467 temp => head_sts_terms
468 do while(associated(temp))
469
470 if(.not.temp%evolve_magnetic_field) then
471 ! not do fix conserve and getbc for staggered values
472 stagger_flag=stagger_grid
473 stagger_grid=.false.
474 else if(stagger_grid) then
475 ixcmax^d=ixmhi^d;
476 ixcmin^d=ixmlo^d-1;
477 end if
478
479 call init_comm_fix_conserve(1,ndim,temp%nflux)
480
481 if(associated(temp%sts_before_first_cycle)) then
482 prolong_flag=prolongprimitive
483 coarsen_flag=coarsenprimitive
484 prolongprimitive=.false.
485 coarsenprimitive=.false.
486 do iigrid=1,igridstail; igrid=igrids(iigrid);
487 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
488 block=>ps(igrid)
489 call temp%sts_before_first_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
490 end do
491 end if
492
493 allocate(bj(1:temp%s))
494 do j=1,temp%s
495 bj(j) = chev(j,nu_sts,sts_ncycles)
496 end do
497
498 type_send_srl=>temp%type_send_srl_sts_1
499 type_recv_srl=>temp%type_recv_srl_sts_1
500 type_send_r=>temp%type_send_r_sts_1
501 type_recv_r=>temp%type_recv_r_sts_1
502 type_send_p=>temp%type_send_p_sts_1
503 type_recv_p=>temp%type_recv_p_sts_1
504
505 if(.not. temp%types_initialized) then
506 call create_bc_mpi_datatype(temp%startwbc,temp%nwbc)
507 if(temp%nflux>temp%nwbc) then
508 ! prepare types for the changed no-need-ghost-update variables in the last getbc
509 type_send_srl=>temp%type_send_srl_sts_2
510 type_recv_srl=>temp%type_recv_srl_sts_2
511 type_send_r=>temp%type_send_r_sts_2
512 type_recv_r=>temp%type_recv_r_sts_2
513 type_send_p=>temp%type_send_p_sts_2
514 type_recv_p=>temp%type_recv_p_sts_2
515 call create_bc_mpi_datatype(temp%startVar,temp%nflux)
516 type_send_srl=>temp%type_send_srl_sts_1
517 type_recv_srl=>temp%type_recv_srl_sts_1
518 type_send_r=>temp%type_send_r_sts_1
519 type_recv_r=>temp%type_recv_r_sts_1
520 type_send_p=>temp%type_send_p_sts_1
521 type_recv_p=>temp%type_recv_p_sts_1
522 end if
523 temp%types_initialized = .true.
524 end if
525
526 sumbj=0.d0
527 do j=1,temp%s
528 if(j .eq. temp%s .and. (sumbj + bj(j)) * temp%dt_expl > my_dt) then
529 dtj = my_dt - sumbj * temp%dt_expl
530 else
531 dtj = bj(j)* temp%dt_expl
532 end if
533 sumbj = sumbj + bj(j)
534 if(stagger_grid) then
535 !$OMP PARALLEL DO PRIVATE(igrid)
536 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
537 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
538 block=>ps(igrid)
539 call temp%sts_set_sources(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x,ps1(igrid)%w,fix_conserve_at_step,dtj,igrid,temp%nflux)
540 if(temp%nflux>ndir) then
541 ps(igrid)%w(ixm^t,temp%startVar)=ps(igrid)%w(ixm^t,temp%startVar)+dtj*ps1(igrid)%w(ixm^t,temp%startVar)
542 end if
543 ps(igrid)%ws(ixc^s,1:nws)=ps(igrid)%ws(ixc^s,1:nws)+dtj*ps1(igrid)%w(ixc^s,iw_mag(1:nws))
544 call phys_face_to_center(ixm^ll,ps(igrid))
545 end do
546 !$OMP END PARALLEL DO
547 else
548 !$OMP PARALLEL DO PRIVATE(igrid)
549 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
550 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
551 block=>ps(igrid)
552 call temp%sts_set_sources(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x,ps1(igrid)%w,fix_conserve_at_step,dtj,igrid,temp%nflux)
553 ps(igrid)%w(ixm^t,temp%startVar:temp%endVar)=ps(igrid)%w(ixm^t,temp%startVar:temp%endVar)+&
554 dtj*ps1(igrid)%w(ixm^t,temp%startVar:temp%endVar)
555 end do
556 !$OMP END PARALLEL DO
557 end if
558 !fix conserve the fluxes set in the STS method
559 if(fix_conserve_at_step) then
560 call recvflux(1,ndim)
561 call sendflux(1,ndim)
562 call fix_conserve(ps,1,ndim,temp%startVar,temp%nflux)
563 if(stagger_grid) then
564 call fix_edges(ps,1,ndim)
565 ! fill the cell-center values from the updated staggered variables
566 !$OMP PARALLEL DO PRIVATE(igrid)
567 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
568 call phys_face_to_center(ixg^ll,ps(igrid))
569 end do
570 !$OMP END PARALLEL DO
571 end if
572 end if
573 if(associated(temp%sts_handle_errors)) then
574 !$OMP PARALLEL DO PRIVATE(igrid)
575 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
576 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
577 block=>ps(igrid)
578 call temp%sts_handle_errors(ps(igrid)%w,ps(igrid)%x,ixg^ll,ixm^ll,j)
579 end do
580 !$OMP END PARALLEL DO
581 end if
582
583 if(temp%nflux>temp%nwbc.and.temp%s==j) then
584 ! include the changed no-need-ghost-update variables in the last getbc
585 type_send_srl=>temp%type_send_srl_sts_2
586 type_recv_srl=>temp%type_recv_srl_sts_2
587 type_send_r=>temp%type_send_r_sts_2
588 type_recv_r=>temp%type_recv_r_sts_2
589 type_send_p=>temp%type_send_p_sts_2
590 type_recv_p=>temp%type_recv_p_sts_2
591 call getbc(global_time,0.d0,ps,temp%startVar,temp%nflux)
592 else
593 call getbc(global_time,0.d0,ps,temp%startwbc,temp%nwbc)
594 end if
595 end do
596
597 if(associated(temp%sts_after_last_cycle)) then
598 do iigrid=1,igridstail; igrid=igrids(iigrid);
599 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
600 block=>ps(igrid)
601 call temp%sts_after_last_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
602 end do
603 prolongprimitive = prolong_flag
604 coarsenprimitive = coarsen_flag
605 end if
606 deallocate(bj)
607
608 if(.not.temp%evolve_magnetic_field) then
609 ! restore stagger_grid value
610 stagger_grid=stagger_flag
611 end if
612
613 temp=>temp%next
614 end do
615
616 if(associated(head_sts_terms)) then
617 ! point bc mpi data type back to full type for (M)HD
624 end if
625
626 bcphys=.true.
627
628 if(eos%eos_type == 'PI') then
629 ! update temperature variable in w
630 !$OMP PARALLEL DO PRIVATE(igrid)
631 do iigrid=1,igridstail; igrid=igrids(iigrid);
632 call eos%update_eos(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
633 end do
634 !$OMP END PARALLEL DO
635 end if
636
637 end subroutine sts_add_source2
638
639 !> Iterates all the terms implemented with STS and adds the sources
640 !> STS method 1 implementation
641 subroutine sts_add_source1(my_dt)
642 ! Meyer 2012 MNRAS 422,2102
646 use mod_physics
648
649 double precision, intent(in) :: my_dt
650 double precision :: dtj
651 double precision :: omega1,cmu,cmut,cnu,cnut,one_mu_nu
652 double precision, allocatable :: bj(:)
653 integer:: iigrid, igrid, j, ixc^l, ixgext^l
654 double precision :: lb_t0_tc, lb_t0_block
655 logical :: evenstep, stagger_flag=.false., prolong_flag=.false., coarsen_flag=.false., total_energy_flag=.true.
656 type(sts_term), pointer :: temp
657 type(state), dimension(:), pointer :: tmpps1, tmpps2
658
659 ! do not fill physical boundary conditions
660 bcphys=.false.
661
662 fix_conserve_at_step = time_advance .and. levmax>levmin
663
664 temp => head_sts_terms
665 do while(associated(temp))
666
667 if(.not.temp%evolve_magnetic_field) then
668 ! not do fix conserve and getbc for staggered values
669 stagger_flag=stagger_grid
670 stagger_grid=.false.
671 else if(stagger_grid) then
672 ixcmax^d=ixmhi^d;
673 ixcmin^d=ixmlo^d-1;
674 end if
675
676 call init_comm_fix_conserve(1,ndim,temp%nflux)
677
678 if(associated(temp%sts_before_first_cycle)) then
679 prolong_flag = prolongprimitive
680 coarsen_flag = coarsenprimitive
681 prolongprimitive = .false.
682 coarsenprimitive = .false.
683 total_energy_flag=phys_total_energy
684 phys_total_energy=.false.
685 !$OMP PARALLEL DO PRIVATE(igrid)
686 do iigrid=1,igridstail; igrid=igrids(iigrid);
687 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
688 block=>ps(igrid)
689 call temp%sts_before_first_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
690 if(.not. allocated(ps2(igrid)%w)) allocate(ps2(igrid)%w(ixg^t,1:nw))
691 if(.not. allocated(ps3(igrid)%w)) allocate(ps3(igrid)%w(ixg^t,1:nw))
692 if(.not. allocated(ps4(igrid)%w)) allocate(ps4(igrid)%w(ixg^t,1:nw))
693 ps1(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
694 ps2(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
695 end do
696 !$OMP END PARALLEL DO
697 else
698 if(stagger_grid) then
699 ixgext^l=ixg^ll^ladd1;
700 !$OMP PARALLEL DO PRIVATE(igrid)
701 do iigrid=1,igridstail; igrid=igrids(iigrid);
702 if(.not. allocated(ps2(igrid)%w)) then
703 call alloc_state(igrid, ps2(igrid), ixg^ll, ixgext^l, .false.)
704 end if
705 if(.not. allocated(ps3(igrid)%w)) allocate(ps3(igrid)%w(ixg^t,1:nw))
706 if(.not. allocated(ps4(igrid)%w)) allocate(ps4(igrid)%w(ixg^t,1:nw))
707 ps1(igrid)%w=ps(igrid)%w
708 ps2(igrid)%w=ps(igrid)%w
709 ps1(igrid)%ws=ps(igrid)%ws
710 ps2(igrid)%ws=ps(igrid)%ws
711 end do
712 !$OMP END PARALLEL DO
713 else
714 !$OMP PARALLEL DO PRIVATE(igrid)
715 do iigrid=1,igridstail; igrid=igrids(iigrid);
716 if(.not. allocated(ps2(igrid)%w)) allocate(ps2(igrid)%w(ixg^t,1:nw))
717 if(.not. allocated(ps3(igrid)%w)) allocate(ps3(igrid)%w(ixg^t,1:nw))
718 if(.not. allocated(ps4(igrid)%w)) allocate(ps4(igrid)%w(ixg^t,1:nw))
719 ps1(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
720 ps2(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
721 end do
722 !$OMP END PARALLEL DO
723 end if
724 end if
725
726 allocate(bj(0:temp%s))
727 bj(0)=1.d0/3.d0
728 bj(1)=bj(0)
729 if(temp%s>1) then
730 omega1=4.d0/dble(temp%s**2+temp%s-2)
731 cmut=omega1/3.d0
732 else
733 omega1=0.d0
734 cmut=1.d0
735 end if
736
737 type_send_srl=>temp%type_send_srl_sts_1
738 type_recv_srl=>temp%type_recv_srl_sts_1
739 type_send_r=>temp%type_send_r_sts_1
740 type_recv_r=>temp%type_recv_r_sts_1
741 type_send_p=>temp%type_send_p_sts_1
742 type_recv_p=>temp%type_recv_p_sts_1
743
744 if(.not. temp%types_initialized) then
745 call create_bc_mpi_datatype(temp%startwbc,temp%nwbc)
746 if(temp%nflux>temp%nwbc) then
747 ! prepare types for the changed no-need-ghost-update variables in the last getbc
748 type_send_srl=>temp%type_send_srl_sts_2
749 type_recv_srl=>temp%type_recv_srl_sts_2
750 type_send_r=>temp%type_send_r_sts_2
751 type_recv_r=>temp%type_recv_r_sts_2
752 type_send_p=>temp%type_send_p_sts_2
753 type_recv_p=>temp%type_recv_p_sts_2
754 call create_bc_mpi_datatype(temp%startVar,temp%nflux)
755 type_send_srl=>temp%type_send_srl_sts_1
756 type_recv_srl=>temp%type_recv_srl_sts_1
757 type_send_r=>temp%type_send_r_sts_1
758 type_recv_r=>temp%type_recv_r_sts_1
759 type_send_p=>temp%type_send_p_sts_1
760 type_recv_p=>temp%type_recv_p_sts_1
761 end if
762 temp%types_initialized = .true.
763 end if
764 dtj = cmut*my_dt
765 if (lb_diagnose) lb_t0_tc = mpi_wtime()
766 if(stagger_grid) then
767 !$OMP PARALLEL DO PRIVATE(igrid,lb_t0_block)
768 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
769 if (lb_automatic) lb_t0_block = mpi_wtime()
770 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
771 block=>ps(igrid)
772 ps4(igrid)%w=zero
773 call temp%sts_set_sources(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x,ps4(igrid)%w,fix_conserve_at_step,dtj,igrid,temp%nflux)
774 !!!eq solved: dU/dt = S, ps3 is stored S^n
775 ps3(igrid)%w(ixc^s,temp%startVar:temp%endVar) = my_dt * ps4(igrid)%w(ixc^s,temp%startVar:temp%endVar)
776 if(temp%nflux>ndir) then
777 ps1(igrid)%w(ixm^t,temp%startVar) = ps1(igrid)%w(ixm^t,temp%startVar) + cmut * ps3(igrid)%w(ixm^t,temp%startVar)
778 end if
779 ps1(igrid)%ws(ixc^s,1:nws) = ps1(igrid)%ws(ixc^s,1:nws) + cmut * ps3(igrid)%w(ixc^s,iw_mag(1:nws))
780 call phys_face_to_center(ixm^ll,ps1(igrid))
781 if (lb_automatic) block_cost(igrid) = block_cost(igrid) + (mpi_wtime() - lb_t0_block)
782 end do
783 !$OMP END PARALLEL DO
784 else
785 !$OMP PARALLEL DO PRIVATE(igrid,lb_t0_block)
786 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
787 if (lb_automatic) lb_t0_block = mpi_wtime()
788 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
789 block=>ps(igrid)
790 call temp%sts_set_sources(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x,ps4(igrid)%w,fix_conserve_at_step,dtj,igrid,temp%nflux)
791 !!!eq solved: dU/dt = S, ps3 is stored S^n
792 ps3(igrid)%w(ixm^t,temp%startVar:temp%endVar) = my_dt * ps4(igrid)%w(ixm^t,temp%startVar:temp%endVar)
793 ps1(igrid)%w(ixm^t,temp%startVar:temp%endVar) = ps1(igrid)%w(ixm^t,temp%startVar:temp%endVar) + &
794 cmut * ps3(igrid)%w(ixm^t,temp%startVar:temp%endVar)
795 if (lb_automatic) block_cost(igrid) = block_cost(igrid) + (mpi_wtime() - lb_t0_block)
796 end do
797 !$OMP END PARALLEL DO
798 end if
799 if (lb_diagnose) lb_tc_accum = lb_tc_accum + (mpi_wtime() - lb_t0_tc)
800 if(fix_conserve_at_step) then
801 call recvflux(1,ndim)
802 call sendflux(1,ndim)
803 call fix_conserve(ps1,1,ndim,temp%startVar,temp%nflux)
804 if(stagger_grid) then
805 call fix_edges(ps1,1,ndim)
806 ! fill the cell-center values from the updated staggered variables
807 !$OMP PARALLEL DO PRIVATE(igrid)
808 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
809 call phys_face_to_center(ixg^ll,ps1(igrid))
810 end do
811 !$OMP END PARALLEL DO
812 end if
813 end if
814 ! fix conservation of AMR grid by replacing flux from finer neighbors
815 if(associated(temp%sts_handle_errors)) then
816 !$OMP PARALLEL DO PRIVATE(igrid)
817 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
818 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
819 block=>ps(igrid)
820 call temp%sts_handle_errors(ps1(igrid)%w,ps1(igrid)%x,ixg^ll,ixm^ll,1)
821 end do
822 !$OMP END PARALLEL DO
823 end if
824 if(temp%nflux>temp%nwbc.and.temp%s==1) then
825 ! include the changed no-need-ghost-update variables in the last getbc
826 type_send_srl=>temp%type_send_srl_sts_2
827 type_recv_srl=>temp%type_recv_srl_sts_2
828 type_send_r=>temp%type_send_r_sts_2
829 type_recv_r=>temp%type_recv_r_sts_2
830 type_send_p=>temp%type_send_p_sts_2
831 type_recv_p=>temp%type_recv_p_sts_2
832 call getbc(global_time,0.d0,ps1,temp%startVar,temp%nflux)
833 else
834 call getbc(global_time,0.d0,ps1,temp%startwbc,temp%nwbc)
835 end if
836 !!first step end
837
838 evenstep=.true.
839
840 tmpps2=>ps1
841
842 do j=2,temp%s
843 bj(j)=dble(j**2+j-2)/dble(2*j*(j+1))
844 cmu=dble(2*j-1)/dble(j)*bj(j)/bj(j-1)
845 cmut=omega1*cmu
846 cnu=dble(1-j)/dble(j)*bj(j)/bj(j-2)
847 cnut=(bj(j-1)-1.d0)*cmut
848 one_mu_nu=1.d0-cmu-cnu
849 if(evenstep) then
850 tmpps1=>ps1
851 tmpps2=>ps2
852 else
853 tmpps1=>ps2
854 tmpps2=>ps1
855 end if
856
857 dtj = cmut*my_dt
858 if (lb_diagnose) lb_t0_tc = mpi_wtime()
859 if(stagger_grid) then
860 !$OMP PARALLEL DO PRIVATE(igrid)
861 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
862 ! maybe the following global variables are needed in set_sources
863 ! next few lines ensure correct usage of routines like divvector etc
864 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
865 block=>ps(igrid)
866 ! end maybe the following global variables are needed in set_sources
867 call temp%sts_set_sources(ixg^ll,ixm^ll,tmpps1(igrid)%w,ps(igrid)%x,ps4(igrid)%w,fix_conserve_at_step,dtj,igrid,temp%nflux)
868 if(temp%nflux>ndir) then
869 tmpps2(igrid)%w(ixm^t,temp%startVar)=cmu*tmpps1(igrid)%w(ixm^t,temp%startVar)+&
870 cnu*tmpps2(igrid)%w(ixm^t,temp%startVar)+one_mu_nu*ps(igrid)%w(ixm^t,temp%startVar)+&
871 dtj*ps4(igrid)%w(ixm^t,temp%startVar)+cnut*ps3(igrid)%w(ixm^t,temp%startVar)
872 end if
873 tmpps2(igrid)%ws(ixc^s,1:nws)=cmu*tmpps1(igrid)%ws(ixc^s,1:nws)+&
874 cnu*tmpps2(igrid)%ws(ixc^s,1:nws)+one_mu_nu*ps(igrid)%ws(ixc^s,1:nws)+&
875 dtj*ps4(igrid)%w(ixc^s,iw_mag(1:nws))+cnut*ps3(igrid)%w(ixc^s,iw_mag(1:nws))
876 call phys_face_to_center(ixm^ll,tmpps2(igrid))
877 end do
878 !$OMP END PARALLEL DO
879 else
880 !$OMP PARALLEL DO PRIVATE(igrid)
881 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
882 ! maybe the following global variables are needed in set_sources
883 ! next few lines ensure correct usage of routines like divvector etc
884 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
885 block=>ps(igrid)
886 ! end maybe the following global variables are needed in set_sources
887 call temp%sts_set_sources(ixg^ll,ixm^ll,tmpps1(igrid)%w,ps(igrid)%x,ps4(igrid)%w,fix_conserve_at_step,dtj,igrid,temp%nflux)
888 tmpps2(igrid)%w(ixm^t,temp%startVar:temp%endVar)=cmu*tmpps1(igrid)%w(ixm^t,temp%startVar:temp%endVar)+&
889 cnu*tmpps2(igrid)%w(ixm^t,temp%startVar:temp%endVar)+one_mu_nu*ps(igrid)%w(ixm^t,temp%startVar:temp%endVar)+&
890 dtj*ps4(igrid)%w(ixm^t,temp%startVar:temp%endVar)+cnut*ps3(igrid)%w(ixm^t,temp%startVar:temp%endVar)
891 end do
892 !$OMP END PARALLEL DO
893 end if
894 if (lb_diagnose) lb_tc_accum = lb_tc_accum + (mpi_wtime() - lb_t0_tc)
895 if(fix_conserve_at_step) then
896 call recvflux(1,ndim)
897 call sendflux(1,ndim)
898 call fix_conserve(tmpps2,1,ndim,temp%startVar,temp%nflux)
899 if(stagger_grid) then
900 call fix_edges(tmpps2,1,ndim)
901 ! fill the cell-center values from the updated staggered variables
902 !$OMP PARALLEL DO PRIVATE(igrid)
903 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
904 call phys_face_to_center(ixg^ll,tmpps2(igrid))
905 end do
906 !$OMP END PARALLEL DO
907 end if
908 end if
909 if(associated(temp%sts_handle_errors)) then
910 !$OMP PARALLEL DO PRIVATE(igrid)
911 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
912 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
913 block=>ps(igrid)
914 call temp%sts_handle_errors(tmpps2(igrid)%w,ps(igrid)%x,ixg^ll,ixm^ll,j)
915 end do
916 !$OMP END PARALLEL DO
917 end if
918
919 if(temp%nflux>temp%nwbc.and.temp%s==j) then
920 ! include the changed no-need-ghost-update variables in the last getbc
921 type_send_srl=>temp%type_send_srl_sts_2
922 type_recv_srl=>temp%type_recv_srl_sts_2
923 type_send_r=>temp%type_send_r_sts_2
924 type_recv_r=>temp%type_recv_r_sts_2
925 type_send_p=>temp%type_send_p_sts_2
926 type_recv_p=>temp%type_recv_p_sts_2
927 call getbc(global_time,0.d0,tmpps2,temp%startVar,temp%nflux)
928 else
929 call getbc(global_time,0.d0,tmpps2,temp%startwbc,temp%nwbc)
930 end if
931 evenstep=.not.evenstep
932 end do
933
934 if(associated(temp%sts_after_last_cycle)) then
935 if (lb_diagnose) lb_t0_tc = mpi_wtime()
936 !$OMP PARALLEL DO PRIVATE(igrid)
937 do iigrid=1,igridstail; igrid=igrids(iigrid);
938 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
939 block=>ps(igrid)
940 ps(igrid)%w(ixg^t,temp%startVar:temp%endVar)=tmpps2(igrid)%w(ixg^t,temp%startVar:temp%endVar)
941 call temp%sts_after_last_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
942 end do
943 !$OMP END PARALLEL DO
944 if (lb_diagnose) lb_tc_accum = lb_tc_accum + (mpi_wtime() - lb_t0_tc)
945 phys_total_energy=total_energy_flag
946 prolongprimitive = prolong_flag
947 coarsenprimitive = coarsen_flag
948 else
949 if(stagger_grid) then
950 !$OMP PARALLEL DO PRIVATE(igrid)
951 do iigrid=1,igridstail; igrid=igrids(iigrid);
952 ps(igrid)%w(ixg^t,temp%startVar:temp%endVar)=tmpps2(igrid)%w(ixg^t,temp%startVar:temp%endVar)
953 ps(igrid)%ws=tmpps2(igrid)%ws
954 end do
955 !$OMP END PARALLEL DO
956 else
957 !$OMP PARALLEL DO PRIVATE(igrid)
958 do iigrid=1,igridstail; igrid=igrids(iigrid);
959 ps(igrid)%w(ixg^t,temp%startVar:temp%endVar)=tmpps2(igrid)%w(ixg^t,temp%startVar:temp%endVar)
960 end do
961 !$OMP END PARALLEL DO
962 end if
963 end if
964
965 deallocate(bj)
966
967 if(.not.temp%evolve_magnetic_field) then
968 ! restore stagger_grid value
969 stagger_grid=stagger_flag
970 end if
971
972 temp=>temp%next
973 end do
974
975 if(associated(head_sts_terms)) then
976 ! point bc mpi data type back to full type for (M)HD
983 end if
984
985 bcphys=.true.
986
987 if(eos%eos_type == 'PI') then
988 ! update temperature variable in w
989 !$OMP PARALLEL DO PRIVATE(igrid)
990 do iigrid=1,igridstail; igrid=igrids(iigrid);
991 call eos%update_eos(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
992 end do
993 !$OMP END PARALLEL DO
994 end if
995
996 end subroutine sts_add_source1
997
998end module mod_supertimestepping
subroutine, public alloc_state(igrid, s, ixgl, ixgextl, alloc_once_for_ps)
allocate memory to physical state of igrid node
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter dpi
Pi.
EoS state container – the single thermodynamic authority for AMRVAC.
type(eos_container), allocatable, public eos
The single EoS state object, allocated in eos_init and shared (read-mostly) across all EoS sub-module...
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 fix_conserve(psb, idimlim, nw0, nwfluxin)
Module with geometry-related routines (e.g., divergence, curl)
Definition mod_geometry.t:2
update ghost cells of all blocks including physical boundaries
integer, dimension( :^d &), pointer type_recv_r
integer, dimension(^nd, 0:3) l
subroutine getbc(time, qdt, psb, nwstart, nwbc)
do update ghost cells of all blocks including physical boundaries
integer, dimension(0:3^d &), target type_send_p_f
integer, dimension( :^d &), pointer type_send_p
integer, dimension( :^d &), pointer type_send_srl
subroutine create_bc_mpi_datatype(nwstart, nwbc)
integer, dimension(0:3^d &), target type_recv_r_f
integer, dimension(-1:1^d &), target type_recv_srl_f
integer, dimension(-1:1^d &), target type_send_r_f
integer, dimension(-1:1^d &), target type_send_srl_f
integer, dimension( :^d &), pointer type_send_r
integer, dimension( :^d &), pointer type_recv_p
integer, dimension(0:3^d &), target type_recv_p_f
integer, dimension( :^d &), pointer type_recv_srl
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.
logical lb_diagnose
Per-rank load-balance timing diagnostic toggle (off by default). When .true., per-rank wall times are...
integer, parameter unitpar
file handle for IO
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, parameter ndim
Number of spatial dimensions for grid variables.
logical stagger_grid
True for using stagger grid.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer icomm
The MPI communicator.
logical coarsenprimitive
coarsen primitive variables in level-jump ghost cells
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, dimension(:), allocatable, parameter d
logical lb_automatic
Cost-weighted automatic load balancer toggle (off by default). When .true., the SFC partitioner cuts ...
logical time_advance
do time evolving
logical prolongprimitive
prolongate primitive variables in level-jump ghost cells
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision, dimension(:,:), allocatable dx
spatial steps for all dimensions at all levels
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition mod_physics.t:4
logical phys_total_energy
Solve total energy equation or not.
Definition mod_physics.t:40
procedure(sub_face_to_center), pointer phys_face_to_center
Definition mod_physics.t:87
Module for handling problematic values in simulations, such as negative pressures.
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...
pure logical function, public is_sts_initialized()
integer, parameter, public sourcetype_sts_prior
logical function, public set_dt_sts_ncycles(my_dt)
This sets the explicit dt and calculates the number of cycles for each of the terms implemented with ...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
type(sts_term), pointer head_sts_terms
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
integer, parameter, public sourcetype_sts_split
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
integer, parameter, public sourcetype_sts_after
procedure(subr3), pointer, public sts_add_source