@@ -173,6 +173,63 @@ def test_collocationinvariant(self):
173173 unew_sweep = np .array ([ level .u [l ].values .flatten () for l in range (1 ,nnodes + 1 ) ])
174174 assert np .linalg .norm ( unew_sweep - ucoll , np .infty )< 1e-14 , "Collocation solution not invariant under node-to-node sweep"
175175
176+
177+ #
178+ # Make sure that K node-to-node sweeps give the same result as K sweeps in matrix form and the single matrix formulation for K sweeps
179+ #
180+ def test_manysweepsequalmatrix (self ):
181+ step , level , problem , nnodes = self .setupLevelStepProblem ()
182+ step .levels [0 ].sweep .predict ()
183+ u0full = np .array ([ level .u [l ].values .flatten () for l in range (1 ,nnodes + 1 ) ])
184+
185+ # Perform K node-to-node SDC sweep
186+ K = 1 + np .random .randint (6 )
187+ for i in range (0 ,K ):
188+ level .sweep .update_nodes ()
189+ usweep = np .array ([ level .u [l ].values .flatten () for l in range (1 ,nnodes + 1 ) ])
190+
191+ LHS , RHS = self .setupSweeperMatrices (step , level , problem )
192+ unew = u0full
193+ for i in range (0 ,K ):
194+ unew = np .linalg .inv (LHS ).dot ( u0full + RHS .dot (unew ) )
195+
196+ assert np .linalg .norm (unew - usweep , np .infty )< 1e-14 , "Doing multiple node-to-node sweeps yields different result than same number of matrix-form sweeps"
197+
198+ # Build single matrix representing K sweeps
199+ Pinv = np .linalg .inv (LHS )
200+ Mat_sweep = np .linalg .matrix_power (Pinv .dot (RHS ), K )
201+ for i in range (0 ,K ):
202+ Mat_sweep = Mat_sweep + np .linalg .matrix_power (Pinv .dot (RHS ),i ).dot (Pinv )
203+ usweep_onematrix = Mat_sweep .dot (u0full )
204+ assert np .linalg .norm ( usweep_onematrix - usweep , np .infty )< 1e-14 , "Single-matrix multiple sweep formulation yields different result than multiple sweeps in node-to-node or matrix form form"
205+
206+ #
207+ # Make sure that update function for K sweeps computed from K-sweep matrix gives same result as K sweeps in node-to-node form plus compute_end_point
208+ #
209+ @unittest .skip ("Needs fix of isse #52 before passing" )
210+ def test_maysweepupdate (self ):
211+ step , level , problem , nnodes = self .setupLevelStepProblem ()
212+ step .levels [0 ].sweep .predict ()
213+ u0full = np .array ([ level .u [l ].values .flatten () for l in range (1 ,nnodes + 1 ) ])
214+
215+ # Perform K node-to-node SDC sweep
216+ K = 1 + np .random .randint (4 )
217+ for i in range (0 ,K ):
218+ level .sweep .update_nodes ()
219+ # Fetch final value
220+ level .sweep .compute_end_point ()
221+ uend_sweep = level .uend .values
222+
223+ LHS , RHS = self .setupSweeperMatrices (step , level , problem )
224+ # Build single matrix representing K sweeps
225+ Pinv = np .linalg .inv (LHS )
226+ Mat_sweep = np .linalg .matrix_power (Pinv .dot (RHS ), K )
227+ for i in range (0 ,K ):
228+ Mat_sweep = Mat_sweep + np .linalg .matrix_power (Pinv .dot (RHS ),i ).dot (Pinv )
229+ # Now build update function
230+ update = 1.0 + (problem .lambda_s [0 ] + problem .lambda_f [0 ])* level .sweep .coll .weights .dot (Mat_sweep .dot (np .ones (nnodes )))
231+ uend_matrix = update * self .pparams ['u0' ]
232+ assert abs (uend_matrix - uend_sweep )< 1e-14 , "Node-to-node sweep plus update yields different result than update function computed through K-sweep matrix"
176233 #
177234 #
178235 #
0 commit comments