11from devito .types import Eq , Function , TimeFunction
22
33
4- def superstep_generator_iterative (field , stencil , k ):
4+ def superstep_generator_iterative (field , stencil , k , tn = 0 ):
55 ''' Generate superstep iteratively:
66 A^j+1 = A·A^j
77 '''
@@ -11,6 +11,8 @@ def superstep_generator_iterative(field, stencil, k):
1111 u = TimeFunction (name = f'{ name } _ss' , grid = grid , time_order = 2 , space_order = 2 * k )
1212 u_prev = TimeFunction (name = f'{ name } _ss_p' , grid = grid , time_order = 2 , space_order = 2 * k )
1313
14+ superstep_solution_transfer (field , u , u_prev , tn )
15+
1416 # Substitute new fields into stencil
1517 ss_stencil = stencil .subs ({field : u , field .backward : u_prev }, postprocess = False )
1618 ss_stencil = ss_stencil .expand ().expand (add = True , nest = True )
@@ -38,7 +40,7 @@ def superstep_generator_iterative(field, stencil, k):
3840 return u , u_prev , Eq (u .forward , stencil_next ), Eq (u_prev .forward , current )
3941
4042
41- def superstep_generator (field , stencil , k ):
43+ def superstep_generator (field , stencil , k , tn = 0 ):
4244 ''' Generate superstep using a binary decomposition:
4345 A^k = a_j A^2^j + ... + a_2 A^2^2 + a_1 A² + a_0 A
4446 '''
@@ -48,6 +50,8 @@ def superstep_generator(field, stencil, k):
4850 u = TimeFunction (name = f'{ name } _ss' , grid = grid , time_order = 2 , space_order = 2 * k )
4951 u_prev = TimeFunction (name = f'{ name } _ss_p' , grid = grid , time_order = 2 , space_order = 2 * k )
5052
53+ superstep_solution_transfer (field , u , u_prev , tn )
54+
5155 # Substitute new fields into stencil
5256 ss_stencil = stencil .subs ({field : u , field .backward : u_prev }, postprocess = False )
5357 ss_stencil = ss_stencil .expand ().expand (add = True , nest = True )
@@ -58,13 +62,25 @@ def superstep_generator(field, stencil, k):
5862 accumulate = current if r else (1 , 1 )
5963 while q :
6064 q , r = divmod (q , 2 )
61- current = combine_superstep (current , current , u , u_prev , k )
65+ current = _combine_superstep (current , current , u , u_prev , k )
6266 if r :
63- accumulate = combine_superstep (accumulate , current , u , u_prev , k )
67+ accumulate = _combine_superstep (accumulate , current , u , u_prev , k )
6468
6569 return u , u_prev , Eq (u .forward , accumulate [0 ]), Eq (u_prev .forward , accumulate [1 ])
6670
67- def combine_superstep (stencil_a , stencil_b , u , u_prev , k ):
71+
72+ def superstep_solution_transfer (old , new , new_p , tn ):
73+ ''' Transfer the timesteps from a previous simulation to a 2 field superstep simulation
74+ Used after injecting source using standard timestepping.
75+ '''
76+ idx = tn % 3 if old .save is None else - 1
77+ new .data [0 , :] = old .data [idx - 1 ]
78+ new .data [1 , :] = old .data [idx ]
79+ new_p .data [0 , :] = old .data [idx - 2 ]
80+ new_p .data [1 , :] = old .data [idx - 1 ]
81+
82+
83+ def _combine_superstep (stencil_a , stencil_b , u , u_prev , k ):
6884 ''' Combine two arbitrary order supersteps
6985 '''
7086 # Placeholder fields for forming the superstep
0 commit comments