From bf6854f2f47a6b39eac67c7771a2f5917868d407 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 10 May 2016 15:47:20 +0100 Subject: [PATCH 1/6] matrices QE, QI and Q provided by new function get_sweeper_mats in imex_1st_order sweper class --- pySDC/sweeper_classes/imex_1st_order.py | 7 ++++++- tests/test_imexsweeper.py | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pySDC/sweeper_classes/imex_1st_order.py b/pySDC/sweeper_classes/imex_1st_order.py index 70abaa320c..dcb0726a48 100644 --- a/pySDC/sweeper_classes/imex_1st_order.py +++ b/pySDC/sweeper_classes/imex_1st_order.py @@ -129,7 +129,6 @@ def update_nodes(self): return None - def compute_end_point(self): """ Compute u at the right point of the interval @@ -155,3 +154,9 @@ def compute_end_point(self): L.uend += L.tau[-1] return None + + def get_sweeper_mats(self): + QE = self.QE[1:,1:] + QI = self.QI[1:,1:] + Q = self.coll.Qmat[1:,1:] + return QE, QI, Q diff --git a/tests/test_imexsweeper.py b/tests/test_imexsweeper.py index 5564ea5fed..d3c7dc7039 100644 --- a/tests/test_imexsweeper.py +++ b/tests/test_imexsweeper.py @@ -33,9 +33,7 @@ def setupLevelStepProblem(self): return step, level, problem, nnodes def setupQMatrices(self, level): - QE = level.sweep.QE[1:,1:] - QI = level.sweep.QI[1:,1:] - Q = level.sweep.coll.Qmat[1:,1:] + QE, QI, Q = level.sweep.get_sweeper_mats() return QE, QI, Q def setupSweeperMatrices(self, step, level, problem): From 8306fc03e30df0014854e0b3b1d035bcf43b5758 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 10 May 2016 15:59:37 +0100 Subject: [PATCH 2/6] QE, QI and Q which are unrelated to the problem are returned by get_sweeper_mats; the matrices LHS and RHS which do include lambda as parameter are provided by get_scalar_problems_sweeper_mats --- pySDC/sweeper_classes/imex_1st_order.py | 12 ++++++++++++ tests/test_imexsweeper.py | 9 +++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pySDC/sweeper_classes/imex_1st_order.py b/pySDC/sweeper_classes/imex_1st_order.py index dcb0726a48..0f4bdd7441 100644 --- a/pySDC/sweeper_classes/imex_1st_order.py +++ b/pySDC/sweeper_classes/imex_1st_order.py @@ -160,3 +160,15 @@ def get_sweeper_mats(self): QI = self.QI[1:,1:] Q = self.coll.Qmat[1:,1:] return QE, QI, Q + + def get_scalar_problems_sweeper_mats(self, lambdas=[None, None]): + QE, QI, Q = self.get_sweeper_mats() + if lambdas==[None,None]: + pass + # should use lambdas from attached problem and make sure it is a scalar IMEX + raise NotImplementedError("At the moment, the values for lambda have to be provided") + else: + lambda_fast = lambdas[0] + lambda_slow = lambdas[1] + assert abs(lambda_slow)<=abs(lambda_fast), "First entry in parameter lambdas (lambda_fast) has to be greater than second entry (lambda_slow)" + return QE, QI, Q diff --git a/tests/test_imexsweeper.py b/tests/test_imexsweeper.py index d3c7dc7039..2786901715 100644 --- a/tests/test_imexsweeper.py +++ b/tests/test_imexsweeper.py @@ -32,14 +32,10 @@ def setupLevelStepProblem(self): problem = level.prob return step, level, problem, nnodes - def setupQMatrices(self, level): - QE, QI, Q = level.sweep.get_sweeper_mats() - return QE, QI, Q - def setupSweeperMatrices(self, step, level, problem): nnodes = step.levels[0].sweep.coll.num_nodes # Build SDC sweep matrix - QE, QI, Q = self.setupQMatrices(level) + QE, QI, Q = level.sweep.get_sweeper_mats() dt = step.status.dt LHS = np.eye(nnodes) - step.status.dt*( problem.lambda_f[0]*QI + problem.lambda_s[0]*QE ) RHS = step.status.dt*( (problem.lambda_f[0]+problem.lambda_s[0])*Q - (problem.lambda_f[0]*QI + problem.lambda_s[0]*QE) ) @@ -149,11 +145,12 @@ def test_updateformula(self): def test_collocationinvariant(self): for type in classes: self.swparams['collocation_class'] = getattr(pySDC.CollocationClasses, type) + step, level, problem, nnodes = self.setupLevelStepProblem() level.sweep.predict() u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) - QE, QI, Q = self.setupQMatrices(level) + QE, QI, Q = level.sweep.get_sweeper_mats() # Build collocation matrix Mcoll = np.eye(nnodes) - step.status.dt*Q*(problem.lambda_s[0] + problem.lambda_f[0]) From 1d51a577b23bc427578a94b41be724779cd3bec8 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 10 May 2016 16:09:36 +0100 Subject: [PATCH 3/6] matrices LHS and RHS in test_imexsweeper are now created by a function of the imex_sweeper class --- pySDC/sweeper_classes/imex_1st_order.py | 14 +++++++++++++- tests/test_imexsweeper.py | 18 ++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/pySDC/sweeper_classes/imex_1st_order.py b/pySDC/sweeper_classes/imex_1st_order.py index 0f4bdd7441..fada21295c 100644 --- a/pySDC/sweeper_classes/imex_1st_order.py +++ b/pySDC/sweeper_classes/imex_1st_order.py @@ -156,12 +156,20 @@ def compute_end_point(self): return None def get_sweeper_mats(self): + """ + Returns the three matrices Q, QI, QE which define the sweeper. The first row and column, corresponding to the left starting value, are removed to correspond to the notation + introduced in Ruprecht & Speck, ``Spectral deferred corrections with fast-wave slow-wave splitting'', 2016 + """ QE = self.QE[1:,1:] QI = self.QI[1:,1:] Q = self.coll.Qmat[1:,1:] return QE, QI, Q def get_scalar_problems_sweeper_mats(self, lambdas=[None, None]): + """ + For a scalar problem, an IMEX-SDC sweep can be written in matrix formulation. This function returns the corresponding matrices. + See Ruprecht & Speck, ``Spectral deferred corrections with fast-wave slow-wave splitting'', 2016 for the derivation. + """ QE, QI, Q = self.get_sweeper_mats() if lambdas==[None,None]: pass @@ -171,4 +179,8 @@ def get_scalar_problems_sweeper_mats(self, lambdas=[None, None]): lambda_fast = lambdas[0] lambda_slow = lambdas[1] assert abs(lambda_slow)<=abs(lambda_fast), "First entry in parameter lambdas (lambda_fast) has to be greater than second entry (lambda_slow)" - return QE, QI, Q + nnodes = self.coll.num_nodes + dt = self.level.dt + LHS = np.eye(nnodes) - dt*( lambda_fast*QI + lambda_slow*QE ) + RHS = dt*( (lambda_fast+lambda_slow)*Q - (lambda_fast*QI + lambda_slow*QE) ) + return LHS, RHS diff --git a/tests/test_imexsweeper.py b/tests/test_imexsweeper.py index 2786901715..f04a9ae389 100644 --- a/tests/test_imexsweeper.py +++ b/tests/test_imexsweeper.py @@ -32,13 +32,9 @@ def setupLevelStepProblem(self): problem = level.prob return step, level, problem, nnodes - def setupSweeperMatrices(self, step, level, problem): - nnodes = step.levels[0].sweep.coll.num_nodes - # Build SDC sweep matrix - QE, QI, Q = level.sweep.get_sweeper_mats() - dt = step.status.dt - LHS = np.eye(nnodes) - step.status.dt*( problem.lambda_f[0]*QI + problem.lambda_s[0]*QE ) - RHS = step.status.dt*( (problem.lambda_f[0]+problem.lambda_s[0])*Q - (problem.lambda_f[0]*QI + problem.lambda_s[0]*QE) ) + def setupSweeperMatrices(self, level, problem): + lambdas = [ problem.lambda_f[0] , problem.lambda_s[0] ] + LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) return LHS, RHS # @@ -112,7 +108,7 @@ def test_sweepequalmatrix(self): # Perform node-to-node SDC sweep level.sweep.update_nodes() - LHS, RHS = self.setupSweeperMatrices(step, level, problem) + LHS, RHS = self.setupSweeperMatrices(level, problem) unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(u0full) ) usweep = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -193,7 +189,7 @@ def test_manysweepsequalmatrix(self): level.sweep.update_nodes() usweep = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) - LHS, RHS = self.setupSweeperMatrices(step, level, problem) + LHS, RHS = self.setupSweeperMatrices(level, problem) unew = u0full for i in range(0,K): unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(unew) ) @@ -207,6 +203,7 @@ def test_manysweepsequalmatrix(self): Mat_sweep = Mat_sweep + np.linalg.matrix_power(Pinv.dot(RHS),i).dot(Pinv) usweep_onematrix = Mat_sweep.dot(u0full) 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" + # # 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 @@ -226,7 +223,7 @@ def test_manysweepupdate(self): level.sweep.compute_end_point() uend_sweep = level.uend.values - LHS, RHS = self.setupSweeperMatrices(step, level, problem) + LHS, RHS = self.setupSweeperMatrices(level, problem) # Build single matrix representing K sweeps Pinv = np.linalg.inv(LHS) Mat_sweep = np.linalg.matrix_power(Pinv.dot(RHS), K) @@ -238,6 +235,7 @@ def test_manysweepupdate(self): uend_matrix = update*self.pparams['u0'] 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" + # # Make sure that creating a sweeper object with a collocation object with right_is_node=False and do_coll_update=False throws an exception # From 9a4a9ee667be5b2772fde5ac083c8844601921f3 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 10 May 2016 16:12:55 +0100 Subject: [PATCH 4/6] removed function in test_imexsweeper that build LHS and RHS matrices - now all taken care of inside imex_sweeper --- tests/test_imexsweeper.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/test_imexsweeper.py b/tests/test_imexsweeper.py index f04a9ae389..4c3f3e7e5e 100644 --- a/tests/test_imexsweeper.py +++ b/tests/test_imexsweeper.py @@ -32,11 +32,6 @@ def setupLevelStepProblem(self): problem = level.prob return step, level, problem, nnodes - def setupSweeperMatrices(self, level, problem): - lambdas = [ problem.lambda_f[0] , problem.lambda_s[0] ] - LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) - return LHS, RHS - # # General setUp function used by all tests # @@ -108,7 +103,8 @@ def test_sweepequalmatrix(self): # Perform node-to-node SDC sweep level.sweep.update_nodes() - LHS, RHS = self.setupSweeperMatrices(level, problem) + lambdas = [ problem.lambda_f[0] , problem.lambda_s[0] ] + LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(u0full) ) usweep = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -141,7 +137,6 @@ def test_updateformula(self): def test_collocationinvariant(self): for type in classes: self.swparams['collocation_class'] = getattr(pySDC.CollocationClasses, type) - step, level, problem, nnodes = self.setupLevelStepProblem() level.sweep.predict() u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -163,9 +158,9 @@ def test_collocationinvariant(self): # Perform node-to-node SDC sweep level.sweep.update_nodes() - # Build matrices for matrix formulation of sweep - LHS = np.eye(nnodes) - step.status.dt*( problem.lambda_f[0]*QI + problem.lambda_s[0]*QE ) - RHS = step.status.dt*( (problem.lambda_f[0]+problem.lambda_s[0])*Q - (problem.lambda_f[0]*QI + problem.lambda_s[0]*QE) ) + lambdas = [ problem.lambda_f[0] , problem.lambda_s[0] ] + LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) + # Make sure both matrix and node-to-node sweep leave collocation unaltered unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(ucoll) ) assert np.linalg.norm( unew - ucoll, np.infty )<1e-14, "Collocation solution not invariant under matrix SDC sweep" @@ -189,7 +184,9 @@ def test_manysweepsequalmatrix(self): level.sweep.update_nodes() usweep = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) - LHS, RHS = self.setupSweeperMatrices(level, problem) + lambdas = [ problem.lambda_f[0] , problem.lambda_s[0] ] + LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) + unew = u0full for i in range(0,K): unew = np.linalg.inv(LHS).dot( u0full + RHS.dot(unew) ) @@ -223,7 +220,9 @@ def test_manysweepupdate(self): level.sweep.compute_end_point() uend_sweep = level.uend.values - LHS, RHS = self.setupSweeperMatrices(level, problem) + lambdas = [ problem.lambda_f[0] , problem.lambda_s[0] ] + LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) + # Build single matrix representing K sweeps Pinv = np.linalg.inv(LHS) Mat_sweep = np.linalg.matrix_power(Pinv.dot(RHS), K) From 1c320ba7b8c72e3e86145dd9cab4afe992fc4312 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 10 May 2016 16:32:35 +0100 Subject: [PATCH 5/6] adds function get_scalar_problems_manysweep_mat to imex_sweeper which generates a matrix representing K many sweeps of IMEX-SDC; modified test_imexsweeper to test that this formulation is equivalent to K sweeps using update_nodes --- examples/fwsw/plot_stability.py | 22 ++++++---------------- pySDC/sweeper_classes/imex_1st_order.py | 14 +++++++++++++- tests/test_imexsweeper.py | 15 +++++---------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/examples/fwsw/plot_stability.py b/examples/fwsw/plot_stability.py index 3b8e4bf63d..363732d4a2 100644 --- a/examples/fwsw/plot_stability.py +++ b/examples/fwsw/plot_stability.py @@ -18,8 +18,8 @@ N_s = 100 N_f = 400 - lam_s_max = 12.0 - lam_f_max = 24.0 + lam_s_max = 3.0 + lam_f_max = 12.0 lambda_s = 1j*np.linspace(0.0, lam_s_max, N_s) lambda_f = 1j*np.linspace(0.0, lam_f_max, N_f) @@ -31,7 +31,7 @@ swparams = {} swparams['collocation_class'] = collclass.CollGaussLegendre swparams['num_nodes'] = 3 - K = 0 + K = 3 do_coll_update = True # @@ -47,10 +47,6 @@ nnodes = step.levels[0].sweep.coll.num_nodes level = step.levels[0] problem = level.prob - - QE = level.sweep.QE[1:,1:] - QI = level.sweep.QI[1:,1:] - Q = level.sweep.coll.Qmat[1:,1:] stab = np.zeros((N_f, N_s), dtype='complex') @@ -59,15 +55,9 @@ lambda_fast = lambda_f[j] lambda_slow = lambda_s[i] if K is not 0: - - LHS = np.eye(nnodes) - step.status.dt*( lambda_fast*QI + lambda_slow*QE ) - RHS = step.status.dt*( (lambda_fast+lambda_slow)*Q - (lambda_fast*QI + lambda_slow*QE) ) - - Pinv = np.linalg.inv(LHS) - Mat_sweep = np.linalg.matrix_power(Pinv.dot(RHS), K) - for k in range(0,K): - Mat_sweep = Mat_sweep + np.linalg.matrix_power(Pinv.dot(RHS),k).dot(Pinv) - + lambdas = [ lambda_fast, lambda_slow ] + LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) + Mat_sweep = level.sweep.get_scalar_problems_manysweep_mat( nsweeps = K, lambdas = lambdas ) else: # Compute stability function of collocation solution Mat_sweep = np.linalg.inv(np.eye(nnodes)-step.status.dt*(lambda_fast + lambda_slow)*Q) diff --git a/pySDC/sweeper_classes/imex_1st_order.py b/pySDC/sweeper_classes/imex_1st_order.py index fada21295c..e6293d68a2 100644 --- a/pySDC/sweeper_classes/imex_1st_order.py +++ b/pySDC/sweeper_classes/imex_1st_order.py @@ -169,6 +169,8 @@ def get_scalar_problems_sweeper_mats(self, lambdas=[None, None]): """ For a scalar problem, an IMEX-SDC sweep can be written in matrix formulation. This function returns the corresponding matrices. See Ruprecht & Speck, ``Spectral deferred corrections with fast-wave slow-wave splitting'', 2016 for the derivation. + + The first entry in lambdas is lambda_fast, the second is lambda_slow. """ QE, QI, Q = self.get_sweeper_mats() if lambdas==[None,None]: @@ -178,9 +180,19 @@ def get_scalar_problems_sweeper_mats(self, lambdas=[None, None]): else: lambda_fast = lambdas[0] lambda_slow = lambdas[1] - assert abs(lambda_slow)<=abs(lambda_fast), "First entry in parameter lambdas (lambda_fast) has to be greater than second entry (lambda_slow)" nnodes = self.coll.num_nodes dt = self.level.dt LHS = np.eye(nnodes) - dt*( lambda_fast*QI + lambda_slow*QE ) RHS = dt*( (lambda_fast+lambda_slow)*Q - (lambda_fast*QI + lambda_slow*QE) ) return LHS, RHS + + def get_scalar_problems_manysweep_mat(self, nsweeps, lambdas=[None,None]): + """ + For a scalar problem, K sweeps of IMEX-SDC can be written in matrix form. + """ + LHS, RHS = self.get_scalar_problems_sweeper_mats(lambdas = lambdas) + Pinv = np.linalg.inv(LHS) + Mat_sweep = np.linalg.matrix_power(Pinv.dot(RHS), nsweeps) + for k in range(0,nsweeps): + Mat_sweep += np.linalg.matrix_power(Pinv.dot(RHS), k).dot(Pinv) + return Mat_sweep diff --git a/tests/test_imexsweeper.py b/tests/test_imexsweeper.py index 4c3f3e7e5e..4ba8e235cd 100644 --- a/tests/test_imexsweeper.py +++ b/tests/test_imexsweeper.py @@ -116,6 +116,7 @@ def test_sweepequalmatrix(self): def test_updateformula(self): for type in classes: self.swparams['collocation_class'] = getattr(pySDC.CollocationClasses, type) + step, level, problem, nnodes = self.setupLevelStepProblem() level.sweep.predict() u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -123,7 +124,6 @@ def test_updateformula(self): # Perform update step in sweeper level.sweep.update_nodes() ustages = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) - # Compute end value through provided function level.sweep.compute_end_point() uend_sweep = level.uend.values @@ -131,6 +131,7 @@ def test_updateformula(self): uend_mat = self.pparams['u0'] + step.status.dt*level.sweep.coll.weights.dot(ustages*(problem.lambda_s[0] + problem.lambda_f[0])) assert np.linalg.norm(uend_sweep - uend_mat, np.infty)<1e-14, "Update formula in sweeper gives different result than matrix update formula" + # # Compute the exact collocation solution by matrix inversion and make sure it is a fixed point # @@ -193,11 +194,7 @@ def test_manysweepsequalmatrix(self): 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" - # Build single matrix representing K sweeps - Pinv = np.linalg.inv(LHS) - Mat_sweep = np.linalg.matrix_power(Pinv.dot(RHS), K) - for i in range(0,K): - Mat_sweep = Mat_sweep + np.linalg.matrix_power(Pinv.dot(RHS),i).dot(Pinv) + Mat_sweep = level.sweep.get_scalar_problems_manysweep_mat( nsweeps = K, lambdas = lambdas ) usweep_onematrix = Mat_sweep.dot(u0full) 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" @@ -208,6 +205,7 @@ def test_manysweepsequalmatrix(self): def test_manysweepupdate(self): for type in classes: self.swparams['collocation_class'] = getattr(pySDC.CollocationClasses, type) + step, level, problem, nnodes = self.setupLevelStepProblem() step.levels[0].sweep.predict() u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -224,10 +222,7 @@ def test_manysweepupdate(self): LHS, RHS = level.sweep.get_scalar_problems_sweeper_mats( lambdas = lambdas ) # Build single matrix representing K sweeps - Pinv = np.linalg.inv(LHS) - Mat_sweep = np.linalg.matrix_power(Pinv.dot(RHS), K) - for i in range(0,K): - Mat_sweep = Mat_sweep + np.linalg.matrix_power(Pinv.dot(RHS),i).dot(Pinv) + Mat_sweep = level.sweep.get_scalar_problems_manysweep_mat( nsweeps = K, lambdas = lambdas ) # Now build update function update = 1.0 + (problem.lambda_s[0] + problem.lambda_f[0])*level.sweep.coll.weights.dot(Mat_sweep.dot(np.ones(nnodes))) # Multiply u0 by value of update function to get end value directly From 833ad5a90ad70fd3783f1a8df38de9c89b7a0564 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 10 May 2016 15:39:20 +0100 Subject: [PATCH 6/6] test_collocation and test_imexsweeper now performs tests for four types of quadrature nodes: Legendre, Lobatto, Radau_Right and Radau_Left --- tests/test_imexsweeper.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test_imexsweeper.py b/tests/test_imexsweeper.py index 4ba8e235cd..d52a869bad 100644 --- a/tests/test_imexsweeper.py +++ b/tests/test_imexsweeper.py @@ -116,7 +116,6 @@ def test_sweepequalmatrix(self): def test_updateformula(self): for type in classes: self.swparams['collocation_class'] = getattr(pySDC.CollocationClasses, type) - step, level, problem, nnodes = self.setupLevelStepProblem() level.sweep.predict() u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -197,7 +196,6 @@ def test_manysweepsequalmatrix(self): Mat_sweep = level.sweep.get_scalar_problems_manysweep_mat( nsweeps = K, lambdas = lambdas ) usweep_onematrix = Mat_sweep.dot(u0full) 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" - # # 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 @@ -205,7 +203,6 @@ def test_manysweepsequalmatrix(self): def test_manysweepupdate(self): for type in classes: self.swparams['collocation_class'] = getattr(pySDC.CollocationClasses, type) - step, level, problem, nnodes = self.setupLevelStepProblem() step.levels[0].sweep.predict() u0full = np.array([ level.u[l].values.flatten() for l in range(1,nnodes+1) ]) @@ -229,7 +226,6 @@ def test_manysweepupdate(self): uend_matrix = update*self.pparams['u0'] 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" - # # Make sure that creating a sweeper object with a collocation object with right_is_node=False and do_coll_update=False throws an exception #