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 ! get_bc_comm_type frees the previous committed type before rebuilding, so every
261 ! handle must start as a null datatype rather than whatever the allocation left.
262 temp%type_send_srl_sts_1=mpi_datatype_null; temp%type_recv_srl_sts_1=mpi_datatype_null
263 temp%type_send_r_sts_1 =mpi_datatype_null; temp%type_recv_r_sts_1 =mpi_datatype_null
264 temp%type_send_p_sts_1 =mpi_datatype_null; temp%type_recv_p_sts_1 =mpi_datatype_null
265 temp%type_send_srl_sts_2=mpi_datatype_null; temp%type_recv_srl_sts_2=mpi_datatype_null
266 temp%type_send_r_sts_2 =mpi_datatype_null; temp%type_recv_r_sts_2 =mpi_datatype_null
267 temp%type_send_p_sts_2 =mpi_datatype_null; temp%type_recv_p_sts_2 =mpi_datatype_null
268
269 temp%next => head_sts_terms
270 head_sts_terms => temp
271
272 end subroutine add_sts_method
273
274 !> Set the hooks called before the first cycle and after the last cycle in the STS update
275 !> This method should be called after add_sts_method. The hooks are added to the last term added with this subroutine
276 !> Params: sts_before_first_cycle, sts_after_last_cycle subroutines which implement the hooks called before first cycle and after last cycle
277 subroutine set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
278 interface
279 subroutine sts_before_first_cycle(ixI^L, ixO^L, w, x)
281 integer, intent(in) :: ixi^l, ixo^l
282 double precision, intent(in) :: x(ixi^s,1:ndim)
283 double precision, intent(inout) :: w(ixi^s,1:nw)
284 end subroutine sts_before_first_cycle
285
286 subroutine sts_after_last_cycle(ixI^L, ixO^L, w, x)
288 integer, intent(in) :: ixi^l, ixo^l
289 double precision, intent(in) :: x(ixi^s,1:ndim)
290 double precision, intent(inout) :: w(ixi^s,1:nw)
291 end subroutine sts_after_last_cycle
292 end interface
293
294 head_sts_terms%sts_before_first_cycle => sts_before_first_cycle
295 head_sts_terms%sts_after_last_cycle => sts_after_last_cycle
296
297 end subroutine set_conversion_methods_to_head
298
299 !> Set the hook of error handling in the STS update. This method is called before updating the BC.
300 !> This method should be called after add_sts_method. The hook is added to the last term added with this subroutine.
301 !> Param: sts_error_handing the subroutine which handles the errors
302 subroutine set_error_handling_to_head(sts_error_handling)
303 interface
304 subroutine sts_error_handling(w, x, ixI^L, ixO^L, step)
307 integer, intent(in) :: ixi^l,ixo^l
308 double precision, intent(inout) :: w(ixi^s,1:nw)
309 double precision, intent(in) :: x(ixi^s,1:ndim)
310 integer, intent(in) :: step
311 end subroutine sts_error_handling
312 end interface
313 head_sts_terms%sts_handle_errors => sts_error_handling
314
315 end subroutine set_error_handling_to_head
316
317 !> method used to set the number of cycles for the STS1 method
318 function sts_get_ncycles1(dt,dtnew,dt_modified) result(is)
319 double precision,intent(in) :: dtnew
320 double precision,intent(inout) :: dt
321 logical,intent(inout) :: dt_modified
322 integer :: is
323
324 double precision :: ss
325
326 !!ss is now limit of dt because of sts_ncycles
327 ss = dtnew*((2.d0*sts_ncycles+1)**2-9.d0)/16.d0
328 if(dt>ss) then
329 dt_modified = .true.
330 dt = ss
331 is = sts_ncycles
332 else
333 ss = dt/dtnew
334 ! get number of sub-steps of supertime stepping (Meyer 2012 MNRAS 422,2102)
335 if(ss .le. 1.d0) then
336 is=1
337 else
338 is=ceiling((dsqrt(9.d0+16.d0*ss)-1.d0)*0.5d0)
339 is=is/2*2+1
340 end if
341 end if
342
343 end function sts_get_ncycles1
344
345 !> method used to set the number of cycles for the STS2 method
346 function sts_get_ncycles2(dt,dtnew,dt_modified) result(is)
347 double precision,intent(in) :: dtnew
348 double precision,intent(inout) :: dt
349 logical,intent(inout) :: dt_modified
350 integer :: is
351
352 double precision :: ss,rr
353 integer:: ncycles
354
355 rr = dt/dtnew
356 !print*, dt, " --DTEXPL-- ", dtnew, ", rr ",rr
357 ncycles = sts_ncycles
358 !print*, "NCYCLES BEFORE ",ncycles
359 ss=sum_chev(nu_sts,ncycles,rr)
360 !print*, "NCYCLES AFTER ",ncycles
361 is = ncycles
362 !print*, "SUMCHEV ", ss, " NCYCLES ", is
363 if(ss < rr) then
364 dt_modified = .true.
365 dt = ss * dtnew
366 endif
367
368 end function sts_get_ncycles2
369
370 !> This sets the explicit dt and calculates the number of cycles for each of the terms implemented with STS.
371 function set_dt_sts_ncycles(my_dt) result(dt_modified)
373
374 double precision,intent(inout) :: my_dt
375 double precision :: my_dt1
376 logical :: dt_modified, dt_modified1, dt_modified2
377
378 double precision :: dtnew,dtmin_mype
379 double precision :: dx^d, ss
380 integer:: iigrid, igrid, ncycles
381 type(sts_term), pointer :: temp,oldtemp
382 nullify(oldtemp)
383 temp => head_sts_terms
384 dt_modified = .false.
385 do while(associated(temp))
386 dt_modified2 = .false.
387 dtmin_mype=bigdouble
388 !$OMP PARALLEL DO PRIVATE(igrid,dx^D) REDUCTION(min:dtmin_mype)
389 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
390 ! maybe the following global variables are needed in get_dt!
391 ! next few lines ensure correct usage of routines like divvector etc
392 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
393 block=>ps(igrid)
394 ! end maybe the following global variables are needed in get_dt!!!!!!!
395 dx^d=rnode(rpdx^d_,igrid);
396 dtmin_mype=min(dtmin_mype, sts_dtpar * temp%sts_getdt(ps(igrid)%w,ixg^ll,ixm^ll,dx^d,ps(igrid)%x))
397 end do
398 !$OMP END PARALLEL DO
399 call mpi_allreduce(dtmin_mype,dtnew,1,mpi_double_precision,mpi_min,icomm,ierrmpi)
400 temp%s = sts_get_ncycles(my_dt,dtnew,dt_modified2)
401
402 !print*, "NCYCLES ", temp%s, dt_modified2, my_dt, dtnew
403 temp%dt_expl = dtnew
404
405 ! Note that as for some term it may happen that the dt is modified: it may be reduced if the
406 ! number of cycles is overpassed, the list has to be reiterated to update ncycles for previous
407 ! terms which did not modify dt TODO add pointer to previous and loop backward to update
408 if(dt_modified2) then
409 dt_modified = .true.
410 !reiterate all the other sts elements and recalculate s
411 oldtemp => head_sts_terms
412 my_dt1 = my_dt
413 dt_modified1 = .false.
414 do while(.not. associated(oldtemp,temp))
415 oldtemp%s = sts_get_ncycles(my_dt1,oldtemp%dt_expl,dt_modified1)
416 !check dt is not modified again, and this should not happen, except for bug in sts_get_ncycles1,2
417 if(dt_modified1) call mpistop("sts dt modified twice")
418 oldtemp=>oldtemp%next
419 end do
420 end if
421 temp=>temp%next
422
423 end do
424
425 end function set_dt_sts_ncycles
426
427 pure FUNCTION chev(j,nu,N)
428 use mod_constants
429
430 double precision, INTENT(IN) :: nu
431 INTEGER, INTENT(IN) :: j, n
432 double precision :: chev
433
434 chev = 1d0 / ((-1d0 + nu)*cos(((2d0*j - 1d0) / n)* (dpi/2d0)) + 1d0 + nu)
435
436 END FUNCTION chev
437
438 FUNCTION sum_chev(nu,N,limMax)
439 double precision, intent(in) :: nu,limmax
440 integer, intent(inout) :: n
441 double precision :: sum_chev, tmp
442
443 integer :: j
444
445 j=1
446 sum_chev = 0d0
447 do while (j < n .and. sum_chev < limmax)
448 sum_chev = sum_chev + chev(j,nu,n)
449 j=j+1
450 enddo
451 n=j-1
452 END FUNCTION sum_chev
453
454 !> Iterates all the terms implemented with STS and adds the sources
455 !> STS method 2 implementation
456 subroutine sts_add_source2(my_dt)
457 ! Turlough Downes 2006,2007
461 use mod_physics
462
463 double precision, intent(in) :: my_dt
464 double precision, allocatable :: bj(:)
465 double precision :: sumbj,dtj
466
467 integer:: iigrid, igrid, j, ixc^l
468 logical :: stagger_flag=.false., prolong_flag=.false., coarsen_flag=.false.
469 type(sts_term), pointer :: temp
470
471 ! do not fill physical boundary conditions
472 bcphys=.false.
473
474 fix_conserve_at_step = time_advance .and. levmax>levmin
475
476 temp => head_sts_terms
477 do while(associated(temp))
478
479 if(.not.temp%evolve_magnetic_field) then
480 ! not do fix conserve and getbc for staggered values
481 stagger_flag=stagger_grid
482 stagger_grid=.false.
483 else if(stagger_grid) then
484 ixcmax^d=ixmhi^d;
485 ixcmin^d=ixmlo^d-1;
486 end if
487
488 call init_comm_fix_conserve(1,ndim,temp%nflux)
489
490 if(associated(temp%sts_before_first_cycle)) then
491 prolong_flag=prolongprimitive
492 coarsen_flag=coarsenprimitive
493 prolongprimitive=.false.
494 coarsenprimitive=.false.
495 do iigrid=1,igridstail; igrid=igrids(iigrid);
496 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
497 block=>ps(igrid)
498 call temp%sts_before_first_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
499 end do
500 end if
501
502 allocate(bj(1:temp%s))
503 do j=1,temp%s
504 bj(j) = chev(j,nu_sts,sts_ncycles)
505 end do
506
507 type_send_srl=>temp%type_send_srl_sts_1
508 type_recv_srl=>temp%type_recv_srl_sts_1
509 type_send_r=>temp%type_send_r_sts_1
510 type_recv_r=>temp%type_recv_r_sts_1
511 type_send_p=>temp%type_send_p_sts_1
512 type_recv_p=>temp%type_recv_p_sts_1
513
514 if(.not. temp%types_initialized) then
515 call create_bc_mpi_datatype(temp%startwbc,temp%nwbc)
516 if(temp%nflux>temp%nwbc) then
517 ! prepare types for the changed no-need-ghost-update variables in the last getbc
518 type_send_srl=>temp%type_send_srl_sts_2
519 type_recv_srl=>temp%type_recv_srl_sts_2
520 type_send_r=>temp%type_send_r_sts_2
521 type_recv_r=>temp%type_recv_r_sts_2
522 type_send_p=>temp%type_send_p_sts_2
523 type_recv_p=>temp%type_recv_p_sts_2
524 call create_bc_mpi_datatype(temp%startVar,temp%nflux)
525 type_send_srl=>temp%type_send_srl_sts_1
526 type_recv_srl=>temp%type_recv_srl_sts_1
527 type_send_r=>temp%type_send_r_sts_1
528 type_recv_r=>temp%type_recv_r_sts_1
529 type_send_p=>temp%type_send_p_sts_1
530 type_recv_p=>temp%type_recv_p_sts_1
531 end if
532 temp%types_initialized = .true.
533 end if
534
535 sumbj=0.d0
536 do j=1,temp%s
537 if(j .eq. temp%s .and. (sumbj + bj(j)) * temp%dt_expl > my_dt) then
538 dtj = my_dt - sumbj * temp%dt_expl
539 else
540 dtj = bj(j)* temp%dt_expl
541 end if
542 sumbj = sumbj + bj(j)
543 if(stagger_grid) then
544 !$OMP PARALLEL DO PRIVATE(igrid)
545 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
546 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
547 block=>ps(igrid)
548 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)
549 if(temp%nflux>ndir) then
550 ps(igrid)%w(ixm^t,temp%startVar)=ps(igrid)%w(ixm^t,temp%startVar)+dtj*ps1(igrid)%w(ixm^t,temp%startVar)
551 end if
552 ps(igrid)%ws(ixc^s,1:nws)=ps(igrid)%ws(ixc^s,1:nws)+dtj*ps1(igrid)%w(ixc^s,iw_mag(1:nws))
553 call phys_face_to_center(ixm^ll,ps(igrid))
554 end do
555 !$OMP END PARALLEL DO
556 else
557 !$OMP PARALLEL DO PRIVATE(igrid)
558 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
559 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
560 block=>ps(igrid)
561 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)
562 ps(igrid)%w(ixm^t,temp%startVar:temp%endVar)=ps(igrid)%w(ixm^t,temp%startVar:temp%endVar)+&
563 dtj*ps1(igrid)%w(ixm^t,temp%startVar:temp%endVar)
564 end do
565 !$OMP END PARALLEL DO
566 end if
567 !fix conserve the fluxes set in the STS method
568 if(fix_conserve_at_step) then
569 call recvflux(1,ndim)
570 call sendflux(1,ndim)
571 call fix_conserve(ps,1,ndim,temp%startVar,temp%nflux)
572 if(stagger_grid) then
573 call fix_edges(ps,1,ndim)
574 ! fill the cell-center values from the updated staggered variables
575 !$OMP PARALLEL DO PRIVATE(igrid)
576 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
577 call phys_face_to_center(ixg^ll,ps(igrid))
578 end do
579 !$OMP END PARALLEL DO
580 end if
581 end if
582 if(associated(temp%sts_handle_errors)) then
583 !$OMP PARALLEL DO PRIVATE(igrid)
584 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
585 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
586 block=>ps(igrid)
587 call temp%sts_handle_errors(ps(igrid)%w,ps(igrid)%x,ixg^ll,ixm^ll,j)
588 end do
589 !$OMP END PARALLEL DO
590 end if
591
592 if(temp%nflux>temp%nwbc.and.temp%s==j) then
593 ! include the changed no-need-ghost-update variables in the last getbc
594 type_send_srl=>temp%type_send_srl_sts_2
595 type_recv_srl=>temp%type_recv_srl_sts_2
596 type_send_r=>temp%type_send_r_sts_2
597 type_recv_r=>temp%type_recv_r_sts_2
598 type_send_p=>temp%type_send_p_sts_2
599 type_recv_p=>temp%type_recv_p_sts_2
600 call getbc(global_time,0.d0,ps,temp%startVar,temp%nflux)
601 else
602 call getbc(global_time,0.d0,ps,temp%startwbc,temp%nwbc)
603 end if
604 end do
605
606 if(associated(temp%sts_after_last_cycle)) then
607 do iigrid=1,igridstail; igrid=igrids(iigrid);
608 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
609 block=>ps(igrid)
610 call temp%sts_after_last_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
611 end do
612 prolongprimitive = prolong_flag
613 coarsenprimitive = coarsen_flag
614 end if
615 deallocate(bj)
616
617 if(.not.temp%evolve_magnetic_field) then
618 ! restore stagger_grid value
619 stagger_grid=stagger_flag
620 end if
621
622 temp=>temp%next
623 end do
624
625 if(associated(head_sts_terms)) then
626 ! point bc mpi data type back to full type for (M)HD
633 end if
634
635 bcphys=.true.
636
637 if(eos%eos_type == 'PI') then
638 ! update temperature variable in w
639 !$OMP PARALLEL DO PRIVATE(igrid)
640 do iigrid=1,igridstail; igrid=igrids(iigrid);
641 call eos%update_eos(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
642 end do
643 !$OMP END PARALLEL DO
644 end if
645
646 end subroutine sts_add_source2
647
648 !> Iterates all the terms implemented with STS and adds the sources
649 !> STS method 1 implementation
650 subroutine sts_add_source1(my_dt)
651 ! Meyer 2012 MNRAS 422,2102
655 use mod_physics
657
658 double precision, intent(in) :: my_dt
659 double precision :: dtj
660 double precision :: omega1,cmu,cmut,cnu,cnut,one_mu_nu
661 double precision, allocatable :: bj(:)
662 integer:: iigrid, igrid, j, ixc^l, ixgext^l
663 double precision :: lb_t0_tc, lb_t0_block
664 logical :: evenstep, stagger_flag=.false., prolong_flag=.false., coarsen_flag=.false., total_energy_flag=.true.
665 type(sts_term), pointer :: temp
666 type(state), dimension(:), pointer :: tmpps1, tmpps2
667
668 ! do not fill physical boundary conditions
669 bcphys=.false.
670
671 fix_conserve_at_step = time_advance .and. levmax>levmin
672
673 temp => head_sts_terms
674 do while(associated(temp))
675
676 if(.not.temp%evolve_magnetic_field) then
677 ! not do fix conserve and getbc for staggered values
678 stagger_flag=stagger_grid
679 stagger_grid=.false.
680 else if(stagger_grid) then
681 ixcmax^d=ixmhi^d;
682 ixcmin^d=ixmlo^d-1;
683 end if
684
685 call init_comm_fix_conserve(1,ndim,temp%nflux)
686
687 if(associated(temp%sts_before_first_cycle)) then
688 prolong_flag = prolongprimitive
689 coarsen_flag = coarsenprimitive
690 prolongprimitive = .false.
691 coarsenprimitive = .false.
692 total_energy_flag=phys_total_energy
693 phys_total_energy=.false.
694 !$OMP PARALLEL DO PRIVATE(igrid)
695 do iigrid=1,igridstail; igrid=igrids(iigrid);
696 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
697 block=>ps(igrid)
698 call temp%sts_before_first_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
699 if(.not. allocated(ps2(igrid)%w)) allocate(ps2(igrid)%w(ixg^t,1:nw))
700 if(.not. allocated(ps3(igrid)%w)) allocate(ps3(igrid)%w(ixg^t,1:nw))
701 if(.not. allocated(ps4(igrid)%w)) allocate(ps4(igrid)%w(ixg^t,1:nw))
702 ps1(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
703 ps2(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
704 end do
705 !$OMP END PARALLEL DO
706 else
707 if(stagger_grid) then
708 ixgext^l=ixg^ll^ladd1;
709 !$OMP PARALLEL DO PRIVATE(igrid)
710 do iigrid=1,igridstail; igrid=igrids(iigrid);
711 if(.not. allocated(ps2(igrid)%w)) then
712 call alloc_state(igrid, ps2(igrid), ixg^ll, ixgext^l, .false.)
713 end if
714 if(.not. allocated(ps3(igrid)%w)) allocate(ps3(igrid)%w(ixg^t,1:nw))
715 if(.not. allocated(ps4(igrid)%w)) allocate(ps4(igrid)%w(ixg^t,1:nw))
716 ps1(igrid)%w=ps(igrid)%w
717 ps2(igrid)%w=ps(igrid)%w
718 ps1(igrid)%ws=ps(igrid)%ws
719 ps2(igrid)%ws=ps(igrid)%ws
720 end do
721 !$OMP END PARALLEL DO
722 else
723 !$OMP PARALLEL DO PRIVATE(igrid)
724 do iigrid=1,igridstail; igrid=igrids(iigrid);
725 if(.not. allocated(ps2(igrid)%w)) allocate(ps2(igrid)%w(ixg^t,1:nw))
726 if(.not. allocated(ps3(igrid)%w)) allocate(ps3(igrid)%w(ixg^t,1:nw))
727 if(.not. allocated(ps4(igrid)%w)) allocate(ps4(igrid)%w(ixg^t,1:nw))
728 ps1(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
729 ps2(igrid)%w(ixg^t,1:nw)=ps(igrid)%w(ixg^t,1:nw)
730 end do
731 !$OMP END PARALLEL DO
732 end if
733 end if
734
735 allocate(bj(0:temp%s))
736 bj(0)=1.d0/3.d0
737 bj(1)=bj(0)
738 if(temp%s>1) then
739 omega1=4.d0/dble(temp%s**2+temp%s-2)
740 cmut=omega1/3.d0
741 else
742 omega1=0.d0
743 cmut=1.d0
744 end if
745
746 type_send_srl=>temp%type_send_srl_sts_1
747 type_recv_srl=>temp%type_recv_srl_sts_1
748 type_send_r=>temp%type_send_r_sts_1
749 type_recv_r=>temp%type_recv_r_sts_1
750 type_send_p=>temp%type_send_p_sts_1
751 type_recv_p=>temp%type_recv_p_sts_1
752
753 if(.not. temp%types_initialized) then
754 call create_bc_mpi_datatype(temp%startwbc,temp%nwbc)
755 if(temp%nflux>temp%nwbc) then
756 ! prepare types for the changed no-need-ghost-update variables in the last getbc
757 type_send_srl=>temp%type_send_srl_sts_2
758 type_recv_srl=>temp%type_recv_srl_sts_2
759 type_send_r=>temp%type_send_r_sts_2
760 type_recv_r=>temp%type_recv_r_sts_2
761 type_send_p=>temp%type_send_p_sts_2
762 type_recv_p=>temp%type_recv_p_sts_2
763 call create_bc_mpi_datatype(temp%startVar,temp%nflux)
764 type_send_srl=>temp%type_send_srl_sts_1
765 type_recv_srl=>temp%type_recv_srl_sts_1
766 type_send_r=>temp%type_send_r_sts_1
767 type_recv_r=>temp%type_recv_r_sts_1
768 type_send_p=>temp%type_send_p_sts_1
769 type_recv_p=>temp%type_recv_p_sts_1
770 end if
771 temp%types_initialized = .true.
772 end if
773 dtj = cmut*my_dt
774 if (lb_diagnose) lb_t0_tc = mpi_wtime()
775 if(stagger_grid) then
776 !$OMP PARALLEL DO PRIVATE(igrid,lb_t0_block)
777 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
778 if (lb_automatic) lb_t0_block = mpi_wtime()
779 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
780 block=>ps(igrid)
781 ps4(igrid)%w=zero
782 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)
783 !!!eq solved: dU/dt = S, ps3 is stored S^n
784 ps3(igrid)%w(ixc^s,temp%startVar:temp%endVar) = my_dt * ps4(igrid)%w(ixc^s,temp%startVar:temp%endVar)
785 if(temp%nflux>ndir) then
786 ps1(igrid)%w(ixm^t,temp%startVar) = ps1(igrid)%w(ixm^t,temp%startVar) + cmut * ps3(igrid)%w(ixm^t,temp%startVar)
787 end if
788 ps1(igrid)%ws(ixc^s,1:nws) = ps1(igrid)%ws(ixc^s,1:nws) + cmut * ps3(igrid)%w(ixc^s,iw_mag(1:nws))
789 call phys_face_to_center(ixm^ll,ps1(igrid))
790 if (lb_automatic) block_cost(igrid) = block_cost(igrid) + (mpi_wtime() - lb_t0_block)
791 end do
792 !$OMP END PARALLEL DO
793 else
794 !$OMP PARALLEL DO PRIVATE(igrid,lb_t0_block)
795 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
796 if (lb_automatic) lb_t0_block = mpi_wtime()
797 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
798 block=>ps(igrid)
799 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)
800 !!!eq solved: dU/dt = S, ps3 is stored S^n
801 ps3(igrid)%w(ixm^t,temp%startVar:temp%endVar) = my_dt * ps4(igrid)%w(ixm^t,temp%startVar:temp%endVar)
802 ps1(igrid)%w(ixm^t,temp%startVar:temp%endVar) = ps1(igrid)%w(ixm^t,temp%startVar:temp%endVar) + &
803 cmut * ps3(igrid)%w(ixm^t,temp%startVar:temp%endVar)
804 if (lb_automatic) block_cost(igrid) = block_cost(igrid) + (mpi_wtime() - lb_t0_block)
805 end do
806 !$OMP END PARALLEL DO
807 end if
808 if (lb_diagnose) lb_tc_accum = lb_tc_accum + (mpi_wtime() - lb_t0_tc)
809 if(fix_conserve_at_step) then
810 call recvflux(1,ndim)
811 call sendflux(1,ndim)
812 call fix_conserve(ps1,1,ndim,temp%startVar,temp%nflux)
813 if(stagger_grid) then
814 call fix_edges(ps1,1,ndim)
815 ! fill the cell-center values from the updated staggered variables
816 !$OMP PARALLEL DO PRIVATE(igrid)
817 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
818 call phys_face_to_center(ixg^ll,ps1(igrid))
819 end do
820 !$OMP END PARALLEL DO
821 end if
822 end if
823 ! fix conservation of AMR grid by replacing flux from finer neighbors
824 if(associated(temp%sts_handle_errors)) then
825 !$OMP PARALLEL DO PRIVATE(igrid)
826 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
827 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
828 block=>ps(igrid)
829 call temp%sts_handle_errors(ps1(igrid)%w,ps1(igrid)%x,ixg^ll,ixm^ll,1)
830 end do
831 !$OMP END PARALLEL DO
832 end if
833 if(temp%nflux>temp%nwbc.and.temp%s==1) then
834 ! include the changed no-need-ghost-update variables in the last getbc
835 type_send_srl=>temp%type_send_srl_sts_2
836 type_recv_srl=>temp%type_recv_srl_sts_2
837 type_send_r=>temp%type_send_r_sts_2
838 type_recv_r=>temp%type_recv_r_sts_2
839 type_send_p=>temp%type_send_p_sts_2
840 type_recv_p=>temp%type_recv_p_sts_2
841 call getbc(global_time,0.d0,ps1,temp%startVar,temp%nflux)
842 else
843 call getbc(global_time,0.d0,ps1,temp%startwbc,temp%nwbc)
844 end if
845 !!first step end
846
847 evenstep=.true.
848
849 tmpps2=>ps1
850
851 do j=2,temp%s
852 bj(j)=dble(j**2+j-2)/dble(2*j*(j+1))
853 cmu=dble(2*j-1)/dble(j)*bj(j)/bj(j-1)
854 cmut=omega1*cmu
855 cnu=dble(1-j)/dble(j)*bj(j)/bj(j-2)
856 cnut=(bj(j-1)-1.d0)*cmut
857 one_mu_nu=1.d0-cmu-cnu
858 if(evenstep) then
859 tmpps1=>ps1
860 tmpps2=>ps2
861 else
862 tmpps1=>ps2
863 tmpps2=>ps1
864 end if
865
866 dtj = cmut*my_dt
867 if (lb_diagnose) lb_t0_tc = mpi_wtime()
868 if(stagger_grid) then
869 !$OMP PARALLEL DO PRIVATE(igrid)
870 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
871 ! maybe the following global variables are needed in set_sources
872 ! next few lines ensure correct usage of routines like divvector etc
873 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
874 block=>ps(igrid)
875 ! end maybe the following global variables are needed in set_sources
876 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)
877 if(temp%nflux>ndir) then
878 tmpps2(igrid)%w(ixm^t,temp%startVar)=cmu*tmpps1(igrid)%w(ixm^t,temp%startVar)+&
879 cnu*tmpps2(igrid)%w(ixm^t,temp%startVar)+one_mu_nu*ps(igrid)%w(ixm^t,temp%startVar)+&
880 dtj*ps4(igrid)%w(ixm^t,temp%startVar)+cnut*ps3(igrid)%w(ixm^t,temp%startVar)
881 end if
882 tmpps2(igrid)%ws(ixc^s,1:nws)=cmu*tmpps1(igrid)%ws(ixc^s,1:nws)+&
883 cnu*tmpps2(igrid)%ws(ixc^s,1:nws)+one_mu_nu*ps(igrid)%ws(ixc^s,1:nws)+&
884 dtj*ps4(igrid)%w(ixc^s,iw_mag(1:nws))+cnut*ps3(igrid)%w(ixc^s,iw_mag(1:nws))
885 call phys_face_to_center(ixm^ll,tmpps2(igrid))
886 end do
887 !$OMP END PARALLEL DO
888 else
889 !$OMP PARALLEL DO PRIVATE(igrid)
890 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
891 ! maybe the following global variables are needed in set_sources
892 ! next few lines ensure correct usage of routines like divvector etc
893 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
894 block=>ps(igrid)
895 ! end maybe the following global variables are needed in set_sources
896 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)
897 tmpps2(igrid)%w(ixm^t,temp%startVar:temp%endVar)=cmu*tmpps1(igrid)%w(ixm^t,temp%startVar:temp%endVar)+&
898 cnu*tmpps2(igrid)%w(ixm^t,temp%startVar:temp%endVar)+one_mu_nu*ps(igrid)%w(ixm^t,temp%startVar:temp%endVar)+&
899 dtj*ps4(igrid)%w(ixm^t,temp%startVar:temp%endVar)+cnut*ps3(igrid)%w(ixm^t,temp%startVar:temp%endVar)
900 end do
901 !$OMP END PARALLEL DO
902 end if
903 if (lb_diagnose) lb_tc_accum = lb_tc_accum + (mpi_wtime() - lb_t0_tc)
904 if(fix_conserve_at_step) then
905 call recvflux(1,ndim)
906 call sendflux(1,ndim)
907 call fix_conserve(tmpps2,1,ndim,temp%startVar,temp%nflux)
908 if(stagger_grid) then
909 call fix_edges(tmpps2,1,ndim)
910 ! fill the cell-center values from the updated staggered variables
911 !$OMP PARALLEL DO PRIVATE(igrid)
912 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
913 call phys_face_to_center(ixg^ll,tmpps2(igrid))
914 end do
915 !$OMP END PARALLEL DO
916 end if
917 end if
918 if(associated(temp%sts_handle_errors)) then
919 !$OMP PARALLEL DO PRIVATE(igrid)
920 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
921 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
922 block=>ps(igrid)
923 call temp%sts_handle_errors(tmpps2(igrid)%w,ps(igrid)%x,ixg^ll,ixm^ll,j)
924 end do
925 !$OMP END PARALLEL DO
926 end if
927
928 if(temp%nflux>temp%nwbc.and.temp%s==j) then
929 ! include the changed no-need-ghost-update variables in the last getbc
930 type_send_srl=>temp%type_send_srl_sts_2
931 type_recv_srl=>temp%type_recv_srl_sts_2
932 type_send_r=>temp%type_send_r_sts_2
933 type_recv_r=>temp%type_recv_r_sts_2
934 type_send_p=>temp%type_send_p_sts_2
935 type_recv_p=>temp%type_recv_p_sts_2
936 call getbc(global_time,0.d0,tmpps2,temp%startVar,temp%nflux)
937 else
938 call getbc(global_time,0.d0,tmpps2,temp%startwbc,temp%nwbc)
939 end if
940 evenstep=.not.evenstep
941 end do
942
943 if(associated(temp%sts_after_last_cycle)) then
944 if (lb_diagnose) lb_t0_tc = mpi_wtime()
945 !$OMP PARALLEL DO PRIVATE(igrid)
946 do iigrid=1,igridstail; igrid=igrids(iigrid);
947 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
948 block=>ps(igrid)
949 ps(igrid)%w(ixg^t,temp%startVar:temp%endVar)=tmpps2(igrid)%w(ixg^t,temp%startVar:temp%endVar)
950 call temp%sts_after_last_cycle(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
951 end do
952 !$OMP END PARALLEL DO
953 if (lb_diagnose) lb_tc_accum = lb_tc_accum + (mpi_wtime() - lb_t0_tc)
954 phys_total_energy=total_energy_flag
955 prolongprimitive = prolong_flag
956 coarsenprimitive = coarsen_flag
957 else
958 if(stagger_grid) then
959 !$OMP PARALLEL DO PRIVATE(igrid)
960 do iigrid=1,igridstail; igrid=igrids(iigrid);
961 ps(igrid)%w(ixg^t,temp%startVar:temp%endVar)=tmpps2(igrid)%w(ixg^t,temp%startVar:temp%endVar)
962 ps(igrid)%ws=tmpps2(igrid)%ws
963 end do
964 !$OMP END PARALLEL DO
965 else
966 !$OMP PARALLEL DO PRIVATE(igrid)
967 do iigrid=1,igridstail; igrid=igrids(iigrid);
968 ps(igrid)%w(ixg^t,temp%startVar:temp%endVar)=tmpps2(igrid)%w(ixg^t,temp%startVar:temp%endVar)
969 end do
970 !$OMP END PARALLEL DO
971 end if
972 end if
973
974 deallocate(bj)
975
976 if(.not.temp%evolve_magnetic_field) then
977 ! restore stagger_grid value
978 stagger_grid=stagger_flag
979 end if
980
981 temp=>temp%next
982 end do
983
984 if(associated(head_sts_terms)) then
985 ! point bc mpi data type back to full type for (M)HD
992 end if
993
994 bcphys=.true.
995
996 if(eos%eos_type == 'PI') then
997 ! update temperature variable in w
998 !$OMP PARALLEL DO PRIVATE(igrid)
999 do iigrid=1,igridstail; igrid=igrids(iigrid);
1000 call eos%update_eos(ixg^ll,ixg^ll,ps(igrid)%w,ps(igrid)%x)
1001 end do
1002 !$OMP END PARALLEL DO
1003 end if
1004
1005 end subroutine sts_add_source1
1006
1007end 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
subroutine create_bc_mpi_datatype(nwstart, nwbc, nwfull)
integer, dimension( :^d &), pointer type_send_p
integer, dimension( :^d &), pointer type_send_srl
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