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