11from devito .types import Eq , Function , TimeFunction
22
33
4- def superstep_generator_iterative (field , stencil , k , tn = 0 ):
5- ''' Generate superstep iteratively:
4+ def superstep_generator_iterative (field , stencil , k , nt = 0 ):
5+ """
6+ Generate superstep iteratively:
67 Aʲ⁺¹ = A·Aʲ
7- '''
8+ """
89 # New fields, for vector formulation both current and previous timestep are needed
910 name = field .name
1011 grid = field .grid
1112 u = TimeFunction (name = f'{ name } _ss' , grid = grid , time_order = 2 , space_order = 2 * k )
1213 u_prev = TimeFunction (name = f'{ name } _ss_p' , grid = grid , time_order = 2 , space_order = 2 * k )
1314
14- superstep_solution_transfer (field , u , u_prev , tn )
15+ superstep_solution_transfer (field , u , u_prev , nt )
1516
1617 # Substitute new fields into stencil
1718 ss_stencil = stencil .subs ({field : u , field .backward : u_prev }, postprocess = False )
@@ -40,25 +41,27 @@ def superstep_generator_iterative(field, stencil, k, tn=0):
4041 return u , u_prev , Eq (u .forward , stencil_next ), Eq (u_prev .forward , current )
4142
4243
43- def superstep_generator (field , stencil , k , tn = 0 ):
44- ''' Generate superstep using a binary decomposition:
44+ def superstep_generator (field , stencil , k , nt = 0 ):
45+ """
46+ Generate superstep using a binary decomposition:
4547 A^k = aⱼ A^2ʲ × ... × a₂ A^2² × a₁ A² × a₀ A
4648 where k = aⱼ·2ʲ + ... + a₂·2² + a₁·2¹ + a₀·2⁰
47- '''
49+ """
4850 # New fields, for vector formulation both current and previous timestep are needed
4951 name = field .name
50- grid = field .grid
5152 # time_order of `field` needs to be 2
52- u = TimeFunction (name = f'{ name } _ss' , grid = grid , time_order = 1 , space_order = 2 * k )
53- u_prev = TimeFunction (name = f'{ name } _ss_p' , grid = grid , time_order = 1 , space_order = 2 * k )
53+ u = field . _rebuild (name = f'{ name } _ss' , time_order = 1 , space_order = 2 * k )
54+ u_prev = field . _rebuild (name = f'{ name } _ss' , time_order = 1 , space_order = 2 * k )
5455
55- superstep_solution_transfer (field , u , u_prev , tn )
56+ superstep_solution_transfer (field , u , u_prev , nt )
5657
5758 # Substitute new fields into stencil
5859 ss_stencil = stencil .subs ({field : u , field .backward : u_prev }, postprocess = False )
5960 ss_stencil = ss_stencil .expand ().expand (add = True , nest = True )
6061
61- # Binary decomposition algorithm
62+ # Binary decomposition algorithm (see docstring):
63+ # Calculate the binary decomposition of the exponent (k) and accumulate the
64+ # resultant operator
6265 current = (ss_stencil , u )
6366 q , r = divmod (k , 2 )
6467 accumulate = current if r else (1 , 1 )
@@ -71,23 +74,26 @@ def superstep_generator(field, stencil, k, tn=0):
7174 return u , u_prev , Eq (u .forward , accumulate [0 ]), Eq (u_prev .forward , accumulate [1 ])
7275
7376
74- def superstep_solution_transfer (old , new , new_p , tn ):
75- ''' Transfer state from a previous TimeFunction to a 2 field superstep
77+ def superstep_solution_transfer (old , new , new_p , nt ):
78+ """
79+ Transfer state from a previous TimeFunction to a 2 field superstep
7680 Used after injecting source using standard timestepping.
77- '''
78- # 3 should be replaced with `old.time_order + 1` although this needs some thought
79- idx = tn % 3 if old . save is None else - 1
80- new . data [ 0 , :] = old .data [ idx - 1 ]
81- new . data [ 1 , :] = old .data [ idx ]
82- new_p .data [0 , :] = old .data [idx - 2 ]
83- new_p .data [1 , :] = old .data [idx - 1 ]
81+ """
82+ # This method is completely generic for future development, but currently
83+ # only time_order == 2 is implemented!
84+ idx = nt % ( old . time_order + 1 ) if old .save is None else - 1
85+ for ii in range ( old .time_order + 1 ):
86+ new .data [ii , :] = old .data [idx - ii - 1 ]
87+ new_p .data [ii , :] = old .data [idx - ii - 2 ]
8488
8589
8690def _combine_superstep (stencil_a , stencil_b , u , u_prev , k ):
87- ''' Combine two arbitrary order supersteps
88- '''
91+ """
92+ Combine two arbitrary order supersteps
93+ """
8994 # Placeholder fields for forming the superstep
9095 grid = u .grid
96+ # Can I use a TempFunction here?
9197 a_tmp = Function (name = "a_tmp" , grid = grid , space_order = 2 * k )
9298 b_tmp = Function (name = "b_tmp" , grid = grid , space_order = 2 * k )
9399
0 commit comments